summary refs log tree commit diff
path: root/crypto/src/crypto/tls/SrpTlsClient.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/crypto/tls/SrpTlsClient.cs')
-rw-r--r--crypto/src/crypto/tls/SrpTlsClient.cs188
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);
+		}
+	}
+}