summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-07-05 15:39:36 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-07-05 15:39:36 +0700
commit62ef1a674bbf28517321f07c855a111c9290854d (patch)
tree2ce007798566a4624daea623168be0acee48fb3f
parentRemove redundant test and add Parallelizable (diff)
downloadBouncyCastle.NET-ed25519-62ef1a674bbf28517321f07c855a111c9290854d.tar.xz
Move m_resumedSession to SecurityParameters
-rw-r--r--crypto/src/tls/SecurityParameters.cs6
-rw-r--r--crypto/src/tls/TlsClientProtocol.cs28
-rw-r--r--crypto/src/tls/TlsProtocol.cs18
-rw-r--r--crypto/src/tls/TlsServerProtocol.cs46
4 files changed, 53 insertions, 45 deletions
diff --git a/crypto/src/tls/SecurityParameters.cs b/crypto/src/tls/SecurityParameters.cs
index 0681401eb..7891549b6 100644
--- a/crypto/src/tls/SecurityParameters.cs
+++ b/crypto/src/tls/SecurityParameters.cs
@@ -8,6 +8,7 @@ namespace Org.BouncyCastle.Tls
     public sealed class SecurityParameters
     {
         internal int m_entity = -1;
+        internal bool m_resumedSession = false;
         internal bool m_secureRenegotiation = false;
         internal int m_cipherSuite = Tls.CipherSuite.TLS_NULL_WITH_NULL_NULL;
         internal short m_maxFragmentLength = -1;
@@ -174,6 +175,11 @@ namespace Org.BouncyCastle.Tls
             get { return m_extendedPadding; }
         }
 
+        public bool IsResumedSession
+        {
+            get { return m_resumedSession; }
+        }
+
         public bool IsSecureRenegotiation
         {
             get { return m_secureRenegotiation; }
diff --git a/crypto/src/tls/TlsClientProtocol.cs b/crypto/src/tls/TlsClientProtocol.cs
index d750c5e2c..fc3894710 100644
--- a/crypto/src/tls/TlsClientProtocol.cs
+++ b/crypto/src/tls/TlsClientProtocol.cs
@@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Tls
         /// <exception cref="IOException"/>
         protected virtual void Handle13HandshakeMessage(short type, HandshakeMessageInput buf)
         {
-            if (!IsTlsV13ConnectionState() || m_resumedSession)
+            if (!IsTlsV13ConnectionState())
                 throw new TlsFatalAlert(AlertDescription.internal_error);
 
             switch (type)
@@ -335,6 +335,9 @@ namespace Org.BouncyCastle.Tls
             if (m_connectionState > CS_CLIENT_HELLO
                 && TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion))
             {
+                if (securityParameters.IsResumedSession)
+                    throw new TlsFatalAlert(AlertDescription.internal_error);
+
                 Handle13HandshakeMessage(type, buf);
                 return;
             }
@@ -342,7 +345,7 @@ namespace Org.BouncyCastle.Tls
             if (!IsLegacyConnectionState())
                 throw new TlsFatalAlert(AlertDescription.internal_error);
 
-            if (m_resumedSession)
+            if (securityParameters.IsResumedSession)
             {
                 if (type != HandshakeType.finished || m_connectionState != CS_SERVER_HELLO)
                     throw new TlsFatalAlert(AlertDescription.unexpected_message);
@@ -871,7 +874,7 @@ namespace Org.BouncyCastle.Tls
             securityParameters.m_negotiatedVersion = server_version;
             TlsUtilities.NegotiatedVersionTlsClient(m_tlsClientContext, m_tlsClient);
 
-            this.m_resumedSession = false;
+            securityParameters.m_resumedSession = false;
             securityParameters.m_sessionID = TlsUtilities.EmptyBytes;
             m_tlsClient.NotifySessionID(TlsUtilities.EmptyBytes);
 
@@ -926,7 +929,7 @@ namespace Org.BouncyCastle.Tls
                     throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                 }
 
-                this.m_resumedSession = false;
+                securityParameters.m_resumedSession = false;
                 securityParameters.m_sessionID = TlsUtilities.EmptyBytes;
                 m_tlsClient.NotifySessionID(TlsUtilities.EmptyBytes);
 
@@ -1108,7 +1111,7 @@ namespace Org.BouncyCastle.Tls
                 byte[] selectedSessionID = serverHello.SessionID;
                 securityParameters.m_sessionID = selectedSessionID;
                 m_tlsClient.NotifySessionID(selectedSessionID);
-                this.m_resumedSession = selectedSessionID.Length > 0 && m_tlsSession != null
+                securityParameters.m_resumedSession = selectedSessionID.Length > 0 && m_tlsSession != null
                     && Arrays.AreEqual(selectedSessionID, m_tlsSession.SessionID);
             }
 
@@ -1166,7 +1169,7 @@ namespace Org.BouncyCastle.Tls
                      * extensions appearing in the client hello, and send a server hello containing no
                      * extensions[.]
                      */
-                    if (m_resumedSession)
+                    if (securityParameters.IsResumedSession)
                     {
                         // TODO[compat-gnutls] GnuTLS test server sends server extensions e.g. ec_point_formats
                         // TODO[compat-openssl] OpenSSL test server sends server extensions e.g. ec_point_formats
@@ -1227,11 +1230,12 @@ namespace Org.BouncyCastle.Tls
             {
                 bool acceptedExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(
                     m_serverExtensions);
+                bool resumedSession = securityParameters.IsResumedSession;
 
                 if (acceptedExtendedMasterSecret)
                 {
                     if (server_version.IsSsl
-                        || (!m_resumedSession && !m_tlsClient.ShouldUseExtendedMasterSecret()))
+                        || (!resumedSession && !m_tlsClient.ShouldUseExtendedMasterSecret()))
                     {
                         throw new TlsFatalAlert(AlertDescription.handshake_failure);
                     }
@@ -1239,7 +1243,7 @@ namespace Org.BouncyCastle.Tls
                 else
                 {
                     if (m_tlsClient.RequiresExtendedMasterSecret()
-                        || (m_resumedSession && !m_tlsClient.AllowLegacyResumption()))
+                        || (resumedSession && !m_tlsClient.AllowLegacyResumption()))
                     {
                         throw new TlsFatalAlert(AlertDescription.handshake_failure);
                     }
@@ -1259,7 +1263,7 @@ namespace Org.BouncyCastle.Tls
 
             var sessionClientExtensions = m_clientExtensions;
             var sessionServerExtensions = m_serverExtensions;
-            if (m_resumedSession)
+            if (securityParameters.IsResumedSession)
             {
                 if (securityParameters.CipherSuite != m_sessionParameters.CipherSuite
                     || !server_version.Equals(m_sessionParameters.NegotiatedVersion))
@@ -1298,7 +1302,7 @@ namespace Org.BouncyCastle.Tls
                  * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in
                  * a session resumption handshake.
                  */
-                if (!m_resumedSession)
+                if (!securityParameters.IsResumedSession)
                 {
                     // TODO[tls13] See RFC 8446 4.4.2.1
                     if (TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions,
@@ -1324,7 +1328,7 @@ namespace Org.BouncyCastle.Tls
 
             ApplyMaxFragmentLengthExtension(securityParameters.MaxFragmentLength);
 
-            if (m_resumedSession)
+            if (securityParameters.IsResumedSession)
             {
                 securityParameters.m_masterSecret = m_sessionMasterSecret;
                 m_recordStream.SetPendingCipher(TlsUtilities.InitCipher(m_tlsClientContext));
@@ -1397,7 +1401,7 @@ namespace Org.BouncyCastle.Tls
 
             var sessionClientExtensions = m_clientExtensions;
             var sessionServerExtensions = m_serverExtensions;
-            if (m_resumedSession)
+            if (securityParameters.IsResumedSession)
             {
                 if (securityParameters.CipherSuite != m_sessionParameters.CipherSuite
                     || !negotiatedVersion.Equals(m_sessionParameters.NegotiatedVersion))
diff --git a/crypto/src/tls/TlsProtocol.cs b/crypto/src/tls/TlsProtocol.cs
index 67ee5773b..dbbb6e0f5 100644
--- a/crypto/src/tls/TlsProtocol.cs
+++ b/crypto/src/tls/TlsProtocol.cs
@@ -150,7 +150,6 @@ namespace Org.BouncyCastle.Tls
         protected IDictionary<int, byte[]> m_serverExtensions = null;
 
         protected short m_connectionState = CS_START;
-        protected bool m_resumedSession = false;
         protected bool m_selectedPsk13 = false;
         protected bool m_receivedChangeCipherSpec = false;
         protected bool m_expectSessionTicket = false;
@@ -361,7 +360,6 @@ namespace Org.BouncyCastle.Tls
 
             this.m_handshakeHash = new DeferredHash(context);
             this.m_connectionState = CS_START;
-            this.m_resumedSession = false;
             this.m_selectedPsk13 = false;
 
             context.HandshakeBeginning(peer);
@@ -392,7 +390,6 @@ namespace Org.BouncyCastle.Tls
             this.m_clientExtensions = null;
             this.m_serverExtensions = null;
 
-            this.m_resumedSession = false;
             this.m_selectedPsk13 = false;
             this.m_receivedChangeCipherSpec = false;
             this.m_expectSessionTicket = false;
@@ -1320,9 +1317,8 @@ namespace Org.BouncyCastle.Tls
                     return false;
 
                 /*
-                 * NOTE: For session resumption without extended_master_secret, renegotiation MUST be
-                 * disabled (see RFC 7627 5.4). We currently do not implement renegotiation and it is
-                 * unlikely we ever would since it was removed in TLS 1.3.
+                 * NOTE: For session resumption without extended_master_secret, renegotiation MUST be disabled
+                 * (see RFC 7627 5.4).
                  */
             }
 
@@ -1385,7 +1381,7 @@ namespace Org.BouncyCastle.Tls
 
             securityParameters.m_peerVerifyData = expected_verify_data;
 
-            if (!m_resumedSession || securityParameters.IsExtendedMasterSecret)
+            if (!securityParameters.IsResumedSession || securityParameters.IsExtendedMasterSecret)
             {
                 if (null == securityParameters.LocalVerifyData)
                 {
@@ -1553,7 +1549,7 @@ namespace Org.BouncyCastle.Tls
 
             securityParameters.m_localVerifyData = verify_data;
 
-            if (!m_resumedSession || securityParameters.IsExtendedMasterSecret)
+            if (!securityParameters.IsResumedSession || securityParameters.IsExtendedMasterSecret)
             {
                 if (null == securityParameters.PeerVerifyData)
                 {
@@ -1660,9 +1656,9 @@ namespace Org.BouncyCastle.Tls
             short maxFragmentLength = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(serverExtensions);
             if (maxFragmentLength >= 0)
             {
-                if (!MaxFragmentLength.IsValid(maxFragmentLength)
-                    || (!m_resumedSession &&
-                        maxFragmentLength != TlsExtensionsUtilities.GetMaxFragmentLengthExtension(clientExtensions)))
+                if (!MaxFragmentLength.IsValid(maxFragmentLength) ||
+                (clientExtensions != null &&
+                    maxFragmentLength != TlsExtensionsUtilities.GetMaxFragmentLengthExtension(clientExtensions)))
                 {
                     throw new TlsFatalAlert(alertDescription);
                 }
diff --git a/crypto/src/tls/TlsServerProtocol.cs b/crypto/src/tls/TlsServerProtocol.cs
index a222b998d..3acbe90df 100644
--- a/crypto/src/tls/TlsServerProtocol.cs
+++ b/crypto/src/tls/TlsServerProtocol.cs
@@ -226,6 +226,7 @@ namespace Org.BouncyCastle.Tls
                  */
                 {
                     // TODO[tls13] Resumption/PSK
+                    securityParameters.m_resumedSession = false;
 
                     this.m_tlsSession = TlsUtilities.ImportSession(TlsUtilities.EmptyBytes, null);
                     this.m_sessionParameters = null;
@@ -314,8 +315,9 @@ namespace Org.BouncyCastle.Tls
 
             if (serverEncryptedExtensions.Count > 0)
             {
-                securityParameters.m_maxFragmentLength = ProcessMaxFragmentLengthExtension(clientHelloExtensions,
-                    serverEncryptedExtensions, AlertDescription.internal_error);
+                securityParameters.m_maxFragmentLength = ProcessMaxFragmentLengthExtension(
+                    securityParameters.IsResumedSession ? null : clientHelloExtensions, serverEncryptedExtensions,
+                    AlertDescription.internal_error);
             }
 
             securityParameters.m_encryptThenMac = false;
@@ -546,9 +548,10 @@ namespace Org.BouncyCastle.Tls
                 m_tlsServer.ProcessClientExtensions(m_clientExtensions);
             }
 
-            this.m_resumedSession = EstablishSession(m_tlsServer.GetSessionToResume(clientHello.SessionID));
+            bool resumedSession = EstablishSession(m_tlsServer.GetSessionToResume(clientHello.SessionID));
+            securityParameters.m_resumedSession = resumedSession;
 
-            if (!m_resumedSession)
+            if (!resumedSession)
             {
                 byte[] newSessionID = m_tlsServer.GetNewSessionID();
                 if (null == newSessionID)
@@ -568,7 +571,7 @@ namespace Org.BouncyCastle.Tls
             TlsUtilities.NegotiatedVersionTlsServer(m_tlsServerContext);
 
             {
-                int cipherSuite = m_resumedSession
+                int cipherSuite = resumedSession
                     ?   m_sessionParameters.CipherSuite
                     :   m_tlsServer.GetSelectedCipherSuite();
 
@@ -584,7 +587,7 @@ namespace Org.BouncyCastle.Tls
             m_tlsServerContext.SetRsaPreMasterSecretVersion(clientLegacyVersion);
 
             {
-                var sessionServerExtensions = m_resumedSession
+                var sessionServerExtensions = resumedSession
                     ?   m_sessionParameters.ReadServerExtensions()
                     :   m_tlsServer.GetServerExtensions();
 
@@ -628,7 +631,7 @@ namespace Org.BouncyCastle.Tls
              * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended
              * master secret [..]. (and see 5.2, 5.3)
              */
-            if (m_resumedSession)
+            if (resumedSession)
             {
                 if (!m_sessionParameters.IsExtendedMasterSecret)
                 {
@@ -669,13 +672,13 @@ namespace Org.BouncyCastle.Tls
                 securityParameters.m_encryptThenMac = TlsExtensionsUtilities.HasEncryptThenMacExtension(
                     m_serverExtensions);
 
-                securityParameters.m_maxFragmentLength = ProcessMaxFragmentLengthExtension(m_clientExtensions,
-                    m_serverExtensions, AlertDescription.internal_error);
+                securityParameters.m_maxFragmentLength = ProcessMaxFragmentLengthExtension(
+                    resumedSession ? null : m_clientExtensions, m_serverExtensions, AlertDescription.internal_error);
 
                 securityParameters.m_truncatedHmac = TlsExtensionsUtilities.HasTruncatedHmacExtension(
                     m_serverExtensions);
 
-                if (!m_resumedSession)
+                if (!resumedSession)
                 {
                     if (TlsUtilities.HasExpectedEmptyExtensionData(m_serverExtensions, ExtensionType.status_request_v2,
                         AlertDescription.internal_error))
@@ -720,16 +723,12 @@ namespace Org.BouncyCastle.Tls
             if (!IsTlsV13ConnectionState())
                 throw new TlsFatalAlert(AlertDescription.internal_error);
 
-            if (m_resumedSession)
-            {
-                /*
-                 * TODO[tls13] Abbreviated handshakes (PSK resumption)
-                 * 
-                 * NOTE: No CertificateRequest, Certificate, CertificateVerify messages, but client
-                 * might now send EndOfEarlyData after receiving server Finished message.
-                 */
-                throw new TlsFatalAlert(AlertDescription.internal_error);
-            }
+            /*
+             * TODO[tls13] Abbreviated handshakes (PSK resumption)
+             * 
+             * NOTE: No CertificateRequest, Certificate, CertificateVerify messages, but client
+             * might now send EndOfEarlyData after receiving server Finished message.
+             */
 
             switch (type)
             {
@@ -857,6 +856,9 @@ namespace Org.BouncyCastle.Tls
             if (m_connectionState > CS_CLIENT_HELLO
                 && TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion))
             {
+                if (securityParameters.IsResumedSession)
+                    throw new TlsFatalAlert(AlertDescription.internal_error);
+
                 Handle13HandshakeMessage(type, buf);
                 return;
             }
@@ -864,7 +866,7 @@ namespace Org.BouncyCastle.Tls
             if (!IsLegacyConnectionState())
                 throw new TlsFatalAlert(AlertDescription.internal_error);
 
-            if (m_resumedSession)
+            if (securityParameters.IsResumedSession)
             {
                 if (type != HandshakeType.finished || m_connectionState != CS_SERVER_FINISHED)
                     throw new TlsFatalAlert(AlertDescription.unexpected_message);
@@ -933,7 +935,7 @@ namespace Org.BouncyCastle.Tls
                     SendServerHelloMessage(serverHello);
                     this.m_connectionState = CS_SERVER_HELLO;
 
-                    if (m_resumedSession)
+                    if (securityParameters.IsResumedSession)
                     {
                         securityParameters.m_masterSecret = m_sessionMasterSecret;
                         m_recordStream.SetPendingCipher(TlsUtilities.InitCipher(m_tlsServerContext));