Skip to content

Commit 8808951

Browse files
authored
Merge pull request #729 from tls-attacker/sess_ticket_version37
2 parents eb8672c + 2bfc95f commit 8808951

File tree

13 files changed

+107
-36
lines changed

13 files changed

+107
-36
lines changed

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/constants/AlgorithmResolver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,9 @@ public static CipherAlgorithm getCipher(CipherSuite cipherSuite) {
297297
return CipherAlgorithm.GOST_28147_CNT;
298298
} else if (cipher.contains("CHACHA20_POLY1305")) {
299299
if (cipher.contains("UNOFFICIAL")) {
300-
return CipherAlgorithm.UNOFFICIAL_CHA_CHA_20_POLY1305;
300+
return CipherAlgorithm.UNOFFICIAL_CHACHA20_POLY1305;
301301
} else {
302-
return CipherAlgorithm.CHA_CHA_20_POLY1305;
302+
return CipherAlgorithm.CHACHA20_POLY1305;
303303
}
304304
}
305305
if (cipherSuite == CipherSuite.TLS_FALLBACK_SCSV

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/constants/CipherAlgorithm.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ public enum CipherAlgorithm {
3131
SEED_CBC(16, 16, 0, 16, "SEED/CBC/NoPadding"),
3232
AES_128_CCM(16, 4, 8, 16, "AES/CCM/NoPadding"),
3333
AES_256_CCM(32, 4, 8, 16, "AES/CCM/NoPadding"),
34-
CHA_CHA_20_POLY1305(32, 12, 0, 0, "ChaCha20Poly1305"),
35-
UNOFFICIAL_CHA_CHA_20_POLY1305(32, 12, 0, 0, "ChaCha20Poly1305"),
34+
CHACHA20_POLY1305(32, 12, 0, 0, "ChaCha20-Poly1305"),
35+
UNOFFICIAL_CHACHA20_POLY1305(32, 12, 0, 0, "ChaCha20-Poly1305"),
3636
DES40_CBC(8, 8, 0, 8, "DES/CBC/NoPadding"), // currently
3737
// uses
3838
// des
@@ -42,7 +42,9 @@ public enum CipherAlgorithm {
4242
ARIA_128_GCM(16, 16, 8, 16, "ARIA/GCM/NoPadding"), // not tested yet
4343
ARIA_256_GCM(16, 16, 8, 16, "ARIA/GCM/NoPadding"), // not tested yet
4444
GOST_28147_CNT(32, 8, 0, 8, "GOST28147/ECB/NoPadding"),
45-
FORTEZZA_CBC(0, 0, 0, 0); // TODO
45+
FORTEZZA_CBC(0, 0, 0, 0), // TODO
46+
AES_128_CTR(16, 16, 0, 0, "AES/CTR/NoPadding"),
47+
AES_256_CTR(32, 16, 0, 0, "AES/CTR/NoPadding");
4648

4749
CipherAlgorithm(int keySize, int nonceBytesFromHandshake, int nonceBytesFromRecord, int blocksize,
4850
String javaName) {

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/crypto/cipher/CipherWrapper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ public static EncryptionCipher getEncryptionCipher(CipherSuite cipherSuite, Conn
3030
if (cipherAlg == CipherAlgorithm.GOST_28147_CNT) {
3131
return new GOST28147Cipher(GOSTUtils.getGostSpec(cipherSuite), keySet.getWriteKey(connectionEndType),
3232
keySet.getWriteIv(connectionEndType));
33-
} else if (cipherAlg == CipherAlgorithm.CHA_CHA_20_POLY1305) {
33+
} else if (cipherAlg == CipherAlgorithm.CHACHA20_POLY1305) {
3434
return new StandardizedChaCha20Poly1305Cipher(keySet.getWriteKey(connectionEndType));
35-
} else if (cipherAlg == CipherAlgorithm.UNOFFICIAL_CHA_CHA_20_POLY1305) {
35+
} else if (cipherAlg == CipherAlgorithm.UNOFFICIAL_CHACHA20_POLY1305) {
3636
return new UnofficialChaCha20Poly1305Cipher(keySet.getWriteKey(connectionEndType));
3737
} else if (cipherAlg.getJavaName() != null) {
3838
return new JavaCipher(cipherAlg, keySet.getWriteKey(connectionEndType),
@@ -51,9 +51,9 @@ public static DecryptionCipher getDecryptionCipher(CipherSuite cipherSuite, Conn
5151
if (cipherAlg == CipherAlgorithm.GOST_28147_CNT) {
5252
return new GOST28147Cipher(GOSTUtils.getGostSpec(cipherSuite), keySet.getReadKey(connectionEndType),
5353
keySet.getReadIv(connectionEndType));
54-
} else if (cipherAlg == CipherAlgorithm.CHA_CHA_20_POLY1305) {
54+
} else if (cipherAlg == CipherAlgorithm.CHACHA20_POLY1305) {
5555
return new StandardizedChaCha20Poly1305Cipher(keySet.getReadKey(connectionEndType));
56-
} else if (cipherAlg == CipherAlgorithm.UNOFFICIAL_CHA_CHA_20_POLY1305) {
56+
} else if (cipherAlg == CipherAlgorithm.UNOFFICIAL_CHACHA20_POLY1305) {
5757
return new UnofficialChaCha20Poly1305Cipher(keySet.getReadKey(connectionEndType));
5858
} else if (cipherAlg.getJavaName() != null) {
5959
return new JavaCipher(cipherAlg, keySet.getReadKey(connectionEndType),

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/FinishedHandler.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@
1010
package de.rub.nds.tlsattacker.core.protocol.handler;
1111

1212
import de.rub.nds.modifiablevariable.util.ArrayConverter;
13-
import de.rub.nds.tlsattacker.core.constants.AlgorithmResolver;
14-
import de.rub.nds.tlsattacker.core.constants.DigestAlgorithm;
15-
import de.rub.nds.tlsattacker.core.constants.ExtensionType;
16-
import de.rub.nds.tlsattacker.core.constants.HKDFAlgorithm;
17-
import de.rub.nds.tlsattacker.core.constants.Tls13KeySetType;
13+
import de.rub.nds.tlsattacker.core.constants.*;
1814
import de.rub.nds.tlsattacker.core.crypto.HKDFunction;
1915
import de.rub.nds.tlsattacker.core.exceptions.AdjustmentException;
2016
import de.rub.nds.tlsattacker.core.exceptions.CryptoException;
17+
import de.rub.nds.tlsattacker.core.protocol.handler.factory.HandlerFactory;
2118
import de.rub.nds.tlsattacker.core.protocol.message.FinishedMessage;
19+
import de.rub.nds.tlsattacker.core.protocol.message.extension.psk.PskSet;
2220
import de.rub.nds.tlsattacker.core.protocol.parser.FinishedParser;
2321
import de.rub.nds.tlsattacker.core.protocol.preparator.FinishedPreparator;
2422
import de.rub.nds.tlsattacker.core.protocol.serializer.FinishedSerializer;
@@ -28,11 +26,12 @@
2826
import de.rub.nds.tlsattacker.core.record.cipher.cryptohelper.KeySetGenerator;
2927
import de.rub.nds.tlsattacker.core.state.TlsContext;
3028
import de.rub.nds.tlsattacker.transport.ConnectionEndType;
31-
import java.security.NoSuchAlgorithmException;
32-
import javax.crypto.Mac;
3329
import org.apache.logging.log4j.LogManager;
3430
import org.apache.logging.log4j.Logger;
3531

32+
import javax.crypto.Mac;
33+
import java.security.NoSuchAlgorithmException;
34+
3635
public class FinishedHandler extends HandshakeMessageHandler<FinishedMessage> {
3736

3837
private static final Logger LOGGER = LogManager.getLogger();
@@ -64,13 +63,25 @@ public void adjustTLSContext(FinishedMessage message) {
6463
if (tlsContext.getTalkingConnectionEndType() == ConnectionEndType.SERVER) {
6564
adjustApplicationTrafficSecrets();
6665
setServerRecordCipher(Tls13KeySetType.APPLICATION_TRAFFIC_SECRETS);
67-
6866
} else {
6967
setClientRecordCipher(Tls13KeySetType.APPLICATION_TRAFFIC_SECRETS);
7068
}
7169
} else if (tlsContext.getChooser().getConnectionEndType() == ConnectionEndType.CLIENT
7270
|| !tlsContext.isExtensionNegotiated(ExtensionType.EARLY_DATA)) {
7371
setClientRecordCipher(Tls13KeySetType.HANDSHAKE_TRAFFIC_SECRETS);
72+
73+
if (tlsContext.getTalkingConnectionEndType() == ConnectionEndType.CLIENT) {
74+
NewSessionTicketHandler ticketHandler = (NewSessionTicketHandler) HandlerFactory
75+
.getHandshakeHandler(tlsContext, HandshakeMessageType.NEW_SESSION_TICKET);
76+
if (tlsContext.getPskSets() != null) {
77+
for (PskSet pskSet : tlsContext.getPskSets()) {
78+
// if psk was derived earliers, skip derivation (especially for state reusage helpful)
79+
if (pskSet.getPreSharedKey() == null) {
80+
pskSet.setPreSharedKey(ticketHandler.derivePsk(pskSet));
81+
}
82+
}
83+
}
84+
}
7485
}
7586
}
7687
if (tlsContext.getTalkingConnectionEndType() == ConnectionEndType.CLIENT) {

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/handler/NewSessionTicketHandler.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import de.rub.nds.tlsattacker.core.constants.AlgorithmResolver;
1414
import de.rub.nds.tlsattacker.core.constants.DigestAlgorithm;
1515
import de.rub.nds.tlsattacker.core.constants.HKDFAlgorithm;
16+
import de.rub.nds.tlsattacker.core.constants.Tls13KeySetType;
1617
import de.rub.nds.tlsattacker.core.crypto.HKDFunction;
1718
import de.rub.nds.tlsattacker.core.exceptions.CryptoException;
1819
import de.rub.nds.tlsattacker.core.exceptions.WorkflowExecutionException;
@@ -80,11 +81,21 @@ private void adjustPskSets(NewSessionTicketMessage message) {
8081
if (message.getTicket().getIdentity() != null) {
8182
pskSet.setPreSharedKeyIdentity(message.getTicket().getIdentity().getValue());
8283
} else {
83-
LOGGER.warn("No Identity in ticket. Using new byte[] instead");
84+
LOGGER.warn("No Identity in ticket. Using new byte[0] instead");
8485
pskSet.setPreSharedKeyIdentity(new byte[0]);
8586
}
8687
pskSet.setTicketAge(getTicketAge());
87-
pskSet.setPreSharedKey(derivePsk(message));
88+
if (message.getTicket().getTicketNonce() != null) {
89+
pskSet.setTicketNonce(message.getTicket().getTicketNonce().getValue());
90+
} else {
91+
LOGGER.warn("No nonce in ticket. Using new byte[0] instead");
92+
pskSet.setTicketNonce(new byte[0]);
93+
}
94+
// only derive PSK if client finished was already sent, because full handshake transcript is required
95+
if (tlsContext.getActiveClientKeySetType() == Tls13KeySetType.APPLICATION_TRAFFIC_SECRETS) {
96+
pskSet.setPreSharedKey(derivePsk(pskSet));
97+
}
98+
8899
LOGGER.debug("Adding PSK Set");
89100
pskSets.add(pskSet);
90101
tlsContext.setPskSets(pskSets);
@@ -98,7 +109,7 @@ private String getTicketAge() {
98109
return ticketDate.format(dateTimeFormatter);
99110
}
100111

101-
private byte[] derivePsk(NewSessionTicketMessage message) {
112+
protected byte[] derivePsk(PskSet pskSet) {
102113
try {
103114
LOGGER.debug("Deriving PSK from current session");
104115
HKDFAlgorithm hkdfAlgorithm =
@@ -109,10 +120,14 @@ private byte[] derivePsk(NewSessionTicketMessage message) {
109120
byte[] resumptionMasterSecret =
110121
HKDFunction.deriveSecret(hkdfAlgorithm, digestAlgo.getJavaName(), tlsContext.getMasterSecret(),
111122
HKDFunction.RESUMPTION_MASTER_SECRET, tlsContext.getDigest().getRawBytes());
123+
tlsContext.setResumptionMasterSecret(resumptionMasterSecret);
112124
LOGGER.debug("Derived ResumptionMasterSecret: " + ArrayConverter.bytesToHexString(resumptionMasterSecret));
125+
LOGGER.debug("Derived Master Secret: " + ArrayConverter.bytesToHexString(tlsContext.getMasterSecret()));
126+
LOGGER.debug("Handshake Transcript Raw Bytes: "
127+
+ ArrayConverter.bytesToHexString(tlsContext.getDigest().getRawBytes()));
113128
byte[] psk = HKDFunction.expandLabel(hkdfAlgorithm, resumptionMasterSecret, HKDFunction.RESUMPTION,
114-
message.getTicket().getTicketNonce().getValue(), macLength);
115-
LOGGER.debug("Derived PSK: " + ArrayConverter.bytesToHexString(psk));
129+
pskSet.getTicketNonce(), macLength);
130+
LOGGER.debug("New derived pre-shared-key: " + ArrayConverter.bytesToHexString(psk));
116131
return psk;
117132

118133
} catch (NoSuchAlgorithmException | CryptoException ex) {

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/message/extension/psk/PskSet.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,24 @@ public class PskSet implements Serializable {
4747
@XmlJavaTypeAdapter(UnformattedByteArrayAdapter.class)
4848
private byte[] ticketAgeAdd;
4949

50+
/**
51+
* ticket nonce used to derive PSK
52+
*/
53+
@XmlJavaTypeAdapter(UnformattedByteArrayAdapter.class)
54+
private byte[] ticketNonce;
55+
5056
private CipherSuite cipherSuite;
5157

5258
public PskSet() {
5359
}
5460

5561
public PskSet(byte[] preSharedKeyIdentity, byte[] preSharedKey, String ticketAge, byte[] ticketAgeAdd,
56-
CipherSuite cipherSuite) {
62+
byte[] ticketNonce, CipherSuite cipherSuite) {
5763
this.preSharedKeyIdentity = preSharedKeyIdentity;
5864
this.preSharedKey = preSharedKey;
5965
this.ticketAge = ticketAge;
6066
this.ticketAgeAdd = ticketAgeAdd;
67+
this.ticketNonce = ticketNonce;
6168
this.cipherSuite = cipherSuite;
6269
}
6370

@@ -121,6 +128,14 @@ public void setTicketAgeAdd(byte[] ticketAgeAdd) {
121128
this.ticketAgeAdd = ticketAgeAdd;
122129
}
123130

131+
public byte[] getTicketNonce() {
132+
return ticketNonce;
133+
}
134+
135+
public void setTicketNonce(byte[] ticketNonce) {
136+
this.ticketNonce = ticketNonce;
137+
}
138+
124139
/**
125140
* @return the cipherSuite
126141
*/
@@ -143,6 +158,7 @@ public int hashCode() {
143158
hash = 43 * hash + Arrays.hashCode(this.preSharedKey);
144159
hash = 43 * hash + Objects.hashCode(this.ticketAge);
145160
hash = 43 * hash + Arrays.hashCode(this.ticketAgeAdd);
161+
hash = 43 * hash + Objects.hashCode(this.ticketNonce);
146162
hash = 43 * hash + Objects.hashCode(this.cipherSuite);
147163
return hash;
148164
}
@@ -171,6 +187,10 @@ public boolean equals(Object obj) {
171187
if (!Arrays.equals(this.ticketAgeAdd, other.ticketAgeAdd)) {
172188
return false;
173189
}
190+
if (!Arrays.equals(this.ticketNonce, other.ticketNonce)) {
191+
return false;
192+
}
174193
return this.cipherSuite == other.cipherSuite;
175194
}
195+
176196
}

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/protocol/preparator/extension/PSKIdentityPreparator.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616
import de.rub.nds.tlsattacker.core.workflow.chooser.Chooser;
1717
import java.math.BigInteger;
1818
import java.time.Duration;
19+
import java.time.Instant;
1920
import java.time.LocalDateTime;
21+
import java.time.ZoneId;
2022
import java.time.format.DateTimeFormatter;
23+
24+
import de.rub.nds.tlsattacker.util.TimeHelper;
2125
import org.apache.logging.log4j.LogManager;
2226
import org.apache.logging.log4j.Logger;
2327

@@ -52,7 +56,10 @@ private void prepareObfuscatedTicketAge() {
5256
private byte[] getObfuscatedTicketAge(byte[] ticketAgeAdd, String ticketAge) {
5357
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
5458
LocalDateTime ticketDate = LocalDateTime.parse(ticketAge, dateTimeFormatter);
55-
BigInteger difference = BigInteger.valueOf(Duration.between(ticketDate, LocalDateTime.now()).toMillis());
59+
long time = TimeHelper.getTime();
60+
LocalDateTime dateNow = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault());
61+
62+
BigInteger difference = BigInteger.valueOf(Duration.between(ticketDate, dateNow).toMillis());
5663
BigInteger addValue = BigInteger.valueOf(ArrayConverter.bytesToLong(ticketAgeAdd));
5764
BigInteger mod = BigInteger.valueOf(2).pow(32);
5865
difference = difference.add(addValue);

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/record/cipher/RecordAEADCipher.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ private byte[] prepareEncryptionGcmNonce(byte[] aeadSalt, byte[] explicitNonce,
8181
byte[] gcmNonce = ArrayConverter.concatenate(aeadSalt, explicitNonce);
8282

8383
// Nonce construction is different for chacha & tls1.3
84-
if (version.isTLS13() || cipherAlg == CipherAlgorithm.CHA_CHA_20_POLY1305) {
84+
if (version.isTLS13() || cipherAlg == CipherAlgorithm.CHACHA20_POLY1305) {
8585
gcmNonce = preprocessIv(record.getSequenceNumber().getValue().longValue(), gcmNonce);
86-
} else if (cipherAlg == CipherAlgorithm.UNOFFICIAL_CHA_CHA_20_POLY1305) {
86+
} else if (cipherAlg == CipherAlgorithm.UNOFFICIAL_CHACHA20_POLY1305) {
8787
gcmNonce = ArrayConverter.longToUint64Bytes(record.getSequenceNumber().getValue().longValue());
8888
}
8989
record.getComputations().setGcmNonce(gcmNonce);
@@ -216,9 +216,9 @@ public void decrypt(Record record) throws CryptoException {
216216
byte[] gcmNonce = ArrayConverter.concatenate(salt, explicitNonce);
217217

218218
// Nonce construction is different for chacha & tls1.3
219-
if (version.isTLS13() || cipherAlg == CipherAlgorithm.CHA_CHA_20_POLY1305) {
219+
if (version.isTLS13() || cipherAlg == CipherAlgorithm.CHACHA20_POLY1305) {
220220
gcmNonce = preprocessIv(record.getSequenceNumber().getValue().longValue(), gcmNonce);
221-
} else if (cipherAlg == CipherAlgorithm.UNOFFICIAL_CHA_CHA_20_POLY1305) {
221+
} else if (cipherAlg == CipherAlgorithm.UNOFFICIAL_CHACHA20_POLY1305) {
222222
gcmNonce = ArrayConverter.longToUint64Bytes(record.getSequenceNumber().getValue().longValue());
223223
}
224224
record.getComputations().setGcmNonce(gcmNonce);

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/state/TlsContext.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import de.rub.nds.tlsattacker.core.dtls.FragmentManager;
4343
import de.rub.nds.tlsattacker.core.exceptions.ConfigurationException;
4444
import de.rub.nds.tlsattacker.core.exceptions.TransportHandlerConnectException;
45+
import de.rub.nds.tlsattacker.core.protocol.message.NewSessionTicketMessage;
4546
import de.rub.nds.tlsattacker.core.protocol.message.ProtocolMessage;
4647
import de.rub.nds.tlsattacker.core.protocol.message.extension.cachedinfo.CachedObject;
4748
import de.rub.nds.tlsattacker.core.protocol.message.extension.keyshare.KeyShareEntry;
@@ -177,6 +178,11 @@ public class TlsContext {
177178
*/
178179
private byte[] preMasterSecret;
179180

181+
/**
182+
* Master secret established during the handshake.
183+
*/
184+
private byte[] resumptionMasterSecret;
185+
180186
/**
181187
* Client Extended Random used in Extended Random Extension
182188
*/
@@ -1377,6 +1383,10 @@ public byte[] getMasterSecret() {
13771383
return masterSecret;
13781384
}
13791385

1386+
public byte[] getResumptionMasterSecret() {
1387+
return resumptionMasterSecret;
1388+
}
1389+
13801390
public CipherSuite getSelectedCipherSuite() {
13811391
return selectedCipherSuite;
13821392
}
@@ -1390,6 +1400,10 @@ public void setMasterSecret(byte[] masterSecret) {
13901400
this.masterSecret = masterSecret;
13911401
}
13921402

1403+
public byte[] setResumptionMasterSecret(byte[] resumptionMasterSecret) {
1404+
return this.resumptionMasterSecret = resumptionMasterSecret;
1405+
}
1406+
13931407
public void setSelectedCipherSuite(CipherSuite selectedCipherSuite) {
13941408
this.selectedCipherSuite = selectedCipherSuite;
13951409
}

TLS-Core/src/main/resources/Config.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,7 @@
12171217
<xs:element name="preSharedKey" type="xs:string" minOccurs="0"/>
12181218
<xs:element name="ticketAge" type="xs:string" minOccurs="0"/>
12191219
<xs:element name="ticketAgeAdd" type="xs:string" minOccurs="0"/>
1220+
<xs:element name="ticketNonce" type="xs:string" minOccurs="0"/>
12201221
<xs:element name="cipherSuite" type="cipherSuite" minOccurs="0"/>
12211222
</xs:sequence>
12221223
</xs:complexType>

0 commit comments

Comments
 (0)