diff options
Diffstat (limited to 'crypto/src/tls/TlsClientProtocol.cs')
-rw-r--r-- | crypto/src/tls/TlsClientProtocol.cs | 115 |
1 files changed, 78 insertions, 37 deletions
diff --git a/crypto/src/tls/TlsClientProtocol.cs b/crypto/src/tls/TlsClientProtocol.cs index cff541db3..7b2f148d3 100644 --- a/crypto/src/tls/TlsClientProtocol.cs +++ b/crypto/src/tls/TlsClientProtocol.cs @@ -1229,37 +1229,41 @@ namespace Org.BouncyCastle.Tls // TODO[compat-gnutls] GnuTLS test server fails to send renegotiation_info extension when resuming m_tlsClient.NotifySecureRenegotiation(securityParameters.IsSecureRenegotiation); - /* - * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended - * master secret [..]. (and see 5.2, 5.3) - * - * RFC 8446 Appendix D. Because TLS 1.3 always hashes in the transcript up to the server - * Finished, implementations which support both TLS 1.3 and earlier versions SHOULD indicate - * the use of the Extended Master Secret extension in their APIs whenever TLS 1.3 is used. - */ + // extended_master_secret { - bool acceptedExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension( - m_serverExtensions); - bool resumedSession = securityParameters.IsResumedSession; + bool negotiatedEms = false; - if (acceptedExtendedMasterSecret) + if (TlsExtensionsUtilities.HasExtendedMasterSecretExtension(m_clientExtensions)) { - if (server_version.IsSsl - || (!resumedSession && !m_tlsClient.ShouldUseExtendedMasterSecret())) + negotiatedEms = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(m_serverExtensions); + + if (TlsUtilities.IsExtendedMasterSecretOptional(server_version)) { - throw new TlsFatalAlert(AlertDescription.handshake_failure); + if (!negotiatedEms && + m_tlsClient.RequiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Extended Master Secret extension is required"); + } } - } - else - { - if (m_tlsClient.RequiresExtendedMasterSecret() - || (resumedSession && !m_tlsClient.AllowLegacyResumption())) + else { - throw new TlsFatalAlert(AlertDescription.handshake_failure); + if (negotiatedEms) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "Server sent an unexpected extended_master_secret extension negotiating " + server_version); + } } } - securityParameters.m_extendedMasterSecret = acceptedExtendedMasterSecret; + securityParameters.m_extendedMasterSecret = negotiatedEms; + } + + if (securityParameters.IsResumedSession && + securityParameters.IsExtendedMasterSecret != m_sessionParameters.IsExtendedMasterSecret) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, + "Server resumed session with mismatched extended_master_secret negotiation"); } /* @@ -1670,8 +1674,17 @@ namespace Org.BouncyCastle.Tls securityParameters.m_clientRandom = CreateRandomBlock(useGmtUnixTime, m_tlsClientContext); } - EstablishSession(offeringTlsV12Minus ? m_tlsClient.GetSessionToResume() : null); - m_tlsClient.NotifySessionToResume(m_tlsSession); + TlsSession sessionToResume = offeringTlsV12Minus ? m_tlsClient.GetSessionToResume() : null; + + bool fallback = m_tlsClient.IsFallback(); + + int[] offeredCipherSuites = m_tlsClient.GetCipherSuites(); + + this.m_clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(m_tlsClient.GetClientExtensions()); + + bool shouldUseEms = m_tlsClient.ShouldUseExtendedMasterSecret(); + + EstablishSession(sessionToResume); /* * TODO RFC 5077 3.4. When presenting a ticket, the client MAY generate and include a @@ -1679,11 +1692,7 @@ namespace Org.BouncyCastle.Tls */ byte[] legacy_session_id = TlsUtilities.GetSessionID(m_tlsSession); - bool fallback = m_tlsClient.IsFallback(); - - int[] offeredCipherSuites = m_tlsClient.GetCipherSuites(); - - if (legacy_session_id.Length > 0 && m_sessionParameters != null) + if (legacy_session_id.Length > 0) { if (!Arrays.Contains(offeredCipherSuites, m_sessionParameters.CipherSuite)) { @@ -1691,8 +1700,42 @@ namespace Org.BouncyCastle.Tls } } - this.m_clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised( - m_tlsClient.GetClientExtensions()); + ProtocolVersion sessionVersion = null; + if (legacy_session_id.Length > 0) + { + sessionVersion = m_sessionParameters.NegotiatedVersion; + + if (!ProtocolVersion.Contains(supportedVersions, sessionVersion)) + { + legacy_session_id = TlsUtilities.EmptyBytes; + } + } + + if (legacy_session_id.Length > 0 && TlsUtilities.IsExtendedMasterSecretOptional(sessionVersion)) + { + if (shouldUseEms) + { + if (!m_sessionParameters.IsExtendedMasterSecret && + !m_tlsClient.AllowLegacyResumption()) + { + legacy_session_id = TlsUtilities.EmptyBytes; + } + } + else + { + if (m_sessionParameters.IsExtendedMasterSecret) + { + legacy_session_id = TlsUtilities.EmptyBytes; + } + } + } + + if (legacy_session_id.Length < 1) + { + CancelSession(); + } + + m_tlsClient.NotifySessionToResume(m_tlsSession); ProtocolVersion legacy_version = latestVersion; if (offeringTlsV13Plus) @@ -1731,15 +1774,13 @@ namespace Org.BouncyCastle.Tls this.m_clientAgreements = TlsUtilities.AddKeyShareToClientHello(m_tlsClientContext, m_tlsClient, m_clientExtensions); - if (TlsUtilities.IsExtendedMasterSecretOptionalTls(supportedVersions) - && (m_tlsClient.ShouldUseExtendedMasterSecret() || - (null != m_sessionParameters && m_sessionParameters.IsExtendedMasterSecret))) + if (shouldUseEms && TlsUtilities.IsExtendedMasterSecretOptional(supportedVersions)) { - TlsExtensionsUtilities.AddExtendedMasterSecretExtension(m_clientExtensions); + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(this.m_clientExtensions); } - else if (!offeringTlsV13Plus && m_tlsClient.RequiresExtendedMasterSecret()) + else { - throw new TlsFatalAlert(AlertDescription.internal_error); + this.m_clientExtensions.Remove(ExtensionType.extended_master_secret); } // NOT renegotiating |