summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-03-28 18:32:09 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-03-28 18:32:09 +0700
commit62e20a26b09241bde55034d329fc2393a5f208fe (patch)
treedbff91b17092aed93e6dd353303c37be1b7c5377
parentminor corrections, updated ECPointTest (diff)
downloadBouncyCastle.NET-ed25519-62e20a26b09241bde55034d329fc2393a5f208fe.tar.xz
Fix TLS 1.3 Export Keying Material
- see https://github.com/bcgit/bc-java/issues/1133
-rw-r--r--crypto/src/tls/AbstractTlsContext.cs17
-rw-r--r--crypto/test/src/tls/test/TlsTestCase.cs2
-rw-r--r--crypto/test/src/tls/test/TlsTestClientImpl.cs9
-rw-r--r--crypto/test/src/tls/test/TlsTestServerImpl.cs9
4 files changed, 35 insertions, 2 deletions
diff --git a/crypto/src/tls/AbstractTlsContext.cs b/crypto/src/tls/AbstractTlsContext.cs
index 75e46d993..0317b1430 100644
--- a/crypto/src/tls/AbstractTlsContext.cs
+++ b/crypto/src/tls/AbstractTlsContext.cs
@@ -261,8 +261,21 @@ namespace Org.BouncyCastle.Tls
                 throw new ArgumentException("must have length less than 2^16 (or be null)", "context");
             }
 
-            return TlsCryptoUtilities.HkdfExpandLabel(secret, cryptoHashAlgorithm, asciiLabel, context, length)
-                .Extract();
+            TlsHash exporterHash = Crypto.CreateHash(cryptoHashAlgorithm);
+            byte[] emptyTranscriptHash = exporterHash.CalculateHash();
+
+            TlsSecret exporterSecret = TlsUtilities.DeriveSecret(SecurityParameters, secret, asciiLabel,
+                emptyTranscriptHash);
+
+            byte[] exporterContext = emptyTranscriptHash;
+            if (context.Length > 0)
+            {
+                exporterHash.Update(context, 0, context.Length);
+                exporterContext = exporterHash.CalculateHash();
+            }
+
+            return TlsCryptoUtilities
+                .HkdfExpandLabel(exporterSecret, cryptoHashAlgorithm, "exporter", exporterContext, length).Extract();
         }
 
         protected virtual TlsSecret CheckEarlyExportSecret(TlsSecret secret)
diff --git a/crypto/test/src/tls/test/TlsTestCase.cs b/crypto/test/src/tls/test/TlsTestCase.cs
index 0489d22c1..cb136db92 100644
--- a/crypto/test/src/tls/test/TlsTestCase.cs
+++ b/crypto/test/src/tls/test/TlsTestCase.cs
@@ -70,6 +70,8 @@ namespace Org.BouncyCastle.Tls.Tests
                 Assert.AreEqual(count, data.Length);
                 Assert.IsTrue(Arrays.AreEqual(data, echo));
 
+                Assert.IsTrue(Arrays.AreEqual(clientImpl.m_tlsKeyingMaterial1, serverImpl.m_tlsKeyingMaterial1));
+                Assert.IsTrue(Arrays.AreEqual(clientImpl.m_tlsKeyingMaterial2, serverImpl.m_tlsKeyingMaterial2));
                 Assert.IsTrue(Arrays.AreEqual(clientImpl.m_tlsServerEndPoint, serverImpl.m_tlsServerEndPoint));
 
                 if (!TlsUtilities.IsTlsV13(clientImpl.m_negotiatedVersion))
diff --git a/crypto/test/src/tls/test/TlsTestClientImpl.cs b/crypto/test/src/tls/test/TlsTestClientImpl.cs
index d436df3f7..8f878eeb8 100644
--- a/crypto/test/src/tls/test/TlsTestClientImpl.cs
+++ b/crypto/test/src/tls/test/TlsTestClientImpl.cs
@@ -47,6 +47,8 @@ namespace Org.BouncyCastle.Tls.Tests
         protected short m_firstFatalAlertDescription = -1;
 
         internal ProtocolVersion m_negotiatedVersion = null;
+        internal byte[] m_tlsKeyingMaterial1 = null;
+        internal byte[] m_tlsKeyingMaterial2 = null;
         internal byte[] m_tlsServerEndPoint = null;
         internal byte[] m_tlsUnique = null;
 
@@ -143,6 +145,13 @@ namespace Org.BouncyCastle.Tls.Tests
         {
             base.NotifyHandshakeComplete();
 
+            SecurityParameters securityParameters = m_context.SecurityParameters;
+            if (securityParameters.IsExtendedMasterSecret)
+            {
+                m_tlsKeyingMaterial1 = m_context.ExportKeyingMaterial("BC_TLS_TESTS_1", null, 16);
+                m_tlsKeyingMaterial2 = m_context.ExportKeyingMaterial("BC_TLS_TESTS_2", new byte[8], 16);
+            }
+
             m_tlsServerEndPoint = m_context.ExportChannelBinding(ChannelBinding.tls_server_end_point);
             m_tlsUnique = m_context.ExportChannelBinding(ChannelBinding.tls_unique);
 
diff --git a/crypto/test/src/tls/test/TlsTestServerImpl.cs b/crypto/test/src/tls/test/TlsTestServerImpl.cs
index 6bc4d315d..77df632fe 100644
--- a/crypto/test/src/tls/test/TlsTestServerImpl.cs
+++ b/crypto/test/src/tls/test/TlsTestServerImpl.cs
@@ -50,6 +50,8 @@ namespace Org.BouncyCastle.Tls.Tests
         protected int m_firstFatalAlertConnectionEnd = -1;
         protected short m_firstFatalAlertDescription = -1;
 
+        internal byte[] m_tlsKeyingMaterial1 = null;
+        internal byte[] m_tlsKeyingMaterial2 = null;
         internal byte[] m_tlsServerEndPoint = null;
         internal byte[] m_tlsUnique = null;
 
@@ -128,6 +130,13 @@ namespace Org.BouncyCastle.Tls.Tests
         {
             base.NotifyHandshakeComplete();
 
+            SecurityParameters securityParameters = m_context.SecurityParameters;
+            if (securityParameters.IsExtendedMasterSecret)
+            {
+                m_tlsKeyingMaterial1 = m_context.ExportKeyingMaterial("BC_TLS_TESTS_1", null, 16);
+                m_tlsKeyingMaterial2 = m_context.ExportKeyingMaterial("BC_TLS_TESTS_2", new byte[8], 16);
+            }
+
             m_tlsServerEndPoint = m_context.ExportChannelBinding(ChannelBinding.tls_server_end_point);
             m_tlsUnique = m_context.ExportChannelBinding(ChannelBinding.tls_unique);