diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-12-16 22:50:41 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-12-16 22:50:41 +0700 |
commit | ae227e65ab48b8747c80e1b336a3e6896e9e346e (patch) | |
tree | bff90e085f89872399328db0391f9e8b4f7368f0 /crypto/test | |
parent | Update version for release (diff) | |
download | BouncyCastle.NET-ed25519-ae227e65ab48b8747c80e1b336a3e6896e9e346e.tar.xz |
Validate CertificateVerify signature algorithm (TLS 1.2+)
- check the algorithm is in the CertificateRequest list - add (D)TLS test scenarios for various failure modes
Diffstat (limited to 'crypto/test')
-rw-r--r-- | crypto/test/UnitTests.csproj | 4 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/DtlsTestCase.cs | 9 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/DtlsTestClientProtocol.cs | 28 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/DtlsTestServerProtocol.cs | 18 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/DtlsTestSuite.cs | 122 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/TlsTestCase.cs | 8 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/TlsTestClientImpl.cs | 11 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/TlsTestClientProtocol.cs | 29 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/TlsTestConfig.cs | 19 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/TlsTestServerImpl.cs | 27 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/TlsTestServerProtocol.cs | 19 | ||||
-rw-r--r-- | crypto/test/src/crypto/tls/test/TlsTestSuite.cs | 74 |
12 files changed, 314 insertions, 54 deletions
diff --git a/crypto/test/UnitTests.csproj b/crypto/test/UnitTests.csproj index 71896d203..24a60346e 100644 --- a/crypto/test/UnitTests.csproj +++ b/crypto/test/UnitTests.csproj @@ -277,6 +277,8 @@ <Compile Include="src\crypto\tls\test\ByteQueueStreamTest.cs" /> <Compile Include="src\crypto\tls\test\DtlsProtocolTest.cs" /> <Compile Include="src\crypto\tls\test\DtlsTestCase.cs" /> + <Compile Include="src\crypto\tls\test\DtlsTestClientProtocol.cs" /> + <Compile Include="src\crypto\tls\test\DtlsTestServerProtocol.cs" /> <Compile Include="src\crypto\tls\test\DtlsTestSuite.cs" /> <Compile Include="src\crypto\tls\test\LoggingDatagramTransport.cs" /> <Compile Include="src\crypto\tls\test\MockDatagramAssociation.cs" /> @@ -299,8 +301,10 @@ <Compile Include="src\crypto\tls\test\TlsSrpProtocolTest.cs" /> <Compile Include="src\crypto\tls\test\TlsTestCase.cs" /> <Compile Include="src\crypto\tls\test\TlsTestClientImpl.cs" /> + <Compile Include="src\crypto\tls\test\TlsTestClientProtocol.cs" /> <Compile Include="src\crypto\tls\test\TlsTestConfig.cs" /> <Compile Include="src\crypto\tls\test\TlsTestServerImpl.cs" /> + <Compile Include="src\crypto\tls\test\TlsTestServerProtocol.cs" /> <Compile Include="src\crypto\tls\test\TlsTestSuite.cs" /> <Compile Include="src\crypto\tls\test\TlsTestUtilities.cs" /> <Compile Include="src\crypto\tls\test\UnreliableDatagramTransport.cs" /> diff --git a/crypto/test/src/crypto/tls/test/DtlsTestCase.cs b/crypto/test/src/crypto/tls/test/DtlsTestCase.cs index d4af04fac..5e43337f4 100644 --- a/crypto/test/src/crypto/tls/test/DtlsTestCase.cs +++ b/crypto/test/src/crypto/tls/test/DtlsTestCase.cs @@ -28,8 +28,8 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests SecureRandom secureRandom = new SecureRandom(); - DtlsClientProtocol clientProtocol = new DtlsClientProtocol(secureRandom); - DtlsServerProtocol serverProtocol = new DtlsServerProtocol(secureRandom); + DtlsTestClientProtocol clientProtocol = new DtlsTestClientProtocol(secureRandom, config); + DtlsTestServerProtocol serverProtocol = new DtlsTestServerProtocol(secureRandom, config); MockDatagramAssociation network = new MockDatagramAssociation(1500); @@ -101,14 +101,15 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests internal class Server { private readonly DtlsTestCase mOuter; - private readonly DtlsServerProtocol mServerProtocol; + private readonly DtlsTestServerProtocol mServerProtocol; private readonly DatagramTransport mServerTransport; private readonly TlsTestServerImpl mServerImpl; private volatile bool isShutdown = false; internal Exception mCaught = null; - internal Server(DtlsTestCase outer, DtlsServerProtocol serverProtocol, DatagramTransport serverTransport, TlsTestServerImpl serverImpl) + internal Server(DtlsTestCase outer, DtlsTestServerProtocol serverProtocol, + DatagramTransport serverTransport, TlsTestServerImpl serverImpl) { this.mOuter = outer; this.mServerProtocol = serverProtocol; diff --git a/crypto/test/src/crypto/tls/test/DtlsTestClientProtocol.cs b/crypto/test/src/crypto/tls/test/DtlsTestClientProtocol.cs new file mode 100644 index 000000000..41ed93eb0 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/DtlsTestClientProtocol.cs @@ -0,0 +1,28 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class DtlsTestClientProtocol + : DtlsClientProtocol + { + protected readonly TlsTestConfig config; + + public DtlsTestClientProtocol(SecureRandom secureRandom, TlsTestConfig config) + : base(secureRandom) + { + this.config = config; + } + + protected override byte[] GenerateCertificateVerify(ClientHandshakeState state, DigitallySigned certificateVerify) + { + if (certificateVerify.Algorithm != null && config.clientAuthSigAlgClaimed != null) + { + certificateVerify = new DigitallySigned(config.clientAuthSigAlgClaimed, certificateVerify.Signature); + } + + return base.GenerateCertificateVerify(state, certificateVerify); + } + } +} diff --git a/crypto/test/src/crypto/tls/test/DtlsTestServerProtocol.cs b/crypto/test/src/crypto/tls/test/DtlsTestServerProtocol.cs new file mode 100644 index 000000000..006473cef --- /dev/null +++ b/crypto/test/src/crypto/tls/test/DtlsTestServerProtocol.cs @@ -0,0 +1,18 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class DtlsTestServerProtocol + : DtlsServerProtocol + { + protected readonly TlsTestConfig config; + + public DtlsTestServerProtocol(SecureRandom secureRandom, TlsTestConfig config) + : base(secureRandom) + { + this.config = config; + } + } +} diff --git a/crypto/test/src/crypto/tls/test/DtlsTestSuite.cs b/crypto/test/src/crypto/tls/test/DtlsTestSuite.cs index eb9d42e5f..69ce36071 100644 --- a/crypto/test/src/crypto/tls/test/DtlsTestSuite.cs +++ b/crypto/test/src/crypto/tls/test/DtlsTestSuite.cs @@ -31,7 +31,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests TlsTestConfig c = CreateDtlsTestConfig(ProtocolVersion.DTLSv12); c.clientFallback = true; - testSuite.Add(new TestCaseData(c).SetName("FallbackGood")); + AddTestCase(testSuite, c, "FallbackGood"); } /* @@ -40,20 +40,22 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests * alerts being raised */ - //{ - // TlsTestConfig c = CreateDtlsTestConfig(ProtocolVersion.DTLSv12); - // c.clientOfferVersion = ProtocolVersion.DTLSv10; - // c.clientFallback = true; - // c.ExpectServerFatalAlert(AlertDescription.inappropriate_fallback); +#if false + { + TlsTestConfig c = CreateDtlsTestConfig(ProtocolVersion.DTLSv12); + c.clientOfferVersion = ProtocolVersion.DTLSv10; + c.clientFallback = true; + c.ExpectServerFatalAlert(AlertDescription.inappropriate_fallback); - // testSuite.Add(new TestCaseData(c).SetName("FallbackBad")); - //} + AddTestCase(testSuite, c, "FallbackBad"); + } +#endif { TlsTestConfig c = CreateDtlsTestConfig(ProtocolVersion.DTLSv12); c.clientOfferVersion = ProtocolVersion.DTLSv10; - testSuite.Add(new TestCaseData(c).SetName("FallbackNone")); + AddTestCase(testSuite, c, "FallbackNone"); } } @@ -71,52 +73,110 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests * alerts being raised */ - //{ - // TlsTestConfig c = CreateDtlsTestConfig(version); - // c.clientAuth = C.CLIENT_AUTH_INVALID_VERIFY; - // c.ExpectServerFatalAlert(AlertDescription.decrypt_error); +#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. + */ + 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.ExpectClientFatalAlert(AlertDescription.internal_error); - // testSuite.Add(new TestCaseData(c).SetName(prefix + "BadCertificateVerify")); - //} + AddTestCase(testSuite, c, prefix + "BadCertificateVerifyHashAlg"); + } - //{ - // TlsTestConfig c = CreateDtlsTestConfig(version); - // c.clientAuth = C.CLIENT_AUTH_INVALID_CERT; - // c.ExpectServerFatalAlert(AlertDescription.bad_certificate); + /* + * 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. + */ + 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.ExpectServerFatalAlert(AlertDescription.illegal_parameter); - // testSuite.Add(new TestCaseData(c).SetName(prefix + "BadClientCertificate")); - //} + AddTestCase(testSuite, c, prefix + "BadCertificateVerifySigAlg"); + } - //{ - // TlsTestConfig c = CreateDtlsTestConfig(version); - // c.clientAuth = C.CLIENT_AUTH_NONE; - // c.serverCertReq = C.SERVER_CERT_REQ_MANDATORY; - // c.ExpectServerFatalAlert(AlertDescription.handshake_failure); + /* + * 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. + */ + 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); - // testSuite.Add(new TestCaseData(c).SetName(prefix + "BadMandatoryCertReqDeclined")); - //} + AddTestCase(testSuite, c, prefix + "BadCertificateVerifySigAlgMismatch"); + } { TlsTestConfig c = CreateDtlsTestConfig(version); + c.clientAuth = C.CLIENT_AUTH_INVALID_VERIFY; + c.ExpectServerFatalAlert(AlertDescription.decrypt_error); - testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodDefault")); + AddTestCase(testSuite, c, prefix + "BadCertificateVerifySignature"); + } + + { + TlsTestConfig c = CreateDtlsTestConfig(version); + c.clientAuth = C.CLIENT_AUTH_INVALID_CERT; + c.ExpectServerFatalAlert(AlertDescription.bad_certificate); + + AddTestCase(testSuite, c, prefix + "BadClientCertificate"); + } + + { + TlsTestConfig c = CreateDtlsTestConfig(version); + c.clientAuth = C.CLIENT_AUTH_NONE; + c.serverCertReq = C.SERVER_CERT_REQ_MANDATORY; + c.ExpectServerFatalAlert(AlertDescription.handshake_failure); + + AddTestCase(testSuite, c, prefix + "BadMandatoryCertReqDeclined"); + } +#endif + + { + TlsTestConfig c = CreateDtlsTestConfig(version); + + AddTestCase(testSuite, c, prefix + "GoodDefault"); } { TlsTestConfig c = CreateDtlsTestConfig(version); c.serverCertReq = C.SERVER_CERT_REQ_NONE; - testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodNoCertReq")); + AddTestCase(testSuite, c, prefix + "GoodNoCertReq"); } { TlsTestConfig c = CreateDtlsTestConfig(version); c.clientAuth = C.CLIENT_AUTH_NONE; - testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodOptionalCertReqDeclined")); + AddTestCase(testSuite, c, prefix + "GoodOptionalCertReqDeclined"); } } + private static void AddTestCase(IList testSuite, TlsTestConfig config, String name) + { + testSuite.Add(new TestCaseData(config).SetName(name)); + } + private static TlsTestConfig CreateDtlsTestConfig(ProtocolVersion version) { TlsTestConfig c = new TlsTestConfig(); diff --git a/crypto/test/src/crypto/tls/test/TlsTestCase.cs b/crypto/test/src/crypto/tls/test/TlsTestCase.cs index 4b0c12710..7fb5db6ce 100644 --- a/crypto/test/src/crypto/tls/test/TlsTestCase.cs +++ b/crypto/test/src/crypto/tls/test/TlsTestCase.cs @@ -35,8 +35,8 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests NetworkStream clientNet = new NetworkStream(clientPipe); NetworkStream serverNet = new NetworkStream(serverPipe); - TlsClientProtocol clientProtocol = new TlsClientProtocol(clientNet, secureRandom); - TlsServerProtocol serverProtocol = new TlsServerProtocol(serverNet, secureRandom); + TlsTestClientProtocol clientProtocol = new TlsTestClientProtocol(clientNet, secureRandom, config); + TlsTestServerProtocol serverProtocol = new TlsTestServerProtocol(serverNet, secureRandom, config); TlsTestClientImpl clientImpl = new TlsTestClientImpl(config); TlsTestServerImpl serverImpl = new TlsTestServerImpl(config); @@ -104,13 +104,13 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests internal class Server { protected readonly TlsTestCase mOuter; - protected readonly TlsServerProtocol mServerProtocol; + protected readonly TlsTestServerProtocol mServerProtocol; protected readonly TlsTestServerImpl mServerImpl; internal bool mCanExit = false; internal Exception mCaught = null; - internal Server(TlsTestCase outer, TlsServerProtocol serverProtocol, TlsTestServerImpl serverImpl) + internal Server(TlsTestCase outer, TlsTestServerProtocol serverProtocol, TlsTestServerImpl serverImpl) { this.mOuter = outer; this.mServerProtocol = serverProtocol; diff --git a/crypto/test/src/crypto/tls/test/TlsTestClientImpl.cs b/crypto/test/src/crypto/tls/test/TlsTestClientImpl.cs index 0cc1883ba..f313f75fe 100644 --- a/crypto/test/src/crypto/tls/test/TlsTestClientImpl.cs +++ b/crypto/test/src/crypto/tls/test/TlsTestClientImpl.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.IO; using Org.BouncyCastle.Asn1; @@ -201,9 +202,15 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests return null; } + IList supportedSigAlgs = certificateRequest.SupportedSignatureAlgorithms; + if (supportedSigAlgs != null && mOuter.mConfig.clientAuthSigAlg != null) + { + supportedSigAlgs = new ArrayList(1); + supportedSigAlgs.Add(mOuter.mConfig.clientAuthSigAlg); + } + TlsSignerCredentials signerCredentials = TlsTestUtilities.LoadSignerCredentials(mContext, - certificateRequest.SupportedSignatureAlgorithms, SignatureAlgorithm.rsa, - "x509-client.pem", "x509-client-key.pem"); + supportedSigAlgs, SignatureAlgorithm.rsa, "x509-client.pem", "x509-client-key.pem"); if (mOuter.mConfig.clientAuth == TlsTestConfig.CLIENT_AUTH_VALID) { diff --git a/crypto/test/src/crypto/tls/test/TlsTestClientProtocol.cs b/crypto/test/src/crypto/tls/test/TlsTestClientProtocol.cs new file mode 100644 index 000000000..97b7c91bc --- /dev/null +++ b/crypto/test/src/crypto/tls/test/TlsTestClientProtocol.cs @@ -0,0 +1,29 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class TlsTestClientProtocol + : TlsClientProtocol + { + protected readonly TlsTestConfig config; + + public TlsTestClientProtocol(Stream stream, SecureRandom secureRandom, TlsTestConfig config) + : base(stream, secureRandom) + { + this.config = config; + } + + protected override void SendCertificateVerifyMessage(DigitallySigned certificateVerify) + { + if (certificateVerify.Algorithm != null && config.clientAuthSigAlgClaimed != null) + { + certificateVerify = new DigitallySigned(config.clientAuthSigAlgClaimed, certificateVerify.Signature); + } + + base.SendCertificateVerifyMessage(certificateVerify); + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsTestConfig.cs b/crypto/test/src/crypto/tls/test/TlsTestConfig.cs index 0d1e7badb..212d2b63c 100644 --- a/crypto/test/src/crypto/tls/test/TlsTestConfig.cs +++ b/crypto/test/src/crypto/tls/test/TlsTestConfig.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; namespace Org.BouncyCastle.Crypto.Tls.Tests { @@ -47,6 +48,18 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests public int clientAuth = CLIENT_AUTH_VALID; /** + * If not null, and TLS 1.2 or higher is negotiated, selects a fixed signature/hash algorithm to + * be used for the CertificateVerify signature (if one is sent). + */ + public SignatureAndHashAlgorithm clientAuthSigAlg = null; + + /** + * If not null, and TLS 1.2 or higher is negotiated, selects a fixed signature/hash algorithm to + * be _claimed_ in the CertificateVerify (if one is sent), independently of what was actually used. + */ + public SignatureAndHashAlgorithm clientAuthSigAlgClaimed = null; + + /** * Configures the minimum protocol version the client will accept. If null, uses the library's default. */ public ProtocolVersion clientMinimumVersion = null; @@ -67,6 +80,12 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests public int serverCertReq = SERVER_CERT_REQ_OPTIONAL; /** + * If TLS 1.2 or higher is negotiated, configures the set of supported signature algorithms in the + * CertificateRequest (if one is sent). If null, uses a default set. + */ + public IList serverCertReqSigAlgs = null; + + /** * Configures the maximum protocol version the server will accept. If null, uses the library's default. */ public ProtocolVersion serverMaximumVersion = null; diff --git a/crypto/test/src/crypto/tls/test/TlsTestServerImpl.cs b/crypto/test/src/crypto/tls/test/TlsTestServerImpl.cs index 152d5dbdc..6f9d35b5c 100644 --- a/crypto/test/src/crypto/tls/test/TlsTestServerImpl.cs +++ b/crypto/test/src/crypto/tls/test/TlsTestServerImpl.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.IO; +using System.Threading; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; @@ -72,11 +73,11 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests + ", " + AlertDescription.GetText(alertDescription)); if (message != null) { - output.WriteLine("> " + message); + SafeWriteLine(output, "> " + message); } if (cause != null) { - output.WriteLine(cause); + SafeWriteLine(output, cause); } } } @@ -92,7 +93,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests if (TlsTestConfig.DEBUG) { TextWriter output = (alertLevel == AlertLevel.fatal) ? Console.Error : Console.Out; - output.WriteLine("TLS server received alert: " + AlertLevel.GetText(alertLevel) + SafeWriteLine(output, "TLS server received alert: " + AlertLevel.GetText(alertLevel) + ", " + AlertDescription.GetText(alertDescription)); } } @@ -122,7 +123,11 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests IList serverSigAlgs = null; if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(mServerVersion)) { - serverSigAlgs = TlsUtilities.GetDefaultSupportedSignatureAlgorithms(); + serverSigAlgs = mConfig.serverCertReqSigAlgs; + if (serverSigAlgs == null) + { + serverSigAlgs = TlsUtilities.GetDefaultSupportedSignatureAlgorithms(); + } } IList certificateAuthorities = new ArrayList(); @@ -190,5 +195,19 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests return TlsTestUtilities.LoadSignerCredentials(mContext, mSupportedSignatureAlgorithms, SignatureAlgorithm.rsa, "x509-server.pem", "x509-server-key.pem"); } + + private static void SafeWriteLine(TextWriter output, object line) + { + try + { + output.WriteLine(line); + } + catch (ThreadInterruptedException) + { + /* + * For some reason the NUnit plugin in Visual Studio started throwing these during alert logging + */ + } + } } } diff --git a/crypto/test/src/crypto/tls/test/TlsTestServerProtocol.cs b/crypto/test/src/crypto/tls/test/TlsTestServerProtocol.cs new file mode 100644 index 000000000..845b7f0b9 --- /dev/null +++ b/crypto/test/src/crypto/tls/test/TlsTestServerProtocol.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls.Tests +{ + internal class TlsTestServerProtocol + : TlsServerProtocol + { + protected readonly TlsTestConfig config; + + public TlsTestServerProtocol(Stream stream, SecureRandom secureRandom, TlsTestConfig config) + : base(stream, secureRandom) + { + this.config = config; + } + } +} diff --git a/crypto/test/src/crypto/tls/test/TlsTestSuite.cs b/crypto/test/src/crypto/tls/test/TlsTestSuite.cs index dfd09d06e..0770187d5 100644 --- a/crypto/test/src/crypto/tls/test/TlsTestSuite.cs +++ b/crypto/test/src/crypto/tls/test/TlsTestSuite.cs @@ -32,7 +32,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests TlsTestConfig c = CreateTlsTestConfig(ProtocolVersion.TLSv12); c.clientFallback = true; - testSuite.Add(new TestCaseData(c).SetName("FallbackGood")); + AddTestCase(testSuite, c, "FallbackGood"); } { @@ -41,14 +41,14 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests c.clientFallback = true; c.ExpectServerFatalAlert(AlertDescription.inappropriate_fallback); - testSuite.Add(new TestCaseData(c).SetName("FallbackBad")); + AddTestCase(testSuite, c, "FallbackBad"); } { TlsTestConfig c = CreateTlsTestConfig(ProtocolVersion.TLSv12); c.clientOfferVersion = ProtocolVersion.TLSv11; - testSuite.Add(new TestCaseData(c).SetName("FallbackNone")); + AddTestCase(testSuite, c, "FallbackNone"); } } @@ -63,7 +63,58 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests { TlsTestConfig c = CreateTlsTestConfig(version); - testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodDefault")); + AddTestCase(testSuite, c, prefix + "GoodDefault"); + } + + /* + * 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. + */ + if (TlsUtilities.IsTlsV12(version)) + { + TlsTestConfig c = CreateTlsTestConfig(version); + c.clientAuth = C.CLIENT_AUTH_VALID; + c.clientAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.md5, SignatureAlgorithm.rsa); + c.serverCertReqSigAlgs = TlsUtilities.GetDefaultRsaSignatureAlgorithms(); + c.ExpectClientFatalAlert(AlertDescription.internal_error); + + AddTestCase(testSuite, c, prefix + "BadCertificateVerifyHashAlg"); + } + + /* + * 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. + */ + if (TlsUtilities.IsTlsV12(version)) + { + TlsTestConfig c = CreateTlsTestConfig(version); + c.clientAuth = C.CLIENT_AUTH_VALID; + c.clientAuthSigAlg = new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.rsa); + c.serverCertReqSigAlgs = TlsUtilities.GetDefaultECDsaSignatureAlgorithms(); + c.ExpectServerFatalAlert(AlertDescription.illegal_parameter); + + AddTestCase(testSuite, c, prefix + "BadCertificateVerifySigAlg"); + } + + /* + * 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. + */ + if (TlsUtilities.IsTlsV12(version)) + { + TlsTestConfig c = CreateTlsTestConfig(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); + + AddTestCase(testSuite, c, prefix + "BadCertificateVerifySigAlgMismatch"); } { @@ -71,7 +122,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests c.clientAuth = C.CLIENT_AUTH_INVALID_VERIFY; c.ExpectServerFatalAlert(AlertDescription.decrypt_error); - testSuite.Add(new TestCaseData(c).SetName(prefix + "BadCertificateVerify")); + AddTestCase(testSuite, c, prefix + "BadCertificateVerifySignature"); } { @@ -79,7 +130,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests c.clientAuth = C.CLIENT_AUTH_INVALID_CERT; c.ExpectServerFatalAlert(AlertDescription.bad_certificate); - testSuite.Add(new TestCaseData(c).SetName(prefix + "BadClientCertificate")); + AddTestCase(testSuite, c, prefix + "BadClientCertificate"); } { @@ -88,24 +139,29 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests c.serverCertReq = C.SERVER_CERT_REQ_MANDATORY; c.ExpectServerFatalAlert(AlertDescription.handshake_failure); - testSuite.Add(new TestCaseData(c).SetName(prefix + "BadMandatoryCertReqDeclined")); + AddTestCase(testSuite, c, prefix + "BadMandatoryCertReqDeclined"); } { TlsTestConfig c = CreateTlsTestConfig(version); c.serverCertReq = C.SERVER_CERT_REQ_NONE; - testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodNoCertReq")); + AddTestCase(testSuite, c, prefix + "GoodNoCertReq"); } { TlsTestConfig c = CreateTlsTestConfig(version); c.clientAuth = C.CLIENT_AUTH_NONE; - testSuite.Add(new TestCaseData(c).SetName(prefix + "GoodOptionalCertReqDeclined")); + AddTestCase(testSuite, c, prefix + "GoodOptionalCertReqDeclined"); } } + private static void AddTestCase(IList testSuite, TlsTestConfig config, string name) + { + testSuite.Add(new TestCaseData(config).SetName(name)); + } + private static TlsTestConfig CreateTlsTestConfig(ProtocolVersion version) { TlsTestConfig c = new TlsTestConfig(); |