using Org.BouncyCastle.Security; using Org.BouncyCastle.Tls; using Org.BouncyCastle.Tls.Crypto; using Org.BouncyCastle.Tls.Crypto.Impl.BC; using System.Collections; using System.IO; using System.Linq; using System.Net.Sockets; namespace Cryville.Common.Network { public class TlsTcpClient { readonly TcpClient _tcpClient; readonly TlsClientProtocol _protocol; readonly TlsClient _tlsClient; public Stream Stream { get; private set; } public TlsTcpClient(string hostname, int port) { _tcpClient = new TcpClient(hostname, port); _protocol = new TlsClientProtocol(_tcpClient.GetStream()); _tlsClient = new InternalTlsClient(new BcTlsCrypto(new SecureRandom())); } public void Connect() { _protocol.Connect(_tlsClient); Stream = _protocol.Stream; } public void Close() { _protocol.Close(); } private class InternalTlsClient : DefaultTlsClient { public InternalTlsClient(TlsCrypto crypto) : base(crypto) { } protected override ProtocolVersion[] GetSupportedVersions() { return ProtocolVersion.TLSv13.DownTo(ProtocolVersion.TLSv12); } protected override IList GetProtocolNames() { IList list = new ArrayList { ProtocolName.Http_1_1, ProtocolName.Http_2_Tls }; return list; } private static readonly int[] supportedCipherSuites = { CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_AES_256_GCM_SHA384, CipherSuite.TLS_CHACHA20_POLY1305_SHA256, CipherSuite.TLS_AES_128_CCM_SHA256, CipherSuite.TLS_AES_128_CCM_8_SHA256, }; protected override int[] GetSupportedCipherSuites() { return base.GetSupportedCipherSuites().Union(supportedCipherSuites).ToArray(); } protected override IList GetSupportedSignatureAlgorithms() { var result = base.GetSupportedSignatureAlgorithms(); result.Add(SignatureAndHashAlgorithm.ecdsa_brainpoolP256r1tls13_sha256); result.Add(SignatureAndHashAlgorithm.ecdsa_brainpoolP384r1tls13_sha384); result.Add(SignatureAndHashAlgorithm.ecdsa_brainpoolP512r1tls13_sha512); return result; } public override TlsAuthentication GetAuthentication() { return new NullTlsAuthentication(); } public override void NotifyAlertReceived(short alertLevel, short alertDescription) { Logger.Log("main", 0, "Network/TLS", "TLS Alert {0} {1}", alertLevel, alertDescription); } public override void NotifyServerVersion(ProtocolVersion serverVersion) { base.NotifyServerVersion(serverVersion); Logger.Log("main", 0, "Network/TLS", "NotifyServerVersion {0}", serverVersion); } public override void NotifySelectedCipherSuite(int selectedCipherSuite) { base.NotifySelectedCipherSuite(selectedCipherSuite); Logger.Log("main", 0, "Network/TLS", "NotifySelectedCipherSuite {0}", selectedCipherSuite); } } private class NullTlsAuthentication : TlsAuthentication { public TlsCredentials GetClientCredentials(CertificateRequest certificateRequest) { return null; } public void NotifyServerCertificate(TlsServerCertificate serverCertificate) { // Do nothing } } } }