From c8711aa012d416940309afb7cbf21cf5da54738f Mon Sep 17 00:00:00 2001 From: Leonie Theobald Date: Tue, 30 Jul 2024 16:35:44 +0200 Subject: [PATCH] Fixed wrong key usage for finish message when using early data --- .../core/layer/context/TlsContext.java | 18 ++++++ .../handler/EndOfEarlyDataHandler.java | 59 ++++++++++++------- .../protocol/handler/FinishedHandler.java | 26 ++++++-- .../protocol/handler/ServerHelloHandler.java | 20 +++++++ 4 files changed, 97 insertions(+), 26 deletions(-) diff --git a/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/layer/context/TlsContext.java b/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/layer/context/TlsContext.java index 399d48eb1f..5d7d779d8b 100644 --- a/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/layer/context/TlsContext.java +++ b/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/layer/context/TlsContext.java @@ -31,6 +31,7 @@ import de.rub.nds.tlsattacker.core.protocol.message.extension.trustedauthority.TrustedAuthority; import de.rub.nds.tlsattacker.core.record.Record; import de.rub.nds.tlsattacker.core.record.cipher.RecordNullCipher; +import de.rub.nds.tlsattacker.core.record.cipher.cryptohelper.KeySet; import de.rub.nds.tlsattacker.core.state.Context; import de.rub.nds.tlsattacker.core.state.Keylogfile; import de.rub.nds.tlsattacker.core.state.session.IdSession; @@ -71,6 +72,9 @@ public class TlsContext extends LayerContext { /** Early traffic secret used to encrypt early data. */ private byte[] clientEarlyTrafficSecret; + /** Handshake traffic secret in case it needs to be precalculated during early data * */ + private KeySet keySetHandshake; + /** CipherSuite used for early data. */ private CipherSuite earlyDataCipherSuite; @@ -1747,6 +1751,20 @@ public void setUseExtendedMasterSecret(boolean useExtendedMasterSecret) { this.useExtendedMasterSecret = useExtendedMasterSecret; } + /** + * @return the keySetHandshake + */ + public KeySet getkeySetHandshake() { + return keySetHandshake; + } + + /** + * @param keySetHandshake the keySetHandshake to set + */ + public void setkeySetHandshake(KeySet keySetHandshake) { + this.keySetHandshake = keySetHandshake; + } + /** * @return the clientEarlyTrafficSecret */ diff --git a/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/EndOfEarlyDataHandler.java b/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/EndOfEarlyDataHandler.java index b546ef6115..943793e5d9 100644 --- a/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/EndOfEarlyDataHandler.java +++ b/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/EndOfEarlyDataHandler.java @@ -9,16 +9,11 @@ package de.rub.nds.tlsattacker.core.protocol.handler; import de.rub.nds.tlsattacker.core.constants.Tls13KeySetType; -import de.rub.nds.tlsattacker.core.exceptions.CryptoException; -import de.rub.nds.tlsattacker.core.exceptions.WorkflowExecutionException; import de.rub.nds.tlsattacker.core.layer.context.TlsContext; import de.rub.nds.tlsattacker.core.protocol.message.EndOfEarlyDataMessage; -import de.rub.nds.tlsattacker.core.record.cipher.RecordCipher; import de.rub.nds.tlsattacker.core.record.cipher.RecordCipherFactory; import de.rub.nds.tlsattacker.core.record.cipher.cryptohelper.KeySet; -import de.rub.nds.tlsattacker.core.record.cipher.cryptohelper.KeySetGenerator; import de.rub.nds.tlsattacker.transport.ConnectionEndType; -import java.security.NoSuchAlgorithmException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -32,26 +27,48 @@ public EndOfEarlyDataHandler(TlsContext tlsContext) { @Override public void adjustContext(EndOfEarlyDataMessage message) { + // nothing to adjust + } + + @Override + public void adjustContextAfterSerialize(EndOfEarlyDataMessage message) { + if (tlsContext.getChooser().getSelectedProtocolVersion().isTLS13()) { + setClientRecordCipher(); + setServertRecordCipher(); + } + } + + private void setClientRecordCipher() { + tlsContext.setActiveClientKeySetType(Tls13KeySetType.HANDSHAKE_TRAFFIC_SECRETS); + KeySet keySet = tlsContext.getkeySetHandshake(); + if (tlsContext.getChooser().getConnectionEndType() == ConnectionEndType.SERVER) { - adjustClientCipherAfterEarly(); + tlsContext + .getRecordLayer() + .updateDecryptionCipher( + RecordCipherFactory.getRecordCipher(tlsContext, keySet, false)); + } else { + tlsContext + .getRecordLayer() + .updateEncryptionCipher( + RecordCipherFactory.getRecordCipher(tlsContext, keySet, true)); } } - private void adjustClientCipherAfterEarly() { - try { - tlsContext.setActiveClientKeySetType(Tls13KeySetType.HANDSHAKE_TRAFFIC_SECRETS); - LOGGER.debug("Setting cipher for client to use handshake secrets"); - KeySet clientKeySet = - KeySetGenerator.generateKeySet( - tlsContext, - tlsContext.getChooser().getSelectedProtocolVersion(), - tlsContext.getActiveClientKeySetType()); - RecordCipher recordCipherClient = - RecordCipherFactory.getRecordCipher(tlsContext, clientKeySet, false); - tlsContext.getRecordLayer().updateDecryptionCipher(recordCipherClient); - } catch (CryptoException | NoSuchAlgorithmException ex) { - LOGGER.error("Generating KeySet failed", ex); - throw new WorkflowExecutionException(ex); + private void setServertRecordCipher() { + tlsContext.setActiveClientKeySetType(Tls13KeySetType.HANDSHAKE_TRAFFIC_SECRETS); + KeySet keySet = tlsContext.getkeySetHandshake(); + + if (tlsContext.getChooser().getConnectionEndType() == ConnectionEndType.SERVER) { + tlsContext + .getRecordLayer() + .updateDecryptionCipher( + RecordCipherFactory.getRecordCipher(tlsContext, keySet, true)); + } else { + tlsContext + .getRecordLayer() + .updateEncryptionCipher( + RecordCipherFactory.getRecordCipher(tlsContext, keySet, false)); } } } diff --git a/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/FinishedHandler.java b/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/FinishedHandler.java index 02599d462f..14d156a7f4 100644 --- a/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/FinishedHandler.java +++ b/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/FinishedHandler.java @@ -9,7 +9,11 @@ package de.rub.nds.tlsattacker.core.protocol.handler; import de.rub.nds.modifiablevariable.util.ArrayConverter; -import de.rub.nds.tlsattacker.core.constants.*; +import de.rub.nds.tlsattacker.core.constants.AlgorithmResolver; +import de.rub.nds.tlsattacker.core.constants.DigestAlgorithm; +import de.rub.nds.tlsattacker.core.constants.ExtensionType; +import de.rub.nds.tlsattacker.core.constants.HKDFAlgorithm; +import de.rub.nds.tlsattacker.core.constants.Tls13KeySetType; import de.rub.nds.tlsattacker.core.crypto.HKDFunction; import de.rub.nds.tlsattacker.core.exceptions.AdjustmentException; import de.rub.nds.tlsattacker.core.exceptions.CryptoException; @@ -44,6 +48,7 @@ public void adjustContext(FinishedMessage message) { if (!tlsContext.isExtensionNegotiated(ExtensionType.EARLY_DATA)) { setClientRecordCipher(Tls13KeySetType.HANDSHAKE_TRAFFIC_SECRETS); } + // in case of EARLY_DATA we stick to the EARLY_TRAFFIC_SECRETS } else { setClientRecordCipher(Tls13KeySetType.APPLICATION_TRAFFIC_SECRETS); } @@ -171,19 +176,30 @@ private void setServerRecordCipher(Tls13KeySetType keySetType) { private void setClientRecordCipher(Tls13KeySetType keySetType) { tlsContext.setActiveClientKeySetType(keySetType); - LOGGER.debug("Setting cipher for client to use " + keySetType); - KeySet clientKeySet = getKeySet(tlsContext, tlsContext.getActiveClientKeySetType()); + KeySet keySet = new KeySet(); + + switch (keySetType) { + case APPLICATION_TRAFFIC_SECRETS: + keySet = getKeySet(tlsContext, tlsContext.getActiveClientKeySetType()); + break; + case HANDSHAKE_TRAFFIC_SECRETS: + keySet = tlsContext.getkeySetHandshake(); + break; + default: + throw new Error( + "In this state only application_traffic_secrets handshake_traffic_secrets are valid."); + } if (tlsContext.getChooser().getConnectionEndType() == ConnectionEndType.SERVER) { tlsContext .getRecordLayer() .updateDecryptionCipher( - RecordCipherFactory.getRecordCipher(tlsContext, clientKeySet, false)); + RecordCipherFactory.getRecordCipher(tlsContext, keySet, false)); } else { tlsContext .getRecordLayer() .updateEncryptionCipher( - RecordCipherFactory.getRecordCipher(tlsContext, clientKeySet, true)); + RecordCipherFactory.getRecordCipher(tlsContext, keySet, true)); } } } diff --git a/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/ServerHelloHandler.java b/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/ServerHelloHandler.java index b448d935fd..510b89bfee 100644 --- a/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/ServerHelloHandler.java +++ b/TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/ServerHelloHandler.java @@ -81,6 +81,7 @@ public void adjustContext(ServerHelloMessage message) { if (tlsContext.getTalkingConnectionEndType() != tlsContext.getChooser().getConnectionEndType()) { setServerRecordCipher(); + precalculateHandshakeKeysClient(); } } adjustPRF(message); @@ -576,4 +577,23 @@ private KeyShareStoreEntry adjustKeyShareStoreEntry() { return selectedKeyShareStore; } + + private KeySet getKeySet(TlsContext tlsContext, Tls13KeySetType keySetType) { + try { + LOGGER.debug("Generating new KeySet"); + KeySet keySet = + KeySetGenerator.generateKeySet( + tlsContext, + tlsContext.getChooser().getSelectedProtocolVersion(), + keySetType); + return keySet; + } catch (NoSuchAlgorithmException | CryptoException ex) { + throw new UnsupportedOperationException("The specified Algorithm is not supported", ex); + } + } + + private void precalculateHandshakeKeysClient() { + KeySet keySet = getKeySet(tlsContext, Tls13KeySetType.HANDSHAKE_TRAFFIC_SECRETS); + tlsContext.setkeySetHandshake(keySet); + } }