summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/BouncyCastle.Android.csproj7
-rw-r--r--crypto/BouncyCastle.csproj7
-rw-r--r--crypto/BouncyCastle.iOS.csproj7
-rw-r--r--crypto/Readme.html22
-rw-r--r--crypto/crypto.csproj35
-rw-r--r--crypto/src/crypto/macs/HMac.cs14
-rw-r--r--crypto/src/crypto/signers/PssSigner.cs28
-rw-r--r--crypto/src/tls/AbstractTlsPeer.cs3
-rw-r--r--crypto/src/tls/CertificateVerify.cs57
-rw-r--r--crypto/src/tls/DefaultTlsClient.cs6
-rw-r--r--crypto/src/tls/DefaultTlsServer.cs12
-rw-r--r--crypto/src/tls/DigitallySigned.cs18
-rw-r--r--crypto/src/tls/DtlsClientProtocol.cs103
-rw-r--r--crypto/src/tls/DtlsServerProtocol.cs37
-rw-r--r--crypto/src/tls/KeyExchangeAlgorithm.cs13
-rw-r--r--crypto/src/tls/ProtocolVersion.cs72
-rw-r--r--crypto/src/tls/PskTlsClient.cs2
-rw-r--r--crypto/src/tls/PskTlsServer.cs2
-rw-r--r--crypto/src/tls/SignatureAlgorithm.cs43
-rw-r--r--crypto/src/tls/SignatureScheme.cs7
-rw-r--r--crypto/src/tls/SrpTlsClient.cs2
-rw-r--r--crypto/src/tls/SrpTlsServer.cs2
-rw-r--r--crypto/src/tls/TlsClientProtocol.cs117
-rw-r--r--crypto/src/tls/TlsServerProtocol.cs43
-rw-r--r--crypto/src/tls/TlsUtilities.cs269
-rw-r--r--crypto/src/tls/crypto/CryptoSignatureAlgorithm.cs3
-rw-r--r--crypto/src/tls/crypto/Tls13Verifier.cs14
-rw-r--r--crypto/src/tls/crypto/TlsCertificate.cs2
-rw-r--r--crypto/src/tls/crypto/TlsCrypto.cs22
-rw-r--r--crypto/src/tls/crypto/TlsCryptoUtilities.cs35
-rw-r--r--crypto/src/tls/crypto/TlsStreamSigner.cs2
-rw-r--r--crypto/src/tls/crypto/TlsStreamVerifier.cs2
-rw-r--r--crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs6
-rw-r--r--crypto/src/tls/crypto/impl/LegacyTls13Verifier.cs60
-rw-r--r--crypto/src/tls/crypto/impl/TlsAeadCipher.cs5
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTls13Verifier.cs32
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsCertificate.cs106
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs49
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs40
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs28
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs28
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs16
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs9
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs4
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs4
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs4
-rw-r--r--crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs75
-rw-r--r--crypto/test/src/tls/test/DtlsTestSuite.cs80
-rw-r--r--crypto/test/src/tls/test/MockDtlsClient.cs2
-rw-r--r--crypto/test/src/tls/test/MockDtlsServer.cs2
-rw-r--r--crypto/test/src/tls/test/MockTlsServer.cs36
-rw-r--r--crypto/test/src/tls/test/TlsTestClientImpl.cs52
-rw-r--r--crypto/test/src/tls/test/TlsTestClientProtocol.cs10
-rw-r--r--crypto/test/src/tls/test/TlsTestConfig.cs4
-rw-r--r--crypto/test/src/tls/test/TlsTestServerImpl.cs4
-rw-r--r--crypto/test/src/tls/test/TlsTestSuite.cs64
56 files changed, 1066 insertions, 662 deletions
diff --git a/crypto/BouncyCastle.Android.csproj b/crypto/BouncyCastle.Android.csproj

index 3d84af346..9f584cd3b 100644 --- a/crypto/BouncyCastle.Android.csproj +++ b/crypto/BouncyCastle.Android.csproj
@@ -1611,6 +1611,7 @@ <Compile Include="src\tls\CertificateStatusType.cs" /> <Compile Include="src\tls\CertificateType.cs" /> <Compile Include="src\tls\CertificateUrl.cs" /> + <Compile Include="src\tls\CertificateVerify.cs" /> <Compile Include="src\tls\ChangeCipherSpec.cs" /> <Compile Include="src\tls\ChannelBinding.cs" /> <Compile Include="src\tls\CipherSuite.cs" /> @@ -1633,6 +1634,7 @@ <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedDecryptor.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedSigner.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcSsl3Hmac.cs" /> + <Compile Include="src\tls\crypto\impl\bc\BcTls13Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsAeadCipherImpl.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsBlockCipherImpl.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsCertificate.cs" /> @@ -1646,13 +1648,10 @@ <Compile Include="src\tls\crypto\impl\bc\BcTlsECDH.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDomain.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Signer.cs" /> - <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaSigner.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaVerifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Signer.cs" /> - <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Signer.cs" /> - <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsHash.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsHmac.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsNonceGenerator.cs" /> @@ -1674,6 +1673,7 @@ <Compile Include="src\tls\crypto\impl\bc\BcX25519Domain.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcX448.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcX448Domain.cs" /> + <Compile Include="src\tls\crypto\impl\LegacyTls13Verifier.cs" /> <Compile Include="src\tls\crypto\impl\RsaUtilities.cs" /> <Compile Include="src\tls\crypto\impl\TlsAeadCipher.cs" /> <Compile Include="src\tls\crypto\impl\TlsAeadCipherImpl.cs" /> @@ -1685,6 +1685,7 @@ <Compile Include="src\tls\crypto\impl\TlsSuiteMac.cs" /> <Compile Include="src\tls\crypto\Srp6Group.cs" /> <Compile Include="src\tls\crypto\Srp6StandardGroups.cs" /> + <Compile Include="src\tls\crypto\Tls13Verifier.cs" /> <Compile Include="src\tls\crypto\TlsAgreement.cs" /> <Compile Include="src\tls\crypto\TlsCertificate.cs" /> <Compile Include="src\tls\crypto\TlsCertificateRole.cs" /> diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj
index 84d7bf6fc..82ea19337 100644 --- a/crypto/BouncyCastle.csproj +++ b/crypto/BouncyCastle.csproj
@@ -1605,6 +1605,7 @@ <Compile Include="src\tls\CertificateStatusType.cs" /> <Compile Include="src\tls\CertificateType.cs" /> <Compile Include="src\tls\CertificateUrl.cs" /> + <Compile Include="src\tls\CertificateVerify.cs" /> <Compile Include="src\tls\ChangeCipherSpec.cs" /> <Compile Include="src\tls\ChannelBinding.cs" /> <Compile Include="src\tls\CipherSuite.cs" /> @@ -1627,6 +1628,7 @@ <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedDecryptor.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedSigner.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcSsl3Hmac.cs" /> + <Compile Include="src\tls\crypto\impl\bc\BcTls13Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsAeadCipherImpl.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsBlockCipherImpl.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsCertificate.cs" /> @@ -1640,13 +1642,10 @@ <Compile Include="src\tls\crypto\impl\bc\BcTlsECDH.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDomain.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Signer.cs" /> - <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaSigner.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaVerifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Signer.cs" /> - <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Signer.cs" /> - <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsHash.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsHmac.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsNonceGenerator.cs" /> @@ -1668,6 +1667,7 @@ <Compile Include="src\tls\crypto\impl\bc\BcX25519Domain.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcX448.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcX448Domain.cs" /> + <Compile Include="src\tls\crypto\impl\LegacyTls13Verifier.cs" /> <Compile Include="src\tls\crypto\impl\RsaUtilities.cs" /> <Compile Include="src\tls\crypto\impl\TlsAeadCipher.cs" /> <Compile Include="src\tls\crypto\impl\TlsAeadCipherImpl.cs" /> @@ -1679,6 +1679,7 @@ <Compile Include="src\tls\crypto\impl\TlsSuiteMac.cs" /> <Compile Include="src\tls\crypto\Srp6Group.cs" /> <Compile Include="src\tls\crypto\Srp6StandardGroups.cs" /> + <Compile Include="src\tls\crypto\Tls13Verifier.cs" /> <Compile Include="src\tls\crypto\TlsAgreement.cs" /> <Compile Include="src\tls\crypto\TlsCertificate.cs" /> <Compile Include="src\tls\crypto\TlsCertificateRole.cs" /> diff --git a/crypto/BouncyCastle.iOS.csproj b/crypto/BouncyCastle.iOS.csproj
index d76444e71..31ac62f93 100644 --- a/crypto/BouncyCastle.iOS.csproj +++ b/crypto/BouncyCastle.iOS.csproj
@@ -1606,6 +1606,7 @@ <Compile Include="src\tls\CertificateStatusType.cs" /> <Compile Include="src\tls\CertificateType.cs" /> <Compile Include="src\tls\CertificateUrl.cs" /> + <Compile Include="src\tls\CertificateVerify.cs" /> <Compile Include="src\tls\ChangeCipherSpec.cs" /> <Compile Include="src\tls\ChannelBinding.cs" /> <Compile Include="src\tls\CipherSuite.cs" /> @@ -1628,6 +1629,7 @@ <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedDecryptor.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcDefaultTlsCredentialedSigner.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcSsl3Hmac.cs" /> + <Compile Include="src\tls\crypto\impl\bc\BcTls13Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsAeadCipherImpl.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsBlockCipherImpl.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsCertificate.cs" /> @@ -1641,13 +1643,10 @@ <Compile Include="src\tls\crypto\impl\bc\BcTlsECDH.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDomain.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Signer.cs" /> - <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsa13Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaSigner.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsECDsaVerifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Signer.cs" /> - <Compile Include="src\tls\crypto\impl\bc\BcTlsEd25519Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Signer.cs" /> - <Compile Include="src\tls\crypto\impl\bc\BcTlsEd448Verifier.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsHash.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsHmac.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcTlsNonceGenerator.cs" /> @@ -1669,6 +1668,7 @@ <Compile Include="src\tls\crypto\impl\bc\BcX25519Domain.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcX448.cs" /> <Compile Include="src\tls\crypto\impl\bc\BcX448Domain.cs" /> + <Compile Include="src\tls\crypto\impl\LegacyTls13Verifier.cs" /> <Compile Include="src\tls\crypto\impl\RsaUtilities.cs" /> <Compile Include="src\tls\crypto\impl\TlsAeadCipher.cs" /> <Compile Include="src\tls\crypto\impl\TlsAeadCipherImpl.cs" /> @@ -1680,6 +1680,7 @@ <Compile Include="src\tls\crypto\impl\TlsSuiteMac.cs" /> <Compile Include="src\tls\crypto\Srp6Group.cs" /> <Compile Include="src\tls\crypto\Srp6StandardGroups.cs" /> + <Compile Include="src\tls\crypto\Tls13Verifier.cs" /> <Compile Include="src\tls\crypto\TlsAgreement.cs" /> <Compile Include="src\tls\crypto\TlsCertificate.cs" /> <Compile Include="src\tls\crypto\TlsCertificateRole.cs" /> diff --git a/crypto/Readme.html b/crypto/Readme.html
index ac9efdb33..f7d2fec3f 100644 --- a/crypto/Readme.html +++ b/crypto/Readme.html
@@ -31,6 +31,8 @@ <a href="#mozTocId3413">Notes:</a> <ol> <li> + <a href="#mozTocId85326">Release 2.0.0</a> + <li> <a href="#mozTocId85325">Release 1.9.0</a> <li> <a href="#mozTocId85324">Release 1.8.10</a> @@ -310,6 +312,26 @@ We state, where EC MQV has not otherwise been disabled or removed: <hr style="WIDTH: 100%; HEIGHT: 2px"> <h3><a class="mozTocH3" name="mozTocId3413"></a>Notes:</h3> + <h4><a class="mozTocH4" name="mozTocId85326"></a>Release 2.0.0, TBD</h4> + + <h5>Defects Fixed</h5> + <ul> + </ul> + <h5>Additional Features and Functionality</h5> + <ul> + <li> + (D)TLS: By default, only (D)TLS 1.2 and TLS 1.3 are offered now. Earlier versions are still supported + if explicitly enabled. Users may need to check they are offering suitable cipher suites for TLS 1.3. + </li> + </ul> + <h5>Additional Notes</h5> + <ul> + <li> + See the (cumulative) list of GitHub pull requests that we have accepted at + <a href="https://github.com/bcgit/bc-csharp/pulls?q=is%3Apr+is%3Aclosed">bcgit/bc-csharp</a>. + </li> + </ul> + <h4><a class="mozTocH4" name="mozTocId85325"></a>Release 1.9.0, Sunday October 17, 2021</h4> <h5>Defects Fixed</h5> diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj
index 092331032..1529174f1 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj
@@ -7914,6 +7914,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\tls\CertificateVerify.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\tls\ChangeCipherSpec.cs" SubType = "Code" BuildAction = "Compile" @@ -8024,6 +8029,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\tls\crypto\impl\bc\BcTls13Verifier.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\tls\crypto\impl\bc\BcTlsAeadCipherImpl.cs" SubType = "Code" BuildAction = "Compile" @@ -8089,11 +8099,6 @@ BuildAction = "Compile" /> <File - RelPath = "src\tls\crypto\impl\bc\BcTlsECDsa13Verifier.cs" - SubType = "Code" - BuildAction = "Compile" - /> - <File RelPath = "src\tls\crypto\impl\bc\BcTlsECDsaSigner.cs" SubType = "Code" BuildAction = "Compile" @@ -8109,21 +8114,11 @@ BuildAction = "Compile" /> <File - RelPath = "src\tls\crypto\impl\bc\BcTlsEd25519Verifier.cs" - SubType = "Code" - BuildAction = "Compile" - /> - <File RelPath = "src\tls\crypto\impl\bc\BcTlsEd448Signer.cs" SubType = "Code" BuildAction = "Compile" /> <File - RelPath = "src\tls\crypto\impl\bc\BcTlsEd448Verifier.cs" - SubType = "Code" - BuildAction = "Compile" - /> - <File RelPath = "src\tls\crypto\impl\bc\BcTlsHash.cs" SubType = "Code" BuildAction = "Compile" @@ -8229,6 +8224,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\tls\crypto\impl\LegacyTls13Verifier.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\tls\crypto\impl\RsaUtilities.cs" SubType = "Code" BuildAction = "Compile" @@ -8284,6 +8284,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\tls\crypto\Tls13Verifier.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\tls\crypto\TlsAgreement.cs" SubType = "Code" BuildAction = "Compile" diff --git a/crypto/src/crypto/macs/HMac.cs b/crypto/src/crypto/macs/HMac.cs
index 460f3c5a0..3d42aec0f 100644 --- a/crypto/src/crypto/macs/HMac.cs +++ b/crypto/src/crypto/macs/HMac.cs
@@ -136,11 +136,15 @@ namespace Org.BouncyCastle.Crypto.Macs */ public virtual void Reset() { - // Reset underlying digest - digest.Reset(); - - // Initialise the digest - digest.BlockUpdate(inputPad, 0, inputPad.Length); + if (ipadState != null) + { + ((IMemoable)digest).Reset(ipadState); + } + else + { + digest.Reset(); + digest.BlockUpdate(inputPad, 0, inputPad.Length); + } } private static void XorPad(byte[] pad, int len, byte n) diff --git a/crypto/src/crypto/signers/PssSigner.cs b/crypto/src/crypto/signers/PssSigner.cs
index 66efa51b8..2a941df47 100644 --- a/crypto/src/crypto/signers/PssSigner.cs +++ b/crypto/src/crypto/signers/PssSigner.cs
@@ -15,7 +15,7 @@ namespace Org.BouncyCastle.Crypto.Signers public class PssSigner : ISigner { - public const byte TrailerImplicit = (byte)0xBC; + public const byte TrailerImplicit = 0xBC; private readonly IDigest contentDigest1, contentDigest2; private readonly IDigest mgfDigest; @@ -33,23 +33,23 @@ namespace Org.BouncyCastle.Crypto.Signers private byte[] block; private byte trailer; - public static PssSigner CreateRawSigner( - IAsymmetricBlockCipher cipher, - IDigest digest) + public static PssSigner CreateRawSigner(IAsymmetricBlockCipher cipher, IDigest digest) { return new PssSigner(cipher, new NullDigest(), digest, digest, digest.GetDigestSize(), null, TrailerImplicit); } - public static PssSigner CreateRawSigner( - IAsymmetricBlockCipher cipher, - IDigest contentDigest, - IDigest mgfDigest, - int saltLen, - byte trailer) + public static PssSigner CreateRawSigner(IAsymmetricBlockCipher cipher, IDigest contentDigest, IDigest mgfDigest, + int saltLen, byte trailer) { return new PssSigner(cipher, new NullDigest(), contentDigest, mgfDigest, saltLen, null, trailer); } + public static PssSigner CreateRawSigner(IAsymmetricBlockCipher cipher, IDigest contentDigest, IDigest mgfDigest, + byte[] salt, byte trailer) + { + return new PssSigner(cipher, new NullDigest(), contentDigest, mgfDigest, salt.Length, salt, trailer); + } + public PssSigner( IAsymmetricBlockCipher cipher, IDigest digest) @@ -225,6 +225,9 @@ namespace Org.BouncyCastle.Crypto.Signers /// </summary> public virtual byte[] GenerateSignature() { + if (contentDigest1.GetDigestSize() != hLen) + throw new InvalidOperationException(); + contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen); if (sLen != 0) @@ -271,7 +274,10 @@ namespace Org.BouncyCastle.Crypto.Signers public virtual bool VerifySignature( byte[] signature) { - contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen); + if (contentDigest1.GetDigestSize() != hLen) + throw new InvalidOperationException(); + + contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen); byte[] b = cipher.ProcessBlock(signature, 0, signature.Length); Arrays.Fill(block, 0, block.Length - b.Length, 0); diff --git a/crypto/src/tls/AbstractTlsPeer.cs b/crypto/src/tls/AbstractTlsPeer.cs
index 6d29953ee..4e1b28e58 100644 --- a/crypto/src/tls/AbstractTlsPeer.cs +++ b/crypto/src/tls/AbstractTlsPeer.cs
@@ -26,8 +26,7 @@ namespace Org.BouncyCastle.Tls /// <returns>an array of supported <see cref="ProtocolVersion"/> values.</returns> protected virtual ProtocolVersion[] GetSupportedVersions() { - // TODO[tls13] Enable TLSv13 by default in due course - return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10); + return ProtocolVersion.TLSv13.DownTo(ProtocolVersion.TLSv12); } protected abstract int[] GetSupportedCipherSuites(); diff --git a/crypto/src/tls/CertificateVerify.cs b/crypto/src/tls/CertificateVerify.cs new file mode 100644
index 000000000..7c9f02735 --- /dev/null +++ b/crypto/src/tls/CertificateVerify.cs
@@ -0,0 +1,57 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public sealed class CertificateVerify + { + private readonly int m_algorithm; + private readonly byte[] m_signature; + + public CertificateVerify(int algorithm, byte[] signature) + { + if (!TlsUtilities.IsValidUint16(algorithm)) + throw new ArgumentException("algorithm"); + if (signature == null) + throw new ArgumentNullException("signature"); + + this.m_algorithm = algorithm; + this.m_signature = signature; + } + + /// <returns>a <see cref="SignatureScheme"/> value.</returns> + public int Algorithm + { + get { return m_algorithm; } + } + + public byte[] Signature + { + get { return m_signature; } + } + + /// <summary>Encode this <see cref="CertificateVerify"/> to a <see cref="Stream"/>.</summary> + /// <param name="output">the <see cref="Stream"/> to encode to.</param> + /// <exception cref="IOException"/> + public void Encode(Stream output) + { + TlsUtilities.WriteUint16(m_algorithm, output); + TlsUtilities.WriteOpaque16(m_signature, output); + } + + /// <summary>Parse a <see cref="CertificateVerify"/> from a <see cref="Stream"/>.</summary> + /// <param name="context">the <see cref="TlsContext"/> of the current connection.</param> + /// <param name="input">the <see cref="Stream"/> to parse from.</param> + /// <returns>a <see cref="CertificateVerify"/> object.</returns> + /// <exception cref="IOException"/> + public static CertificateVerify Parse(TlsContext context, Stream input) + { + if (!TlsUtilities.IsTlsV13(context)) + throw new InvalidOperationException(); + + int algorithm = TlsUtilities.ReadUint16(input); + byte[] signature = TlsUtilities.ReadOpaque16(input); + return new CertificateVerify(algorithm, signature); + } + } +} diff --git a/crypto/src/tls/DefaultTlsClient.cs b/crypto/src/tls/DefaultTlsClient.cs
index a2a742633..00827b5e7 100644 --- a/crypto/src/tls/DefaultTlsClient.cs +++ b/crypto/src/tls/DefaultTlsClient.cs
@@ -10,10 +10,10 @@ namespace Org.BouncyCastle.Tls private static readonly int[] DefaultCipherSuites = new int[] { /* - * TODO[tls13] TLS 1.3 + * TLS 1.3 */ - //CipherSuite.TLS_CHACHA20_POLY1305_SHA256, - //CipherSuite.TLS_AES_128_GCM_SHA256, + CipherSuite.TLS_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_AES_128_GCM_SHA256, /* * pre-TLS 1.3 diff --git a/crypto/src/tls/DefaultTlsServer.cs b/crypto/src/tls/DefaultTlsServer.cs
index de8a3f4a0..2df6c37eb 100644 --- a/crypto/src/tls/DefaultTlsServer.cs +++ b/crypto/src/tls/DefaultTlsServer.cs
@@ -11,11 +11,11 @@ namespace Org.BouncyCastle.Tls private static readonly int[] DefaultCipherSuites = new int[] { /* - * TODO[tls13] TLS 1.3 + * TLS 1.3 */ - //CipherSuite.TLS_CHACHA20_POLY1305_SHA256, - //CipherSuite.TLS_AES_256_GCM_SHA384, - //CipherSuite.TLS_AES_128_GCM_SHA256, + CipherSuite.TLS_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_AES_256_GCM_SHA384, + CipherSuite.TLS_AES_128_GCM_SHA256, /* * pre-TLS 1.3 @@ -85,10 +85,6 @@ namespace Org.BouncyCastle.Tls case KeyExchangeAlgorithm.DHE_DSS: return GetDsaSignerCredentials(); - case KeyExchangeAlgorithm.DH_anon: - case KeyExchangeAlgorithm.ECDH_anon: - return null; - case KeyExchangeAlgorithm.ECDHE_ECDSA: return GetECDsaSignerCredentials(); diff --git a/crypto/src/tls/DigitallySigned.cs b/crypto/src/tls/DigitallySigned.cs
index e977b350b..137847ada 100644 --- a/crypto/src/tls/DigitallySigned.cs +++ b/crypto/src/tls/DigitallySigned.cs
@@ -5,27 +5,27 @@ namespace Org.BouncyCastle.Tls { public sealed class DigitallySigned { - private readonly SignatureAndHashAlgorithm algorithm; - private readonly byte[] signature; + private readonly SignatureAndHashAlgorithm m_algorithm; + private readonly byte[] m_signature; public DigitallySigned(SignatureAndHashAlgorithm algorithm, byte[] signature) { if (signature == null) throw new ArgumentNullException("signature"); - this.algorithm = algorithm; - this.signature = signature; + this.m_algorithm = algorithm; + this.m_signature = signature; } /// <returns>a <see cref="SignatureAndHashAlgorithm"/> (or null before TLS 1.2).</returns> public SignatureAndHashAlgorithm Algorithm { - get { return algorithm; } + get { return m_algorithm; } } public byte[] Signature { - get { return signature; } + get { return m_signature; } } /// <summary>Encode this <see cref="DigitallySigned"/> to a <see cref="Stream"/>.</summary> @@ -33,11 +33,11 @@ namespace Org.BouncyCastle.Tls /// <exception cref="IOException"/> public void Encode(Stream output) { - if (algorithm != null) + if (m_algorithm != null) { - algorithm.Encode(output); + m_algorithm.Encode(output); } - TlsUtilities.WriteOpaque16(signature, output); + TlsUtilities.WriteOpaque16(m_signature, output); } /// <summary>Parse a <see cref="DigitallySigned"/> from a <see cref="Stream"/>.</summary> diff --git a/crypto/src/tls/DtlsClientProtocol.cs b/crypto/src/tls/DtlsClientProtocol.cs
index 44f574e3a..fd9985ab5 100644 --- a/crypto/src/tls/DtlsClientProtocol.cs +++ b/crypto/src/tls/DtlsClientProtocol.cs
@@ -237,12 +237,6 @@ namespace Org.BouncyCastle.Tls TlsUtilities.EstablishServerSigAlgs(securityParameters, state.certificateRequest); - /* - * TODO Give the client a chance to immediately select the CertificateVerify hash - * algorithm here to avoid tracking the other hash algorithms unnecessarily? - */ - TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, securityParameters.ServerSigAlgs); - serverMessage = handshake.ReceiveMessage(); } else @@ -262,54 +256,68 @@ namespace Org.BouncyCastle.Tls throw new TlsFatalAlert(AlertDescription.unexpected_message); } - IList clientSupplementalData = state.client.GetClientSupplementalData(); - if (clientSupplementalData != null) - { - byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData); - handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); - } + TlsCredentials clientAuthCredentials = null; + TlsCredentialedSigner clientAuthSigner = null; + Certificate clientAuthCertificate = null; + SignatureAndHashAlgorithm clientAuthAlgorithm = null; + TlsStreamSigner clientAuthStreamSigner = null; - if (null != state.certificateRequest) + if (state.certificateRequest != null) { - state.clientCredentials = TlsUtilities.EstablishClientCredentials(state.authentication, + clientAuthCredentials = TlsUtilities.EstablishClientCredentials(state.authentication, state.certificateRequest); + if (clientAuthCredentials != null) + { + clientAuthCertificate = clientAuthCredentials.Certificate; - /* - * RFC 5246 If no suitable certificate is available, the client MUST send a certificate - * message containing no certificates. - * - * NOTE: In previous RFCs, this was SHOULD instead of MUST. - */ + if (clientAuthCredentials is TlsCredentialedSigner) + { + clientAuthSigner = (TlsCredentialedSigner)clientAuthCredentials; + clientAuthAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( + securityParameters.NegotiatedVersion, clientAuthSigner); + clientAuthStreamSigner = clientAuthSigner.GetStreamSigner(); - Certificate clientCertificate = null; - if (null != state.clientCredentials) - { - clientCertificate = state.clientCredentials.Certificate; - } + if (ProtocolVersion.DTLSv12.Equals(securityParameters.NegotiatedVersion)) + { + TlsUtilities.VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs, + clientAuthAlgorithm, AlertDescription.internal_error); + + if (clientAuthStreamSigner == null) + { + TlsUtilities.TrackHashAlgorithmClient(handshake.HandshakeHash, clientAuthAlgorithm); + } + } - SendCertificateMessage(state.clientContext, handshake, clientCertificate, null); + if (clientAuthStreamSigner != null) + { + handshake.HandshakeHash.ForceBuffering(); + } + } + } } - TlsCredentialedSigner credentialedSigner = null; - TlsStreamSigner streamSigner = null; + handshake.HandshakeHash.SealHashAlgorithms(); - if (null != state.clientCredentials) + if (clientAuthCredentials == null) { - state.keyExchange.ProcessClientCredentials(state.clientCredentials); - - if (state.clientCredentials is TlsCredentialedSigner) - { - credentialedSigner = (TlsCredentialedSigner)state.clientCredentials; - streamSigner = credentialedSigner.GetStreamSigner(); - } + state.keyExchange.SkipClientCredentials(); } else { - state.keyExchange.SkipClientCredentials(); + state.keyExchange.ProcessClientCredentials(clientAuthCredentials); } - bool forceBuffering = streamSigner != null; - TlsUtilities.SealHandshakeHash(state.clientContext, handshake.HandshakeHash, forceBuffering); + IList clientSupplementalData = state.client.GetClientSupplementalData(); + if (clientSupplementalData != null) + { + byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData); + handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); + } + + if (null != state.certificateRequest) + { + SendCertificateMessage(state.clientContext, handshake, clientAuthCertificate, null); + } byte[] clientKeyExchangeBody = GenerateClientKeyExchange(state); handshake.SendMessage(HandshakeType.client_key_exchange, clientKeyExchangeBody); @@ -319,18 +327,16 @@ namespace Org.BouncyCastle.Tls TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange); recordLayer.InitPendingEpoch(TlsUtilities.InitCipher(state.clientContext)); + if (clientAuthSigner != null) { - if (credentialedSigner != null) - { - DigitallySigned certificateVerify = TlsUtilities.GenerateCertificateVerifyClient( - state.clientContext, credentialedSigner, streamSigner, handshake.HandshakeHash); - byte[] certificateVerifyBody = GenerateCertificateVerify(state, certificateVerify); - handshake.SendMessage(HandshakeType.certificate_verify, certificateVerifyBody); - } - - handshake.PrepareToFinish(); + DigitallySigned certificateVerify = TlsUtilities.GenerateCertificateVerifyClient(state.clientContext, + clientAuthSigner, clientAuthAlgorithm, clientAuthStreamSigner, handshake.HandshakeHash); + byte[] certificateVerifyBody = GenerateCertificateVerify(state, certificateVerify); + handshake.SendMessage(HandshakeType.certificate_verify, certificateVerifyBody); } + handshake.PrepareToFinish(); + securityParameters.m_localVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, handshake.HandshakeHash, false); handshake.SendMessage(HandshakeType.finished, securityParameters.LocalVerifyData); @@ -973,7 +979,6 @@ namespace Org.BouncyCastle.Tls internal TlsAuthentication authentication = null; internal CertificateStatus certificateStatus = null; internal CertificateRequest certificateRequest = null; - internal TlsCredentials clientCredentials = null; internal TlsHeartbeat heartbeat = null; internal short heartbeatPolicy = HeartbeatMode.peer_not_allowed_to_send; } diff --git a/crypto/src/tls/DtlsServerProtocol.cs b/crypto/src/tls/DtlsServerProtocol.cs
index b49122423..b01c6e34f 100644 --- a/crypto/src/tls/DtlsServerProtocol.cs +++ b/crypto/src/tls/DtlsServerProtocol.cs
@@ -155,7 +155,13 @@ namespace Org.BouncyCastle.Tls } state.keyExchange = TlsUtilities.InitKeyExchangeServer(state.serverContext, state.server); - state.serverCredentials = TlsUtilities.EstablishServerCredentials(state.server); + + state.serverCredentials = null; + + if (!KeyExchangeAlgorithm.IsAnonymous(securityParameters.KeyExchangeAlgorithm)) + { + state.serverCredentials = TlsUtilities.EstablishServerCredentials(state.server); + } // Server certificate { @@ -225,17 +231,34 @@ namespace Org.BouncyCastle.Tls TlsUtilities.EstablishServerSigAlgs(securityParameters, state.certificateRequest); - TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, securityParameters.ServerSigAlgs); + if (ProtocolVersion.DTLSv12.Equals(securityParameters.NegotiatedVersion)) + { + TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, securityParameters.ServerSigAlgs); - byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest); - handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody); + if (state.serverContext.Crypto.HasAnyStreamVerifiers(securityParameters.ServerSigAlgs)) + { + handshake.HandshakeHash.ForceBuffering(); + } + } + else + { + if (state.serverContext.Crypto.HasAnyStreamVerifiersLegacy(state.certificateRequest.CertificateTypes)) + { + handshake.HandshakeHash.ForceBuffering(); + } + } } } - handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes); + handshake.HandshakeHash.SealHashAlgorithms(); - bool forceBuffering = false; - TlsUtilities.SealHandshakeHash(state.serverContext, handshake.HandshakeHash, forceBuffering); + if (null != state.certificateRequest) + { + byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest); + handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody); + } + + handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes); clientMessage = handshake.ReceiveMessage(); diff --git a/crypto/src/tls/KeyExchangeAlgorithm.cs b/crypto/src/tls/KeyExchangeAlgorithm.cs
index 1dfa6db66..fdb2773f1 100644 --- a/crypto/src/tls/KeyExchangeAlgorithm.cs +++ b/crypto/src/tls/KeyExchangeAlgorithm.cs
@@ -59,5 +59,18 @@ namespace Org.BouncyCastle.Tls * GMT 0024-2014 */ public const int SM2 = 25; + + public static bool IsAnonymous(int keyExchangeAlgorithm) + { + switch (keyExchangeAlgorithm) + { + case DH_anon: + case DH_anon_EXPORT: + case ECDH_anon: + return true; + default: + return false; + } + } } } diff --git a/crypto/src/tls/ProtocolVersion.cs b/crypto/src/tls/ProtocolVersion.cs
index f37ce382d..f516aed2a 100644 --- a/crypto/src/tls/ProtocolVersion.cs +++ b/crypto/src/tls/ProtocolVersion.cs
@@ -14,6 +14,7 @@ namespace Org.BouncyCastle.Tls public static readonly ProtocolVersion TLSv13 = new ProtocolVersion(0x0304, "TLS 1.3"); public static readonly ProtocolVersion DTLSv10 = new ProtocolVersion(0xFEFF, "DTLS 1.0"); public static readonly ProtocolVersion DTLSv12 = new ProtocolVersion(0xFEFD, "DTLS 1.2"); + public static readonly ProtocolVersion DTLSv13 = new ProtocolVersion(0xFEFC, "DTLS 1.3"); internal static readonly ProtocolVersion CLIENT_EARLIEST_SUPPORTED_DTLS = DTLSv10; internal static readonly ProtocolVersion CLIENT_EARLIEST_SUPPORTED_TLS = SSLv3; @@ -225,17 +226,22 @@ namespace Org.BouncyCastle.Tls { switch (MajorVersion) { - case 0x03: - return this; - case 0xFE: - switch (MinorVersion) - { - case 0xFF: return TLSv11; - case 0xFD: return TLSv12; - default: return null; - } + case 0x03: + return this; + case 0xFE: + switch (MinorVersion) + { + case 0xFF: + return TLSv11; + case 0xFD: + return TLSv12; + case 0xFC: + return TLSv13; default: return null; + } + default: + return null; } } @@ -247,15 +253,20 @@ namespace Org.BouncyCastle.Tls case 0x03: switch (minor) { - case 0xFF: return null; - default: return Get(major, minor + 1); + case 0xFF: + return null; + default: + return Get(major, minor + 1); } case 0xFE: switch (minor) { - case 0x00: return null; - case 0xFF: return DTLSv12; - default: return Get(major, minor - 1); + case 0x00: + return null; + case 0xFF: + return DTLSv12; + default: + return Get(major, minor - 1); } default: return null; @@ -267,21 +278,26 @@ namespace Org.BouncyCastle.Tls int major = MajorVersion, minor = MinorVersion; switch (major) { - case 0x03: - switch (minor) - { - case 0x00: return null; - default: return Get(major, minor - 1); - } - case 0xFE: - switch (minor) - { - case 0xFF: return null; - case 0xFD: return DTLSv10; - default: return Get(major, minor + 1); - } + case 0x03: + switch (minor) + { + case 0x00: + return null; default: + return Get(major, minor - 1); + } + case 0xFE: + switch (minor) + { + case 0xFF: return null; + case 0xFD: + return DTLSv10; + default: + return Get(major, minor + 1); + } + default: + return null; } } @@ -367,6 +383,8 @@ namespace Org.BouncyCastle.Tls throw new ArgumentException("{0xFE, 0xFE} is a reserved protocol version"); case 0xFD: return DTLSv12; + case 0xFC: + return DTLSv13; } return GetUnknownVersion(major, minor, "DTLS"); } diff --git a/crypto/src/tls/PskTlsClient.cs b/crypto/src/tls/PskTlsClient.cs
index 3e9a00390..c475be63b 100644 --- a/crypto/src/tls/PskTlsClient.cs +++ b/crypto/src/tls/PskTlsClient.cs
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Tls protected override ProtocolVersion[] GetSupportedVersions() { - return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10); + return ProtocolVersion.TLSv12.Only(); } protected override int[] GetSupportedCipherSuites() diff --git a/crypto/src/tls/PskTlsServer.cs b/crypto/src/tls/PskTlsServer.cs
index 7197b6ad8..968cd5ce3 100644 --- a/crypto/src/tls/PskTlsServer.cs +++ b/crypto/src/tls/PskTlsServer.cs
@@ -40,7 +40,7 @@ namespace Org.BouncyCastle.Tls protected override ProtocolVersion[] GetSupportedVersions() { - return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10); + return ProtocolVersion.TLSv12.Only(); } protected override int[] GetSupportedCipherSuites() diff --git a/crypto/src/tls/SignatureAlgorithm.cs b/crypto/src/tls/SignatureAlgorithm.cs
index 726504c52..baf5620e3 100644 --- a/crypto/src/tls/SignatureAlgorithm.cs +++ b/crypto/src/tls/SignatureAlgorithm.cs
@@ -86,20 +86,16 @@ namespace Org.BouncyCastle.Tls return "dsa"; case ecdsa: return "ecdsa"; - case ed25519: - return "ed25519"; - case ed448: - return "ed448"; - case gostr34102012_256: - return "gostr34102012_256"; - case gostr34102012_512: - return "gostr34102012_512"; case rsa_pss_rsae_sha256: return "rsa_pss_rsae_sha256"; case rsa_pss_rsae_sha384: return "rsa_pss_rsae_sha384"; case rsa_pss_rsae_sha512: return "rsa_pss_rsae_sha512"; + case ed25519: + return "ed25519"; + case ed448: + return "ed448"; case rsa_pss_pss_sha256: return "rsa_pss_pss_sha256"; case rsa_pss_pss_sha384: @@ -112,6 +108,10 @@ namespace Org.BouncyCastle.Tls return "ecdsa_brainpoolP384r1tls13_sha384"; case ecdsa_brainpoolP512r1tls13_sha512: return "ecdsa_brainpoolP512r1tls13_sha512"; + case gostr34102012_256: + return "gostr34102012_256"; + case gostr34102012_512: + return "gostr34102012_512"; default: return "UNKNOWN"; } @@ -121,5 +121,32 @@ namespace Org.BouncyCastle.Tls { return GetName(signatureAlgorithm) + "(" + signatureAlgorithm + ")"; } + + public static bool IsRecognized(short signatureAlgorithm) + { + switch (signatureAlgorithm) + { + case anonymous: + case rsa: + case dsa: + case ecdsa: + case rsa_pss_rsae_sha256: + case rsa_pss_rsae_sha384: + case rsa_pss_rsae_sha512: + case ed25519: + case ed448: + case rsa_pss_pss_sha256: + case rsa_pss_pss_sha384: + case rsa_pss_pss_sha512: + case ecdsa_brainpoolP256r1tls13_sha256: + case ecdsa_brainpoolP384r1tls13_sha384: + case ecdsa_brainpoolP512r1tls13_sha512: + case gostr34102012_256: + case gostr34102012_512: + return true; + default: + return false; + } + } } } diff --git a/crypto/src/tls/SignatureScheme.cs b/crypto/src/tls/SignatureScheme.cs
index 4b934133d..ed8e3c21b 100644 --- a/crypto/src/tls/SignatureScheme.cs +++ b/crypto/src/tls/SignatureScheme.cs
@@ -92,11 +92,16 @@ namespace Org.BouncyCastle.Tls if (HashAlgorithm.Intrinsic == hashAlgorithm || !HashAlgorithm.IsRecognized(hashAlgorithm)) return -1; - return TlsCryptoUtilities.GetHash(GetHashAlgorithm(signatureScheme)); + return TlsCryptoUtilities.GetHash(hashAlgorithm); } } } + public static int GetCryptoHashAlgorithm(SignatureAndHashAlgorithm signatureAndHashAlgorithm) + { + return GetCryptoHashAlgorithm(From(signatureAndHashAlgorithm)); + } + public static string GetName(int signatureScheme) { switch (signatureScheme) diff --git a/crypto/src/tls/SrpTlsClient.cs b/crypto/src/tls/SrpTlsClient.cs
index a2b0e9461..f6f6472bc 100644 --- a/crypto/src/tls/SrpTlsClient.cs +++ b/crypto/src/tls/SrpTlsClient.cs
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Tls protected override ProtocolVersion[] GetSupportedVersions() { - return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10); + return ProtocolVersion.TLSv12.Only(); } protected virtual bool RequireSrpServerExtension diff --git a/crypto/src/tls/SrpTlsServer.cs b/crypto/src/tls/SrpTlsServer.cs
index 58f89ee22..1e2f09e03 100644 --- a/crypto/src/tls/SrpTlsServer.cs +++ b/crypto/src/tls/SrpTlsServer.cs
@@ -44,7 +44,7 @@ namespace Org.BouncyCastle.Tls protected override ProtocolVersion[] GetSupportedVersions() { - return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10); + return ProtocolVersion.TLSv12.Only(); } protected override int[] GetSupportedCipherSuites() diff --git a/crypto/src/tls/TlsClientProtocol.cs b/crypto/src/tls/TlsClientProtocol.cs
index cb59289ae..ba2b565ca 100644 --- a/crypto/src/tls/TlsClientProtocol.cs +++ b/crypto/src/tls/TlsClientProtocol.cs
@@ -450,24 +450,27 @@ namespace Org.BouncyCastle.Tls { Process13HelloRetryRequest(serverHello); m_handshakeHash.NotifyPrfDetermined(); + m_handshakeHash.SealHashAlgorithms(); TlsUtilities.AdjustTranscriptForRetry(m_handshakeHash); buf.UpdateHash(m_handshakeHash); this.m_connectionState = CS_SERVER_HELLO_RETRY_REQUEST; Send13ClientHelloRetry(); - m_handshakeHash.SealHashAlgorithms(); this.m_connectionState = CS_CLIENT_HELLO_RETRY; } else { ProcessServerHello(serverHello); m_handshakeHash.NotifyPrfDetermined(); + if (TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion)) + { + m_handshakeHash.SealHashAlgorithms(); + } buf.UpdateHash(m_handshakeHash); this.m_connectionState = CS_SERVER_HELLO; if (TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion)) { - m_handshakeHash.SealHashAlgorithms(); Process13ServerHelloCoda(serverHello, false); } } @@ -526,61 +529,70 @@ namespace Org.BouncyCastle.Tls this.m_connectionState = CS_SERVER_HELLO_DONE; - IList clientSupplementalData = m_tlsClient.GetClientSupplementalData(); - if (clientSupplementalData != null) + TlsCredentials clientAuthCredentials = null; + TlsCredentialedSigner clientAuthSigner = null; + Certificate clientAuthCertificate = null; + SignatureAndHashAlgorithm clientAuthAlgorithm = null; + TlsStreamSigner clientAuthStreamSigner = null; + + if (m_certificateRequest != null) { - SendSupplementalDataMessage(clientSupplementalData); - this.m_connectionState = CS_CLIENT_SUPPLEMENTAL_DATA; + clientAuthCredentials = TlsUtilities.EstablishClientCredentials(m_authentication, + m_certificateRequest); + if (clientAuthCredentials != null) + { + clientAuthCertificate = clientAuthCredentials.Certificate; + + if (clientAuthCredentials is TlsCredentialedSigner) + { + clientAuthSigner = (TlsCredentialedSigner)clientAuthCredentials; + clientAuthAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( + securityParameters.NegotiatedVersion, clientAuthSigner); + clientAuthStreamSigner = clientAuthSigner.GetStreamSigner(); + + if (ProtocolVersion.TLSv12.Equals(securityParameters.NegotiatedVersion)) + { + TlsUtilities.VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs, + clientAuthAlgorithm, AlertDescription.internal_error); + + if (clientAuthStreamSigner == null) + { + TlsUtilities.TrackHashAlgorithmClient(m_handshakeHash, clientAuthAlgorithm); + } + } + + if (clientAuthStreamSigner != null) + { + m_handshakeHash.ForceBuffering(); + } + } + } } - TlsCredentialedSigner credentialedSigner = null; - TlsStreamSigner streamSigner = null; + m_handshakeHash.SealHashAlgorithms(); - if (m_certificateRequest == null) + if (clientAuthCredentials == null) { m_keyExchange.SkipClientCredentials(); } else { - Certificate clientCertificate = null; - - TlsCredentials clientCredentials = TlsUtilities.EstablishClientCredentials(m_authentication, - m_certificateRequest); - if (null == clientCredentials) - { - m_keyExchange.SkipClientCredentials(); - - /* - * RFC 5246 If no suitable certificate is available, the client MUST send a - * certificate message containing no certificates. - * - * NOTE: In previous RFCs, this was SHOULD instead of MUST. - */ - } - else - { - m_keyExchange.ProcessClientCredentials(clientCredentials); - - clientCertificate = clientCredentials.Certificate; - - if (clientCredentials is TlsCredentialedSigner) - { - credentialedSigner = (TlsCredentialedSigner)clientCredentials; - streamSigner = credentialedSigner.GetStreamSigner(); - } - } + m_keyExchange.ProcessClientCredentials(clientAuthCredentials); + } - SendCertificateMessage(clientCertificate, null); - this.m_connectionState = CS_CLIENT_CERTIFICATE; + IList clientSupplementalData = m_tlsClient.GetClientSupplementalData(); + if (clientSupplementalData != null) + { + SendSupplementalDataMessage(clientSupplementalData); + this.m_connectionState = CS_CLIENT_SUPPLEMENTAL_DATA; } - bool forceBuffering = streamSigner != null; - TlsUtilities.SealHandshakeHash(m_tlsClientContext, m_handshakeHash, forceBuffering); + if (m_certificateRequest != null) + { + SendCertificateMessage(clientAuthCertificate, null); + this.m_connectionState = CS_CLIENT_CERTIFICATE; + } - /* - * Send the client key exchange message, depending on the key exchange we are using - * in our CipherSuite. - */ SendClientKeyExchange(); this.m_connectionState = CS_CLIENT_KEY_EXCHANGE; @@ -601,10 +613,11 @@ namespace Org.BouncyCastle.Tls m_recordStream.SetPendingCipher(TlsUtilities.InitCipher(m_tlsClientContext)); - if (credentialedSigner != null) + if (clientAuthSigner != null) { DigitallySigned certificateVerify = TlsUtilities.GenerateCertificateVerifyClient( - m_tlsClientContext, credentialedSigner, streamSigner, m_handshakeHash); + m_tlsClientContext, clientAuthSigner, clientAuthAlgorithm, clientAuthStreamSigner, + m_handshakeHash); SendCertificateVerifyMessage(certificateVerify); this.m_connectionState = CS_CLIENT_CERTIFICATE_VERIFY; } @@ -674,13 +687,6 @@ namespace Org.BouncyCastle.Tls ReceiveCertificateRequest(buf); TlsUtilities.EstablishServerSigAlgs(securityParameters, m_certificateRequest); - - /* - * TODO Give the client a chance to immediately select the CertificateVerify hash - * algorithm here to avoid tracking the other hash algorithms unnecessarily? - */ - TlsUtilities.TrackHashAlgorithms(m_handshakeHash, securityParameters.ServerSigAlgs); - break; } default: @@ -1467,12 +1473,11 @@ namespace Org.BouncyCastle.Tls if (null == serverCertificate || serverCertificate.IsEmpty) throw new TlsFatalAlert(AlertDescription.internal_error); - // TODO[tls13] Actual structure is 'CertificateVerify' in RFC 8446, consider adding for clarity - DigitallySigned certificateVerify = DigitallySigned.Parse(m_tlsClientContext, buf); + CertificateVerify certificateVerify = CertificateVerify.Parse(m_tlsClientContext, buf); AssertEmpty(buf); - TlsUtilities.Verify13CertificateVerifyServer(m_tlsClientContext, certificateVerify, m_handshakeHash); + TlsUtilities.Verify13CertificateVerifyServer(m_tlsClientContext, m_handshakeHash, certificateVerify); } /// <exception cref="IOException"/> diff --git a/crypto/src/tls/TlsServerProtocol.cs b/crypto/src/tls/TlsServerProtocol.cs
index 0ab8a7a98..c90ef4109 100644 --- a/crypto/src/tls/TlsServerProtocol.cs +++ b/crypto/src/tls/TlsServerProtocol.cs
@@ -907,6 +907,7 @@ namespace Org.BouncyCastle.Tls if (serverHello.IsHelloRetryRequest()) { TlsUtilities.AdjustTranscriptForRetry(m_handshakeHash); + SendServerHelloMessage(serverHello); this.m_connectionState = CS_SERVER_HELLO_RETRY_REQUEST; @@ -952,7 +953,12 @@ namespace Org.BouncyCastle.Tls this.m_keyExchange = TlsUtilities.InitKeyExchangeServer(m_tlsServerContext, m_tlsServer); - TlsCredentials serverCredentials = TlsUtilities.EstablishServerCredentials(m_tlsServer); + TlsCredentials serverCredentials = null; + + if (!KeyExchangeAlgorithm.IsAnonymous(securityParameters.KeyExchangeAlgorithm)) + { + serverCredentials = TlsUtilities.EstablishServerCredentials(m_tlsServer); + } // Server certificate { @@ -1026,19 +1032,36 @@ namespace Org.BouncyCastle.Tls TlsUtilities.EstablishServerSigAlgs(securityParameters, m_certificateRequest); - TlsUtilities.TrackHashAlgorithms(m_handshakeHash, securityParameters.ServerSigAlgs); + if (ProtocolVersion.TLSv12.Equals(securityParameters.NegotiatedVersion)) + { + TlsUtilities.TrackHashAlgorithms(m_handshakeHash, securityParameters.ServerSigAlgs); - SendCertificateRequestMessage(m_certificateRequest); - this.m_connectionState = CS_SERVER_CERTIFICATE_REQUEST; + if (m_tlsServerContext.Crypto.HasAnyStreamVerifiers(securityParameters.ServerSigAlgs)) + { + m_handshakeHash.ForceBuffering(); + } + } + else + { + if (m_tlsServerContext.Crypto.HasAnyStreamVerifiersLegacy(m_certificateRequest.CertificateTypes)) + { + m_handshakeHash.ForceBuffering(); + } + } } } + m_handshakeHash.SealHashAlgorithms(); + + if (null != m_certificateRequest) + { + SendCertificateRequestMessage(m_certificateRequest); + this.m_connectionState = CS_SERVER_CERTIFICATE_REQUEST; + } + SendServerHelloDoneMessage(); this.m_connectionState = CS_SERVER_HELLO_DONE; - bool forceBuffering = false; - TlsUtilities.SealHandshakeHash(m_tlsServerContext, m_handshakeHash, forceBuffering); - break; } default: @@ -1281,13 +1304,11 @@ namespace Org.BouncyCastle.Tls if (null == clientCertificate || clientCertificate.IsEmpty) throw new TlsFatalAlert(AlertDescription.internal_error); - // TODO[tls13] Actual structure is 'CertificateVerify' in RFC 8446, consider adding for clarity - DigitallySigned certificateVerify = DigitallySigned.Parse(m_tlsServerContext, buf); + CertificateVerify certificateVerify = CertificateVerify.Parse(m_tlsServerContext, buf); AssertEmpty(buf); - TlsUtilities.Verify13CertificateVerifyClient(m_tlsServerContext, m_certificateRequest, certificateVerify, - m_handshakeHash); + TlsUtilities.Verify13CertificateVerifyClient(m_tlsServerContext, m_handshakeHash, certificateVerify); } /// <exception cref="IOException"/> diff --git a/crypto/src/tls/TlsUtilities.cs b/crypto/src/tls/TlsUtilities.cs
index 05d38c59c..72ff92271 100644 --- a/crypto/src/tls/TlsUtilities.cs +++ b/crypto/src/tls/TlsUtilities.cs
@@ -1068,16 +1068,22 @@ namespace Org.BouncyCastle.Tls public static IList GetDefaultSupportedSignatureAlgorithms(TlsContext context) { + return GetSupportedSignatureAlgorithms(context, DefaultSupportedSigAlgs); + } + + public static IList GetSupportedSignatureAlgorithms(TlsContext context, IList candidates) + { TlsCrypto crypto = context.Crypto; IList result = Platform.CreateArrayList(DefaultSupportedSigAlgs.Count); - foreach (SignatureAndHashAlgorithm sigAndHashAlg in DefaultSupportedSigAlgs) + foreach (SignatureAndHashAlgorithm sigAndHashAlg in candidates) { AddIfSupported(result, crypto, sigAndHashAlg); } return result; } + [Obsolete("Will be removed")] public static SignatureAndHashAlgorithm GetSignatureAndHashAlgorithm(TlsContext context, TlsCredentialedSigner signerCredentials) { @@ -1085,14 +1091,19 @@ namespace Org.BouncyCastle.Tls } internal static SignatureAndHashAlgorithm GetSignatureAndHashAlgorithm(ProtocolVersion negotiatedVersion, - TlsCredentialedSigner signerCredentials) + TlsCredentialedSigner credentialedSigner) { SignatureAndHashAlgorithm signatureAndHashAlgorithm = null; - if (IsTlsV12(negotiatedVersion)) + if (IsSignatureAlgorithmsExtensionAllowed(negotiatedVersion)) { - signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm; + signatureAndHashAlgorithm = credentialedSigner.SignatureAndHashAlgorithm; if (signatureAndHashAlgorithm == null) + { + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ throw new TlsFatalAlert(AlertDescription.internal_error); + } } return signatureAndHashAlgorithm; } @@ -1347,6 +1358,14 @@ namespace Org.BouncyCastle.Tls public static void VerifySupportedSignatureAlgorithm(IList supportedSignatureAlgorithms, SignatureAndHashAlgorithm signatureAlgorithm) { + VerifySupportedSignatureAlgorithm(supportedSignatureAlgorithms, signatureAlgorithm, + AlertDescription.illegal_parameter); + } + + /// <exception cref="IOException"/> + internal static void VerifySupportedSignatureAlgorithm(IList supportedSignatureAlgorithms, + SignatureAndHashAlgorithm signatureAlgorithm, short alertDescription) + { if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.Count < 1 || supportedSignatureAlgorithms.Count >= (1 << 15)) { @@ -1358,7 +1377,7 @@ namespace Org.BouncyCastle.Tls if (signatureAlgorithm.Signature == SignatureAlgorithm.anonymous || !ContainsSignatureAlgorithm(supportedSignatureAlgorithms, signatureAlgorithm)) { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); + throw new TlsFatalAlert(alertDescription); } } @@ -2088,7 +2107,7 @@ namespace Org.BouncyCastle.Tls TlsHash h = algorithm == null ? new CombinedHash(crypto) - : CreateHash(crypto, algorithm.Hash); + : CreateHash(crypto, algorithm); SecurityParameters sp = context.SecurityParameters; // NOTE: The implicit copy here is intended (and important) @@ -2124,48 +2143,38 @@ namespace Org.BouncyCastle.Tls } internal static DigitallySigned GenerateCertificateVerifyClient(TlsClientContext clientContext, - TlsCredentialedSigner credentialedSigner, TlsStreamSigner streamSigner, TlsHandshakeHash handshakeHash) + TlsCredentialedSigner clientAuthSigner, SignatureAndHashAlgorithm clientAuthAlgorithm, + TlsStreamSigner clientAuthStreamSigner, TlsHandshakeHash handshakeHash) { SecurityParameters securityParameters = clientContext.SecurityParameters; - ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; - - if (IsTlsV13(negotiatedVersion)) + if (IsTlsV13(securityParameters.NegotiatedVersion)) { - // Should be using GenerateCertificateVerify13 instead + // Should be using Generate13CertificateVerify instead throw new TlsFatalAlert(AlertDescription.internal_error); } - /* - * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 - */ - SignatureAndHashAlgorithm signatureAndHashAlgorithm = GetSignatureAndHashAlgorithm(negotiatedVersion, - credentialedSigner); - byte[] signature; - if (streamSigner != null) + if (clientAuthStreamSigner != null) { - handshakeHash.CopyBufferTo(streamSigner.GetOutputStream()); - signature = streamSigner.GetSignature(); + handshakeHash.CopyBufferTo(clientAuthStreamSigner.Stream); + signature = clientAuthStreamSigner.GetSignature(); } else { byte[] hash; - if (signatureAndHashAlgorithm == null) + if (clientAuthAlgorithm == null) { hash = securityParameters.SessionHash; } else { - int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm); - int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); - - hash = handshakeHash.GetFinalHash(cryptoHashAlgorithm); + hash = handshakeHash.GetFinalHash(SignatureScheme.GetCryptoHashAlgorithm(clientAuthAlgorithm)); } - signature = credentialedSigner.GenerateRawSignature(hash); + signature = clientAuthSigner.GenerateRawSignature(hash); } - return new DigitallySigned(signatureAndHashAlgorithm, signature); + return new DigitallySigned(clientAuthAlgorithm, signature); } internal static DigitallySigned Generate13CertificateVerify(TlsContext context, @@ -2195,16 +2204,13 @@ namespace Org.BouncyCastle.Tls if (null != streamSigner) { - Stream output = streamSigner.GetOutputStream(); + Stream output = streamSigner.Stream; output.Write(header, 0, header.Length); output.Write(prfHash, 0, prfHash.Length); return streamSigner.GetSignature(); } - int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm); - int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); - - TlsHash tlsHash = crypto.CreateHash(cryptoHashAlgorithm); + TlsHash tlsHash = CreateHash(crypto, signatureAndHashAlgorithm); tlsHash.Update(header, 0, header.Length); tlsHash.Update(prfHash, 0, prfHash.Length); byte[] hash = tlsHash.CalculateHash(); @@ -2224,22 +2230,17 @@ namespace Org.BouncyCastle.Tls { signatureAlgorithm = verifyingCert.GetLegacySignatureAlgorithm(); - short clientCertType = GetLegacyClientCertType(signatureAlgorithm); - if (clientCertType < 0 || !Arrays.Contains(certificateRequest.CertificateTypes, clientCertType)) - throw new TlsFatalAlert(AlertDescription.unsupported_certificate); + CheckClientCertificateType(certificateRequest, GetLegacyClientCertType(signatureAlgorithm), + AlertDescription.unsupported_certificate); } else { - signatureAlgorithm = sigAndHashAlg.Signature; + VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs, sigAndHashAlg); - // TODO Is it possible (maybe only pre-1.2 to check this immediately when the Certificate arrives? - if (!IsValidSignatureAlgorithmForCertificateVerify(signatureAlgorithm, - certificateRequest.CertificateTypes)) - { - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } + signatureAlgorithm = sigAndHashAlg.Signature; - VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs, sigAndHashAlg); + CheckClientCertificateType(certificateRequest, + SignatureAlgorithm.GetClientCertificateType(signatureAlgorithm), AlertDescription.illegal_parameter); } // Verify the CertificateVerify message contains a correct signature. @@ -2251,7 +2252,7 @@ namespace Org.BouncyCastle.Tls if (streamVerifier != null) { - handshakeHash.CopyBufferTo(streamVerifier.GetOutputStream()); + handshakeHash.CopyBufferTo(streamVerifier.Stream); verified = streamVerifier.IsVerified(); } else @@ -2259,10 +2260,7 @@ namespace Org.BouncyCastle.Tls byte[] hash; if (IsTlsV12(serverContext)) { - int signatureScheme = SignatureScheme.From(sigAndHashAlg); - int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); - - hash = handshakeHash.GetFinalHash(cryptoHashAlgorithm); + hash = handshakeHash.GetFinalHash(SignatureScheme.GetCryptoHashAlgorithm(sigAndHashAlg)); } else { @@ -2287,62 +2285,54 @@ namespace Org.BouncyCastle.Tls } } + /// <exception cref="IOException"/> internal static void Verify13CertificateVerifyClient(TlsServerContext serverContext, - CertificateRequest certificateRequest, DigitallySigned certificateVerify, TlsHandshakeHash handshakeHash) + TlsHandshakeHash handshakeHash, CertificateVerify certificateVerify) { SecurityParameters securityParameters = serverContext.SecurityParameters; - Certificate clientCertificate = securityParameters.PeerCertificate; - TlsCertificate verifyingCert = clientCertificate.GetCertificateAt(0); - - SignatureAndHashAlgorithm sigAndHashAlg = certificateVerify.Algorithm; - VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs, sigAndHashAlg); - - int signatureScheme = SignatureScheme.From(sigAndHashAlg); - - // Verify the CertificateVerify message contains a correct signature. - bool verified; - try - { - TlsVerifier verifier = verifyingCert.CreateVerifier(signatureScheme); - verified = Verify13CertificateVerify(serverContext.Crypto, certificateVerify, verifier, - "TLS 1.3, client CertificateVerify", handshakeHash); - } - catch (TlsFatalAlert e) - { - throw e; - } - catch (Exception e) - { - throw new TlsFatalAlert(AlertDescription.decrypt_error, e); - } + IList supportedAlgorithms = securityParameters.ServerSigAlgs; + TlsCertificate certificate = securityParameters.PeerCertificate.GetCertificateAt(0); - if (!verified) - { - throw new TlsFatalAlert(AlertDescription.decrypt_error); - } + Verify13CertificateVerify(supportedAlgorithms, "TLS 1.3, client CertificateVerify", handshakeHash, + certificate, certificateVerify); } + /// <exception cref="IOException"/> internal static void Verify13CertificateVerifyServer(TlsClientContext clientContext, - DigitallySigned certificateVerify, TlsHandshakeHash handshakeHash) + TlsHandshakeHash handshakeHash, CertificateVerify certificateVerify) { SecurityParameters securityParameters = clientContext.SecurityParameters; - Certificate serverCertificate = securityParameters.PeerCertificate; - TlsCertificate verifyingCert = serverCertificate.GetCertificateAt(0); - SignatureAndHashAlgorithm sigAndHashAlg = certificateVerify.Algorithm; - VerifySupportedSignatureAlgorithm(securityParameters.ClientSigAlgs, sigAndHashAlg); + IList supportedAlgorithms = securityParameters.ClientSigAlgs; + TlsCertificate certificate = securityParameters.PeerCertificate.GetCertificateAt(0); - int signatureScheme = SignatureScheme.From(sigAndHashAlg); + Verify13CertificateVerify(supportedAlgorithms, "TLS 1.3, server CertificateVerify", handshakeHash, + certificate, certificateVerify); + } + /// <exception cref="IOException"/> + private static void Verify13CertificateVerify(IList supportedAlgorithms, string contextString, + TlsHandshakeHash handshakeHash, TlsCertificate certificate, CertificateVerify certificateVerify) + { // Verify the CertificateVerify message contains a correct signature. bool verified; try { - TlsVerifier verifier = verifyingCert.CreateVerifier(signatureScheme); + int signatureScheme = certificateVerify.Algorithm; + + SignatureAndHashAlgorithm algorithm = SignatureScheme.GetSignatureAndHashAlgorithm(signatureScheme); + VerifySupportedSignatureAlgorithm(supportedAlgorithms, algorithm); + + Tls13Verifier verifier = certificate.CreateVerifier(signatureScheme); + + byte[] header = GetCertificateVerifyHeader(contextString); + byte[] prfHash = GetCurrentPrfHash(handshakeHash); - verified = Verify13CertificateVerify(clientContext.Crypto, certificateVerify, verifier, - "TLS 1.3, server CertificateVerify", handshakeHash); + Stream output = verifier.Stream; + output.Write(header, 0, header.Length); + output.Write(prfHash, 0, prfHash.Length); + verified = verifier.VerifySignature(certificateVerify.Signature); } catch (TlsFatalAlert e) { @@ -2359,32 +2349,6 @@ namespace Org.BouncyCastle.Tls } } - private static bool Verify13CertificateVerify(TlsCrypto crypto, DigitallySigned certificateVerify, - TlsVerifier verifier, string contextString, TlsHandshakeHash handshakeHash) - { - TlsStreamVerifier streamVerifier = verifier.GetStreamVerifier(certificateVerify); - - byte[] header = GetCertificateVerifyHeader(contextString); - byte[] prfHash = GetCurrentPrfHash(handshakeHash); - - if (null != streamVerifier) - { - Stream output = streamVerifier.GetOutputStream(); - output.Write(header, 0, header.Length); - output.Write(prfHash, 0, prfHash.Length); - return streamVerifier.IsVerified(); - } - - int signatureScheme = SignatureScheme.From(certificateVerify.Algorithm); - int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); - - TlsHash tlsHash = crypto.CreateHash(cryptoHashAlgorithm); - tlsHash.Update(header, 0, header.Length); - tlsHash.Update(prfHash, 0, prfHash.Length); - byte[] hash = tlsHash.CalculateHash(); - return verifier.VerifyRawSignature(certificateVerify, hash); - } - private static byte[] GetCertificateVerifyHeader(string contextString) { int count = contextString.Length; @@ -2409,13 +2373,13 @@ namespace Org.BouncyCastle.Tls /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ - SignatureAndHashAlgorithm algorithm = GetSignatureAndHashAlgorithm(context, credentials); + SignatureAndHashAlgorithm algorithm = GetSignatureAndHashAlgorithm(context.ServerVersion, credentials); TlsStreamSigner streamSigner = credentials.GetStreamSigner(); byte[] signature; if (streamSigner != null) { - SendSignatureInput(context, extraSignatureInput, digestBuffer, streamSigner.GetOutputStream()); + SendSignatureInput(context, extraSignatureInput, digestBuffer, streamSigner.Stream); signature = streamSigner.GetSignature(); } else @@ -2461,7 +2425,7 @@ namespace Org.BouncyCastle.Tls bool verified; if (streamVerifier != null) { - SendSignatureInput(context, null, digestBuffer, streamVerifier.GetOutputStream()); + SendSignatureInput(context, null, digestBuffer, streamVerifier.Stream); verified = streamVerifier.IsVerified(); } else @@ -2476,28 +2440,28 @@ namespace Org.BouncyCastle.Tls } } + internal static void TrackHashAlgorithmClient(TlsHandshakeHash handshakeHash, + SignatureAndHashAlgorithm signatureAndHashAlgorithm) + { + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureAndHashAlgorithm); + if (cryptoHashAlgorithm >= 0) + { + handshakeHash.TrackHashAlgorithm(cryptoHashAlgorithm); + } + } + internal static void TrackHashAlgorithms(TlsHandshakeHash handshakeHash, IList supportedSignatureAlgorithms) { - if (supportedSignatureAlgorithms != null) + foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in supportedSignatureAlgorithms) { - foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in supportedSignatureAlgorithms) + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureAndHashAlgorithm); + if (cryptoHashAlgorithm >= 0) { - /* - * TODO We could validate the signature algorithm part. Currently the impact is - * that we might be tracking extra hashes pointlessly (but there are only a - * limited number of recognized hash algorithms). - */ - int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm); - int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); - - if (cryptoHashAlgorithm >= 0) - { - handshakeHash.TrackHashAlgorithm(cryptoHashAlgorithm); - } - else if (HashAlgorithm.Intrinsic == signatureAndHashAlgorithm.Hash) - { - handshakeHash.ForceBuffering(); - } + handshakeHash.TrackHashAlgorithm(cryptoHashAlgorithm); + } + else if (HashAlgorithm.Intrinsic == signatureAndHashAlgorithm.Hash) + { + handshakeHash.ForceBuffering(); } } } @@ -3896,14 +3860,6 @@ namespace Org.BouncyCastle.Tls && NamedGroup.CanBeNegotiated(keyShareGroup, negotiatedVersion); } - internal static bool IsValidSignatureAlgorithmForCertificateVerify(short signatureAlgorithm, - short[] clientCertificateTypes) - { - short clientCertificateType = SignatureAlgorithm.GetClientCertificateType(signatureAlgorithm); - - return clientCertificateType >= 0 && Arrays.Contains(clientCertificateTypes, clientCertificateType); - } - internal static bool IsValidSignatureAlgorithmForServerKeyExchange(short signatureAlgorithm, int keyExchangeAlgorithm) { @@ -4238,21 +4194,14 @@ namespace Org.BouncyCastle.Tls return handshakeHash.ForkPrfHash().CalculateHash(); } - internal static void SealHandshakeHash(TlsContext context, TlsHandshakeHash handshakeHash, bool forceBuffering) + private static TlsHash CreateHash(TlsCrypto crypto, short hashAlgorithm) { - if (forceBuffering || !context.Crypto.HasAllRawSignatureAlgorithms()) - { - handshakeHash.ForceBuffering(); - } - - handshakeHash.SealHashAlgorithms(); + return crypto.CreateHash(TlsCryptoUtilities.GetHash(hashAlgorithm)); } - private static TlsHash CreateHash(TlsCrypto crypto, short hashAlgorithm) + private static TlsHash CreateHash(TlsCrypto crypto, SignatureAndHashAlgorithm signatureAndHashAlgorithm) { - int cryptoHashAlgorithm = TlsCryptoUtilities.GetHash(hashAlgorithm); - - return crypto.CreateHash(cryptoHashAlgorithm); + return crypto.CreateHash(SignatureScheme.GetCryptoHashAlgorithm(signatureAndHashAlgorithm)); } /// <exception cref="IOException"/> @@ -4793,6 +4742,17 @@ namespace Org.BouncyCastle.Tls return (TlsCredentialedSigner)credentials; } + /// <exception cref="IOException"/> + private static void CheckClientCertificateType(CertificateRequest certificateRequest, + short clientCertificateType, short alertDescription) + { + if (clientCertificateType < 0 + || !Arrays.Contains(certificateRequest.CertificateTypes, clientCertificateType)) + { + throw new TlsFatalAlert(alertDescription); + } + } + private static void CheckDowngradeMarker(byte[] randomBlock, byte[] downgradeMarker) { int len = downgradeMarker.Length; @@ -4839,8 +4799,11 @@ namespace Org.BouncyCastle.Tls MemoryStream buf) { SecurityParameters securityParameters = clientContext.SecurityParameters; - if (null != securityParameters.PeerCertificate) + if (KeyExchangeAlgorithm.IsAnonymous(securityParameters.KeyExchangeAlgorithm) + || null != securityParameters.PeerCertificate) + { throw new TlsFatalAlert(AlertDescription.unexpected_message); + } MemoryStream endPointHash = new MemoryStream(); diff --git a/crypto/src/tls/crypto/CryptoSignatureAlgorithm.cs b/crypto/src/tls/crypto/CryptoSignatureAlgorithm.cs
index ed58820b8..15435cab5 100644 --- a/crypto/src/tls/crypto/CryptoSignatureAlgorithm.cs +++ b/crypto/src/tls/crypto/CryptoSignatureAlgorithm.cs
@@ -15,6 +15,9 @@ namespace Org.BouncyCastle.Tls.Crypto public const int rsa_pss_pss_sha256 = 9; public const int rsa_pss_pss_sha384 = 10; public const int rsa_pss_pss_sha512 = 11; + public const int ecdsa_brainpoolP256r1tls13_sha256 = 26; + public const int ecdsa_brainpoolP384r1tls13_sha384 = 27; + public const int ecdsa_brainpoolP512r1tls13_sha512 = 28; public const int gostr34102012_256 = 64; public const int gostr34102012_512 = 65; public const int sm2 = 200; diff --git a/crypto/src/tls/crypto/Tls13Verifier.cs b/crypto/src/tls/crypto/Tls13Verifier.cs new file mode 100644
index 000000000..143ea7394 --- /dev/null +++ b/crypto/src/tls/crypto/Tls13Verifier.cs
@@ -0,0 +1,14 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public interface Tls13Verifier + { + /// <exception cref="IOException"/> + Stream Stream { get; } + + /// <exception cref="IOException"/> + bool VerifySignature(byte[] signature); + } +} diff --git a/crypto/src/tls/crypto/TlsCertificate.cs b/crypto/src/tls/crypto/TlsCertificate.cs
index fe507a662..6b3e3220a 100644 --- a/crypto/src/tls/crypto/TlsCertificate.cs +++ b/crypto/src/tls/crypto/TlsCertificate.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Tls.Crypto /// <param name="signatureScheme"><see cref="SignatureScheme"/></param> /// <exception cref="IOException"/> - TlsVerifier CreateVerifier(int signatureScheme); + Tls13Verifier CreateVerifier(int signatureScheme); /// <exception cref="IOException"/> byte[] GetEncoded(); diff --git a/crypto/src/tls/crypto/TlsCrypto.cs b/crypto/src/tls/crypto/TlsCrypto.cs
index 4dab6bc57..27c5fb9e1 100644 --- a/crypto/src/tls/crypto/TlsCrypto.cs +++ b/crypto/src/tls/crypto/TlsCrypto.cs
@@ -1,4 +1,5 @@ using System; +using System.Collections; using System.IO; using Org.BouncyCastle.Math; @@ -10,11 +11,22 @@ namespace Org.BouncyCastle.Tls.Crypto /// cryptography in the API.</summary> public interface TlsCrypto { - /// <summary>Return true if this TlsCrypto can perform raw signatures and verifications for all supported - /// algorithms.</summary> - /// <returns>true if this instance can perform raw signatures and verifications for all supported algorithms, - /// false otherwise.</returns> - bool HasAllRawSignatureAlgorithms(); + /// <summary>Return true if this TlsCrypto would use a stream verifier for any of the passed in algorithms. + /// </summary> + /// <remarks>This method is only relevant to handshakes negotiating (D)TLS 1.2.</remarks> + /// <param name="signatureAndHashAlgorithms">A <see cref="IList">list</see> of + /// <see cref="SignatureAndHashAlgorithm"/> values.</param> + /// <returns>true if this instance would use a stream verifier for any of the passed in algorithms, otherwise + /// false.</returns> + bool HasAnyStreamVerifiers(IList signatureAndHashAlgorithms); + + /// <summary>Return true if this TlsCrypto would use a stream verifier for any of the passed in algorithms. + /// </summary> + /// <remarks>This method is only relevant to handshakes negotiating (D)TLS versions older than 1.2.</remarks> + /// <param name="clientCertificateTypes">An array of <see cref="ClientCertificateType"/> values.</param> + /// <returns>true if this instance would use a stream verifier for any of the passed in algorithms, otherwise + /// false.</returns> + bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes); /// <summary>Return true if this TlsCrypto can support the passed in hash algorithm.</summary> /// <param name="cryptoHashAlgorithm">the algorithm of interest.</param> diff --git a/crypto/src/tls/crypto/TlsCryptoUtilities.cs b/crypto/src/tls/crypto/TlsCryptoUtilities.cs
index 757eda1be..98ac87a83 100644 --- a/crypto/src/tls/crypto/TlsCryptoUtilities.cs +++ b/crypto/src/tls/crypto/TlsCryptoUtilities.cs
@@ -1,6 +1,11 @@ using System; using System.IO; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; + namespace Org.BouncyCastle.Tls.Crypto { public abstract class TlsCryptoUtilities @@ -108,6 +113,30 @@ namespace Org.BouncyCastle.Tls.Crypto } } + public static DerObjectIdentifier GetOidForHash(int cryptoHashAlgorithm) + { + switch (cryptoHashAlgorithm) + { + case CryptoHashAlgorithm.md5: + return PkcsObjectIdentifiers.MD5; + case CryptoHashAlgorithm.sha1: + return X509ObjectIdentifiers.IdSha1; + case CryptoHashAlgorithm.sha224: + return NistObjectIdentifiers.IdSha224; + case CryptoHashAlgorithm.sha256: + return NistObjectIdentifiers.IdSha256; + case CryptoHashAlgorithm.sha384: + return NistObjectIdentifiers.IdSha384; + case CryptoHashAlgorithm.sha512: + return NistObjectIdentifiers.IdSha512; + // TODO[RFC 8998] + //case CryptoHashAlgorithm.sm3: + // return GMObjectIdentifiers.sm3; + default: + throw new ArgumentException(); + } + } + public static int GetSignature(short signatureAlgorithm) { switch (signatureAlgorithm) @@ -134,6 +163,12 @@ namespace Org.BouncyCastle.Tls.Crypto return CryptoSignatureAlgorithm.rsa_pss_pss_sha384; case SignatureAlgorithm.rsa_pss_pss_sha512: return CryptoSignatureAlgorithm.rsa_pss_pss_sha512; + case SignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256: + return CryptoSignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256; + case SignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384: + return CryptoSignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384; + case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512: + return CryptoSignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512; case SignatureAlgorithm.gostr34102012_256: return CryptoSignatureAlgorithm.gostr34102012_256; case SignatureAlgorithm.gostr34102012_512: diff --git a/crypto/src/tls/crypto/TlsStreamSigner.cs b/crypto/src/tls/crypto/TlsStreamSigner.cs
index 8f79346bf..c3634fe27 100644 --- a/crypto/src/tls/crypto/TlsStreamSigner.cs +++ b/crypto/src/tls/crypto/TlsStreamSigner.cs
@@ -6,7 +6,7 @@ namespace Org.BouncyCastle.Tls.Crypto public interface TlsStreamSigner { /// <exception cref="IOException"/> - Stream GetOutputStream(); + Stream Stream { get; } /// <exception cref="IOException"/> byte[] GetSignature(); diff --git a/crypto/src/tls/crypto/TlsStreamVerifier.cs b/crypto/src/tls/crypto/TlsStreamVerifier.cs
index 9d18a9c9c..33b0e3879 100644 --- a/crypto/src/tls/crypto/TlsStreamVerifier.cs +++ b/crypto/src/tls/crypto/TlsStreamVerifier.cs
@@ -6,7 +6,7 @@ namespace Org.BouncyCastle.Tls.Crypto public interface TlsStreamVerifier { /// <exception cref="IOException"/> - Stream GetOutputStream(); + Stream Stream { get; } /// <exception cref="IOException"/> bool IsVerified(); diff --git a/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs b/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs
index 39d86c241..87fe66dff 100644 --- a/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs +++ b/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs
@@ -1,5 +1,5 @@ using System; -using System.IO; +using System.Collections; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; @@ -12,7 +12,9 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl public abstract class AbstractTlsCrypto : TlsCrypto { - public abstract bool HasAllRawSignatureAlgorithms(); + public abstract bool HasAnyStreamVerifiers(IList signatureAndHashAlgorithms); + + public abstract bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes); public abstract bool HasCryptoHashAlgorithm(int cryptoHashAlgorithm); diff --git a/crypto/src/tls/crypto/impl/LegacyTls13Verifier.cs b/crypto/src/tls/crypto/impl/LegacyTls13Verifier.cs new file mode 100644
index 000000000..294a14da4 --- /dev/null +++ b/crypto/src/tls/crypto/impl/LegacyTls13Verifier.cs
@@ -0,0 +1,60 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + public sealed class LegacyTls13Verifier + : TlsVerifier + { + private readonly int m_signatureScheme; + private readonly Tls13Verifier m_tls13Verifier; + + public LegacyTls13Verifier(int signatureScheme, Tls13Verifier tls13Verifier) + { + if (!TlsUtilities.IsValidUint16(signatureScheme)) + throw new ArgumentException("signatureScheme"); + if (tls13Verifier == null) + throw new ArgumentNullException("tls13Verifier"); + + this.m_signatureScheme = signatureScheme; + this.m_tls13Verifier = tls13Verifier; + } + + public TlsStreamVerifier GetStreamVerifier(DigitallySigned digitallySigned) + { + SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm; + if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + return new TlsStreamVerifierImpl(m_tls13Verifier, digitallySigned.Signature); + } + + public bool VerifyRawSignature(DigitallySigned digitallySigned, byte[] hash) + { + throw new NotSupportedException(); + } + + private class TlsStreamVerifierImpl + : TlsStreamVerifier + { + private readonly Tls13Verifier m_tls13Verifier; + private readonly byte[] m_signature; + + internal TlsStreamVerifierImpl(Tls13Verifier tls13Verifier, byte[] signature) + { + this.m_tls13Verifier = tls13Verifier; + this.m_signature = signature; + } + + public Stream Stream + { + get { return m_tls13Verifier.Stream; } + } + + public bool IsVerified() + { + return m_tls13Verifier.VerifySignature(m_signature); + } + } + } +} diff --git a/crypto/src/tls/crypto/impl/TlsAeadCipher.cs b/crypto/src/tls/crypto/impl/TlsAeadCipher.cs
index ec76e98c1..04f9ce80f 100644 --- a/crypto/src/tls/crypto/impl/TlsAeadCipher.cs +++ b/crypto/src/tls/crypto/impl/TlsAeadCipher.cs
@@ -175,14 +175,13 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl try { - m_encryptCipher.Init(nonce, m_macSize, additionalData); - Array.Copy(plaintext, plaintextOffset, output, outputPos, plaintextLength); if (m_isTlsV13) { output[outputPos + plaintextLength] = (byte)contentType; } + m_encryptCipher.Init(nonce, m_macSize, additionalData); outputPos += m_encryptCipher.DoFinal(output, outputPos, plaintextLength + extraLength, output, outputPos); } @@ -354,7 +353,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl Array.Copy(iv, 0, nonce, 0, m_fixed_iv_length); // NOTE: Ensure dummy nonce is not part of the generated sequence(s) - iv [0] ^= 0x80; + iv[0] ^= 0x80; cipher.Init(iv, m_macSize, null); } diff --git a/crypto/src/tls/crypto/impl/bc/BcTls13Verifier.cs b/crypto/src/tls/crypto/impl/bc/BcTls13Verifier.cs new file mode 100644
index 000000000..ba4d0ccf8 --- /dev/null +++ b/crypto/src/tls/crypto/impl/bc/BcTls13Verifier.cs
@@ -0,0 +1,32 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTls13Verifier + : Tls13Verifier + { + private readonly SignerSink m_output; + + internal BcTls13Verifier(ISigner verifier) + { + if (verifier == null) + throw new ArgumentNullException("verifier"); + + this.m_output = new SignerSink(verifier); + } + + public Stream Stream + { + get { return m_output; } + } + + public bool VerifySignature(byte[] signature) + { + return m_output.Signer.VerifySignature(signature); + } + } +} diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsCertificate.cs b/crypto/src/tls/crypto/impl/bc/BcTlsCertificate.cs
index 469785dc2..7e946ce23 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsCertificate.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsCertificate.cs
@@ -4,7 +4,9 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; @@ -87,38 +89,56 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC { switch (signatureAlgorithm) { - case SignatureAlgorithm.rsa_pss_rsae_sha256: - case SignatureAlgorithm.rsa_pss_rsae_sha384: - case SignatureAlgorithm.rsa_pss_rsae_sha512: case SignatureAlgorithm.ed25519: case SignatureAlgorithm.ed448: - case SignatureAlgorithm.rsa_pss_pss_sha256: - case SignatureAlgorithm.rsa_pss_pss_sha384: - case SignatureAlgorithm.rsa_pss_pss_sha512: - return CreateVerifier(SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm)); + { + int signatureScheme = SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm); + Tls13Verifier tls13Verifier = CreateVerifier(signatureScheme); + return new LegacyTls13Verifier(signatureScheme, tls13Verifier); + } } ValidateKeyUsage(KeyUsage.DigitalSignature); switch (signatureAlgorithm) { - case SignatureAlgorithm.rsa: - ValidateRsa_Pkcs1(); - return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa()); - case SignatureAlgorithm.dsa: return new BcTlsDsaVerifier(m_crypto, GetPubKeyDss()); case SignatureAlgorithm.ecdsa: return new BcTlsECDsaVerifier(m_crypto, GetPubKeyEC()); + case SignatureAlgorithm.rsa: + { + ValidateRsa_Pkcs1(); + return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa()); + } + + case SignatureAlgorithm.rsa_pss_pss_sha256: + case SignatureAlgorithm.rsa_pss_pss_sha384: + case SignatureAlgorithm.rsa_pss_pss_sha512: + { + ValidateRsa_Pss_Pss(signatureAlgorithm); + int signatureScheme = SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm); + return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme); + } + + case SignatureAlgorithm.rsa_pss_rsae_sha256: + case SignatureAlgorithm.rsa_pss_rsae_sha384: + case SignatureAlgorithm.rsa_pss_rsae_sha512: + { + ValidateRsa_Pss_Rsae(); + int signatureScheme = SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm); + return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme); + } + default: throw new TlsFatalAlert(AlertDescription.certificate_unknown); } } /// <exception cref="IOException"/> - public virtual TlsVerifier CreateVerifier(int signatureScheme) + public virtual Tls13Verifier CreateVerifier(int signatureScheme) { ValidateKeyUsage(KeyUsage.DigitalSignature); @@ -131,13 +151,31 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC case SignatureScheme.ecdsa_secp384r1_sha384: case SignatureScheme.ecdsa_secp521r1_sha512: case SignatureScheme.ecdsa_sha1: - return new BcTlsECDsa13Verifier(m_crypto, GetPubKeyEC(), signatureScheme); + { + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm); + + ISigner verifier = new DsaDigestSigner(new ECDsaSigner(), digest); + verifier.Init(false, GetPubKeyEC()); + + return new BcTls13Verifier(verifier); + } case SignatureScheme.ed25519: - return new BcTlsEd25519Verifier(m_crypto, GetPubKeyEd25519()); + { + Ed25519Signer verifier = new Ed25519Signer(); + verifier.Init(false, GetPubKeyEd25519()); + + return new BcTls13Verifier(verifier); + } case SignatureScheme.ed448: - return new BcTlsEd448Verifier(m_crypto, GetPubKeyEd448()); + { + Ed448Signer verifier = new Ed448Signer(TlsUtilities.EmptyBytes); + verifier.Init(false, GetPubKeyEd448()); + + return new BcTls13Verifier(verifier); + } case SignatureScheme.rsa_pkcs1_sha1: case SignatureScheme.rsa_pkcs1_sha256: @@ -145,7 +183,15 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC case SignatureScheme.rsa_pkcs1_sha512: { ValidateRsa_Pkcs1(); - return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa()); + + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm); + + RsaDigestSigner verifier = new RsaDigestSigner(digest, + TlsCryptoUtilities.GetOidForHash(cryptoHashAlgorithm)); + verifier.Init(false, GetPubKeyRsa()); + + return new BcTls13Verifier(verifier); } case SignatureScheme.rsa_pss_pss_sha256: @@ -153,7 +199,14 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC case SignatureScheme.rsa_pss_pss_sha512: { ValidateRsa_Pss_Pss(SignatureScheme.GetSignatureAlgorithm(signatureScheme)); - return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme); + + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm); + + PssSigner verifier = new PssSigner(new RsaEngine(), digest, digest.GetDigestSize()); + verifier.Init(false, GetPubKeyRsa()); + + return new BcTls13Verifier(verifier); } case SignatureScheme.rsa_pss_rsae_sha256: @@ -161,12 +214,27 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC case SignatureScheme.rsa_pss_rsae_sha512: { ValidateRsa_Pss_Rsae(); - return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme); + + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm); + + PssSigner verifier = new PssSigner(new RsaEngine(), digest, digest.GetDigestSize()); + verifier.Init(false, GetPubKeyRsa()); + + return new BcTls13Verifier(verifier); } // TODO[RFC 8998] //case SignatureScheme.sm2sig_sm3: - // return new BcTlsSM2Verifier(m_crypto, GetPubKeyEC(), Strings.ToByteArray("TLSv1.3+GM+Cipher+Suite")); + //{ + // ParametersWithID parametersWithID = new ParametersWithID(GetPubKeyEC(), + // Strings.ToByteArray("TLSv1.3+GM+Cipher+Suite")); + + // SM2Signer verifier = new SM2Signer(); + // verifier.Init(false, parametersWithID); + + // return new BcTls13Verifier(verifier); + //} default: throw new TlsFatalAlert(AlertDescription.certificate_unknown); diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
index a56835105..38062829e 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
@@ -1,4 +1,5 @@ using System; +using System.Collections; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Agreement.Srp; @@ -152,9 +153,22 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC return new BcTlsNonceGenerator(randomGenerator); } - public override bool HasAllRawSignatureAlgorithms() + public override bool HasAnyStreamVerifiers(IList signatureAndHashAlgorithms) + { + foreach (SignatureAndHashAlgorithm algorithm in signatureAndHashAlgorithms) + { + switch (SignatureScheme.From(algorithm)) + { + case SignatureScheme.ed25519: + case SignatureScheme.ed448: + return true; + } + } + return false; + } + + public override bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes) { - // TODO[RFC 8422] Revisit the need to buffer the handshake for "Intrinsic" hash signatures return false; } @@ -219,16 +233,39 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC { switch (encryptionAlgorithm) { - case EncryptionAlgorithm.DES40_CBC: + case EncryptionAlgorithm.AES_128_CBC: + case EncryptionAlgorithm.AES_128_CCM: + case EncryptionAlgorithm.AES_128_CCM_8: + case EncryptionAlgorithm.AES_128_GCM: + case EncryptionAlgorithm.AES_256_CBC: + case EncryptionAlgorithm.AES_256_CCM: + case EncryptionAlgorithm.AES_256_CCM_8: + case EncryptionAlgorithm.AES_256_GCM: + case EncryptionAlgorithm.ARIA_128_CBC: + case EncryptionAlgorithm.ARIA_128_GCM: + case EncryptionAlgorithm.ARIA_256_CBC: + case EncryptionAlgorithm.ARIA_256_GCM: + case EncryptionAlgorithm.CAMELLIA_128_CBC: + case EncryptionAlgorithm.CAMELLIA_128_GCM: + case EncryptionAlgorithm.CAMELLIA_256_CBC: + case EncryptionAlgorithm.CAMELLIA_256_GCM: + case EncryptionAlgorithm.CHACHA20_POLY1305: + case EncryptionAlgorithm.cls_3DES_EDE_CBC: + case EncryptionAlgorithm.NULL: + case EncryptionAlgorithm.SEED_CBC: + case EncryptionAlgorithm.SM4_CBC: + case EncryptionAlgorithm.SM4_CCM: + case EncryptionAlgorithm.SM4_GCM: + return true; + case EncryptionAlgorithm.DES_CBC: + case EncryptionAlgorithm.DES40_CBC: case EncryptionAlgorithm.IDEA_CBC: case EncryptionAlgorithm.RC2_CBC_40: case EncryptionAlgorithm.RC4_128: case EncryptionAlgorithm.RC4_40: - return false; - default: - return true; + return false; } } diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs b/crypto/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs deleted file mode 100644
index 159b17c0b..000000000 --- a/crypto/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs +++ /dev/null
@@ -1,40 +0,0 @@ -using System; - -using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Crypto.Digests; -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Crypto.Signers; - -namespace Org.BouncyCastle.Tls.Crypto.Impl.BC -{ - /// <summary>Implementation class for verification of ECDSA signatures in TLS 1.3+ using the BC light-weight API. - /// </summary> - public class BcTlsECDsa13Verifier - : BcTlsVerifier - { - private readonly int m_signatureScheme; - - public BcTlsECDsa13Verifier(BcTlsCrypto crypto, ECPublicKeyParameters publicKey, int signatureScheme) - : base(crypto, publicKey) - { - if (!SignatureScheme.IsECDsa(signatureScheme)) - throw new ArgumentException("signatureScheme"); - - this.m_signatureScheme = signatureScheme; - } - - public override bool VerifyRawSignature(DigitallySigned digitallySigned, byte[] hash) - { - SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm; - if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme) - throw new InvalidOperationException("Invalid algorithm: " + algorithm); - - IDsa dsa = new ECDsaSigner(); - - ISigner signer = new DsaDigestSigner(dsa, new NullDigest()); - signer.Init(false, m_publicKey); - signer.BlockUpdate(hash, 0, hash.Length); - return signer.VerifySignature(digitallySigned.Signature); - } - } -} diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs b/crypto/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs deleted file mode 100644
index a787bb92a..000000000 --- a/crypto/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs +++ /dev/null
@@ -1,28 +0,0 @@ -using System; - -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Crypto.Signers; - -namespace Org.BouncyCastle.Tls.Crypto.Impl.BC -{ - public class BcTlsEd25519Verifier - : BcTlsVerifier - { - public BcTlsEd25519Verifier(BcTlsCrypto crypto, Ed25519PublicKeyParameters publicKey) - : base(crypto, publicKey) - { - } - - public override TlsStreamVerifier GetStreamVerifier(DigitallySigned digitallySigned) - { - SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm; - if (algorithm == null || SignatureScheme.From(algorithm) != SignatureScheme.ed25519) - throw new InvalidOperationException("Invalid algorithm: " + algorithm); - - Ed25519Signer verifier = new Ed25519Signer(); - verifier.Init(false, m_publicKey); - - return new BcTlsStreamVerifier(verifier, digitallySigned.Signature); - } - } -} diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs b/crypto/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs deleted file mode 100644
index 7940d0757..000000000 --- a/crypto/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs +++ /dev/null
@@ -1,28 +0,0 @@ -using System; - -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Crypto.Signers; - -namespace Org.BouncyCastle.Tls.Crypto.Impl.BC -{ - public class BcTlsEd448Verifier - : BcTlsVerifier - { - public BcTlsEd448Verifier(BcTlsCrypto crypto, Ed448PublicKeyParameters publicKey) - : base(crypto, publicKey) - { - } - - public override TlsStreamVerifier GetStreamVerifier(DigitallySigned digitallySigned) - { - SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm; - if (algorithm == null || SignatureScheme.From(algorithm) != SignatureScheme.ed448) - throw new InvalidOperationException("Invalid algorithm: " + algorithm); - - Ed448Signer verifier = new Ed448Signer(TlsUtilities.EmptyBytes); - verifier.Init(false, m_publicKey); - - return new BcTlsStreamVerifier(verifier, digitallySigned.Signature); - } - } -} diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs b/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs
index 3e7d1ceef..1b33573f6 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs
@@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC this.m_signatureScheme = signatureScheme; } - public override TlsStreamSigner GetStreamSigner(SignatureAndHashAlgorithm algorithm) + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash) { if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme) throw new InvalidOperationException("Invalid algorithm: " + algorithm); @@ -30,10 +30,18 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme); IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm); - PssSigner signer = new PssSigner(new RsaBlindedEngine(), digest, digest.GetDigestSize()); + PssSigner signer = PssSigner.CreateRawSigner(new RsaBlindedEngine(), digest, digest, digest.GetDigestSize(), + PssSigner.TrailerImplicit); signer.Init(true, new ParametersWithRandom(m_privateKey, m_crypto.SecureRandom)); - - return new BcTlsStreamSigner(signer); + signer.BlockUpdate(hash, 0, hash.Length); + try + { + return signer.GenerateSignature(); + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } } } } diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs b/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs
index dc8cebdd9..18c2082aa 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs
@@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC this.m_signatureScheme = signatureScheme; } - public override TlsStreamVerifier GetStreamVerifier(DigitallySigned digitallySigned) + public override bool VerifyRawSignature(DigitallySigned digitallySigned, byte[] hash) { SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm; if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme) @@ -31,10 +31,11 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme); IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm); - PssSigner verifier = new PssSigner(new RsaEngine(), digest, digest.GetDigestSize()); + PssSigner verifier = PssSigner.CreateRawSigner(new RsaEngine(), digest, digest, digest.GetDigestSize(), + PssSigner.TrailerImplicit); verifier.Init(false, m_publicKey); - - return new BcTlsStreamVerifier(verifier, digitallySigned.Signature); + verifier.BlockUpdate(hash, 0, hash.Length); + return verifier.VerifySignature(digitallySigned.Signature); } } } diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs b/crypto/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs
index 158fb053e..21db0af8e 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs
@@ -16,9 +16,9 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC this.m_output = new SignerSink(signer); } - public Stream GetOutputStream() + public Stream Stream { - return m_output; + get { return m_output; } } public byte[] GetSignature() diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs b/crypto/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs
index 0848a30dd..edf13e6ec 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs
@@ -18,9 +18,9 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC this.m_signature = signature; } - public Stream GetOutputStream() + public Stream Stream { - return m_output; + get { return m_output; } } public bool IsVerified() diff --git a/crypto/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs b/crypto/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs
index 4d9506857..4093fc52f 100644 --- a/crypto/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs +++ b/crypto/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs
@@ -24,9 +24,9 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC this.m_output = new TeeOutputStream(outputSigner, outputVerifier); } - public Stream GetOutputStream() + public Stream Stream { - return m_output; + get { return m_output; } } public byte[] GetSignature() diff --git a/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs b/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs
index ddbe4c6b8..9e2679fbb 100644 --- a/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs +++ b/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs
@@ -585,6 +585,20 @@ namespace Org.BouncyCastle.Tls.Crypto.Tests return Utilities.Encoders.Hex.Decode(s.Replace(" ", "")); } + private byte[] ImplPrehash(int signatureScheme, byte[] message) + { + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + TlsHash tlsHash = m_crypto.CreateHash(cryptoHashAlgorithm); + tlsHash.Update(message, 0, message.Length); + return tlsHash.CalculateHash(); + } + + private byte[] ImplPrehash(SignatureAndHashAlgorithm signatureAndHashAlgorithm, byte[] message) + { + int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm); + return ImplPrehash(signatureScheme, message); + } + private void ImplTestAgreement(TlsAgreement aA, TlsAgreement aB) { byte[] pA = aA.GenerateEphemeral(); @@ -643,7 +657,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Tests TlsStreamSigner tlsStreamSigner = credentialedSigner.GetStreamSigner(); if (null != tlsStreamSigner) { - Stream output = tlsStreamSigner.GetOutputStream(); + Stream output = tlsStreamSigner.Stream; output.Write(message, 0, message.Length); signature = tlsStreamSigner.GetSignature(); } @@ -664,7 +678,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Tests TlsStreamVerifier tlsStreamVerifier = tlsVerifier.GetStreamVerifier(digitallySigned); if (null != tlsStreamVerifier) { - Stream output = tlsStreamVerifier.GetOutputStream(); + Stream output = tlsStreamVerifier.Stream; output.Write(message, 0, message.Length); verified = tlsStreamVerifier.IsVerified(); } @@ -682,28 +696,19 @@ namespace Org.BouncyCastle.Tls.Crypto.Tests private void ImplTestSignature12(TlsCredentialedSigner credentialedSigner, SignatureAndHashAlgorithm signatureAndHashAlgorithm) { - short hashAlgorithm = signatureAndHashAlgorithm.Hash; - byte[] message = m_crypto.CreateNonceGenerator(TlsUtilities.EmptyBytes).GenerateNonce(100); byte[] signature; TlsStreamSigner tlsStreamSigner = credentialedSigner.GetStreamSigner(); if (null != tlsStreamSigner) { - Stream output = tlsStreamSigner.GetOutputStream(); + Stream output = tlsStreamSigner.Stream; output.Write(message, 0, message.Length); signature = tlsStreamSigner.GetSignature(); } else { - // Currently 1.2 relies on these being handled by stream signers - Assert.IsTrue(HashAlgorithm.Intrinsic != hashAlgorithm); - - int cryptoHashAlgorithm = TlsCryptoUtilities.GetHash(hashAlgorithm); - - TlsHash tlsHash = m_crypto.CreateHash(cryptoHashAlgorithm); - tlsHash.Update(message, 0, message.Length); - byte[] hash = tlsHash.CalculateHash(); + byte[] hash = ImplPrehash(signatureAndHashAlgorithm, message); signature = credentialedSigner.GenerateRawSignature(hash); } @@ -716,20 +721,13 @@ namespace Org.BouncyCastle.Tls.Crypto.Tests TlsStreamVerifier tlsStreamVerifier = tlsVerifier.GetStreamVerifier(digitallySigned); if (null != tlsStreamVerifier) { - Stream output = tlsStreamVerifier.GetOutputStream(); + Stream output = tlsStreamVerifier.Stream; output.Write(message, 0, message.Length); verified = tlsStreamVerifier.IsVerified(); } else { - // Currently 1.2 relies on these being handled by stream verifiers - Assert.IsTrue(HashAlgorithm.Intrinsic != hashAlgorithm); - - int cryptoHashAlgorithm = TlsCryptoUtilities.GetHash(hashAlgorithm); - - TlsHash tlsHash = m_crypto.CreateHash(cryptoHashAlgorithm); - tlsHash.Update(message, 0, message.Length); - byte[] hash = tlsHash.CalculateHash(); + byte[] hash = ImplPrehash(signatureAndHashAlgorithm, message); verified = tlsVerifier.VerifyRawSignature(digitallySigned, hash); } @@ -744,43 +742,22 @@ namespace Org.BouncyCastle.Tls.Crypto.Tests TlsStreamSigner tlsStreamSigner = credentialedSigner.GetStreamSigner(); if (null != tlsStreamSigner) { - Stream output = tlsStreamSigner.GetOutputStream(); + Stream output = tlsStreamSigner.Stream; output.Write(message, 0, message.Length); signature = tlsStreamSigner.GetSignature(); } else { - int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); - - TlsHash tlsHash = m_crypto.CreateHash(cryptoHashAlgorithm); - tlsHash.Update(message, 0, message.Length); - byte[] hash = tlsHash.CalculateHash(); + byte[] hash = ImplPrehash(signatureScheme, message); signature = credentialedSigner.GenerateRawSignature(hash); } - DigitallySigned digitallySigned = new DigitallySigned( - SignatureScheme.GetSignatureAndHashAlgorithm(signatureScheme), signature); - TlsCertificate tlsCertificate = credentialedSigner.Certificate.GetCertificateAt(0); - TlsVerifier tlsVerifier = tlsCertificate.CreateVerifier(signatureScheme); - - bool verified; - TlsStreamVerifier tlsStreamVerifier = tlsVerifier.GetStreamVerifier(digitallySigned); - if (null != tlsStreamVerifier) - { - Stream output = tlsStreamVerifier.GetOutputStream(); - output.Write(message, 0, message.Length); - verified = tlsStreamVerifier.IsVerified(); - } - else - { - int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + Tls13Verifier tls13Verifier = tlsCertificate.CreateVerifier(signatureScheme); - TlsHash tlsHash = m_crypto.CreateHash(cryptoHashAlgorithm); - tlsHash.Update(message, 0, message.Length); - byte[] hash = tlsHash.CalculateHash(); - verified = tlsVerifier.VerifyRawSignature(digitallySigned, hash); - } + Stream output13 = tls13Verifier.Stream; + output13.Write(message, 0, message.Length); + bool verified = tls13Verifier.VerifySignature(signature); Assert.IsTrue(verified); } diff --git a/crypto/test/src/tls/test/DtlsTestSuite.cs b/crypto/test/src/tls/test/DtlsTestSuite.cs
index 0af2be32c..158620fae 100644 --- a/crypto/test/src/tls/test/DtlsTestSuite.cs +++ b/crypto/test/src/tls/test/DtlsTestSuite.cs
@@ -68,63 +68,57 @@ namespace Org.BouncyCastle.Tls.Tests + "_"; /* - * NOTE: Temporarily disabled automatic test runs because of problems getting a clean exit - * of the DTLS server after a fatal alert. As of writing, manual runs show the correct - * alerts being raised - */ - -#if false - /* - * Server only declares support for SHA1/RSA, client selects MD5/RSA. Since the client is - * NOT actually tracking MD5 over the handshake, we expect fatal alert from the client. + * Server only declares support for SHA256/ECDSA, client selects SHA256/RSA, so we expect fatal alert + * from the client validation of the CertificateVerify algorithm. */ if (TlsUtilities.IsTlsV12(version)) { TlsTestConfig c = CreateDtlsTestConfig(version); c.clientAuth = C.CLIENT_AUTH_VALID; - c.clientAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.md5, SignatureAlgorithm.rsa); - c.serverCertReqSigAlgs = TlsUtilities.GetDefaultRsaSignatureAlgorithms(); + c.clientAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.rsa); + c.serverCertReqSigAlgs = TlsUtilities.VectorOfOne( + new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.ecdsa)); c.ExpectClientFatalAlert(AlertDescription.internal_error); - AddTestCase(testSuite, c, prefix + "BadCertificateVerifyHashAlg"); + AddTestCase(testSuite, c, prefix + "BadCertVerifySigAlgClient"); } /* - * Server only declares support for SHA1/ECDSA, client selects SHA1/RSA. Since the client is - * actually tracking SHA1 over the handshake, we expect fatal alert to come from the server - * when it verifies the selected algorithm against the CertificateRequest supported - * algorithms. + * Server only declares support for rsa_pss_rsae_sha256, client selects rsa_pss_rsae_sha256 but claims + * ecdsa_secp256r1_sha256, so we expect fatal alert from the server validation of the + * CertificateVerify algorithm. */ if (TlsUtilities.IsTlsV12(version)) { TlsTestConfig c = CreateDtlsTestConfig(version); c.clientAuth = C.CLIENT_AUTH_VALID; - c.clientAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.rsa); - c.serverCertReqSigAlgs = TlsUtilities.GetDefaultECDsaSignatureAlgorithms(); + c.clientAuthSigAlg = SignatureAndHashAlgorithm.rsa_pss_rsae_sha256; + c.clientAuthSigAlgClaimed = SignatureScheme.GetSignatureAndHashAlgorithm(SignatureScheme.ecdsa_secp256r1_sha256); + c.serverCertReqSigAlgs = TlsUtilities.VectorOfOne(SignatureAndHashAlgorithm.rsa_pss_rsae_sha256); c.serverCheckSigAlgOfClientCerts = false; c.ExpectServerFatalAlert(AlertDescription.illegal_parameter); - AddTestCase(testSuite, c, prefix + "BadCertificateVerifySigAlg"); + AddTestCase(testSuite, c, prefix + "BadCertVerifySigAlgServer1"); } /* - * Server only declares support for SHA1/ECDSA, client signs with SHA1/RSA, but sends - * SHA1/ECDSA in the CertificateVerify. Since the client is actually tracking SHA1 over the - * handshake, and the claimed algorithm is in the CertificateRequest supported algorithms, - * we expect fatal alert to come from the server when it finds the claimed algorithm - * doesn't match the client certificate. + * Server declares support for rsa_pss_rsae_sha256 and ecdsa_secp256r1_sha256, client selects + * rsa_pss_rsae_sha256 but claims ecdsa_secp256r1_sha256, so we expect fatal alert from the server + * validation of the client certificate. */ if (TlsUtilities.IsTlsV12(version)) { TlsTestConfig c = CreateDtlsTestConfig(version); c.clientAuth = C.CLIENT_AUTH_VALID; - c.clientAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.rsa); - c.clientAuthSigAlgClaimed = new SignatureAndHashAlgorithm(HashAlgorithm.sha1, - SignatureAlgorithm.ecdsa); - c.serverCertReqSigAlgs = TlsUtilities.GetDefaultECDsaSignatureAlgorithms(); - c.ExpectServerFatalAlert(AlertDescription.decrypt_error); + c.clientAuthSigAlg = SignatureAndHashAlgorithm.rsa_pss_rsae_sha256; + c.clientAuthSigAlgClaimed = SignatureScheme.GetSignatureAndHashAlgorithm(SignatureScheme.ecdsa_secp256r1_sha256); + c.serverCertReqSigAlgs = new ArrayList(2); + c.serverCertReqSigAlgs.Add(SignatureAndHashAlgorithm.rsa_pss_rsae_sha256); + c.serverCertReqSigAlgs.Add( + SignatureScheme.GetSignatureAndHashAlgorithm(SignatureScheme.ecdsa_secp256r1_sha256)); + c.ExpectServerFatalAlert(AlertDescription.bad_certificate); - AddTestCase(testSuite, c, prefix + "BadCertificateVerifySigAlgMismatch"); + AddTestCase(testSuite, c, prefix + "BadCertVerifySigAlgServer2"); } { @@ -132,7 +126,7 @@ namespace Org.BouncyCastle.Tls.Tests c.clientAuth = C.CLIENT_AUTH_INVALID_VERIFY; c.ExpectServerFatalAlert(AlertDescription.decrypt_error); - AddTestCase(testSuite, c, prefix + "BadCertificateVerifySignature"); + AddTestCase(testSuite, c, prefix + "BadCertVerifySignature"); } { @@ -161,42 +155,44 @@ namespace Org.BouncyCastle.Tls.Tests { TlsTestConfig c = CreateDtlsTestConfig(version); c.clientSendSignatureAlgorithms = false; + c.clientSendSignatureAlgorithmsCert = false; c.serverAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.rsa); - c.ExpectClientFatalAlert(AlertDescription.certificate_unknown); + c.ExpectClientFatalAlert(AlertDescription.bad_certificate); AddTestCase(testSuite, c, prefix + "BadServerCertSigAlg"); } /* - * Server selects MD5/RSA for ServerKeyExchange signature, which is not in the default - * supported signature algorithms that the client sent. We expect fatal alert from the - * client when it verifies the selected algorithm against the supported algorithms. + * Client declares support for SHA256/RSA, server selects SHA384/RSA, so we expect fatal alert from the + * client validation of the ServerKeyExchange algorithm. */ if (TlsUtilities.IsTlsV12(version)) { TlsTestConfig c = CreateDtlsTestConfig(version); - c.serverAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.md5, SignatureAlgorithm.rsa); + c.clientCHSigAlgs = TlsUtilities.VectorOfOne( + new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.rsa)); + c.serverAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha384, SignatureAlgorithm.rsa); c.ExpectClientFatalAlert(AlertDescription.illegal_parameter); AddTestCase(testSuite, c, prefix + "BadServerKeyExchangeSigAlg"); } /* - * Server selects MD5/RSA for ServerKeyExchange signature, which is not the default {sha1,rsa} - * implied by the absent signature_algorithms extension. We expect fatal alert from the - * client when it verifies the selected algorithm against the implicit default. + * Server selects SHA256/RSA for ServerKeyExchange signature, which is not the default {sha1,rsa} implied by + * the absent signature_algorithms extension. We expect fatal alert from the client when it verifies the + * selected algorithm against the implicit default. */ if (TlsUtilities.IsTlsV12(version)) { TlsTestConfig c = CreateDtlsTestConfig(version); c.clientCheckSigAlgOfServerCerts = false; c.clientSendSignatureAlgorithms = false; - c.serverAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.md5, SignatureAlgorithm.rsa); + c.clientSendSignatureAlgorithmsCert = false; + c.serverAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.rsa); c.ExpectClientFatalAlert(AlertDescription.illegal_parameter); AddTestCase(testSuite, c, prefix + "BadServerKeyExchangeSigAlg2"); } -#endif { TlsTestConfig c = CreateDtlsTestConfig(version); @@ -218,7 +214,6 @@ namespace Org.BouncyCastle.Tls.Tests AddTestCase(testSuite, c, prefix + "GoodOptionalCertReqDeclined"); } -#if false /* * Server generates downgraded (RFC 8446) ServerHello. We expect fatal alert * (illegal_parameter) from the client. @@ -232,7 +227,6 @@ namespace Org.BouncyCastle.Tls.Tests AddTestCase(testSuite, c, prefix + "BadDowngrade"); } -#endif } private static void AddTestCase(IList testSuite, TlsTestConfig config, string name) diff --git a/crypto/test/src/tls/test/MockDtlsClient.cs b/crypto/test/src/tls/test/MockDtlsClient.cs
index 5aa1ebbd3..deef119ca 100644 --- a/crypto/test/src/tls/test/MockDtlsClient.cs +++ b/crypto/test/src/tls/test/MockDtlsClient.cs
@@ -109,7 +109,7 @@ namespace Org.BouncyCastle.Tls.Tests protected override ProtocolVersion[] GetSupportedVersions() { - return ProtocolVersion.DTLSv12.DownTo(ProtocolVersion.DTLSv10); + return ProtocolVersion.DTLSv12.Only(); } internal class MyTlsAuthentication diff --git a/crypto/test/src/tls/test/MockDtlsServer.cs b/crypto/test/src/tls/test/MockDtlsServer.cs
index 18e53628e..b3ea7f91c 100644 --- a/crypto/test/src/tls/test/MockDtlsServer.cs +++ b/crypto/test/src/tls/test/MockDtlsServer.cs
@@ -140,7 +140,7 @@ namespace Org.BouncyCastle.Tls.Tests protected override ProtocolVersion[] GetSupportedVersions() { - return ProtocolVersion.DTLSv12.DownTo(ProtocolVersion.DTLSv10); + return ProtocolVersion.DTLSv12.Only(); } } } diff --git a/crypto/test/src/tls/test/MockTlsServer.cs b/crypto/test/src/tls/test/MockTlsServer.cs
index 94d4c7dfd..f7c197342 100644 --- a/crypto/test/src/tls/test/MockTlsServer.cs +++ b/crypto/test/src/tls/test/MockTlsServer.cs
@@ -26,6 +26,20 @@ namespace Org.BouncyCastle.Tls.Tests return protocolNames; } + public override TlsCredentials GetCredentials() + { + /* + * TODO[tls13] Should really be finding the first client-supported signature scheme that the + * server also supports and has credentials for. + */ + if (TlsUtilities.IsTlsV13(m_context)) + { + return GetRsaSignerCredentials(); + } + + return base.GetCredentials(); + } + public override void NotifyAlertRaised(short alertLevel, short alertDescription, string message, Exception cause) { @@ -60,9 +74,6 @@ namespace Org.BouncyCastle.Tls.Tests public override CertificateRequest GetCertificateRequest() { - short[] certificateTypes = new short[]{ ClientCertificateType.rsa_sign, - ClientCertificateType.dss_sign, ClientCertificateType.ecdsa_sign }; - IList serverSigAlgs = null; if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(m_context.ServerVersion)) { @@ -77,7 +88,24 @@ namespace Org.BouncyCastle.Tls.Tests // All the CA certificates are currently configured with this subject certificateAuthorities.Add(new X509Name("CN=BouncyCastle TLS Test CA")); - return new CertificateRequest(certificateTypes, serverSigAlgs, certificateAuthorities); + if (TlsUtilities.IsTlsV13(m_context)) + { + // TODO[tls13] Support for non-empty request context + byte[] certificateRequestContext = TlsUtilities.EmptyBytes; + + // TODO[tls13] Add TlsTestConfig.serverCertReqSigAlgsCert + IList serverSigAlgsCert = null; + + return new CertificateRequest(certificateRequestContext, serverSigAlgs, serverSigAlgsCert, + certificateAuthorities); + } + else + { + short[] certificateTypes = new short[]{ ClientCertificateType.rsa_sign, + ClientCertificateType.dss_sign, ClientCertificateType.ecdsa_sign }; + + return new CertificateRequest(certificateTypes, serverSigAlgs, certificateAuthorities); + } } public override void NotifyClientCertificate(Certificate clientCertificate) diff --git a/crypto/test/src/tls/test/TlsTestClientImpl.cs b/crypto/test/src/tls/test/TlsTestClientImpl.cs
index 8f878eeb8..ca5175a73 100644 --- a/crypto/test/src/tls/test/TlsTestClientImpl.cs +++ b/crypto/test/src/tls/test/TlsTestClientImpl.cs
@@ -95,6 +95,14 @@ namespace Org.BouncyCastle.Tls.Tests return base.GetEarlyKeyShareGroups(); } + protected override IList GetSupportedSignatureAlgorithms() + { + if (m_config.clientCHSigAlgs != null) + return TlsUtilities.GetSupportedSignatureAlgorithms(m_context, m_config.clientCHSigAlgs); + + return base.GetSupportedSignatureAlgorithms(); + } + public override bool IsFallback() { return m_config.clientFallback; @@ -310,14 +318,22 @@ namespace Org.BouncyCastle.Tls.Tests IList supportedSigAlgs = certificateRequest.SupportedSignatureAlgorithms; if (supportedSigAlgs != null && config.clientAuthSigAlg != null) { - supportedSigAlgs = new ArrayList(1); - supportedSigAlgs.Add(config.clientAuthSigAlg); + supportedSigAlgs = TlsUtilities.VectorOfOne(config.clientAuthSigAlg); } // TODO[tls13] Check also supportedSigAlgsCert against the chain signature(s) TlsCredentialedSigner signerCredentials = TlsTestUtilities.LoadSignerCredentials(m_context, supportedSigAlgs, SignatureAlgorithm.rsa, "x509-client-rsa.pem", "x509-client-key-rsa.pem"); + if (signerCredentials == null && supportedSigAlgs != null) + { + SignatureAndHashAlgorithm pss = SignatureAndHashAlgorithm.rsa_pss_rsae_sha256; + if (TlsUtilities.ContainsSignatureAlgorithm(supportedSigAlgs, pss)) + { + signerCredentials = TlsTestUtilities.LoadSignerCredentials(m_context, + new string[]{ "x509-client-rsa.pem" }, "x509-client-key-rsa.pem", pss); + } + } if (config.clientAuth == TlsTestConfig.CLIENT_AUTH_VALID) return signerCredentials; @@ -372,8 +388,36 @@ namespace Org.BouncyCastle.Tls.Tests public virtual TlsStreamSigner GetStreamSigner() { - return null; + TlsStreamSigner streamSigner = m_inner.GetStreamSigner(); + + if (streamSigner != null && m_outer.m_config.clientAuth == TlsTestConfig.CLIENT_AUTH_INVALID_VERIFY) + return new CorruptingStreamSigner(m_outer, streamSigner); + + return streamSigner; } - }; + } + + internal class CorruptingStreamSigner + : TlsStreamSigner + { + private readonly TlsTestClientImpl m_outer; + private readonly TlsStreamSigner m_inner; + + internal CorruptingStreamSigner(TlsTestClientImpl outer, TlsStreamSigner inner) + { + this.m_outer = outer; + this.m_inner = inner; + } + + public Stream Stream + { + get { return m_inner.Stream; } + } + + public byte[] GetSignature() + { + return m_outer.CorruptBit(m_inner.GetSignature()); + } + } } } diff --git a/crypto/test/src/tls/test/TlsTestClientProtocol.cs b/crypto/test/src/tls/test/TlsTestClientProtocol.cs
index f7e94680a..879996040 100644 --- a/crypto/test/src/tls/test/TlsTestClientProtocol.cs +++ b/crypto/test/src/tls/test/TlsTestClientProtocol.cs
@@ -19,6 +19,16 @@ namespace Org.BouncyCastle.Tls.Tests this.m_config = config; } + protected override void Send13CertificateVerifyMessage(DigitallySigned certificateVerify) + { + if (m_config.clientAuthSigAlgClaimed != null) + { + certificateVerify = new DigitallySigned(m_config.clientAuthSigAlgClaimed, certificateVerify.Signature); + } + + base.Send13CertificateVerifyMessage(certificateVerify); + } + protected override void SendCertificateVerifyMessage(DigitallySigned certificateVerify) { if (certificateVerify.Algorithm != null && m_config.clientAuthSigAlgClaimed != null) diff --git a/crypto/test/src/tls/test/TlsTestConfig.cs b/crypto/test/src/tls/test/TlsTestConfig.cs
index a15d4e535..81784e3e3 100644 --- a/crypto/test/src/tls/test/TlsTestConfig.cs +++ b/crypto/test/src/tls/test/TlsTestConfig.cs
@@ -45,6 +45,10 @@ namespace Org.BouncyCastle.Tls.Tests /// _claimed_ in the CertificateVerify (if one is sent), independently of what was actually used.</summary> public SignatureAndHashAlgorithm clientAuthSigAlgClaimed = null; + /// <summary>If TLS 1.2 or higher is negotiated, configures the set of supported signature algorithms in the + /// ClientHello. If null, uses a default set.</summary> + public IList clientCHSigAlgs = null; + /// <summary>Control whether the client will call /// <see cref="TlsUtilities.CheckPeerSigAlgs(TlsContext, Crypto.TlsCertificate[])"/> to check the server /// certificate chain.</summary> diff --git a/crypto/test/src/tls/test/TlsTestServerImpl.cs b/crypto/test/src/tls/test/TlsTestServerImpl.cs
index 77df632fe..273de3d31 100644 --- a/crypto/test/src/tls/test/TlsTestServerImpl.cs +++ b/crypto/test/src/tls/test/TlsTestServerImpl.cs
@@ -258,9 +258,7 @@ namespace Org.BouncyCastle.Tls.Tests { if (TlsUtilities.IsTlsV12(m_context) && m_config.serverAuthSigAlg != null) { - IList signatureAlgorithms = new ArrayList(1); - signatureAlgorithms.Add(m_config.serverAuthSigAlg); - return signatureAlgorithms; + return TlsUtilities.VectorOfOne(m_config.serverAuthSigAlg); } return m_context.SecurityParameters.ClientSigAlgs; diff --git a/crypto/test/src/tls/test/TlsTestSuite.cs b/crypto/test/src/tls/test/TlsTestSuite.cs
index adedd8249..4f4e4e023 100644 --- a/crypto/test/src/tls/test/TlsTestSuite.cs +++ b/crypto/test/src/tls/test/TlsTestSuite.cs
@@ -104,56 +104,57 @@ namespace Org.BouncyCastle.Tls.Tests } /* - * Server only declares support for SHA1/RSA, client selects MD5/RSA. Since the client is - * NOT actually tracking MD5 over the handshake, we expect fatal alert from the client. + * Server only declares support for SHA256/ECDSA, client selects SHA256/RSA, so we expect fatal alert + * from the client validation of the CertificateVerify algorithm. */ if (isTlsV12Exactly) { TlsTestConfig c = CreateTlsTestConfig(version, clientCrypto, serverCrypto); c.clientAuth = C.CLIENT_AUTH_VALID; - c.clientAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.md5, SignatureAlgorithm.rsa); - c.serverCertReqSigAlgs = TlsUtilities.GetDefaultRsaSignatureAlgorithms(); - c.serverCheckSigAlgOfClientCerts = false; + c.clientAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.rsa); + c.serverCertReqSigAlgs = TlsUtilities.VectorOfOne( + new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.ecdsa)); c.ExpectClientFatalAlert(AlertDescription.internal_error); - AddTestCase(testSuite, c, prefix + "BadCertificateVerifyHashAlg"); + AddTestCase(testSuite, c, prefix + "BadCertVerifySigAlgClient"); } /* - * Server only declares support for SHA1/ECDSA, client selects SHA1/RSA. Since the client is - * actually tracking SHA1 over the handshake, we expect fatal alert to come from the server - * when it verifies the selected algorithm against the CertificateRequest supported - * algorithms. + * Server only declares support for rsa_pss_rsae_sha256, client selects rsa_pss_rsae_sha256 but claims + * ecdsa_secp256r1_sha256, so we expect fatal alert from the server validation of the + * CertificateVerify algorithm. */ if (isTlsV12) { TlsTestConfig c = CreateTlsTestConfig(version, clientCrypto, serverCrypto); c.clientAuth = C.CLIENT_AUTH_VALID; - c.clientAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.rsa); - c.serverCertReqSigAlgs = TlsUtilities.GetDefaultECDsaSignatureAlgorithms(); + c.clientAuthSigAlg = SignatureAndHashAlgorithm.rsa_pss_rsae_sha256; + c.clientAuthSigAlgClaimed = SignatureScheme.GetSignatureAndHashAlgorithm(SignatureScheme.ecdsa_secp256r1_sha256); + c.serverCertReqSigAlgs = TlsUtilities.VectorOfOne(SignatureAndHashAlgorithm.rsa_pss_rsae_sha256); c.serverCheckSigAlgOfClientCerts = false; c.ExpectServerFatalAlert(AlertDescription.illegal_parameter); - AddTestCase(testSuite, c, prefix + "BadCertificateVerifySigAlg"); + AddTestCase(testSuite, c, prefix + "BadCertVerifySigAlgServer1"); } /* - * Server only declares support for SHA1/ECDSA, client signs with SHA1/RSA, but sends - * SHA1/ECDSA in the CertificateVerify. Since the client is actually tracking SHA1 over the - * handshake, and the claimed algorithm is in the CertificateRequest supported algorithms, - * we expect fatal alert to come from the server when it finds the claimed algorithm - * doesn't match the client certificate. + * Server declares support for rsa_pss_rsae_sha256 and ecdsa_secp256r1_sha256, client selects + * rsa_pss_rsae_sha256 but claims ecdsa_secp256r1_sha256, so we expect fatal alert from the server + * validation of the client certificate. */ if (isTlsV12) { TlsTestConfig c = CreateTlsTestConfig(version, clientCrypto, serverCrypto); c.clientAuth = C.CLIENT_AUTH_VALID; - c.clientAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.rsa); - c.clientAuthSigAlgClaimed = new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.ecdsa); - c.serverCertReqSigAlgs = TlsUtilities.GetDefaultECDsaSignatureAlgorithms(); + c.clientAuthSigAlg = SignatureAndHashAlgorithm.rsa_pss_rsae_sha256; + c.clientAuthSigAlgClaimed = SignatureScheme.GetSignatureAndHashAlgorithm(SignatureScheme.ecdsa_secp256r1_sha256); + c.serverCertReqSigAlgs = new ArrayList(2); + c.serverCertReqSigAlgs.Add(SignatureAndHashAlgorithm.rsa_pss_rsae_sha256); + c.serverCertReqSigAlgs.Add( + SignatureScheme.GetSignatureAndHashAlgorithm(SignatureScheme.ecdsa_secp256r1_sha256)); c.ExpectServerFatalAlert(AlertDescription.bad_certificate); - AddTestCase(testSuite, c, prefix + "BadCertificateVerifySigAlgMismatch"); + AddTestCase(testSuite, c, prefix + "BadCertVerifySigAlgServer2"); } { @@ -161,7 +162,7 @@ namespace Org.BouncyCastle.Tls.Tests c.clientAuth = C.CLIENT_AUTH_INVALID_VERIFY; c.ExpectServerFatalAlert(AlertDescription.decrypt_error); - AddTestCase(testSuite, c, prefix + "BadCertificateVerifySignature"); + AddTestCase(testSuite, c, prefix + "BadCertVerifySignature"); } { @@ -212,23 +213,24 @@ namespace Org.BouncyCastle.Tls.Tests } /* - * Server selects MD5/RSA for ServerKeyExchange signature, which is not in the default - * supported signature algorithms that the client sent. We expect fatal alert from the - * client when it verifies the selected algorithm against the supported algorithms. + * Client declares support for SHA256/RSA, server selects SHA384/RSA, so we expect fatal alert from the + * client validation of the ServerKeyExchange algorithm. */ if (TlsUtilities.IsTlsV12(version)) { TlsTestConfig c = CreateTlsTestConfig(version, clientCrypto, serverCrypto); - c.serverAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.md5, SignatureAlgorithm.rsa); + c.clientCHSigAlgs = TlsUtilities.VectorOfOne( + new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.rsa)); + c.serverAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha384, SignatureAlgorithm.rsa); c.ExpectClientFatalAlert(AlertDescription.illegal_parameter); AddTestCase(testSuite, c, prefix + "BadServerKeyExchangeSigAlg"); } /* - * Server selects MD5/RSA for ServerKeyExchange signature, which is not the default {sha1,rsa} - * implied by the absent signature_algorithms extension. We expect fatal alert from the - * client when it verifies the selected algorithm against the implicit default. + * Server selects SHA256/RSA for ServerKeyExchange signature, which is not the default {sha1,rsa} implied by + * the absent signature_algorithms extension. We expect fatal alert from the client when it verifies the + * selected algorithm against the implicit default. */ if (isTlsV12Exactly) { @@ -236,7 +238,7 @@ namespace Org.BouncyCastle.Tls.Tests c.clientCheckSigAlgOfServerCerts = false; c.clientSendSignatureAlgorithms = false; c.clientSendSignatureAlgorithmsCert = false; - c.serverAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.md5, SignatureAlgorithm.rsa); + c.serverAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.rsa); c.ExpectClientFatalAlert(AlertDescription.illegal_parameter); AddTestCase(testSuite, c, prefix + "BadServerKeyExchangeSigAlg2");