diff options
Diffstat (limited to 'crypto/src/crypto/tls/SrpTlsClient.cs')
-rw-r--r-- | crypto/src/crypto/tls/SrpTlsClient.cs | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/crypto/src/crypto/tls/SrpTlsClient.cs b/crypto/src/crypto/tls/SrpTlsClient.cs new file mode 100644 index 000000000..6c2638bb3 --- /dev/null +++ b/crypto/src/crypto/tls/SrpTlsClient.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class SrpTlsClient + : TlsClient + { + protected TlsCipherFactory cipherFactory; + protected byte[] identity; + protected byte[] password; + + protected TlsClientContext context; + + protected CompressionMethod selectedCompressionMethod; + protected CipherSuite selectedCipherSuite; + + public SrpTlsClient(byte[] identity, byte[] password) + : this(new DefaultTlsCipherFactory(), identity, password) + { + } + + public SrpTlsClient(TlsCipherFactory cipherFactory, byte[] identity, byte[] password) + { + this.cipherFactory = cipherFactory; + this.identity = Arrays.Clone(identity); + this.password = Arrays.Clone(password); + } + + public virtual void Init(TlsClientContext context) + { + this.context = context; + } + + public virtual CipherSuite[] GetCipherSuites() + { + return new CipherSuite[] { + CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, + }; + } + + public virtual IDictionary GetClientExtensions() + { + IDictionary clientExtensions = Platform.CreateHashtable(); + + MemoryStream srpData = new MemoryStream(); + TlsUtilities.WriteOpaque8(this.identity, srpData); + clientExtensions[ExtensionType.srp] = srpData.ToArray(); + + return clientExtensions; + } + + public virtual CompressionMethod[] GetCompressionMethods() + { + return new CompressionMethod[] { CompressionMethod.NULL }; + } + + public virtual void NotifySessionID(byte[] sessionID) + { + // Currently ignored + } + + public virtual void NotifySelectedCipherSuite(CipherSuite selectedCipherSuite) + { + this.selectedCipherSuite = selectedCipherSuite; + } + + public virtual void NotifySelectedCompressionMethod(CompressionMethod selectedCompressionMethod) + { + this.selectedCompressionMethod = selectedCompressionMethod; + } + + public virtual void NotifySecureRenegotiation(bool secureRenegotiation) + { + if (!secureRenegotiation) + { + /* + * RFC 5746 3.4. If the extension is not present, the server does not support + * secure renegotiation; set secure_renegotiation flag to FALSE. In this case, + * some clients may want to terminate the handshake instead of continuing; see + * Section 4.1 for discussion. + */ +// throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + public virtual void ProcessServerExtensions(IDictionary serverExtensions) + { + // There is no server response for the SRP extension + } + + public virtual TlsKeyExchange GetKeyExchange() + { + switch (selectedCipherSuite) + { + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return CreateSrpKeyExchange(KeyExchangeAlgorithm.SRP); + + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + return CreateSrpKeyExchange(KeyExchangeAlgorithm.SRP_RSA); + + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + return CreateSrpKeyExchange(KeyExchangeAlgorithm.SRP_DSS); + + default: + /* + * Note: internal error here; the TlsProtocolHandler verifies that the + * server-selected cipher suite was in the list of client-offered cipher + * suites, so if we now can't produce an implementation, we shouldn't have + * offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public abstract TlsAuthentication GetAuthentication(); + + public virtual TlsCompression GetCompression() + { + switch (selectedCompressionMethod) + { + case CompressionMethod.NULL: + return new TlsNullCompression(); + + default: + /* + * Note: internal error here; the TlsProtocolHandler verifies that the + * server-selected compression method was in the list of client-offered compression + * methods, so if we now can't produce an implementation, we shouldn't have + * offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public virtual TlsCipher GetCipher() + { + switch (selectedCipherSuite) + { + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + return cipherFactory.CreateCipher(context, EncryptionAlgorithm.cls_3DES_EDE_CBC, DigestAlgorithm.SHA); + + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + return cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_128_CBC, DigestAlgorithm.SHA); + + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + return cipherFactory.CreateCipher(context, EncryptionAlgorithm.AES_256_CBC, DigestAlgorithm.SHA); + + default: + /* + * Note: internal error here; the TlsProtocolHandler verifies that the + * server-selected cipher suite was in the list of client-offered cipher + * suites, so if we now can't produce an implementation, we shouldn't have + * offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + protected virtual TlsKeyExchange CreateSrpKeyExchange(KeyExchangeAlgorithm keyExchange) + { + return new TlsSrpKeyExchange(context, keyExchange, identity, password); + } + } +} |