diff --git a/crypto/src/crypto/tls/AbstractTlsContext.cs b/crypto/src/crypto/tls/AbstractTlsContext.cs
index 83150d37e..e283ee58c 100644
--- a/crypto/src/crypto/tls/AbstractTlsContext.cs
+++ b/crypto/src/crypto/tls/AbstractTlsContext.cs
@@ -96,6 +96,15 @@ namespace Org.BouncyCastle.Crypto.Tls
public virtual byte[] ExportKeyingMaterial(string asciiLabel, byte[] context_value, int length)
{
+ /*
+ * TODO[session-hash]
+ *
+ * draft-ietf-tls-session-hash-04 5.4. If a client or server chooses to continue with a full
+ * handshake without the extended master secret extension, [..] the client or server MUST
+ * NOT export any key material based on the new master secret for any subsequent
+ * application-level authentication. In particular, it MUST disable [RFC5705] [..].
+ */
+
if (context_value != null && !TlsUtilities.IsValidUint16(context_value.Length))
throw new ArgumentException("must have length less than 2^16 (or be null)", "context_value");
diff --git a/crypto/src/crypto/tls/DtlsClientProtocol.cs b/crypto/src/crypto/tls/DtlsClientProtocol.cs
index 200bb1946..76635065c 100644
--- a/crypto/src/crypto/tls/DtlsClientProtocol.cs
+++ b/crypto/src/crypto/tls/DtlsClientProtocol.cs
@@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Crypto.Tls
DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.clientContext, client, ContentType.handshake);
TlsSession sessionToResume = state.client.GetSessionToResume();
- if (sessionToResume != null)
+ if (sessionToResume != null && sessionToResume.IsResumable)
{
SessionParameters sessionParameters = sessionToResume.ExportSessionParameters();
if (sessionParameters != null)
@@ -143,6 +143,8 @@ namespace Org.BouncyCastle.Crypto.Tls
IDictionary sessionServerExtensions = state.sessionParameters.ReadServerExtensions();
+ // TODO Check encrypt-then-MAC extension and maybe others
+
securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(sessionServerExtensions);
securityParameters.masterSecret = Arrays.Clone(state.sessionParameters.MasterSecret);
@@ -430,8 +432,6 @@ namespace Org.BouncyCastle.Crypto.Tls
// Integer -> byte[]
state.clientExtensions = client.GetClientExtensions();
- securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.clientExtensions);
-
// Cipher Suites (and SCSV)
{
/*
@@ -646,15 +646,6 @@ namespace Org.BouncyCastle.Crypto.Tls
IDictionary serverExtensions = TlsProtocol.ReadExtensions(buf);
/*
- * draft-ietf-tls-session-hash-01 5.2. If a server receives the "extended_master_secret"
- * extension, it MUST include the "extended_master_secret" extension in its ServerHello
- * message.
- */
- bool serverSentExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(serverExtensions);
- if (serverSentExtendedMasterSecret != securityParameters.extendedMasterSecret)
- throw new TlsFatalAlert(AlertDescription.handshake_failure);
-
- /*
* RFC 3546 2.2 Note that the extended server hello message is only sent in response to an
* extended client hello message. However, see RFC 5746 exception below. We always include
* the SCSV, so an Extended Server Hello is always allowed.
@@ -684,15 +675,6 @@ namespace Org.BouncyCastle.Crypto.Tls
throw new TlsFatalAlert(AlertDescription.unsupported_extension);
/*
- * draft-ietf-tls-session-hash-01 5.2. Implementation note: if the server decides to
- * proceed with resumption, the extension does not have any effect. Requiring the
- * extension to be included anyway makes the extension negotiation logic easier,
- * because it does not depend on whether resumption is accepted or not.
- */
- if (extType == ExtensionType.extended_master_secret)
- continue;
-
- /*
* RFC 3546 2.3. If [...] the older session is resumed, then the server MUST ignore
* extensions appearing in the client hello, and send a server hello containing no
* extensions[.]
@@ -743,6 +725,8 @@ namespace Org.BouncyCastle.Crypto.Tls
securityParameters.encryptThenMac = serverSentEncryptThenMAC;
+ securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(serverExtensions);
+
state.maxFragmentLength = EvaluateMaxFragmentLengthExtension(state.clientExtensions, serverExtensions,
AlertDescription.illegal_parameter);
@@ -755,6 +739,13 @@ namespace Org.BouncyCastle.Crypto.Tls
ExtensionType.session_ticket, AlertDescription.illegal_parameter);
}
+ /*
+ * TODO[session-hash]
+ *
+ * draft-ietf-tls-session-hash-04 4. Clients and servers SHOULD NOT accept handshakes
+ * that do not use the extended master secret [..]. (and see 5.2, 5.3)
+ */
+
state.client.NotifySecureRenegotiation(state.secure_renegotiation);
if (state.clientExtensions != null)
diff --git a/crypto/src/crypto/tls/DtlsServerProtocol.cs b/crypto/src/crypto/tls/DtlsServerProtocol.cs
index 3335a9f36..f148eb7d7 100644
--- a/crypto/src/crypto/tls/DtlsServerProtocol.cs
+++ b/crypto/src/crypto/tls/DtlsServerProtocol.cs
@@ -538,6 +538,12 @@ namespace Org.BouncyCastle.Crypto.Tls
TlsServerContextImpl context = state.serverContext;
SecurityParameters securityParameters = context.SecurityParameters;
+ /*
+ * TODO[session-hash]
+ *
+ * draft-ietf-tls-session-hash-04 4. Clients and servers SHOULD NOT accept handshakes
+ * that do not use the extended master secret [..]. (and see 5.2, 5.3)
+ */
securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.clientExtensions);
context.SetClientVersion(client_version);
diff --git a/crypto/src/crypto/tls/ExporterLabel.cs b/crypto/src/crypto/tls/ExporterLabel.cs
index 280321e2a..5970769d7 100644
--- a/crypto/src/crypto/tls/ExporterLabel.cs
+++ b/crypto/src/crypto/tls/ExporterLabel.cs
@@ -30,7 +30,7 @@ namespace Org.BouncyCastle.Crypto.Tls
public const string dtls_srtp = "EXTRACTOR-dtls_srtp";
/*
- * draft-ietf-tls-session-hash-01
+ * draft-ietf-tls-session-hash-04
*/
public static readonly string extended_master_secret = "extended master secret";
}
diff --git a/crypto/src/crypto/tls/ExtensionType.cs b/crypto/src/crypto/tls/ExtensionType.cs
index acee380b6..b4b24f7c3 100644
--- a/crypto/src/crypto/tls/ExtensionType.cs
+++ b/crypto/src/crypto/tls/ExtensionType.cs
@@ -49,7 +49,7 @@ namespace Org.BouncyCastle.Crypto.Tls
public const int encrypt_then_mac = 22;
/*
- * draft-ietf-tls-session-hash-01
+ * draft-ietf-tls-session-hash-04
*
* NOTE: Early code-point assignment
*/
diff --git a/crypto/src/crypto/tls/TlsClientProtocol.cs b/crypto/src/crypto/tls/TlsClientProtocol.cs
index 1bd0653a6..5b9e81b3f 100644
--- a/crypto/src/crypto/tls/TlsClientProtocol.cs
+++ b/crypto/src/crypto/tls/TlsClientProtocol.cs
@@ -58,7 +58,7 @@ namespace Org.BouncyCastle.Crypto.Tls
this.mRecordStream.Init(mTlsClientContext);
TlsSession sessionToResume = tlsClient.GetSessionToResume();
- if (sessionToResume != null)
+ if (sessionToResume != null && sessionToResume.IsResumable)
{
SessionParameters sessionParameters = sessionToResume.ExportSessionParameters();
if (sessionParameters != null)
@@ -624,15 +624,6 @@ namespace Org.BouncyCastle.Crypto.Tls
this.mServerExtensions = ReadExtensions(buf);
/*
- * draft-ietf-tls-session-hash-01 5.2. If a server receives the "extended_master_secret"
- * extension, it MUST include the "extended_master_secret" extension in its ServerHello
- * message.
- */
- bool serverSentExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(mServerExtensions);
- if (serverSentExtendedMasterSecret != mSecurityParameters.extendedMasterSecret)
- throw new TlsFatalAlert(AlertDescription.handshake_failure);
-
- /*
* RFC 3546 2.2 Note that the extended server hello message is only sent in response to an
* extended client hello message.
*
@@ -664,15 +655,6 @@ namespace Org.BouncyCastle.Crypto.Tls
throw new TlsFatalAlert(AlertDescription.unsupported_extension);
/*
- * draft-ietf-tls-session-hash-01 5.2. Implementation note: if the server decides to
- * proceed with resumption, the extension does not have any effect. Requiring the
- * extension to be included anyway makes the extension negotiation logic easier,
- * because it does not depend on whether resumption is accepted or not.
- */
- if (extType == ExtensionType.extended_master_secret)
- continue;
-
- /*
* RFC 3546 2.3. If [...] the older session is resumed, then the server MUST ignore
* extensions appearing in the client hello, and Send a server hello containing no
* extensions[.]
@@ -725,8 +707,6 @@ namespace Org.BouncyCastle.Crypto.Tls
sessionClientExtensions = null;
sessionServerExtensions = this.mSessionParameters.ReadServerExtensions();
-
- this.mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(sessionServerExtensions);
}
this.mSecurityParameters.cipherSuite = selectedCipherSuite;
@@ -746,6 +726,8 @@ namespace Org.BouncyCastle.Crypto.Tls
this.mSecurityParameters.encryptThenMac = serverSentEncryptThenMAC;
+ this.mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(sessionServerExtensions);
+
this.mSecurityParameters.maxFragmentLength = ProcessMaxFragmentLengthExtension(sessionClientExtensions,
sessionServerExtensions, AlertDescription.illegal_parameter);
@@ -764,6 +746,13 @@ namespace Org.BouncyCastle.Crypto.Tls
AlertDescription.illegal_parameter);
}
+ /*
+ * TODO[session-hash]
+ *
+ * draft-ietf-tls-session-hash-04 4. Clients and servers SHOULD NOT accept handshakes
+ * that do not use the extended master secret [..]. (and see 5.2, 5.3)
+ */
+
if (sessionClientExtensions != null)
{
this.mTlsClient.ProcessServerExtensions(sessionServerExtensions);
@@ -820,8 +809,6 @@ namespace Org.BouncyCastle.Crypto.Tls
this.mClientExtensions = this.mTlsClient.GetClientExtensions();
- this.mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(mClientExtensions);
-
HandshakeMessage message = new HandshakeMessage(HandshakeType.client_hello);
TlsUtilities.WriteVersion(client_version, message);
diff --git a/crypto/src/crypto/tls/TlsServerProtocol.cs b/crypto/src/crypto/tls/TlsServerProtocol.cs
index d2959cfed..fd6808382 100644
--- a/crypto/src/crypto/tls/TlsServerProtocol.cs
+++ b/crypto/src/crypto/tls/TlsServerProtocol.cs
@@ -501,6 +501,12 @@ namespace Org.BouncyCastle.Crypto.Tls
*/
this.mClientExtensions = ReadExtensions(buf);
+ /*
+ * TODO[session-hash]
+ *
+ * draft-ietf-tls-session-hash-04 4. Clients and servers SHOULD NOT accept handshakes
+ * that do not use the extended master secret [..]. (and see 5.2, 5.3)
+ */
this.mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(mClientExtensions);
ContextAdmin.SetClientVersion(client_version);
diff --git a/crypto/test/src/crypto/tls/test/MockDtlsClient.cs b/crypto/test/src/crypto/tls/test/MockDtlsClient.cs
index 32491c425..e3c604db7 100644
--- a/crypto/test/src/crypto/tls/test/MockDtlsClient.cs
+++ b/crypto/test/src/crypto/tls/test/MockDtlsClient.cs
@@ -72,8 +72,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests
{
IDictionary clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(base.GetClientExtensions());
TlsExtensionsUtilities.AddEncryptThenMacExtension(clientExtensions);
- // TODO[draft-ietf-tls-session-hash-01] Enable once code-point assigned (only for compatible server though)
- //TlsExtensionsUtilities.AddExtendedMasterSecretExtension(clientExtensions);
+ TlsExtensionsUtilities.AddExtendedMasterSecretExtension(clientExtensions);
TlsExtensionsUtilities.AddMaxFragmentLengthExtension(clientExtensions, MaxFragmentLength.pow2_9);
TlsExtensionsUtilities.AddTruncatedHMacExtension(clientExtensions);
return clientExtensions;
diff --git a/crypto/test/src/crypto/tls/test/MockTlsClient.cs b/crypto/test/src/crypto/tls/test/MockTlsClient.cs
index 4d7c59afa..7c1198632 100644
--- a/crypto/test/src/crypto/tls/test/MockTlsClient.cs
+++ b/crypto/test/src/crypto/tls/test/MockTlsClient.cs
@@ -62,8 +62,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests
{
IDictionary clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(base.GetClientExtensions());
TlsExtensionsUtilities.AddEncryptThenMacExtension(clientExtensions);
- // TODO[draft-ietf-tls-session-hash-01] Enable once code-point assigned (only for compatible server though)
-// TlsExtensionsUtilities.AddExtendedMasterSecretExtension(clientExtensions);
+ TlsExtensionsUtilities.AddExtendedMasterSecretExtension(clientExtensions);
TlsExtensionsUtilities.AddMaxFragmentLengthExtension(clientExtensions, MaxFragmentLength.pow2_9);
TlsExtensionsUtilities.AddTruncatedHMacExtension(clientExtensions);
return clientExtensions;
|