tls-attacker / TLS-Attacker

TLS-Attacker is a Java-based framework for analyzing TLS libraries. It can be used to manually test TLS clients and servers or as as a software library for more advanced tools.
Apache License 2.0
778 stars 135 forks source link

Crash during wolfSSL 5.3.0 client exploration #152

Closed maxammann closed 1 year ago

maxammann commented 1 year ago

I'm getting this exception while running TLS-Attacker through TLS-Anvil on wolfSSL clients.

The following exception is caused when TLS 1.3 is enabled, which was disabled in the TLS-Anvil publication, because TLS 1.3 is opt-in in wolfSSL.

14:20:01 [pool-3-thread-1] ERROR: WorkflowExecutor.executeAction(WorkflowExecutor.java:145) - Unexpected fatal error during action execution, stopping execution:
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.base/java.util.LinkedList.checkElementIndex(LinkedList.java:559)
        at java.base/java.util.LinkedList.get(LinkedList.java:480)
        at de.rub.nds.tlsattacker.core.protocol.handler.ServerHelloHandler.adjustKeyShareStoreEntry(ServerHelloHandler.java:530)
        at de.rub.nds.tlsattacker.core.protocol.handler.ServerHelloHandler.adjustContext(ServerHelloHandler.java:79)
        at de.rub.nds.tlsattacker.core.protocol.handler.ServerHelloHandler.adjustContext(ServerHelloHandler.java:46)
        at de.rub.nds.tlsattacker.core.layer.impl.MessageLayer.processMessage(MessageLayer.java:96)
        at de.rub.nds.tlsattacker.core.layer.impl.MessageLayer.sendConfiguration(MessageLayer.java:79)
        at de.rub.nds.tlsattacker.core.layer.LayerStack.sendData(LayerStack.java:103)
        at de.rub.nds.tlsattacker.core.workflow.action.MessageAction.send(MessageAction.java:243)
        at de.rub.nds.tlsattacker.core.workflow.action.SendAction.execute(SendAction.java:95)
        at de.rub.nds.tlsattacker.core.workflow.WorkflowExecutor.executeAction(WorkflowExecutor.java:133)
        at de.rub.nds.tlsattacker.core.workflow.DefaultWorkflowExecutor.executeWorkflow(DefaultWorkflowExecutor.java:70)
        at de.rub.nds.tlsattacker.core.workflow.task.StateExecutionTask.execute(StateExecutionTask.java:27)
        at de.rub.nds.tlsattacker.core.workflow.task.TlsTask.call(TlsTask.java:69)
        at de.rub.nds.tlsattacker.core.workflow.task.TlsTask.call(TlsTask.java:20)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)

The next crash is linked to some tested cipher suite.

14:24:09 [pool-3-thread-2] ERROR: WorkflowExecutor.executeAction(WorkflowExecutor.java:145) - Unexpected fatal error during action execution, stopping execution:
java.lang.NullPointerException
        at de.rub.nds.tlsattacker.core.certificate.CertificateKeyPair.isCompatibleWithCipherSuite(CertificateKeyPair.java:609)
        at de.rub.nds.tlsattacker.core.certificate.CertificateByteChooser.rateKeyPair(CertificateByteChooser.java:226)
        at de.rub.nds.tlsattacker.core.certificate.CertificateByteChooser.chooseCertificateKeyPair(CertificateByteChooser.java:184)
        at de.rub.nds.tlsattacker.core.protocol.preparator.CertificateMessagePreparator.prepareCertificateListBytes(CertificateMessagePreparator.java:110)
        at de.rub.nds.tlsattacker.core.protocol.preparator.CertificateMessagePreparator.prepareHandshakeMessageContents(CertificateMessagePreparator.java:53)
        at de.rub.nds.tlsattacker.core.protocol.preparator.HandshakeMessagePreparator.prepareProtocolMessageContents(HandshakeMessagePreparator.java:66)
        at de.rub.nds.tlsattacker.core.protocol.ProtocolMessagePreparator.prepare(ProtocolMessagePreparator.java:28)
        at de.rub.nds.tlsattacker.core.layer.ProtocolLayer.prepareDataContainer(ProtocolLayer.java:269)
        at de.rub.nds.tlsattacker.core.layer.impl.MessageLayer.sendConfiguration(MessageLayer.java:71)
        at de.rub.nds.tlsattacker.core.layer.LayerStack.sendData(LayerStack.java:103)
        at de.rub.nds.tlsattacker.core.workflow.action.MessageAction.send(MessageAction.java:243)
        at de.rub.nds.tlsattacker.core.workflow.action.SendAction.execute(SendAction.java:95)
        at de.rub.nds.tlsattacker.core.workflow.WorkflowExecutor.executeAction(WorkflowExecutor.java:133)
        at de.rub.nds.tlsattacker.core.workflow.DefaultWorkflowExecutor.executeWorkflow(DefaultWorkflowExecutor.java:70)
        at de.rub.nds.tlsattacker.core.workflow.task.StateExecutionTask.execute(StateExecutionTask.java:27)
        at de.rub.nds.tlsattacker.core.workflow.task.TlsTask.call(TlsTask.java:69)
        at de.rub.nds.tlsattacker.core.workflow.task.TlsTask.call(TlsTask.java:20)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)

It think the line where it actually crashes is the following:

https://github.com/tls-attacker/TLS-Anvil/blob/v1.1.0/TLS-Test-Framework/TestFramework/src/main/java/de/rub/nds/tlstest/framework/execution/TestRunner.java#L371

I investigated this, and it turns out this is due to the Renegotiation Info feature enabled in wolfSSL 5.3.0 by default. When disabling it works again: https://github.com/wolfSSL/wolfssl/blob/870f7cc95b1061b0f829d15315c66b6b6823eb99/configure.ac#L5074-L5078

maxammann commented 1 year ago

I patched wolfSSL like this to get it working:

diff --git a/src/tls.c b/src/tls.c
index f2f62dc..2d808f7 100644
--- a/src/tls.c
+++ b/src/tls.c
@@ -5050,7 +5050,8 @@ int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap)
 #define SCR_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX)
 #define SCR_GET_SIZE       TLSX_SecureRenegotiation_GetSize
 #define SCR_WRITE          TLSX_SecureRenegotiation_Write
-#define SCR_PARSE          TLSX_SecureRenegotiation_Parse
+//#define SCR_PARSE          TLSX_SecureRenegotiation_Parse
+#define SCR_PARSE(a, b, c, d) 0

 #else

Not sure if wolfSSL or TLS-Anvil is at fault.

mmaehren commented 1 year ago

Hey,

thank you for these reports, they are much appreciated. Regarding the IndexOutOfBoundsException at the top, did this occur for wolfSSL in TLS 1.3-only mode? In our publication, we actually tested TLS 1.2 and 1.3 for wolfSSL and enabled both versions with the CLI version flag (-v).

maxammann commented 1 year ago

The IndexOutOfBoundsException is also thrown during OpenSSL client exploration I think. It does not let the exploration fail.

The issue comes with enabling this feature in wolfSSL: https://github.com/wolfSSL/wolfssl/blob/870f7cc95b1061b0f829d15315c66b6b6823eb99/configure.ac#L5074-L5078

Apparently TLS-Anvil is sending an invalid renegotiation information, which makes wolfSSL always return errors.

mmaehren commented 1 year ago

This issues has now been addressed with release v5.2.1 of TLS-Attacker and v1.2.0 of TLS-Anvil. Thank you again for the reports.