Skip to content

Commit 4a62640

Browse files
committed
Fix TLS 1.3 Export Keying Material
- see #1133
1 parent 6bdc2e9 commit 4a62640

File tree

4 files changed

+38
-1
lines changed

4 files changed

+38
-1
lines changed

tls/src/main/java/org/bouncycastle/tls/AbstractTlsContext.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import org.bouncycastle.tls.crypto.TlsCrypto;
66
import org.bouncycastle.tls.crypto.TlsCryptoUtils;
7+
import org.bouncycastle.tls.crypto.TlsHash;
78
import org.bouncycastle.tls.crypto.TlsNonceGenerator;
89
import org.bouncycastle.tls.crypto.TlsSecret;
910
import org.bouncycastle.util.Arrays;
@@ -280,7 +281,21 @@ else if (!TlsUtils.isValidUint16(context.length))
280281

281282
try
282283
{
283-
return TlsCryptoUtils.hkdfExpandLabel(secret, cryptoHashAlgorithm, asciiLabel, context, length).extract();
284+
TlsHash exporterHash = getCrypto().createHash(cryptoHashAlgorithm);
285+
byte[] emptyTranscriptHash = exporterHash.calculateHash();
286+
287+
TlsSecret exporterSecret = TlsUtils.deriveSecret(getSecurityParametersConnection(), secret, asciiLabel,
288+
emptyTranscriptHash);
289+
290+
byte[] exporterContext = emptyTranscriptHash;
291+
if (context.length > 0)
292+
{
293+
exporterHash.update(context, 0, context.length);
294+
exporterContext = exporterHash.calculateHash();
295+
}
296+
297+
return TlsCryptoUtils
298+
.hkdfExpandLabel(exporterSecret, cryptoHashAlgorithm, "exporter", exporterContext, length).extract();
284299
}
285300
catch (IOException e)
286301
{

tls/src/test/java/org/bouncycastle/tls/test/TlsTestCase.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ protected void runTest() throws Throwable
119119
assertEquals(count, data.length);
120120
assertTrue(Arrays.areEqual(data, echo));
121121

122+
assertTrue(Arrays.areEqual(clientImpl.tlsKeyingMaterial1, serverImpl.tlsKeyingMaterial1));
123+
assertTrue(Arrays.areEqual(clientImpl.tlsKeyingMaterial2, serverImpl.tlsKeyingMaterial2));
122124
assertTrue(Arrays.areEqual(clientImpl.tlsServerEndPoint, serverImpl.tlsServerEndPoint));
123125

124126
if (!TlsUtils.isTLSv13(clientImpl.negotiatedVersion))

tls/src/test/java/org/bouncycastle/tls/test/TlsTestClientImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.bouncycastle.tls.ConnectionEnd;
2222
import org.bouncycastle.tls.DefaultTlsClient;
2323
import org.bouncycastle.tls.ProtocolVersion;
24+
import org.bouncycastle.tls.SecurityParameters;
2425
import org.bouncycastle.tls.SignatureAlgorithm;
2526
import org.bouncycastle.tls.SignatureAndHashAlgorithm;
2627
import org.bouncycastle.tls.TlsAuthentication;
@@ -72,6 +73,8 @@ class TlsTestClientImpl
7273
protected short firstFatalAlertDescription = -1;
7374

7475
ProtocolVersion negotiatedVersion = null;
76+
byte[] tlsKeyingMaterial1 = null;
77+
byte[] tlsKeyingMaterial2 = null;
7578
byte[] tlsServerEndPoint = null;
7679
byte[] tlsUnique = null;
7780

@@ -170,6 +173,13 @@ public void notifyHandshakeComplete() throws IOException
170173
{
171174
super.notifyHandshakeComplete();
172175

176+
SecurityParameters securityParameters = context.getSecurityParametersConnection();
177+
if (securityParameters.isExtendedMasterSecret())
178+
{
179+
tlsKeyingMaterial1 = context.exportKeyingMaterial("BC_TLS_TESTS_1", null, 16);
180+
tlsKeyingMaterial2 = context.exportKeyingMaterial("BC_TLS_TESTS_2", new byte[8], 16);
181+
}
182+
173183
tlsServerEndPoint = context.exportChannelBinding(ChannelBinding.tls_server_end_point);
174184
tlsUnique = context.exportChannelBinding(ChannelBinding.tls_unique);
175185

tls/src/test/java/org/bouncycastle/tls/test/TlsTestServerImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.bouncycastle.tls.ConnectionEnd;
1616
import org.bouncycastle.tls.DefaultTlsServer;
1717
import org.bouncycastle.tls.ProtocolVersion;
18+
import org.bouncycastle.tls.SecurityParameters;
1819
import org.bouncycastle.tls.SignatureAlgorithm;
1920
import org.bouncycastle.tls.TlsCredentialedDecryptor;
2021
import org.bouncycastle.tls.TlsCredentialedSigner;
@@ -66,6 +67,8 @@ class TlsTestServerImpl
6667
protected int firstFatalAlertConnectionEnd = -1;
6768
protected short firstFatalAlertDescription = -1;
6869

70+
byte[] tlsKeyingMaterial1 = null;
71+
byte[] tlsKeyingMaterial2 = null;
6972
byte[] tlsServerEndPoint = null;
7073
byte[] tlsUnique = null;
7174

@@ -144,6 +147,13 @@ public void notifyHandshakeComplete() throws IOException
144147
{
145148
super.notifyHandshakeComplete();
146149

150+
SecurityParameters securityParameters = context.getSecurityParametersConnection();
151+
if (securityParameters.isExtendedMasterSecret())
152+
{
153+
tlsKeyingMaterial1 = context.exportKeyingMaterial("BC_TLS_TESTS_1", null, 16);
154+
tlsKeyingMaterial2 = context.exportKeyingMaterial("BC_TLS_TESTS_2", new byte[8], 16);
155+
}
156+
147157
tlsServerEndPoint = context.exportChannelBinding(ChannelBinding.tls_server_end_point);
148158
tlsUnique = context.exportChannelBinding(ChannelBinding.tls_unique);
149159

0 commit comments

Comments
 (0)