diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-09-24 18:09:39 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-09-24 18:09:39 +0700 |
commit | ed081e3fe9634391ac496bd79193a7d00dfa6f07 (patch) | |
tree | ecc1382c5f3f9a17c6b21ebf8026076f6a32f15f /crypto/test | |
parent | Cmp updates (diff) | |
download | BouncyCastle.NET-ed25519-ed081e3fe9634391ac496bd79193a7d00dfa6f07.tar.xz |
(D)TLS: RFC 7250 Raw Public Keys
Diffstat (limited to 'crypto/test')
-rw-r--r-- | crypto/test/src/tls/test/MockRawKeysTlsClient.cs | 126 | ||||
-rw-r--r-- | crypto/test/src/tls/test/MockRawKeysTlsServer.cs | 134 | ||||
-rw-r--r-- | crypto/test/src/tls/test/TlsClientRawKeysTest.cs | 99 | ||||
-rw-r--r-- | crypto/test/src/tls/test/TlsRawKeysProtocolTest.cs | 282 | ||||
-rw-r--r-- | crypto/test/src/tls/test/TlsServerRawKeysTest.cs | 90 |
5 files changed, 731 insertions, 0 deletions
diff --git a/crypto/test/src/tls/test/MockRawKeysTlsClient.cs b/crypto/test/src/tls/test/MockRawKeysTlsClient.cs new file mode 100644 index 000000000..594c4c94e --- /dev/null +++ b/crypto/test/src/tls/test/MockRawKeysTlsClient.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Tls.Crypto.Impl.BC; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Tls.Tests +{ + internal class MockRawKeysTlsClient + : DefaultTlsClient + { + private short m_serverCertType; + private short m_clientCertType; + private short[] m_offerServerCertTypes; + private short[] m_offerClientCertTypes; + private ProtocolVersion m_tlsVersion; + private Ed25519PrivateKeyParameters m_privateKey; + + internal MockRawKeysTlsClient(short serverCertType, short clientCertType, short[] offerServerCertTypes, + short[] offerClientCertTypes, Ed25519PrivateKeyParameters privateKey, ProtocolVersion tlsVersion) + : base(new BcTlsCrypto(new SecureRandom())) + { + m_serverCertType = serverCertType; + m_clientCertType = clientCertType; + m_offerServerCertTypes = offerServerCertTypes; + m_offerClientCertTypes = offerClientCertTypes; + m_privateKey = privateKey; + m_tlsVersion = tlsVersion; + } + + protected override ProtocolVersion[] GetSupportedVersions() + { + return new ProtocolVersion[]{ m_tlsVersion }; + } + + protected override int[] GetSupportedCipherSuites() + { + return TlsUtilities.IsTlsV13(m_tlsVersion) + ? new int[]{ CipherSuite.TLS_AES_128_GCM_SHA256 } + : new int[]{ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 }; + } + + protected override short[] GetAllowedClientCertificateTypes() => m_offerClientCertTypes; + + protected override short[] GetAllowedServerCertificateTypes() => m_offerServerCertTypes; + + protected override CertificateStatusRequest GetCertificateStatusRequest() + { + return m_serverCertType == CertificateType.RawPublicKey ? null : base.GetCertificateStatusRequest(); + } + + protected override IList<CertificateStatusRequestItemV2> GetMultiCertStatusRequest() + { + return m_serverCertType == CertificateType.RawPublicKey ? null : base.GetMultiCertStatusRequest(); + } + + public override TlsAuthentication GetAuthentication() + { + return new MyTlsAuthentication(this); + } + + internal class MyTlsAuthentication + : TlsAuthentication + { + private readonly MockRawKeysTlsClient m_outer; + private TlsCredentialedSigner m_credentials; + + internal MyTlsAuthentication(MockRawKeysTlsClient outer) + { + m_outer = outer; + } + + public void NotifyServerCertificate(TlsServerCertificate serverCertificate) + { + Assert.AreEqual(m_outer.m_serverCertType, serverCertificate.Certificate.CertificateType, + "wrong certificate type from server"); + } + + public TlsCredentials GetClientCredentials(CertificateRequest certificateRequest) + { + var clientCertType = m_outer.m_clientCertType; + var context = m_outer.m_context; + var crypto = (BcTlsCrypto)m_outer.Crypto; + var privateKey = m_outer.m_privateKey; + + if (clientCertType < 0) + { + Assert.Fail("should not have received a certificate request"); + } + + Assert.AreEqual(clientCertType, context.SecurityParameters.ClientCertificateType, + "wrong certificate type in request"); + + if (m_credentials == null) + { + switch (clientCertType) + { + case CertificateType.X509: + m_credentials = TlsTestUtilities.LoadSignerCredentials(context, + certificateRequest.SupportedSignatureAlgorithms, SignatureAlgorithm.ed25519, + "x509-client-ed25519.pem", "x509-client-key-ed25519.pem"); + break; + case CertificateType.RawPublicKey: + TlsCertificate rawKeyCert = new BcTlsRawKeyCertificate(crypto, + SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(privateKey.GeneratePublicKey())); + Certificate cert = new Certificate(CertificateType.RawPublicKey, + TlsUtilities.IsTlsV13(context) ? TlsUtilities.EmptyBytes : null, + new CertificateEntry[]{ new CertificateEntry(rawKeyCert, null) }); + m_credentials = new BcDefaultTlsCredentialedSigner(new TlsCryptoParameters(context), + crypto, privateKey, cert, SignatureAndHashAlgorithm.ed25519); + break; + default: + throw new ArgumentException("Only supports X509 and raw keys"); + } + } + + return m_credentials; + } + }; + } +} diff --git a/crypto/test/src/tls/test/MockRawKeysTlsServer.cs b/crypto/test/src/tls/test/MockRawKeysTlsServer.cs new file mode 100644 index 000000000..e136c6571 --- /dev/null +++ b/crypto/test/src/tls/test/MockRawKeysTlsServer.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Tls.Crypto.Impl.BC; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Tls.Tests +{ + internal class MockRawKeysTlsServer + : DefaultTlsServer + { + private short m_serverCertType; + private short m_clientCertType; + private short[] m_allowedClientCertTypes; + private Ed25519PrivateKeyParameters m_privateKey; + private ProtocolVersion m_tlsVersion; + private TlsCredentialedSigner m_credentials; + + internal IDictionary<int, byte[]> m_receivedClientExtensions; + + internal MockRawKeysTlsServer(short serverCertType, short clientCertType, short[] allowedClientCertTypes, + Ed25519PrivateKeyParameters privateKey, ProtocolVersion tlsVersion) + : base(new BcTlsCrypto(new SecureRandom())) + { + m_serverCertType = serverCertType; + m_clientCertType = clientCertType; + m_allowedClientCertTypes = allowedClientCertTypes; + m_privateKey = privateKey; + m_tlsVersion = tlsVersion; + } + + 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 GetECDsaSignerCredentials(); + + return base.GetCredentials(); + } + + protected override ProtocolVersion[] GetSupportedVersions() + { + return new ProtocolVersion[]{ m_tlsVersion }; + } + + protected override int[] GetSupportedCipherSuites() + { + return TlsUtilities.IsTlsV13(m_tlsVersion) + ? new int[]{ CipherSuite.TLS_AES_128_GCM_SHA256 } + : new int[]{ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 }; + } + + public override void ProcessClientExtensions(IDictionary<int, byte[]> clientExtensions) + { + m_receivedClientExtensions = clientExtensions; + + base.ProcessClientExtensions(clientExtensions); + } + + protected override TlsCredentialedSigner GetECDsaSignerCredentials() + { + if (m_credentials == null) + { + var crypto = (BcTlsCrypto)Crypto; + + switch (m_serverCertType) + { + case CertificateType.X509: + m_credentials = TlsTestUtilities.LoadSignerCredentials(m_context, + m_context.SecurityParameters.ClientSigAlgs, SignatureAlgorithm.ed25519, + "x509-client-ed25519.pem", "x509-client-key-ed25519.pem"); + break; + case CertificateType.RawPublicKey: + TlsCertificate rawKeyCert = new BcTlsRawKeyCertificate(crypto, + SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(m_privateKey.GeneratePublicKey())); + Certificate cert = new Certificate(CertificateType.RawPublicKey, + TlsUtilities.IsTlsV13(m_context) ? TlsUtilities.EmptyBytes : null, + new CertificateEntry[]{ new CertificateEntry(rawKeyCert, null) }); + m_credentials = new BcDefaultTlsCredentialedSigner(new TlsCryptoParameters(m_context), + crypto, m_privateKey, cert, SignatureAndHashAlgorithm.ed25519); + break; + default: + throw new ArgumentException("Only supports X509 and raw keys"); + } + } + + return m_credentials; + } + + protected override short[] GetAllowedClientCertificateTypes() => m_allowedClientCertTypes; + + protected override bool AllowCertificateStatus() + { + return m_serverCertType == CertificateType.RawPublicKey ? false : base.AllowCertificateStatus(); + } + + protected override bool AllowMultiCertStatus() + { + return m_serverCertType == CertificateType.RawPublicKey ? false : base.AllowMultiCertStatus(); + } + + public override CertificateRequest GetCertificateRequest() + { + if (m_clientCertType < 0) + return null; + + short[] certificateTypes = new short[]{ ClientCertificateType.ecdsa_sign }; + + IList<SignatureAndHashAlgorithm> serverSigAlgs = null; + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(m_context.ServerVersion)) + { + serverSigAlgs = TlsUtilities.GetDefaultSupportedSignatureAlgorithms(m_context); + } + + return TlsUtilities.IsTlsV13(m_tlsVersion) + ? new CertificateRequest(TlsUtilities.EmptyBytes, serverSigAlgs, null, null) + : new CertificateRequest(certificateTypes, serverSigAlgs, null); + } + + public override void NotifyClientCertificate(Certificate clientCertificate) + { + Assert.AreEqual(m_clientCertType, clientCertificate.CertificateType, + "client certificate is the wrong type"); + } + } +} diff --git a/crypto/test/src/tls/test/TlsClientRawKeysTest.cs b/crypto/test/src/tls/test/TlsClientRawKeysTest.cs new file mode 100644 index 000000000..510213fc7 --- /dev/null +++ b/crypto/test/src/tls/test/TlsClientRawKeysTest.cs @@ -0,0 +1,99 @@ +using System; +using System.IO; +using System.Net.Sockets; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Tls.Tests +{ + /// <summary>A simple test designed to conduct a TLS handshake with an external TLS server.</summary> + /// <remarks> + /// <code> + /// openssl genpkey -out ed25519.priv -algorithm ed25519 + /// openssl pkey -in ed25519.priv -pubout -out ed25519.pub + /// + /// gnutls-serv --http --debug 10 --priority NORMAL:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK --rawpkkeyfile ed25519.priv --rawpkfile ed25519.pub + /// </code> + /// </remarks> + [TestFixture] + public class TlsClientRawKeysTest + { + [Test, Explicit] + public void TestConnection() + { + string host = "localhost"; + int port = 5556; + + RunTest(host, port, ProtocolVersion.TLSv12); + RunTest(host, port, ProtocolVersion.TLSv13); + } + + private static void RunTest(string host, int port, ProtocolVersion tlsVersion) + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient(CertificateType.RawPublicKey, + CertificateType.RawPublicKey, new short[]{ CertificateType.RawPublicKey }, + new short[]{ CertificateType.RawPublicKey }, new Ed25519PrivateKeyParameters(new SecureRandom()), + tlsVersion); + TlsClientProtocol protocol = OpenTlsClientConnection(host, port, client); + + Http11Get(host, port, protocol.Stream); + + protocol.Close(); + } + + private static void Http11Get(string host, int port, Stream s) + { + WriteUtf8Line(s, "GET / HTTP/1.1"); + //WriteUtf8Line(s, "Host: " + host + ":" + port); + WriteUtf8Line(s, ""); + s.Flush(); + + Console.WriteLine("---"); + + string[] ends = new string[] { "</HTML>", "HTTP/1.1 3", "HTTP/1.1 4" }; + + StreamReader reader = new StreamReader(s); + + bool finished = false; + string line; + while (!finished && (line = reader.ReadLine()) != null) + { + Console.WriteLine("<<< " + line); + + string upperLine = TlsTestUtilities.ToUpperInvariant(line); + + // TEST CODE ONLY. This is not a robust way of parsing the result! + foreach (string end in ends) + { + if (upperLine.IndexOf(end) >= 0) + { + finished = true; + break; + } + } + } + + Console.Out.Flush(); + } + + private static TlsClientProtocol OpenTlsClientConnection(string hostname, int port, TlsClient client) + { + TcpClient tcp = new TcpClient(hostname, port); + + TlsClientProtocol protocol = new TlsClientProtocol(tcp.GetStream()); + protocol.Connect(client); + return protocol; + } + + private static void WriteUtf8Line(Stream output, string line) + { + byte[] buf = Encoding.UTF8.GetBytes(line + "\r\n"); + output.Write(buf, 0, buf.Length); + Console.WriteLine(">>> " + line); + } + } +} diff --git a/crypto/test/src/tls/test/TlsRawKeysProtocolTest.cs b/crypto/test/src/tls/test/TlsRawKeysProtocolTest.cs new file mode 100644 index 000000000..976df4009 --- /dev/null +++ b/crypto/test/src/tls/test/TlsRawKeysProtocolTest.cs @@ -0,0 +1,282 @@ +using System; +using System.IO; +using System.Threading; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls.Tests +{ + [TestFixture] + public class TlsRawKeysProtocolTest + { + private readonly SecureRandom Random = new SecureRandom(); + + [Test] + public void TestClientSendsExtensionButServerDoesNotSupportIt() + { + TestClientSendsExtensionButServerDoesNotSupportIt(ProtocolVersion.TLSv12); + } + + [Test] + public void TestClientSendsExtensionButServerDoesNotSupportIt_13() + { + TestClientSendsExtensionButServerDoesNotSupportIt(ProtocolVersion.TLSv13); + } + + private void TestClientSendsExtensionButServerDoesNotSupportIt(ProtocolVersion tlsVersion) + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient(CertificateType.X509, -1, + new short[]{ CertificateType.RawPublicKey, CertificateType.X509 }, null, GenerateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer(CertificateType.X509, -1, null, GenerateKeyPair(), + tlsVersion); + PumpData(client, server); + } + + [Test] + public void TestExtensionsAreOmittedIfSpecifiedButOnlyContainX509() + { + TestExtensionsAreOmittedIfSpecifiedButOnlyContainX509(ProtocolVersion.TLSv12); + } + + [Test] + public void TestExtensionsAreOmittedIfSpecifiedButOnlyContainX509_13() + { + TestExtensionsAreOmittedIfSpecifiedButOnlyContainX509(ProtocolVersion.TLSv13); + } + + private void TestExtensionsAreOmittedIfSpecifiedButOnlyContainX509(ProtocolVersion tlsVersion) + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient(CertificateType.X509, CertificateType.X509, + new short[]{ CertificateType.X509 }, new short[]{ CertificateType.X509 }, GenerateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer(CertificateType.X509, CertificateType.X509, + new short[]{ CertificateType.X509 }, GenerateKeyPair(), tlsVersion); + PumpData(client, server); + + Assert.IsFalse(server.m_receivedClientExtensions.ContainsKey(ExtensionType.client_certificate_type), + "client cert type extension should not be sent"); + Assert.IsFalse(server.m_receivedClientExtensions.ContainsKey(ExtensionType.server_certificate_type), + "server cert type extension should not be sent"); + } + + [Test] + public void TestBothSidesUseRawKey() + { + TestBothSidesUseRawKey(ProtocolVersion.TLSv12); + } + + [Test] + public void TestBothSidesUseRawKey_13() + { + TestBothSidesUseRawKey(ProtocolVersion.TLSv13); + } + + private void TestBothSidesUseRawKey(ProtocolVersion tlsVersion) + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient(CertificateType.RawPublicKey, + CertificateType.RawPublicKey, new short[]{ CertificateType.RawPublicKey }, + new short[]{ CertificateType.RawPublicKey }, GenerateKeyPair(), tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer(CertificateType.RawPublicKey, + CertificateType.RawPublicKey, new short[]{ CertificateType.RawPublicKey }, GenerateKeyPair(), + tlsVersion); + PumpData(client, server); + } + + [Test] + public void TestServerUsesRawKeyAndClientIsAnonymous() + { + TestServerUsesRawKeyAndClientIsAnonymous(ProtocolVersion.TLSv12); + } + + [Test] + public void TestServerUsesRawKeyAndClientIsAnonymous_13() + { + TestServerUsesRawKeyAndClientIsAnonymous(ProtocolVersion.TLSv13); + } + + private void TestServerUsesRawKeyAndClientIsAnonymous(ProtocolVersion tlsVersion) + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient(CertificateType.RawPublicKey, -1, + new short[]{ CertificateType.RawPublicKey }, null, GenerateKeyPair(), tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer(CertificateType.RawPublicKey, -1, null, + GenerateKeyPair(), tlsVersion); + PumpData(client, server); + } + + [Test] + public void TestServerUsesRawKeyAndClientUsesX509() + { + TestServerUsesRawKeyAndClientUsesX509(ProtocolVersion.TLSv12); + } + + [Test] + public void TestServerUsesRawKeyAndClientUsesX509_13() + { + TestServerUsesRawKeyAndClientUsesX509(ProtocolVersion.TLSv13); + } + + private void TestServerUsesRawKeyAndClientUsesX509(ProtocolVersion tlsVersion) + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient(CertificateType.RawPublicKey, + CertificateType.X509, new short[]{ CertificateType.RawPublicKey }, null, GenerateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer(CertificateType.RawPublicKey, + CertificateType.X509, null, GenerateKeyPair(), tlsVersion); + PumpData(client, server); + } + + [Test] + public void TestServerUsesX509AndClientUsesRawKey() + { + TestServerUsesX509AndClientUsesRawKey(ProtocolVersion.TLSv12); + } + + [Test] + public void TestServerUsesX509AndClientUsesRawKey_13() + { + TestServerUsesX509AndClientUsesRawKey(ProtocolVersion.TLSv13); + } + + private void TestServerUsesX509AndClientUsesRawKey(ProtocolVersion tlsVersion) + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient(CertificateType.X509, CertificateType.RawPublicKey, + null, new short[]{ CertificateType.RawPublicKey }, GenerateKeyPair(), tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer(CertificateType.X509, CertificateType.RawPublicKey, + new short[]{ CertificateType.RawPublicKey }, GenerateKeyPair(), tlsVersion); + PumpData(client, server); + } + + [Test] + public void TestClientSendsClientCertExtensionButServerHasNoCommonTypes() + { + TestClientSendsClientCertExtensionButServerHasNoCommonTypes(ProtocolVersion.TLSv12); + } + + [Test] + public void TestClientSendsClientCertExtensionButServerHasNoCommonTypes_13() + { + TestClientSendsClientCertExtensionButServerHasNoCommonTypes(ProtocolVersion.TLSv13); + } + + private void TestClientSendsClientCertExtensionButServerHasNoCommonTypes(ProtocolVersion tlsVersion) + { + try + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient(CertificateType.X509, + CertificateType.RawPublicKey, null, new short[]{ CertificateType.RawPublicKey }, GenerateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer(CertificateType.X509, CertificateType.X509, + new short[]{ CertificateType.X509 }, GenerateKeyPair(), tlsVersion); + PumpData(client, server); + Assert.Fail("Should have caused unsupported_certificate alert"); + } + catch (TlsFatalAlertReceived alert) + { + Assert.AreEqual(AlertDescription.unsupported_certificate, alert.AlertDescription, + "Should have caused unsupported_certificate alert"); + } + } + + [Test] + public void TestClientSendsServerCertExtensionButServerHasNoCommonTypes() + { + TestClientSendsServerCertExtensionButServerHasNoCommonTypes(ProtocolVersion.TLSv12); + } + + [Test] + public void TestClientSendsServerCertExtensionButServerHasNoCommonTypes_13() + { + TestClientSendsServerCertExtensionButServerHasNoCommonTypes(ProtocolVersion.TLSv13); + } + + private void TestClientSendsServerCertExtensionButServerHasNoCommonTypes(ProtocolVersion tlsVersion) + { + try + { + MockRawKeysTlsClient client = new MockRawKeysTlsClient(CertificateType.RawPublicKey, + CertificateType.RawPublicKey, new short[]{ CertificateType.RawPublicKey }, null, GenerateKeyPair(), + tlsVersion); + MockRawKeysTlsServer server = new MockRawKeysTlsServer(CertificateType.X509, + CertificateType.RawPublicKey, new short[]{ CertificateType.RawPublicKey }, GenerateKeyPair(), + tlsVersion); + PumpData(client, server); + Assert.Fail("Should have caused unsupported_certificate alert"); + } + catch (TlsFatalAlertReceived alert) + { + Assert.AreEqual(AlertDescription.unsupported_certificate, alert.AlertDescription, + "Should have caused unsupported_certificate alert"); + } + } + + private Ed25519PrivateKeyParameters GenerateKeyPair() + { + return new Ed25519PrivateKeyParameters(Random); + } + + private void PumpData(TlsClient client, TlsServer server) + { + PipedStream clientPipe = new PipedStream(); + PipedStream serverPipe = new PipedStream(clientPipe); + + TlsClientProtocol clientProtocol = new TlsClientProtocol(clientPipe); + TlsServerProtocol serverProtocol = new TlsServerProtocol(serverPipe); + + Server serverRun = new Server(serverProtocol, server); + Thread serverThread = new Thread(new ThreadStart(serverRun.Run)); + serverThread.Start(); + + clientProtocol.Connect(client); + + // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity + int length = 1000; + + byte[] data = new byte[length]; + Random.NextBytes(data); + + Stream output = clientProtocol.Stream; + output.Write(data, 0, data.Length); + + byte[] echo = new byte[data.Length]; + int count = Streams.ReadFully(clientProtocol.Stream, echo); + + Assert.AreEqual(count, data.Length); + Assert.IsTrue(Arrays.AreEqual(data, echo)); + + output.Close(); + + serverThread.Join(); + } + + internal class Server + { + private readonly TlsServerProtocol m_serverProtocol; + private readonly TlsServer m_server; + + internal Server(TlsServerProtocol serverProtocol, TlsServer server) + { + m_serverProtocol = serverProtocol; + m_server = server; + } + + public void Run() + { + try + { + m_serverProtocol.Accept(m_server); + Streams.PipeAll(m_serverProtocol.Stream, m_serverProtocol.Stream); + m_serverProtocol.Close(); + } + catch (Exception) + { + } + } + } + } +} diff --git a/crypto/test/src/tls/test/TlsServerRawKeysTest.cs b/crypto/test/src/tls/test/TlsServerRawKeysTest.cs new file mode 100644 index 000000000..22e35505c --- /dev/null +++ b/crypto/test/src/tls/test/TlsServerRawKeysTest.cs @@ -0,0 +1,90 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Threading; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls.Tests +{ + /// <summary>A simple test designed to conduct a TLS handshake with an external TLS client.</summary> + /// <remarks> + /// <code> + /// gnutls-cli --rawpkkeyfile ed25519.priv --rawpkfile ed25519.pub --priority NORMAL:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK --insecure --debug 10 --port 5556 localhost + /// </code> + /// </remarks> + [TestFixture] + public class TlsServerRawKeysTest + { + [Test, Explicit] + public void TestConnection() + { + int port = 5556; + ProtocolVersion[] tlsVersions = ProtocolVersion.TLSv13.DownTo(ProtocolVersion.TLSv12); + + TcpListener ss = new TcpListener(IPAddress.Any, port); + ss.Start(); + Stream stdout = Console.OpenStandardOutput(); + try + { + foreach (var tlsVersion in tlsVersions) + { + TcpClient s = ss.AcceptTcpClient(); + Console.WriteLine("--------------------------------------------------------------------------------"); + Console.WriteLine("Accepted " + s); + Server serverRun = new Server(s, stdout, tlsVersion); + Thread t = new Thread(new ThreadStart(serverRun.Run)); + t.Start(); + } + } + finally + { + ss.Stop(); + } + } + + internal class Server + { + private readonly TcpClient s; + private readonly Stream stdout; + private readonly ProtocolVersion tlsVersion; + + internal Server(TcpClient s, Stream stdout, ProtocolVersion tlsVersion) + { + this.s = s; + this.stdout = stdout; + this.tlsVersion = tlsVersion; + } + + public void Run() + { + try + { + MockRawKeysTlsServer server = new MockRawKeysTlsServer(CertificateType.RawPublicKey, + CertificateType.RawPublicKey, new short[]{ CertificateType.RawPublicKey }, + new Ed25519PrivateKeyParameters(new SecureRandom()), tlsVersion); + TlsServerProtocol serverProtocol = new TlsServerProtocol(s.GetStream()); + serverProtocol.Accept(server); + Stream log = new TeeOutputStream(serverProtocol.Stream, stdout); + Streams.PipeAll(serverProtocol.Stream, log); + serverProtocol.Close(); + } + finally + { + try + { + s.Close(); + } + catch (IOException) + { + } + } + } + } + } +} |