From 0db55f1b5e2dbed6bc774432be7172abe3daa1e4 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Wed, 2 Mar 2022 16:36:48 +0700 Subject: RFC 8879 preliminaries --- crypto/BouncyCastle.Android.csproj | 1 + crypto/BouncyCastle.csproj | 1 + crypto/BouncyCastle.iOS.csproj | 1 + crypto/crypto.csproj | 5 +++ crypto/src/tls/CertificateCompressionAlgorithm.cs | 47 +++++++++++++++++++++++ crypto/src/tls/ExtensionType.cs | 8 ++++ crypto/src/tls/HandshakeType.cs | 8 ++++ crypto/src/tls/TlsClientProtocol.cs | 2 + crypto/src/tls/TlsExtensionsUtilities.cs | 32 +++++++++++++++ crypto/src/tls/TlsServerProtocol.cs | 2 + crypto/src/tls/TlsUtilities.cs | 36 +++++++++++++++++ 11 files changed, 143 insertions(+) create mode 100644 crypto/src/tls/CertificateCompressionAlgorithm.cs diff --git a/crypto/BouncyCastle.Android.csproj b/crypto/BouncyCastle.Android.csproj index 875c99cfe..3d84af346 100644 --- a/crypto/BouncyCastle.Android.csproj +++ b/crypto/BouncyCastle.Android.csproj @@ -1602,6 +1602,7 @@ + diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj index f7083b062..84d7bf6fc 100644 --- a/crypto/BouncyCastle.csproj +++ b/crypto/BouncyCastle.csproj @@ -1596,6 +1596,7 @@ + diff --git a/crypto/BouncyCastle.iOS.csproj b/crypto/BouncyCastle.iOS.csproj index 4490f0f07..d76444e71 100644 --- a/crypto/BouncyCastle.iOS.csproj +++ b/crypto/BouncyCastle.iOS.csproj @@ -1597,6 +1597,7 @@ + diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index d3666bfcf..092331032 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -7868,6 +7868,11 @@ SubType = "Code" BuildAction = "Compile" /> + + public static void AddCompressCertificateExtension(IDictionary extensions, int[] algorithms) + { + extensions[ExtensionType.compress_certificate] = CreateCompressCertificateExtension(algorithms); + } + /// public static void AddCookieExtension(IDictionary extensions, byte[] cookie) { @@ -279,6 +285,13 @@ namespace Org.BouncyCastle.Tls return extensionData == null ? (short)-1 : ReadCertificateTypeExtensionServer(extensionData); } + /// + public static int[] GetCompressCertificateExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.compress_certificate); + return extensionData == null ? null : ReadCompressCertificateExtension(extensionData); + } + /// public static byte[] GetCookieExtension(IDictionary extensions) { @@ -579,6 +592,15 @@ namespace Org.BouncyCastle.Tls return CreateEmptyExtensionData(); } + /// + public static byte[] CreateCompressCertificateExtension(int[] algorithms) + { + if (TlsUtilities.IsNullOrEmpty(algorithms) || algorithms.Length > 127) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeUint16ArrayWithUint8Length(algorithms); + } + /// public static byte[] CreateCookieExtension(byte[] cookie) { @@ -994,6 +1016,16 @@ namespace Org.BouncyCastle.Tls return ReadEmptyExtensionData(extensionData); } + /// + public static int[] ReadCompressCertificateExtension(byte[] extensionData) + { + int[] algorithms = TlsUtilities.DecodeUint16ArrayWithUint8Length(extensionData); + if (algorithms.Length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return algorithms; + } + /// public static byte[] ReadCookieExtension(byte[] extensionData) { diff --git a/crypto/src/tls/TlsServerProtocol.cs b/crypto/src/tls/TlsServerProtocol.cs index 40218a2fb..22700a277 100644 --- a/crypto/src/tls/TlsServerProtocol.cs +++ b/crypto/src/tls/TlsServerProtocol.cs @@ -834,6 +834,7 @@ namespace Org.BouncyCastle.Tls case HandshakeType.certificate_status: case HandshakeType.certificate_url: case HandshakeType.client_key_exchange: + case HandshakeType.compressed_certificate: case HandshakeType.encrypted_extensions: case HandshakeType.end_of_early_data: case HandshakeType.hello_request: @@ -1201,6 +1202,7 @@ namespace Org.BouncyCastle.Tls case HandshakeType.certificate_request: case HandshakeType.certificate_status: case HandshakeType.certificate_url: + case HandshakeType.compressed_certificate: case HandshakeType.encrypted_extensions: case HandshakeType.end_of_early_data: case HandshakeType.hello_request: diff --git a/crypto/src/tls/TlsUtilities.cs b/crypto/src/tls/TlsUtilities.cs index 8733fd68f..f48c7e731 100644 --- a/crypto/src/tls/TlsUtilities.cs +++ b/crypto/src/tls/TlsUtilities.cs @@ -486,6 +486,14 @@ namespace Org.BouncyCastle.Tls } } + public static void WriteUint16ArrayWithUint8Length(int[] u16s, byte[] buf, int offset) + { + int length = 2 * u16s.Length; + CheckUint8(length); + WriteUint8(length, buf, offset); + WriteUint16Array(u16s, buf, offset + 1); + } + public static void WriteUint16ArrayWithUint16Length(int[] u16s, Stream output) { int length = 2 * u16s.Length; @@ -577,6 +585,25 @@ namespace Org.BouncyCastle.Tls return ReadUint16(buf, 0); } + public static int[] DecodeUint16ArrayWithUint8Length(byte[] buf) + { + if (buf == null) + throw new ArgumentNullException("buf"); + + int length = ReadUint8(buf, 0); + if (buf.Length != (length + 1) || (length & 1) != 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int count = length / 2, pos = 1; + int[] u16s = new int[count]; + for (int i = 0; i < count; ++i) + { + u16s[i] = ReadUint16(buf, pos); + pos += 2; + } + return u16s; + } + public static long DecodeUint32(byte[] buf) { if (buf == null) @@ -636,6 +663,14 @@ namespace Org.BouncyCastle.Tls return encoding; } + public static byte[] EncodeUint16ArrayWithUint8Length(int[] u16s) + { + int length = 2 * u16s.Length; + byte[] result = new byte[1 + length]; + WriteUint16ArrayWithUint8Length(u16s, result, 0); + return result; + } + public static byte[] EncodeUint16ArrayWithUint16Length(int[] u16s) { int length = 2 * u16s.Length; @@ -5348,6 +5383,7 @@ namespace Org.BouncyCastle.Tls } } case ExtensionType.signature_algorithms: + case ExtensionType.compress_certificate: case ExtensionType.certificate_authorities: case ExtensionType.signature_algorithms_cert: { -- cgit 1.4.1 From a172fd5b8b658a99e4ed8152b08ef3b0054de795 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 12 Mar 2022 00:39:34 +0700 Subject: Refactoring --- .../impl/bc/BcDefaultTlsCredentialedAgreement.cs | 2 +- crypto/src/tls/crypto/impl/bc/BcTlsDH.cs | 4 ---- crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs | 28 ++++++++++------------ crypto/src/tls/crypto/impl/bc/BcTlsECDomain.cs | 20 ++++++++-------- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs b/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs index 15944cd89..863b96634 100644 --- a/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs +++ b/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs @@ -100,7 +100,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC { BcTlsCertificate bcCert = BcTlsCertificate.Convert(m_crypto, peerCertificate); ECPublicKeyParameters peerPublicKey = bcCert.GetPubKeyEC(); - return BcTlsECDomain.CalculateBasicAgreement(m_crypto, m_privateKey, peerPublicKey); + return BcTlsECDomain.CalculateECDHAgreement(m_crypto, m_privateKey, peerPublicKey); } public Certificate Certificate diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsDH.cs b/crypto/src/tls/crypto/impl/bc/BcTlsDH.cs index 8af94f7c6..63fa00ce4 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsDH.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsDH.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; @@ -20,7 +19,6 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC this.m_domain = domain; } - /// public virtual byte[] GenerateEphemeral() { this.m_localKeyPair = m_domain.GenerateKeyPair(); @@ -28,13 +26,11 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC return m_domain.EncodePublicKey((DHPublicKeyParameters)m_localKeyPair.Public); } - /// public virtual void ReceivePeerValue(byte[] peerValue) { this.m_peerPublicKey = m_domain.DecodePublicKey(peerValue); } - /// public virtual TlsSecret CalculateSecret() { return m_domain.CalculateDHAgreement((DHPrivateKeyParameters)m_localKeyPair.Private, m_peerPublicKey); diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs b/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs index 90b8ce94f..faf6b4576 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs @@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC return crypto.AdoptLocalSecret(secret); } - public static DHParameters GetParameters(TlsDHConfig dhConfig) + public static DHParameters GetDomainParameters(TlsDHConfig dhConfig) { DHGroup dhGroup = TlsDHUtilities.GetDHGroup(dhConfig); if (dhGroup == null) @@ -46,21 +46,21 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC return new DHParameters(dhGroup.P, dhGroup.G, dhGroup.Q, dhGroup.L); } - protected readonly BcTlsCrypto crypto; - protected readonly TlsDHConfig dhConfig; - protected readonly DHParameters dhParameters; + protected readonly BcTlsCrypto m_crypto; + protected readonly TlsDHConfig m_config; + protected readonly DHParameters m_domainParameters; public BcTlsDHDomain(BcTlsCrypto crypto, TlsDHConfig dhConfig) { - this.crypto = crypto; - this.dhConfig = dhConfig; - this.dhParameters = GetParameters(dhConfig); + this.m_crypto = crypto; + this.m_config = dhConfig; + this.m_domainParameters = GetDomainParameters(dhConfig); } public virtual BcTlsSecret CalculateDHAgreement(DHPrivateKeyParameters privateKey, DHPublicKeyParameters publicKey) { - return CalculateDHAgreement(crypto, privateKey, publicKey, dhConfig.IsPadded); + return CalculateDHAgreement(m_crypto, privateKey, publicKey, m_config.IsPadded); } public virtual TlsAgreement CreateDH() @@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC /// public virtual BigInteger DecodeParameter(byte[] encoding) { - if (dhConfig.IsPadded && GetValueLength(dhParameters) != encoding.Length) + if (m_config.IsPadded && GetValueLength(m_domainParameters) != encoding.Length) throw new TlsFatalAlert(AlertDescription.illegal_parameter); return new BigInteger(1, encoding); @@ -89,7 +89,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC { BigInteger y = DecodeParameter(encoding); - return new DHPublicKeyParameters(y, dhParameters); + return new DHPublicKeyParameters(y, m_domainParameters); } catch (Exception e) { @@ -97,22 +97,20 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC } } - /// public virtual byte[] EncodeParameter(BigInteger x) { - return EncodeValue(dhParameters, dhConfig.IsPadded, x); + return EncodeValue(m_domainParameters, m_config.IsPadded, x); } - /// public virtual byte[] EncodePublicKey(DHPublicKeyParameters publicKey) { - return EncodeValue(dhParameters, true, publicKey.Y); + return EncodeValue(m_domainParameters, true, publicKey.Y); } public virtual AsymmetricCipherKeyPair GenerateKeyPair() { DHBasicKeyPairGenerator keyPairGenerator = new DHBasicKeyPairGenerator(); - keyPairGenerator.Init(new DHKeyGenerationParameters(crypto.SecureRandom, dhParameters)); + keyPairGenerator.Init(new DHKeyGenerationParameters(m_crypto.SecureRandom, m_domainParameters)); return keyPairGenerator.GenerateKeyPair(); } } diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsECDomain.cs b/crypto/src/tls/crypto/impl/bc/BcTlsECDomain.cs index 61d11fb42..ab3481924 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsECDomain.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsECDomain.cs @@ -4,7 +4,6 @@ using System.IO; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Agreement; -using Org.BouncyCastle.Crypto.EC; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; @@ -19,7 +18,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC public class BcTlsECDomain : TlsECDomain { - public static BcTlsSecret CalculateBasicAgreement(BcTlsCrypto crypto, ECPrivateKeyParameters privateKey, + public static BcTlsSecret CalculateECDHAgreement(BcTlsCrypto crypto, ECPrivateKeyParameters privateKey, ECPublicKeyParameters publicKey) { ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement(); @@ -57,20 +56,20 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC } protected readonly BcTlsCrypto m_crypto; - protected readonly TlsECConfig m_ecConfig; - protected readonly ECDomainParameters m_ecDomainParameters; + protected readonly TlsECConfig m_config; + protected readonly ECDomainParameters m_domainParameters; public BcTlsECDomain(BcTlsCrypto crypto, TlsECConfig ecConfig) { this.m_crypto = crypto; - this.m_ecConfig = ecConfig; - this.m_ecDomainParameters = GetDomainParameters(ecConfig); + this.m_config = ecConfig; + this.m_domainParameters = GetDomainParameters(ecConfig); } public virtual BcTlsSecret CalculateECDHAgreement(ECPrivateKeyParameters privateKey, ECPublicKeyParameters publicKey) { - return CalculateBasicAgreement(m_crypto, privateKey, publicKey); + return CalculateECDHAgreement(m_crypto, privateKey, publicKey); } public virtual TlsAgreement CreateECDH() @@ -80,16 +79,17 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC public virtual ECPoint DecodePoint(byte[] encoding) { - return m_ecDomainParameters.Curve.DecodePoint(encoding); + return m_domainParameters.Curve.DecodePoint(encoding); } + /// public virtual ECPublicKeyParameters DecodePublicKey(byte[] encoding) { try { ECPoint point = DecodePoint(encoding); - return new ECPublicKeyParameters(point, m_ecDomainParameters); + return new ECPublicKeyParameters(point, m_domainParameters); } catch (IOException e) { @@ -114,7 +114,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC public virtual AsymmetricCipherKeyPair GenerateKeyPair() { ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); - keyPairGenerator.Init(new ECKeyGenerationParameters(m_ecDomainParameters, m_crypto.SecureRandom)); + keyPairGenerator.Init(new ECKeyGenerationParameters(m_domainParameters, m_crypto.SecureRandom)); return keyPairGenerator.GenerateKeyPair(); } } -- cgit 1.4.1 From 7951d59c4f69b5cf733ddf0f1911e82d56dc3217 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Wed, 16 Mar 2022 15:49:34 +0700 Subject: Refactoring --- crypto/src/tls/crypto/TlsCryptoUtilities.cs | 18 ++++++++++++++++++ crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs | 20 +++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/crypto/src/tls/crypto/TlsCryptoUtilities.cs b/crypto/src/tls/crypto/TlsCryptoUtilities.cs index a22049e5d..757eda1be 100644 --- a/crypto/src/tls/crypto/TlsCryptoUtilities.cs +++ b/crypto/src/tls/crypto/TlsCryptoUtilities.cs @@ -68,6 +68,24 @@ namespace Org.BouncyCastle.Tls.Crypto } } + public static int GetHashInternalSize(int cryptoHashAlgorithm) + { + switch (cryptoHashAlgorithm) + { + case CryptoHashAlgorithm.md5: + case CryptoHashAlgorithm.sha1: + case CryptoHashAlgorithm.sha224: + case CryptoHashAlgorithm.sha256: + case CryptoHashAlgorithm.sm3: + return 64; + case CryptoHashAlgorithm.sha384: + case CryptoHashAlgorithm.sha512: + return 128; + default: + throw new ArgumentException(); + } + } + public static int GetHashOutputSize(int cryptoHashAlgorithm) { switch (cryptoHashAlgorithm) diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs index 69e353bae..e763422ed 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs @@ -139,9 +139,10 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC public override TlsNonceGenerator CreateNonceGenerator(byte[] additionalSeedMaterial) { - IDigest digest = CreateDigest(CryptoHashAlgorithm.sha256); + int cryptoHashAlgorithm = CryptoHashAlgorithm.sha256; + IDigest digest = CreateDigest(cryptoHashAlgorithm); - byte[] seed = new byte[digest.GetDigestSize()]; + byte[] seed = new byte[TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm)]; SecureRandom.NextBytes(seed); DigestRandomGenerator randomGenerator = new DigestRandomGenerator(digest); @@ -187,7 +188,20 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC public override bool HasCryptoHashAlgorithm(int cryptoHashAlgorithm) { - return true; + switch (cryptoHashAlgorithm) + { + case CryptoHashAlgorithm.md5: + case CryptoHashAlgorithm.sha1: + case CryptoHashAlgorithm.sha224: + case CryptoHashAlgorithm.sha256: + case CryptoHashAlgorithm.sha384: + case CryptoHashAlgorithm.sha512: + case CryptoHashAlgorithm.sm3: + return true; + + default: + return false; + } } public override bool HasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm) -- cgit 1.4.1 From e7844d7f83a4d5321f02c9f169cd206149e9a184 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Wed, 16 Mar 2022 22:12:00 +0700 Subject: DTLS: delayed handshake hash update - avoid clone of handshake hash --- crypto/src/tls/DeferredHash.cs | 21 ++-- crypto/src/tls/DtlsReliableHandshake.cs | 185 +++++++++++++++++--------------- crypto/src/tls/DtlsServerProtocol.cs | 13 ++- crypto/src/tls/TlsClientProtocol.cs | 2 +- crypto/src/tls/TlsHandshakeHash.cs | 2 +- crypto/src/tls/TlsServerProtocol.cs | 4 +- 6 files changed, 122 insertions(+), 105 deletions(-) diff --git a/crypto/src/tls/DeferredHash.cs b/crypto/src/tls/DeferredHash.cs index bba3019a1..f97e9c088 100644 --- a/crypto/src/tls/DeferredHash.cs +++ b/crypto/src/tls/DeferredHash.cs @@ -16,7 +16,7 @@ namespace Org.BouncyCastle.Tls private readonly TlsContext m_context; private DigestInputBuffer m_buf; - private readonly IDictionary m_hashes; + private IDictionary m_hashes; private bool m_forceBuffering; private bool m_sealed; @@ -29,21 +29,12 @@ namespace Org.BouncyCastle.Tls this.m_sealed = false; } - private DeferredHash(TlsContext context, IDictionary hashes) - { - this.m_context = context; - this.m_buf = null; - this.m_hashes = hashes; - this.m_forceBuffering = false; - this.m_sealed = true; - } - /// public void CopyBufferTo(Stream output) { if (m_buf == null) { - // If you see this, you need to call forceBuffering() before SealHashAlgorithms() + // If you see this, you need to call ForceBuffering() before SealHashAlgorithms() throw new InvalidOperationException("Not buffering"); } @@ -96,7 +87,7 @@ namespace Org.BouncyCastle.Tls CheckStopBuffering(); } - public TlsHandshakeHash StopTracking() + public void StopTracking() { SecurityParameters securityParameters = m_context.SecurityParameters; @@ -116,7 +107,11 @@ namespace Org.BouncyCastle.Tls break; } } - return new DeferredHash(m_context, newHashes); + + this.m_buf = null; + this.m_hashes = newHashes; + this.m_forceBuffering = false; + this.m_sealed = true; } public TlsHash ForkPrfHash() diff --git a/crypto/src/tls/DtlsReliableHandshake.cs b/crypto/src/tls/DtlsReliableHandshake.cs index e27d72762..58b9301fd 100644 --- a/crypto/src/tls/DtlsReliableHandshake.cs +++ b/crypto/src/tls/DtlsReliableHandshake.cs @@ -142,11 +142,9 @@ namespace Org.BouncyCastle.Tls get { return m_handshakeHash; } } - internal TlsHandshakeHash PrepareToFinish() + internal void PrepareToFinish() { - TlsHandshakeHash result = m_handshakeHash; - this.m_handshakeHash = m_handshakeHash.StopTracking(); - return result; + m_handshakeHash.StopTracking(); } /// @@ -172,70 +170,64 @@ namespace Org.BouncyCastle.Tls UpdateHandshakeMessagesDigest(message); } + /// + internal Message ReceiveMessage() + { + Message message = ImplReceiveMessage(); + UpdateHandshakeMessagesDigest(message); + return message; + } + /// internal byte[] ReceiveMessageBody(short msg_type) { - Message message = ReceiveMessage(); + Message message = ImplReceiveMessage(); if (message.Type != msg_type) throw new TlsFatalAlert(AlertDescription.unexpected_message); + UpdateHandshakeMessagesDigest(message); return message.Body; } /// - internal Message ReceiveMessage() + internal Message ReceiveMessageDelayedDigest(short msg_type) { - long currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); - - if (null == m_resendTimeout) - { - m_resendMillis = INITIAL_RESEND_MILLIS; - m_resendTimeout = new Timeout(m_resendMillis, currentTimeMillis); - - PrepareInboundFlight(Platform.CreateHashtable()); - } + Message message = ImplReceiveMessage(); + if (message.Type != msg_type) + throw new TlsFatalAlert(AlertDescription.unexpected_message); - byte[] buf = null; + return message; + } - for (;;) + /// + internal Message UpdateHandshakeMessagesDigest(Message message) + { + short msg_type = message.Type; + switch (msg_type) { - if (m_recordLayer.IsClosed) - throw new TlsFatalAlert(AlertDescription.user_canceled); - - Message pending = GetPendingMessage(); - if (pending != null) - return pending; - - if (Timeout.HasExpired(m_handshakeTimeout, currentTimeMillis)) - throw new TlsTimeoutException("Handshake timed out"); - - int waitMillis = Timeout.GetWaitMillis(m_handshakeTimeout, currentTimeMillis); - waitMillis = Timeout.ConstrainWaitMillis(waitMillis, m_resendTimeout, currentTimeMillis); - - // NOTE: Ensure a finite wait, of at least 1ms - if (waitMillis < 1) - { - waitMillis = 1; - } - - int receiveLimit = m_recordLayer.GetReceiveLimit(); - if (buf == null || buf.Length < receiveLimit) - { - buf = new byte[receiveLimit]; - } - - int received = m_recordLayer.Receive(buf, 0, receiveLimit, waitMillis); - if (received < 0) - { - ResendOutboundFlight(); - } - else - { - ProcessRecord(MAX_RECEIVE_AHEAD, m_recordLayer.ReadEpoch, buf, 0, received); - } + case HandshakeType.hello_request: + case HandshakeType.hello_verify_request: + case HandshakeType.key_update: + break; - currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + // TODO[dtls13] Not included in the transcript for (D)TLS 1.3+ + case HandshakeType.new_session_ticket: + default: + { + byte[] body = message.Body; + byte[] buf = new byte[MESSAGE_HEADER_LENGTH]; + TlsUtilities.WriteUint8(msg_type, buf, 0); + TlsUtilities.WriteUint24(body.Length, buf, 1); + TlsUtilities.WriteUint16(message.Seq, buf, 4); + TlsUtilities.WriteUint24(0, buf, 6); + TlsUtilities.WriteUint24(body.Length, buf, 9); + m_handshakeHash.Update(buf, 0, buf.Length); + m_handshakeHash.Update(body, 0, body.Length); + break; + } } + + return message; } internal void Finish() @@ -297,12 +289,68 @@ namespace Org.BouncyCastle.Tls if (body != null) { m_previousInboundFlight = null; - return UpdateHandshakeMessagesDigest(new Message(m_next_receive_seq++, next.MsgType, body)); + return new Message(m_next_receive_seq++, next.MsgType, body); } } return null; } + /// + private Message ImplReceiveMessage() + { + long currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + + if (null == m_resendTimeout) + { + m_resendMillis = INITIAL_RESEND_MILLIS; + m_resendTimeout = new Timeout(m_resendMillis, currentTimeMillis); + + PrepareInboundFlight(Platform.CreateHashtable()); + } + + byte[] buf = null; + + for (; ; ) + { + if (m_recordLayer.IsClosed) + throw new TlsFatalAlert(AlertDescription.user_canceled); + + Message pending = GetPendingMessage(); + if (pending != null) + return pending; + + if (Timeout.HasExpired(m_handshakeTimeout, currentTimeMillis)) + throw new TlsTimeoutException("Handshake timed out"); + + int waitMillis = Timeout.GetWaitMillis(m_handshakeTimeout, currentTimeMillis); + waitMillis = Timeout.ConstrainWaitMillis(waitMillis, m_resendTimeout, currentTimeMillis); + + // NOTE: Ensure a finite wait, of at least 1ms + if (waitMillis < 1) + { + waitMillis = 1; + } + + int receiveLimit = m_recordLayer.GetReceiveLimit(); + if (buf == null || buf.Length < receiveLimit) + { + buf = new byte[receiveLimit]; + } + + int received = m_recordLayer.Receive(buf, 0, receiveLimit, waitMillis); + if (received < 0) + { + ResendOutboundFlight(); + } + else + { + ProcessRecord(MAX_RECEIVE_AHEAD, m_recordLayer.ReadEpoch, buf, 0, received); + } + + currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + } + } + private void PrepareInboundFlight(IDictionary nextFlight) { ResetAll(m_currentInboundFlight); @@ -399,37 +447,6 @@ namespace Org.BouncyCastle.Tls m_resendTimeout = new Timeout(m_resendMillis); } - /// - private Message UpdateHandshakeMessagesDigest(Message message) - { - short msg_type = message.Type; - switch (msg_type) - { - case HandshakeType.hello_request: - case HandshakeType.hello_verify_request: - case HandshakeType.key_update: - break; - - // TODO[dtls13] Not included in the transcript for (D)TLS 1.3+ - case HandshakeType.new_session_ticket: - default: - { - byte[] body = message.Body; - byte[] buf = new byte[MESSAGE_HEADER_LENGTH]; - TlsUtilities.WriteUint8(msg_type, buf, 0); - TlsUtilities.WriteUint24(body.Length, buf, 1); - TlsUtilities.WriteUint16(message.Seq, buf, 4); - TlsUtilities.WriteUint24(0, buf, 6); - TlsUtilities.WriteUint24(body.Length, buf, 9); - m_handshakeHash.Update(buf, 0, buf.Length); - m_handshakeHash.Update(body, 0, body.Length); - break; - } - } - - return message; - } - /// private void WriteMessage(Message message) { diff --git a/crypto/src/tls/DtlsServerProtocol.cs b/crypto/src/tls/DtlsServerProtocol.cs index 99c47ba1b..b49122423 100644 --- a/crypto/src/tls/DtlsServerProtocol.cs +++ b/crypto/src/tls/DtlsServerProtocol.cs @@ -297,12 +297,17 @@ namespace Org.BouncyCastle.Tls * parameters). */ { - TlsHandshakeHash certificateVerifyHash = handshake.PrepareToFinish(); - if (ExpectCertificateVerifyMessage(state)) { - byte[] certificateVerifyBody = handshake.ReceiveMessageBody(HandshakeType.certificate_verify); - ProcessCertificateVerify(state, certificateVerifyBody, certificateVerifyHash); + clientMessage = handshake.ReceiveMessageDelayedDigest(HandshakeType.certificate_verify); + byte[] certificateVerifyBody = clientMessage.Body; + ProcessCertificateVerify(state, certificateVerifyBody, handshake.HandshakeHash); + handshake.PrepareToFinish(); + handshake.UpdateHandshakeMessagesDigest(clientMessage); + } + else + { + handshake.PrepareToFinish(); } } diff --git a/crypto/src/tls/TlsClientProtocol.cs b/crypto/src/tls/TlsClientProtocol.cs index 19e2eda3d..cb59289ae 100644 --- a/crypto/src/tls/TlsClientProtocol.cs +++ b/crypto/src/tls/TlsClientProtocol.cs @@ -609,7 +609,7 @@ namespace Org.BouncyCastle.Tls this.m_connectionState = CS_CLIENT_CERTIFICATE_VERIFY; } - this.m_handshakeHash = m_handshakeHash.StopTracking(); + m_handshakeHash.StopTracking(); SendChangeCipherSpec(); SendFinishedMessage(); diff --git a/crypto/src/tls/TlsHandshakeHash.cs b/crypto/src/tls/TlsHandshakeHash.cs index aa33c680d..88aeaaa32 100644 --- a/crypto/src/tls/TlsHandshakeHash.cs +++ b/crypto/src/tls/TlsHandshakeHash.cs @@ -20,7 +20,7 @@ namespace Org.BouncyCastle.Tls void SealHashAlgorithms(); - TlsHandshakeHash StopTracking(); + void StopTracking(); TlsHash ForkPrfHash(); diff --git a/crypto/src/tls/TlsServerProtocol.cs b/crypto/src/tls/TlsServerProtocol.cs index 22700a277..0ab8a7a98 100644 --- a/crypto/src/tls/TlsServerProtocol.cs +++ b/crypto/src/tls/TlsServerProtocol.cs @@ -1322,7 +1322,7 @@ namespace Org.BouncyCastle.Tls TlsUtilities.VerifyCertificateVerifyClient(m_tlsServerContext, m_certificateRequest, certificateVerify, m_handshakeHash); - this.m_handshakeHash = m_handshakeHash.StopTracking(); + m_handshakeHash.StopTracking(); } /// @@ -1357,7 +1357,7 @@ namespace Org.BouncyCastle.Tls if (!ExpectCertificateVerifyMessage()) { - this.m_handshakeHash = m_handshakeHash.StopTracking(); + m_handshakeHash.StopTracking(); } } -- cgit 1.4.1 From 228c8e787b21b1b471cf4021d72150eb3f1ee791 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Wed, 16 Mar 2022 23:53:43 +0700 Subject: Fix return type --- crypto/src/tls/DtlsReliableHandshake.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crypto/src/tls/DtlsReliableHandshake.cs b/crypto/src/tls/DtlsReliableHandshake.cs index 58b9301fd..7581e4766 100644 --- a/crypto/src/tls/DtlsReliableHandshake.cs +++ b/crypto/src/tls/DtlsReliableHandshake.cs @@ -200,7 +200,7 @@ namespace Org.BouncyCastle.Tls } /// - internal Message UpdateHandshakeMessagesDigest(Message message) + internal void UpdateHandshakeMessagesDigest(Message message) { short msg_type = message.Type; switch (msg_type) @@ -226,8 +226,6 @@ namespace Org.BouncyCastle.Tls break; } } - - return message; } internal void Finish() @@ -310,7 +308,7 @@ namespace Org.BouncyCastle.Tls byte[] buf = null; - for (; ; ) + for (;;) { if (m_recordLayer.IsClosed) throw new TlsFatalAlert(AlertDescription.user_canceled); -- cgit 1.4.1 From f9f4d1a20f8658b9145662f16b0b18c69f673837 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Thu, 17 Mar 2022 01:36:02 +0700 Subject: Refactoring --- crypto/src/tls/DeferredHash.cs | 20 +++++++++++--------- crypto/src/tls/DigestInputBuffer.cs | 2 +- crypto/src/tls/TlsUtilities.cs | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/crypto/src/tls/DeferredHash.cs b/crypto/src/tls/DeferredHash.cs index f97e9c088..ac66c8f0c 100644 --- a/crypto/src/tls/DeferredHash.cs +++ b/crypto/src/tls/DeferredHash.cs @@ -38,7 +38,7 @@ namespace Org.BouncyCastle.Tls throw new InvalidOperationException("Not buffering"); } - m_buf.CopyTo(output); + m_buf.CopyInputTo(output); } public void ForceBuffering() @@ -97,8 +97,8 @@ namespace Org.BouncyCastle.Tls case PrfAlgorithm.ssl_prf_legacy: case PrfAlgorithm.tls_prf_legacy: { - CloneHash(newHashes, HashAlgorithm.md5); - CloneHash(newHashes, HashAlgorithm.sha1); + CloneHash(newHashes, CryptoHashAlgorithm.md5); + CloneHash(newHashes, CryptoHashAlgorithm.sha1); break; } default: @@ -126,7 +126,9 @@ namespace Org.BouncyCastle.Tls case PrfAlgorithm.ssl_prf_legacy: case PrfAlgorithm.tls_prf_legacy: { - prfHash = new CombinedHash(m_context, CloneHash(HashAlgorithm.md5), CloneHash(HashAlgorithm.sha1)); + TlsHash md5Hash = CloneHash(CryptoHashAlgorithm.md5); + TlsHash sha1Hash = CloneHash(CryptoHashAlgorithm.sha1); + prfHash = new CombinedHash(m_context, md5Hash, sha1Hash); break; } default: @@ -146,20 +148,20 @@ namespace Org.BouncyCastle.Tls public byte[] GetFinalHash(int cryptoHashAlgorithm) { - TlsHash d = (TlsHash)m_hashes[cryptoHashAlgorithm]; - if (d == null) + TlsHash hash = (TlsHash)m_hashes[cryptoHashAlgorithm]; + if (hash == null) throw new InvalidOperationException("CryptoHashAlgorithm." + cryptoHashAlgorithm + " is not being tracked"); CheckStopBuffering(); - d = d.CloneHash(); + hash = hash.CloneHash(); if (m_buf != null) { - m_buf.UpdateDigest(d); + m_buf.UpdateDigest(hash); } - return d.CalculateHash(); + return hash.CalculateHash(); } public void Update(byte[] input, int inOff, int len) diff --git a/crypto/src/tls/DigestInputBuffer.cs b/crypto/src/tls/DigestInputBuffer.cs index 7dd525f88..9b4ea4b06 100644 --- a/crypto/src/tls/DigestInputBuffer.cs +++ b/crypto/src/tls/DigestInputBuffer.cs @@ -15,7 +15,7 @@ namespace Org.BouncyCastle.Tls } /// - internal void CopyTo(Stream output) + internal void CopyInputTo(Stream output) { // TODO[tls-port] // NOTE: Copy data since the output here may be under control of external code. diff --git a/crypto/src/tls/TlsUtilities.cs b/crypto/src/tls/TlsUtilities.cs index f48c7e731..1d9759bca 100644 --- a/crypto/src/tls/TlsUtilities.cs +++ b/crypto/src/tls/TlsUtilities.cs @@ -2118,7 +2118,7 @@ namespace Org.BouncyCastle.Tls output.Write(extraSignatureInput, 0, extraSignatureInput.Length); } - buf.CopyTo(output); + buf.CopyInputTo(output); Platform.Dispose(output); } -- cgit 1.4.1