diff --git a/crypto/src/crypto/tls/AbstractTlsKeyExchange.cs b/crypto/src/crypto/tls/AbstractTlsKeyExchange.cs
new file mode 100644
index 000000000..155ac94d8
--- /dev/null
+++ b/crypto/src/crypto/tls/AbstractTlsKeyExchange.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Collections;
+using System.IO;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ public abstract class AbstractTlsKeyExchange
+ : TlsKeyExchange
+ {
+ protected readonly int mKeyExchange;
+ protected IList mSupportedSignatureAlgorithms;
+
+ protected TlsContext context;
+
+ protected AbstractTlsKeyExchange(int keyExchange, IList supportedSignatureAlgorithms)
+ {
+ this.mKeyExchange = keyExchange;
+ this.mSupportedSignatureAlgorithms = supportedSignatureAlgorithms;
+ }
+
+ public virtual void Init(TlsContext context)
+ {
+ this.context = context;
+
+ ProtocolVersion clientVersion = context.ClientVersion;
+
+ if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(clientVersion))
+ {
+ /*
+ * RFC 5264 7.4.1.4.1. If the client does not send the signature_algorithms extension,
+ * the server MUST do the following:
+ *
+ * - If the negotiated key exchange algorithm is one of (RSA, DHE_RSA, DH_RSA, RSA_PSK,
+ * ECDH_RSA, ECDHE_RSA), behave as if client had sent the value {sha1,rsa}.
+ *
+ * - If the negotiated key exchange algorithm is one of (DHE_DSS, DH_DSS), behave as if
+ * the client had sent the value {sha1,dsa}.
+ *
+ * - If the negotiated key exchange algorithm is one of (ECDH_ECDSA, ECDHE_ECDSA),
+ * behave as if the client had sent value {sha1,ecdsa}.
+ */
+ if (this.mSupportedSignatureAlgorithms == null)
+ {
+ switch (mKeyExchange)
+ {
+ case KeyExchangeAlgorithm.DH_DSS:
+ case KeyExchangeAlgorithm.DHE_DSS:
+ case KeyExchangeAlgorithm.SRP_DSS:
+ {
+ this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultDssSignatureAlgorithms();
+ break;
+ }
+
+ case KeyExchangeAlgorithm.ECDH_ECDSA:
+ case KeyExchangeAlgorithm.ECDHE_ECDSA:
+ {
+ this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultECDsaSignatureAlgorithms();
+ break;
+ }
+
+ case KeyExchangeAlgorithm.DH_RSA:
+ case KeyExchangeAlgorithm.DHE_RSA:
+ case KeyExchangeAlgorithm.ECDH_RSA:
+ case KeyExchangeAlgorithm.ECDHE_RSA:
+ case KeyExchangeAlgorithm.RSA:
+ case KeyExchangeAlgorithm.RSA_PSK:
+ case KeyExchangeAlgorithm.SRP_RSA:
+ {
+ this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultRsaSignatureAlgorithms();
+ break;
+ }
+
+ case KeyExchangeAlgorithm.DHE_PSK:
+ case KeyExchangeAlgorithm.ECDHE_PSK:
+ case KeyExchangeAlgorithm.PSK:
+ case KeyExchangeAlgorithm.SRP:
+ break;
+
+ default:
+ throw new InvalidOperationException("unsupported key exchange algorithm");
+ }
+ }
+
+ }
+ else if (this.mSupportedSignatureAlgorithms != null)
+ {
+ throw new InvalidOperationException("supported_signature_algorithms not allowed for " + clientVersion);
+ }
+ }
+
+ public abstract void SkipServerCredentials();
+
+ public virtual void ProcessServerCertificate(Certificate serverCertificate)
+ {
+ if (mSupportedSignatureAlgorithms == null)
+ {
+ /*
+ * TODO RFC 2264 7.4.2. Unless otherwise specified, the signing algorithm for the
+ * certificate must be the same as the algorithm for the certificate key.
+ */
+ }
+ else
+ {
+ /*
+ * TODO RFC 5264 7.4.2. If the client provided a "signature_algorithms" extension, then
+ * all certificates provided by the server MUST be signed by a hash/signature algorithm
+ * pair that appears in that extension.
+ */
+ }
+ }
+
+ public virtual void ProcessServerCredentials(TlsCredentials serverCredentials)
+ {
+ ProcessServerCertificate(serverCredentials.Certificate);
+ }
+
+ public virtual bool RequiresServerKeyExchange
+ {
+ get { return false; }
+ }
+
+ public virtual byte[] GenerateServerKeyExchange()
+ {
+ if (RequiresServerKeyExchange)
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+
+ return null;
+ }
+
+ public virtual void SkipServerKeyExchange()
+ {
+ if (RequiresServerKeyExchange)
+ throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ }
+
+ public virtual void ProcessServerKeyExchange(Stream input)
+ {
+ if (!RequiresServerKeyExchange)
+ {
+ throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ }
+ }
+
+ public abstract void ValidateCertificateRequest(CertificateRequest certificateRequest);
+
+ public virtual void SkipClientCredentials()
+ {
+ }
+
+ public abstract void ProcessClientCredentials(TlsCredentials clientCredentials);
+
+ public virtual void ProcessClientCertificate(Certificate clientCertificate)
+ {
+ }
+
+ public abstract void GenerateClientKeyExchange(Stream output);
+
+ public virtual void ProcessClientKeyExchange(Stream input)
+ {
+ // Key exchange implementation MUST support client key exchange
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
+ public abstract byte[] GeneratePremasterSecret();
+ }
+}
diff --git a/crypto/src/crypto/tls/DefaultTlsClient.cs b/crypto/src/crypto/tls/DefaultTlsClient.cs
index 65106adef..a2a04a33c 100644
--- a/crypto/src/crypto/tls/DefaultTlsClient.cs
+++ b/crypto/src/crypto/tls/DefaultTlsClient.cs
@@ -26,17 +26,14 @@ namespace Org.BouncyCastle.Crypto.Tls
public override int[] GetCipherSuites()
{
- return new int[] {
- CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
+ return new int[]
+ {
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
+ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256,
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_RSA_WITH_RC4_128_SHA,
};
}
@@ -44,62 +41,176 @@ namespace Org.BouncyCastle.Crypto.Tls
{
switch (mSelectedCipherSuite)
{
- case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
- return CreateRsaKeyExchange();
-
case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA:
return CreateDHKeyExchange(KeyExchangeAlgorithm.DH_DSS);
case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA:
return CreateDHKeyExchange(KeyExchangeAlgorithm.DH_RSA);
case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA:
return CreateDheKeyExchange(KeyExchangeAlgorithm.DHE_DSS);
case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
return CreateDheKeyExchange(KeyExchangeAlgorithm.DHE_RSA);
case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA:
case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
return CreateECDHKeyExchange(KeyExchangeAlgorithm.ECDH_ECDSA);
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
- return CreateECDheKeyExchange(KeyExchangeAlgorithm.ECDHE_ECDSA);
-
case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA:
case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA:
return CreateECDHKeyExchange(KeyExchangeAlgorithm.ECDH_RSA);
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1:
+ return CreateECDheKeyExchange(KeyExchangeAlgorithm.ECDHE_ECDSA);
+
case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1:
return CreateECDheKeyExchange(KeyExchangeAlgorithm.ECDHE_RSA);
+ case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_WITH_NULL_MD5:
+ case CipherSuite.TLS_RSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
+ case CipherSuite.TLS_RSA_WITH_RC4_128_MD5:
+ case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA:
+ return CreateRsaKeyExchange();
+
default:
/*
- * Note: internal error here; the TlsProtocol implementation 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!
- */
+ * Note: internal error here; the TlsProtocol implementation 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);
}
}
@@ -108,82 +219,243 @@ namespace Org.BouncyCastle.Crypto.Tls
{
switch (mSelectedCipherSuite)
{
- case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.cls_3DES_EDE_CBC,
- MacAlgorithm.hmac_sha1);
+ case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.cls_3DES_EDE_CBC, MacAlgorithm.hmac_sha1);
- case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA:
- case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128, MacAlgorithm.hmac_sha1);
+ case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AEAD_CHACHA20_POLY1305, MacAlgorithm.cls_null);
- case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC,
- MacAlgorithm.hmac_sha1);
+ case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha256);
+
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM_8, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_GCM, MacAlgorithm.cls_null);
- case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC,
- MacAlgorithm.hmac_sha1);
+ case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha256);
+
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha384);
+
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM_8, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_GCM, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_CBC, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_CBC, MacAlgorithm.hmac_sha256);
+
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_GCM, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha256);
+
+ case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_GCM, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha384);
+
+ case CipherSuite.TLS_DHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_WITH_ESTREAM_SALSA20_SHA1:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.ESTREAM_SALSA20, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_RSA_WITH_NULL_MD5:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_md5);
+
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
+ case CipherSuite.TLS_RSA_WITH_NULL_SHA:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha256);
+
+ case CipherSuite.TLS_RSA_WITH_RC4_128_MD5:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128, MacAlgorithm.hmac_md5);
+
+ case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_RSA_WITH_RC4_128_SHA:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DHE_RSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_ECDSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_RSA_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_WITH_SALSA20_SHA1:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.SALSA20, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA:
+ case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA:
+ case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA:
+ case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
+ case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.SEED_CBC, MacAlgorithm.hmac_sha1);
default:
/*
- * Note: internal error here; the TlsProtocol implementation 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!
- */
+ * Note: internal error here; the TlsProtocol implementation 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 CreateDHKeyExchange(int keyExchange)
{
- return new TlsDHKeyExchange(mContext, keyExchange);
+ return new TlsDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null);
}
protected virtual TlsKeyExchange CreateDheKeyExchange(int keyExchange)
{
- return new TlsDheKeyExchange(mContext, keyExchange);
+ return new TlsDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null);
}
protected virtual TlsKeyExchange CreateECDHKeyExchange(int keyExchange)
{
- return new TlsECDHKeyExchange(mContext, keyExchange);
+ return new TlsECDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mNamedCurves, mClientECPointFormats,
+ mServerECPointFormats);
}
protected virtual TlsKeyExchange CreateECDheKeyExchange(int keyExchange)
{
- return new TlsECDheKeyExchange(mContext, keyExchange);
+ return new TlsECDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mNamedCurves, mClientECPointFormats,
+ mServerECPointFormats);
}
protected virtual TlsKeyExchange CreateRsaKeyExchange()
{
- return new TlsRsaKeyExchange(mContext);
+ return new TlsRsaKeyExchange(mSupportedSignatureAlgorithms);
}
}
}
diff --git a/crypto/src/crypto/tls/PskTlsClient.cs b/crypto/src/crypto/tls/PskTlsClient.cs
index 620a6d8f7..6063572a0 100644
--- a/crypto/src/crypto/tls/PskTlsClient.cs
+++ b/crypto/src/crypto/tls/PskTlsClient.cs
@@ -21,19 +21,12 @@ namespace Org.BouncyCastle.Crypto.Tls
public override int[] GetCipherSuites()
{
- return new int[] {
- CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA,
- CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA,
- CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA,
- CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA,
- CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA,
- CipherSuite.TLS_PSK_WITH_RC4_128_SHA,
+ return new int[]
+ {
+ CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
+ CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
+ CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
+ CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA
};
}
@@ -41,30 +34,92 @@ namespace Org.BouncyCastle.Crypto.Tls
{
switch (mSelectedCipherSuite)
{
+ case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
+ return CreatePskKeyExchange(KeyExchangeAlgorithm.DHE_PSK);
+
+ case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1:
+ return CreatePskKeyExchange(KeyExchangeAlgorithm.ECDHE_PSK);
+
case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA384:
case CipherSuite.TLS_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1:
return CreatePskKeyExchange(KeyExchangeAlgorithm.PSK);
case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384:
case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1:
return CreatePskKeyExchange(KeyExchangeAlgorithm.RSA_PSK);
- case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
- return CreatePskKeyExchange(KeyExchangeAlgorithm.DHE_PSK);
-
default:
/*
- * Note: internal error here; the TlsProtocol implementation 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!
- */
+ * Note: internal error here; the TlsProtocol implementation 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);
}
}
@@ -73,43 +128,134 @@ namespace Org.BouncyCastle.Crypto.Tls
{
switch (mSelectedCipherSuite)
{
+ case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA:
case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.cls_3DES_EDE_CBC,
- MacAlgorithm.hmac_sha1);
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.cls_3DES_EDE_CBC, MacAlgorithm.hmac_sha1);
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC,
- MacAlgorithm.hmac_sha1);
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CBC, MacAlgorithm.hmac_sha256);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM, MacAlgorithm.cls_null);
+ case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
+ case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_CCM_8, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_128_GCM, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC,
- MacAlgorithm.hmac_sha1);
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CBC, MacAlgorithm.hmac_sha384);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
+ case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_CCM_8, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.AES_256_GCM, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_CBC, MacAlgorithm.hmac_sha256);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_128_GCM, MacAlgorithm.cls_null);
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_CBC, MacAlgorithm.hmac_sha384);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.CAMELLIA_256_GCM, MacAlgorithm.cls_null);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_PSK_WITH_ESTREAM_SALSA20_SHA1:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.ESTREAM_SALSA20, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA256:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha256);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_PSK_WITH_NULL_SHA384:
+ case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.NULL, MacAlgorithm.hmac_sha384);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA:
case CipherSuite.TLS_PSK_WITH_RC4_128_SHA:
case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA:
- case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA:
- return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128,
- MacAlgorithm.hmac_sha1);
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.RC4_128, MacAlgorithm.hmac_sha1);
+
+ case CipherSuite.TLS_DHE_PSK_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_ECDHE_PSK_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_PSK_WITH_SALSA20_SHA1:
+ case CipherSuite.TLS_RSA_PSK_WITH_SALSA20_SHA1:
+ return mCipherFactory.CreateCipher(mContext, EncryptionAlgorithm.SALSA20, MacAlgorithm.hmac_sha1);
default:
/*
- * Note: internal error here; the TlsProtocol implementation 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!
- */
+ * Note: internal error here; the TlsProtocol implementation 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 CreatePskKeyExchange(int keyExchange)
{
- return new TlsPskKeyExchange(mContext, keyExchange, mPskIdentity);
+ return new TlsPskKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mPskIdentity, null, mNamedCurves,
+ mClientECPointFormats, mServerECPointFormats);
}
}
}
diff --git a/crypto/src/crypto/tls/SrpTlsClient.cs b/crypto/src/crypto/tls/SrpTlsClient.cs
index a7c72b862..5d82ed470 100644
--- a/crypto/src/crypto/tls/SrpTlsClient.cs
+++ b/crypto/src/crypto/tls/SrpTlsClient.cs
@@ -24,9 +24,18 @@ namespace Org.BouncyCastle.Crypto.Tls
this.mPassword = Arrays.Clone(password);
}
+ protected virtual bool RequireSrpServerExtension
+ {
+ // No explicit guidance in RFC 5054; by default an (empty) extension from server is optional
+ get { return false; }
+ }
+
public override int[] GetCipherSuites()
{
- return new int[] { CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA };
+ return new int[]
+ {
+ CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA
+ };
}
public override IDictionary GetClientExtensions()
@@ -41,7 +50,8 @@ namespace Org.BouncyCastle.Crypto.Tls
if (!TlsUtilities.HasExpectedEmptyExtensionData(serverExtensions, ExtensionType.srp,
AlertDescription.illegal_parameter))
{
- // No explicit guidance in RFC 5054 here; we allow an optional empty extension from server
+ if (RequireSrpServerExtension)
+ throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
base.ProcessServerExtensions(serverExtensions);
@@ -107,7 +117,7 @@ namespace Org.BouncyCastle.Crypto.Tls
protected virtual TlsKeyExchange CreateSrpKeyExchange(int keyExchange)
{
- return new TlsSrpKeyExchange(mContext, keyExchange, mIdentity, mPassword);
+ return new TlsSrpKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mIdentity, mPassword);
}
}
}
diff --git a/crypto/src/crypto/tls/TlsDHKeyExchange.cs b/crypto/src/crypto/tls/TlsDHKeyExchange.cs
index ddc6a4527..b831249a6 100644
--- a/crypto/src/crypto/tls/TlsDHKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsDHKeyExchange.cs
@@ -1,75 +1,87 @@
using System;
+using System.Collections;
using System.IO;
-using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// TLS 1.0 DH key exchange.
- /// </summary>
- internal class TlsDHKeyExchange
- : TlsKeyExchange
+ /// <summary>(D)TLS DH key exchange.</summary>
+ public class TlsDHKeyExchange
+ : AbstractTlsKeyExchange
{
- protected TlsContext context;
- protected int keyExchange;
- protected TlsSigner tlsSigner;
+ protected TlsSigner mTlsSigner;
+ protected DHParameters mDHParameters;
- protected AsymmetricKeyParameter serverPublicKey = null;
- protected DHPublicKeyParameters dhAgreeServerPublicKey = null;
- protected TlsAgreementCredentials agreementCredentials;
- protected DHPrivateKeyParameters dhAgreeClientPrivateKey = null;
+ protected AsymmetricKeyParameter mServerPublicKey;
+ protected DHPublicKeyParameters mDHAgreeServerPublicKey;
+ protected TlsAgreementCredentials mAgreementCredentials;
+ protected DHPrivateKeyParameters mDHAgreeClientPrivateKey;
- internal TlsDHKeyExchange(TlsContext context, int keyExchange)
+ protected DHPrivateKeyParameters mDHAgreeServerPrivateKey;
+ protected DHPublicKeyParameters mDHAgreeClientPublicKey;
+
+ public TlsDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters)
+ : base(keyExchange, supportedSignatureAlgorithms)
{
switch (keyExchange)
{
- case KeyExchangeAlgorithm.DH_RSA:
- case KeyExchangeAlgorithm.DH_DSS:
- this.tlsSigner = null;
- break;
- case KeyExchangeAlgorithm.DHE_RSA:
- this.tlsSigner = new TlsRsaSigner();
- break;
- case KeyExchangeAlgorithm.DHE_DSS:
- this.tlsSigner = new TlsDssSigner();
- break;
- default:
- throw new ArgumentException("unsupported key exchange algorithm", "keyExchange");
+ case KeyExchangeAlgorithm.DH_RSA:
+ case KeyExchangeAlgorithm.DH_DSS:
+ this.mTlsSigner = null;
+ break;
+ case KeyExchangeAlgorithm.DHE_RSA:
+ this.mTlsSigner = new TlsRsaSigner();
+ break;
+ case KeyExchangeAlgorithm.DHE_DSS:
+ this.mTlsSigner = new TlsDssSigner();
+ break;
+ default:
+ throw new InvalidOperationException("unsupported key exchange algorithm");
}
- this.context = context;
- this.keyExchange = keyExchange;
+ this.mDHParameters = dhParameters;
+ }
+
+ public override void Init(TlsContext context)
+ {
+ base.Init(context);
+
+ if (this.mTlsSigner != null)
+ {
+ this.mTlsSigner.Init(context);
+ }
}
- public virtual void SkipServerCertificate()
+ public override void SkipServerCredentials()
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
- public virtual void ProcessServerCertificate(Certificate serverCertificate)
+ public override void ProcessServerCertificate(Certificate serverCertificate)
{
+ if (serverCertificate.IsEmpty)
+ throw new TlsFatalAlert(AlertDescription.bad_certificate);
+
X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
- SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
+ SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
try
{
- this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
+ this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo);
}
catch (Exception e)
{
throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e);
}
- if (tlsSigner == null)
+ if (mTlsSigner == null)
{
try
{
- this.dhAgreeServerPublicKey = ValidateDHPublicKey((DHPublicKeyParameters)this.serverPublicKey);
+ this.mDHAgreeServerPublicKey = TlsDHUtilities.ValidateDHPublicKey((DHPublicKeyParameters)this.mServerPublicKey);
}
catch (InvalidCastException e)
{
@@ -80,7 +92,7 @@ namespace Org.BouncyCastle.Crypto.Tls
}
else
{
- if (!tlsSigner.IsValidPublicKey(this.serverPublicKey))
+ if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey))
{
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
@@ -88,55 +100,51 @@ namespace Org.BouncyCastle.Crypto.Tls
TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature);
}
- // TODO
- /*
- * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
- * signing algorithm for the certificate must be the same as the algorithm for the
- * certificate key."
- */
- }
-
- public virtual void SkipServerKeyExchange()
- {
- // OK
+ base.ProcessServerCertificate(serverCertificate);
}
- public virtual void ProcessServerKeyExchange(Stream input)
+ public override bool RequiresServerKeyExchange
{
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ get
+ {
+ switch (mKeyExchange)
+ {
+ case KeyExchangeAlgorithm.DHE_DSS:
+ case KeyExchangeAlgorithm.DHE_RSA:
+ case KeyExchangeAlgorithm.DH_anon:
+ return true;
+ default:
+ return false;
+ }
+ }
}
- public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
+ public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
{
byte[] types = certificateRequest.CertificateTypes;
- foreach (byte type in types)
+ for (int i = 0; i < types.Length; ++i)
{
- switch (type)
+ switch (types[i])
{
- case ClientCertificateType.rsa_sign:
- case ClientCertificateType.dss_sign:
- case ClientCertificateType.rsa_fixed_dh:
- case ClientCertificateType.dss_fixed_dh:
- case ClientCertificateType.ecdsa_sign:
- break;
- default:
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+ case ClientCertificateType.rsa_sign:
+ case ClientCertificateType.dss_sign:
+ case ClientCertificateType.rsa_fixed_dh:
+ case ClientCertificateType.dss_fixed_dh:
+ case ClientCertificateType.ecdsa_sign:
+ break;
+ default:
+ throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
}
}
- public virtual void SkipClientCredentials()
- {
- this.agreementCredentials = null;
- }
-
- public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
+ public override void ProcessClientCredentials(TlsCredentials clientCredentials)
{
if (clientCredentials is TlsAgreementCredentials)
{
// TODO Validate client cert has matching parameters (see 'areCompatibleParameters')?
- this.agreementCredentials = (TlsAgreementCredentials)clientCredentials;
+ this.mAgreementCredentials = (TlsAgreementCredentials)clientCredentials;
}
else if (clientCredentials is TlsSignerCredentials)
{
@@ -148,54 +156,38 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
- public virtual void GenerateClientKeyExchange(Stream output)
+ public override void GenerateClientKeyExchange(Stream output)
{
/*
- * RFC 2246 7.4.7.2 If the client certificate already contains a suitable
- * Diffie-Hellman key, then Yc is implicit and does not need to be sent again. In
- * this case, the Client Key Exchange message will be sent, but will be empty.
+ * RFC 2246 7.4.7.2 If the client certificate already contains a suitable Diffie-Hellman
+ * key, then Yc is implicit and does not need to be sent again. In this case, the Client Key
+ * Exchange message will be sent, but will be empty.
*/
- if (agreementCredentials == null)
+ if (mAgreementCredentials == null)
{
- GenerateEphemeralClientKeyExchange(dhAgreeServerPublicKey.Parameters, output);
+ this.mDHAgreeClientPrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(context.SecureRandom,
+ mDHAgreeServerPublicKey.Parameters, output);
}
}
- public virtual byte[] GeneratePremasterSecret()
+ public override byte[] GeneratePremasterSecret()
{
- if (agreementCredentials != null)
+ if (mAgreementCredentials != null)
{
- return agreementCredentials.GenerateAgreement(dhAgreeServerPublicKey);
+ return mAgreementCredentials.GenerateAgreement(mDHAgreeServerPublicKey);
}
- return CalculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey);
- }
-
- protected virtual bool AreCompatibleParameters(DHParameters a, DHParameters b)
- {
- return a.P.Equals(b.P) && a.G.Equals(b.G);
- }
-
- protected virtual byte[] CalculateDHBasicAgreement(DHPublicKeyParameters publicKey,
- DHPrivateKeyParameters privateKey)
- {
- return TlsDHUtilities.CalculateDHBasicAgreement(publicKey, privateKey);
- }
-
- protected virtual AsymmetricCipherKeyPair GenerateDHKeyPair(DHParameters dhParams)
- {
- return TlsDHUtilities.GenerateDHKeyPair(context.SecureRandom, dhParams);
- }
+ if (mDHAgreeServerPrivateKey != null)
+ {
+ return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreeClientPublicKey, mDHAgreeServerPrivateKey);
+ }
- protected virtual void GenerateEphemeralClientKeyExchange(DHParameters dhParams, Stream output)
- {
- this.dhAgreeClientPrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(
- context.SecureRandom, dhParams, output);
- }
+ if (mDHAgreeClientPrivateKey != null)
+ {
+ return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreeServerPublicKey, mDHAgreeClientPrivateKey);
+ }
- protected virtual DHPublicKeyParameters ValidateDHPublicKey(DHPublicKeyParameters key)
- {
- return TlsDHUtilities.ValidateDHPublicKey(key);
+ throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
}
diff --git a/crypto/src/crypto/tls/TlsDheKeyExchange.cs b/crypto/src/crypto/tls/TlsDheKeyExchange.cs
index a9e9a394c..3c05bb6f0 100644
--- a/crypto/src/crypto/tls/TlsDheKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsDheKeyExchange.cs
@@ -1,53 +1,102 @@
using System;
+using System.Collections;
using System.IO;
-using Org.BouncyCastle.Crypto.IO;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Crypto.Tls
{
- internal class TlsDheKeyExchange
- : TlsDHKeyExchange
+ public class TlsDheKeyExchange
+ : TlsDHKeyExchange
{
- internal TlsDheKeyExchange(TlsContext context, int keyExchange)
- : base(context, keyExchange)
+ protected TlsSignerCredentials mServerCredentials = null;
+
+ public TlsDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters)
+ : base(keyExchange, supportedSignatureAlgorithms, dhParameters)
{
}
- public override void SkipServerKeyExchange()
+ public override void ProcessServerCredentials(TlsCredentials serverCredentials)
{
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ if (!(serverCredentials is TlsSignerCredentials))
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+
+ ProcessServerCertificate(serverCredentials.Certificate);
+
+ this.mServerCredentials = (TlsSignerCredentials)serverCredentials;
}
- public override void ProcessServerKeyExchange(Stream input)
+ public override byte[] GenerateServerKeyExchange()
{
- SecurityParameters securityParameters = context.SecurityParameters;
+ if (this.mDHParameters == null)
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+
+ DigestInputBuffer buf = new DigestInputBuffer();
- ISigner signer = InitSigner(tlsSigner, securityParameters);
- Stream sigIn = new SignerStream(input, signer, null);
+ this.mDHAgreeServerPrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(context.SecureRandom,
+ this.mDHParameters, buf);
- byte[] pBytes = TlsUtilities.ReadOpaque16(sigIn);
- byte[] gBytes = TlsUtilities.ReadOpaque16(sigIn);
- byte[] YsBytes = TlsUtilities.ReadOpaque16(sigIn);
+ /*
+ * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
+ */
+ SignatureAndHashAlgorithm signatureAndHashAlgorithm;
+ IDigest d;
- byte[] sigByte = TlsUtilities.ReadOpaque16(input);
- if (!signer.VerifySignature(sigByte))
+ if (TlsUtilities.IsTlsV12(context))
{
- throw new TlsFatalAlert(AlertDescription.decrypt_error);
+ signatureAndHashAlgorithm = mServerCredentials.SignatureAndHashAlgorithm;
+ if (signatureAndHashAlgorithm == null)
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+
+ d = TlsUtilities.CreateHash(signatureAndHashAlgorithm.Hash);
+ }
+ else
+ {
+ signatureAndHashAlgorithm = null;
+ d = new CombinedHash();
}
- BigInteger p = new BigInteger(1, pBytes);
- BigInteger g = new BigInteger(1, gBytes);
- BigInteger Ys = new BigInteger(1, YsBytes);
+ SecurityParameters securityParameters = context.SecurityParameters;
+ d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
+ d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
+ buf.UpdateDigest(d);
+
+ byte[] hash = DigestUtilities.DoFinal(d);
+
+ byte[] signature = mServerCredentials.GenerateCertificateSignature(hash);
+
+ DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature);
+ signed_params.Encode(buf);
+
+ return buf.ToArray();
+ }
+
+ public override void ProcessServerKeyExchange(Stream input)
+ {
+ SecurityParameters securityParameters = context.SecurityParameters;
+
+ SignerInputBuffer buf = new SignerInputBuffer();
+ Stream teeIn = new TeeInputStream(input, buf);
+
+ ServerDHParams dhParams = ServerDHParams.Parse(teeIn);
+
+ DigitallySigned signed_params = DigitallySigned.Parse(context, input);
+
+ ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters);
+ buf.UpdateSigner(signer);
+ if (!signer.VerifySignature(signed_params.Signature))
+ throw new TlsFatalAlert(AlertDescription.decrypt_error);
- this.dhAgreeServerPublicKey = ValidateDHPublicKey(
- new DHPublicKeyParameters(Ys, new DHParameters(p, g)));
+ this.mDHAgreeServerPublicKey = TlsDHUtilities.ValidateDHPublicKey(dhParams.PublicKey);
}
- protected virtual ISigner InitSigner(TlsSigner tlsSigner, SecurityParameters securityParameters)
+ protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm,
+ SecurityParameters securityParameters)
{
- ISigner signer = tlsSigner.CreateVerifyer(this.serverPublicKey);
+ ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey);
signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
return signer;
diff --git a/crypto/src/crypto/tls/TlsECDHKeyExchange.cs b/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
index c4780eaaa..42dc2f2ef 100644
--- a/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
@@ -3,76 +3,87 @@ using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Crypto.Agreement;
-using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Tls
{
- /**
- * ECDH key exchange (see RFC 4492)
- */
- internal class TlsECDHKeyExchange
- : TlsKeyExchange
+ /// <summary>(D)TLS ECDH key exchange (see RFC 4492).</summary>
+ public class TlsECDHKeyExchange
+ : AbstractTlsKeyExchange
{
- protected TlsContext context;
- protected int keyExchange;
- protected TlsSigner tlsSigner;
+ protected TlsSigner mTlsSigner;
+ protected int[] mNamedCurves;
+ protected byte[] mClientECPointFormats, mServerECPointFormats;
- protected AsymmetricKeyParameter serverPublicKey;
- protected ECPublicKeyParameters ecAgreeServerPublicKey;
- protected TlsAgreementCredentials agreementCredentials;
- protected ECPrivateKeyParameters ecAgreeClientPrivateKey = null;
+ protected AsymmetricKeyParameter mServerPublicKey;
+ protected TlsAgreementCredentials mAgreementCredentials;
- internal TlsECDHKeyExchange(TlsContext context, int keyExchange)
+ protected ECPrivateKeyParameters mECAgreePrivateKey;
+ protected ECPublicKeyParameters mECAgreePublicKey;
+
+ public TlsECDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, int[] namedCurves,
+ byte[] clientECPointFormats, byte[] serverECPointFormats)
+ : base(keyExchange, supportedSignatureAlgorithms)
{
switch (keyExchange)
{
- case KeyExchangeAlgorithm.ECDHE_RSA:
- this.tlsSigner = new TlsRsaSigner();
- break;
- case KeyExchangeAlgorithm.ECDHE_ECDSA:
- this.tlsSigner = new TlsECDsaSigner();
- break;
- case KeyExchangeAlgorithm.ECDH_RSA:
- case KeyExchangeAlgorithm.ECDH_ECDSA:
- this.tlsSigner = null;
- break;
- default:
- throw new ArgumentException("unsupported key exchange algorithm", "keyExchange");
+ case KeyExchangeAlgorithm.ECDHE_RSA:
+ this.mTlsSigner = new TlsRsaSigner();
+ break;
+ case KeyExchangeAlgorithm.ECDHE_ECDSA:
+ this.mTlsSigner = new TlsECDsaSigner();
+ break;
+ case KeyExchangeAlgorithm.ECDH_RSA:
+ case KeyExchangeAlgorithm.ECDH_ECDSA:
+ this.mTlsSigner = null;
+ break;
+ default:
+ throw new InvalidOperationException("unsupported key exchange algorithm");
}
- this.context = context;
- this.keyExchange = keyExchange;
+ this.mNamedCurves = namedCurves;
+ this.mClientECPointFormats = clientECPointFormats;
+ this.mServerECPointFormats = serverECPointFormats;
}
- public virtual void SkipServerCertificate()
+ public override void Init(TlsContext context)
+ {
+ base.Init(context);
+
+ if (this.mTlsSigner != null)
+ {
+ this.mTlsSigner.Init(context);
+ }
+ }
+
+ public override void SkipServerCredentials()
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
- public virtual void ProcessServerCertificate(Certificate serverCertificate)
+ public override void ProcessServerCertificate(Certificate serverCertificate)
{
+ if (serverCertificate.IsEmpty)
+ throw new TlsFatalAlert(AlertDescription.bad_certificate);
+
X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
- SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
+ SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
try
{
- this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
+ this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo);
}
catch (Exception e)
{
throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e);
}
- if (tlsSigner == null)
+ if (mTlsSigner == null)
{
try
{
- this.ecAgreeServerPublicKey = ValidateECPublicKey((ECPublicKeyParameters)this.serverPublicKey);
+ this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey((ECPublicKeyParameters) this.mServerPublicKey);
}
catch (InvalidCastException e)
{
@@ -83,69 +94,63 @@ namespace Org.BouncyCastle.Crypto.Tls
}
else
{
- if (!tlsSigner.IsValidPublicKey(this.serverPublicKey))
- {
+ if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey))
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
- }
TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature);
}
-
- // TODO
- /*
- * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
- * signing algorithm for the certificate must be the same as the algorithm for the
- * certificate key."
- */
- }
-
- public virtual void SkipServerKeyExchange()
- {
- // do nothing
+
+ base.ProcessServerCertificate(serverCertificate);
}
- public virtual void ProcessServerKeyExchange(Stream input)
+ public override bool RequiresServerKeyExchange
{
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ get
+ {
+ switch (mKeyExchange)
+ {
+ case KeyExchangeAlgorithm.ECDHE_ECDSA:
+ case KeyExchangeAlgorithm.ECDHE_RSA:
+ case KeyExchangeAlgorithm.ECDH_anon:
+ return true;
+ default:
+ return false;
+ }
+ }
}
- public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
+ public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
{
/*
- * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable
- * with ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is
- * prohibited because the use of a long-term ECDH client key would jeopardize the
- * forward secrecy property of these algorithms.
+ * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with
+ * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because
+ * the use of a long-term ECDH client key would jeopardize the forward secrecy property of
+ * these algorithms.
*/
byte[] types = certificateRequest.CertificateTypes;
- foreach (byte type in types)
+ for (int i = 0; i < types.Length; ++i)
{
- switch (type)
+ switch (types[i])
{
- case ClientCertificateType.rsa_sign:
- case ClientCertificateType.dss_sign:
- case ClientCertificateType.ecdsa_sign:
- case ClientCertificateType.rsa_fixed_ecdh:
- case ClientCertificateType.ecdsa_fixed_ecdh:
- break;
- default:
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+ case ClientCertificateType.rsa_sign:
+ case ClientCertificateType.dss_sign:
+ case ClientCertificateType.ecdsa_sign:
+ case ClientCertificateType.rsa_fixed_ecdh:
+ case ClientCertificateType.ecdsa_fixed_ecdh:
+ break;
+ default:
+ throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
}
}
- public virtual void SkipClientCredentials()
- {
- this.agreementCredentials = null;
- }
-
- public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
+ public override void ProcessClientCredentials(TlsCredentials clientCredentials)
{
if (clientCredentials is TlsAgreementCredentials)
{
- // TODO Validate client cert has matching parameters (see 'AreOnSameCurve')?
+ // TODO Validate client cert has matching parameters (see 'TlsEccUtilities.AreOnSameCurve')?
- this.agreementCredentials = (TlsAgreementCredentials)clientCredentials;
+ this.mAgreementCredentials = (TlsAgreementCredentials)clientCredentials;
}
else if (clientCredentials is TlsSignerCredentials)
{
@@ -157,80 +162,50 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
- public virtual void GenerateClientKeyExchange(Stream output)
+ public override void GenerateClientKeyExchange(Stream output)
{
- if (agreementCredentials == null)
+ if (mAgreementCredentials == null)
{
- GenerateEphemeralClientKeyExchange(ecAgreeServerPublicKey.Parameters, output);
+ this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(context.SecureRandom,
+ mServerECPointFormats, mECAgreePublicKey.Parameters, output);
}
}
- public virtual byte[] GeneratePremasterSecret()
+ public override void ProcessClientCertificate(Certificate clientCertificate)
{
- if (agreementCredentials != null)
- {
- return agreementCredentials.GenerateAgreement(ecAgreeServerPublicKey);
- }
-
- return CalculateECDHBasicAgreement(ecAgreeServerPublicKey, ecAgreeClientPrivateKey);
- }
-
- protected virtual bool AreOnSameCurve(ECDomainParameters a, ECDomainParameters b)
- {
- // TODO Move to ECDomainParameters.Equals() or other utility method?
- return a.Curve.Equals(b.Curve) && a.G.Equals(b.G) && a.N.Equals(b.N) && a.H.Equals(b.H);
+ // TODO Extract the public key
+ // TODO If the certificate is 'fixed', take the public key as mECAgreeClientPublicKey
}
- protected virtual byte[] ExternalizeKey(ECPublicKeyParameters keyParameters)
+ public override void ProcessClientKeyExchange(Stream input)
{
- // TODO Add support for compressed encoding and SPF extension
-
- /*
- * RFC 4492 5.7. ...an elliptic curve point in uncompressed or compressed format.
- * Here, the format MUST conform to what the server has requested through a
- * Supported Point Formats Extension if this extension was used, and MUST be
- * uncompressed if this extension was not used.
- */
- return keyParameters.Q.GetEncoded();
- }
+ if (mECAgreePublicKey != null)
+ {
+ // For ecdsa_fixed_ecdh and rsa_fixed_ecdh, the key arrived in the client certificate
+ return;
+ }
- protected virtual AsymmetricCipherKeyPair GenerateECKeyPair(ECDomainParameters ecParams)
- {
- ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
- ECKeyGenerationParameters keyGenerationParameters = new ECKeyGenerationParameters(ecParams,
- context.SecureRandom);
- keyPairGenerator.Init(keyGenerationParameters);
- return keyPairGenerator.GenerateKeyPair();
- }
+ byte[] point = TlsUtilities.ReadOpaque8(input);
- protected virtual void GenerateEphemeralClientKeyExchange(ECDomainParameters ecParams, Stream output)
- {
- AsymmetricCipherKeyPair ecAgreeClientKeyPair = GenerateECKeyPair(ecParams);
- this.ecAgreeClientPrivateKey = (ECPrivateKeyParameters)ecAgreeClientKeyPair.Private;
+ ECDomainParameters curve_params = this.mECAgreePrivateKey.Parameters;
- byte[] keData = ExternalizeKey((ECPublicKeyParameters)ecAgreeClientKeyPair.Public);
- TlsUtilities.WriteOpaque8(keData, output);
+ this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(
+ mServerECPointFormats, curve_params, point));
}
- protected virtual byte[] CalculateECDHBasicAgreement(ECPublicKeyParameters publicKey,
- ECPrivateKeyParameters privateKey)
+ public override byte[] GeneratePremasterSecret()
{
- ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement();
- basicAgreement.Init(privateKey);
- BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey);
+ if (mAgreementCredentials != null)
+ {
+ return mAgreementCredentials.GenerateAgreement(mECAgreePublicKey);
+ }
- /*
- * RFC 4492 5.10. Note that this octet string (Z in IEEE 1363 terminology) as output by
- * FE2OSP, the Field Element to Octet String Conversion Primitive, has constant length for
- * any given field; leading zeros found in this octet string MUST NOT be truncated.
- */
- return BigIntegers.AsUnsignedByteArray(basicAgreement.GetFieldSize(), agreementValue);
- }
+ if (mECAgreePrivateKey != null)
+ {
+ return TlsEccUtilities.CalculateECDHBasicAgreement(mECAgreePublicKey, mECAgreePrivateKey);
+ }
- protected virtual ECPublicKeyParameters ValidateECPublicKey(ECPublicKeyParameters key)
- {
- // TODO Check RFC 4492 for validation
- return key;
+ throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
}
diff --git a/crypto/src/crypto/tls/TlsECDheKeyExchange.cs b/crypto/src/crypto/tls/TlsECDheKeyExchange.cs
index 5f66dbf59..0644bd44d 100644
--- a/crypto/src/crypto/tls/TlsECDheKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsECDheKeyExchange.cs
@@ -2,91 +2,186 @@ using System;
using System.Collections;
using System.IO;
-using Org.BouncyCastle.Crypto.IO;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Crypto.Tls
{
- /**
- * ECDHE key exchange (see RFC 4492)
- */
- internal class TlsECDheKeyExchange : TlsECDHKeyExchange
+ /// <summary>(D)TLS ECDHE key exchange (see RFC 4492).</summary>
+ public class TlsECDheKeyExchange
+ : TlsECDHKeyExchange
{
- internal TlsECDheKeyExchange(TlsContext context, int keyExchange)
- : base(context, keyExchange)
- {
- }
+ protected TlsSignerCredentials mServerCredentials = null;
- public override void SkipServerKeyExchange()
+ public TlsECDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, int[] namedCurves,
+ byte[] clientECPointFormats, byte[] serverECPointFormats)
+ : base(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats)
{
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
- public override void ProcessServerKeyExchange(Stream input)
+ public override void ProcessServerCredentials(TlsCredentials serverCredentials)
{
- SecurityParameters securityParameters = context.SecurityParameters;
+ if (!(serverCredentials is TlsSignerCredentials))
+ throw new TlsFatalAlert(AlertDescription.internal_error);
- ISigner signer = InitSigner(tlsSigner, securityParameters);
- Stream sigIn = new SignerStream(input, signer, null);
+ ProcessServerCertificate(serverCredentials.Certificate);
- byte curveType = TlsUtilities.ReadUint8(sigIn);
- ECDomainParameters curve_params;
+ this.mServerCredentials = (TlsSignerCredentials)serverCredentials;
+ }
- // Currently, we only support named curves
- if (curveType == ECCurveType.named_curve)
+ public override byte[] GenerateServerKeyExchange()
+ {
+ /*
+ * First we try to find a supported named curve from the client's list.
+ */
+ int namedCurve = -1;
+ if (mNamedCurves == null)
{
- int namedCurve = TlsUtilities.ReadUint16(sigIn);
-
- // TODO Check namedCurve is one we offered?
+ // TODO Let the peer choose the default named curve
+ namedCurve = NamedCurve.secp256r1;
+ }
+ else
+ {
+ for (int i = 0; i < mNamedCurves.Length; ++i)
+ {
+ int entry = mNamedCurves[i];
+ if (NamedCurve.IsValid(entry) && TlsEccUtilities.IsSupportedNamedCurve(entry))
+ {
+ namedCurve = entry;
+ break;
+ }
+ }
+ }
+ ECDomainParameters curve_params = null;
+ if (namedCurve >= 0)
+ {
curve_params = TlsEccUtilities.GetParametersForNamedCurve(namedCurve);
}
else
{
- // TODO Add support for explicit curve parameters (read from sigIn)
+ /*
+ * If no named curves are suitable, check if the client supports explicit curves.
+ */
+ if (Arrays.Contains(mNamedCurves, NamedCurve.arbitrary_explicit_prime_curves))
+ {
+ curve_params = TlsEccUtilities.GetParametersForNamedCurve(NamedCurve.secp256r1);
+ }
+ else if (Arrays.Contains(mNamedCurves, NamedCurve.arbitrary_explicit_char2_curves))
+ {
+ curve_params = TlsEccUtilities.GetParametersForNamedCurve(NamedCurve.sect283r1);
+ }
+ }
- throw new TlsFatalAlert(AlertDescription.handshake_failure);
+ if (curve_params == null)
+ {
+ /*
+ * NOTE: We shouldn't have negotiated ECDHE key exchange since we apparently can't find
+ * a suitable curve.
+ */
+ throw new TlsFatalAlert(AlertDescription.internal_error);
}
- byte[] publicBytes = TlsUtilities.ReadOpaque8(sigIn);
+ AsymmetricCipherKeyPair kp = TlsEccUtilities.GenerateECKeyPair(context.SecureRandom, curve_params);
+ this.mECAgreePrivateKey = (ECPrivateKeyParameters)kp.Private;
- byte[] sigByte = TlsUtilities.ReadOpaque16(input);
- if (!signer.VerifySignature(sigByte))
+ DigestInputBuffer buf = new DigestInputBuffer();
+
+ if (namedCurve < 0)
{
- throw new TlsFatalAlert(AlertDescription.decrypt_error);
+ TlsEccUtilities.WriteExplicitECParameters(mClientECPointFormats, curve_params, buf);
+ }
+ else
+ {
+ TlsEccUtilities.WriteNamedECParameters(namedCurve, buf);
}
- // TODO Check curve_params not null
+ ECPublicKeyParameters ecPublicKey = (ECPublicKeyParameters)kp.Public;
+ TlsEccUtilities.WriteECPoint(mClientECPointFormats, ecPublicKey.Q, buf);
- ECPoint Q = curve_params.Curve.DecodePoint(publicBytes);
+ /*
+ * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
+ */
+ SignatureAndHashAlgorithm signatureAndHashAlgorithm;
+ IDigest d;
+
+ if (TlsUtilities.IsTlsV12(context))
+ {
+ signatureAndHashAlgorithm = mServerCredentials.SignatureAndHashAlgorithm;
+ if (signatureAndHashAlgorithm == null)
+ throw new TlsFatalAlert(AlertDescription.internal_error);
- this.ecAgreeServerPublicKey = ValidateECPublicKey(new ECPublicKeyParameters(Q, curve_params));
+ d = TlsUtilities.CreateHash(signatureAndHashAlgorithm.Hash);
+ }
+ else
+ {
+ signatureAndHashAlgorithm = null;
+ d = new CombinedHash();
+ }
+
+ SecurityParameters securityParameters = context.SecurityParameters;
+ d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
+ d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
+ buf.UpdateDigest(d);
+
+ byte[] hash = DigestUtilities.DoFinal(d);
+
+ byte[] signature = mServerCredentials.GenerateCertificateSignature(hash);
+
+ DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature);
+ signed_params.Encode(buf);
+
+ return buf.ToArray();
}
-
+
+ public override void ProcessServerKeyExchange(Stream input)
+ {
+ SecurityParameters securityParameters = context.SecurityParameters;
+
+ SignerInputBuffer buf = new SignerInputBuffer();
+ Stream teeIn = new TeeInputStream(input, buf);
+
+ ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, teeIn);
+
+ byte[] point = TlsUtilities.ReadOpaque8(teeIn);
+
+ DigitallySigned signed_params = DigitallySigned.Parse(context, input);
+
+ ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters);
+ buf.UpdateSigner(signer);
+ if (!signer.VerifySignature(signed_params.Signature))
+ throw new TlsFatalAlert(AlertDescription.decrypt_error);
+
+ this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(
+ mClientECPointFormats, curve_params, point));
+ }
+
public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
{
/*
- * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable
- * with ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is
- * prohibited because the use of a long-term ECDH client key would jeopardize the
- * forward secrecy property of these algorithms.
+ * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with
+ * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because
+ * the use of a long-term ECDH client key would jeopardize the forward secrecy property of
+ * these algorithms.
*/
byte[] types = certificateRequest.CertificateTypes;
- foreach (byte type in types)
+ for (int i = 0; i < types.Length; ++i)
{
- switch (type)
+ switch (types[i])
{
- case ClientCertificateType.rsa_sign:
- case ClientCertificateType.dss_sign:
- case ClientCertificateType.ecdsa_sign:
- break;
- default:
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+ case ClientCertificateType.rsa_sign:
+ case ClientCertificateType.dss_sign:
+ case ClientCertificateType.ecdsa_sign:
+ break;
+ default:
+ throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
}
}
-
+
public override void ProcessClientCredentials(TlsCredentials clientCredentials)
{
if (clientCredentials is TlsSignerCredentials)
@@ -99,9 +194,10 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
- protected virtual ISigner InitSigner(TlsSigner tlsSigner, SecurityParameters securityParameters)
+ protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm,
+ SecurityParameters securityParameters)
{
- ISigner signer = tlsSigner.CreateVerifyer(this.serverPublicKey);
+ ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey);
signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
return signer;
diff --git a/crypto/src/crypto/tls/TlsKeyExchange.cs b/crypto/src/crypto/tls/TlsKeyExchange.cs
index 5102edbec..6731f6f63 100644
--- a/crypto/src/crypto/tls/TlsKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsKeyExchange.cs
@@ -3,36 +3,52 @@ using System.IO;
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// A generic interface for key exchange implementations in TLS 1.0.
- /// </summary>
- public interface TlsKeyExchange
- {
- /// <exception cref="IOException"/>
- void SkipServerCertificate();
-
- /// <exception cref="IOException"/>
- void ProcessServerCertificate(Certificate serverCertificate);
-
- /// <exception cref="IOException"/>
- void SkipServerKeyExchange();
-
- /// <exception cref="IOException"/>
- void ProcessServerKeyExchange(Stream input);
-
- /// <exception cref="IOException"/>
- void ValidateCertificateRequest(CertificateRequest certificateRequest);
-
- /// <exception cref="IOException"/>
- void SkipClientCredentials();
-
- /// <exception cref="IOException"/>
- void ProcessClientCredentials(TlsCredentials clientCredentials);
-
- /// <exception cref="IOException"/>
- void GenerateClientKeyExchange(Stream output);
-
- /// <exception cref="IOException"/>
- byte[] GeneratePremasterSecret();
- }
+ /// <summary>
+ /// A generic interface for key exchange implementations in (D)TLS.
+ /// </summary>
+ public interface TlsKeyExchange
+ {
+ void Init(TlsContext context);
+
+ /// <exception cref="IOException"/>
+ void SkipServerCredentials();
+
+ /// <exception cref="IOException"/>
+ void ProcessServerCredentials(TlsCredentials serverCredentials);
+
+ /// <exception cref="IOException"/>
+ void ProcessServerCertificate(Certificate serverCertificate);
+
+ bool RequiresServerKeyExchange { get; }
+
+ /// <exception cref="IOException"/>
+ byte[] GenerateServerKeyExchange();
+
+ /// <exception cref="IOException"/>
+ void SkipServerKeyExchange();
+
+ /// <exception cref="IOException"/>
+ void ProcessServerKeyExchange(Stream input);
+
+ /// <exception cref="IOException"/>
+ void ValidateCertificateRequest(CertificateRequest certificateRequest);
+
+ /// <exception cref="IOException"/>
+ void SkipClientCredentials();
+
+ /// <exception cref="IOException"/>
+ void ProcessClientCredentials(TlsCredentials clientCredentials);
+
+ /// <exception cref="IOException"/>
+ void ProcessClientCertificate(Certificate clientCertificate);
+
+ /// <exception cref="IOException"/>
+ void GenerateClientKeyExchange(Stream output);
+
+ /// <exception cref="IOException"/>
+ void ProcessClientKeyExchange(Stream input);
+
+ /// <exception cref="IOException"/>
+ byte[] GeneratePremasterSecret();
+ }
}
diff --git a/crypto/src/crypto/tls/TlsProtocolHandler.cs b/crypto/src/crypto/tls/TlsProtocolHandler.cs
index 3dec5ade0..21b3c8d47 100644
--- a/crypto/src/crypto/tls/TlsProtocolHandler.cs
+++ b/crypto/src/crypto/tls/TlsProtocolHandler.cs
@@ -486,7 +486,7 @@ namespace Org.BouncyCastle.Crypto.Tls
if (connection_state == CS_SERVER_HELLO_RECEIVED)
{
// There was no server certificate message; check it's OK
- this.keyExchange.SkipServerCertificate();
+ this.keyExchange.SkipServerCredentials();
this.authentication = null;
// There was no server key exchange message; check it's OK
@@ -605,7 +605,7 @@ namespace Org.BouncyCastle.Crypto.Tls
if (connection_state == CS_SERVER_HELLO_RECEIVED)
{
// There was no server certificate message; check it's OK
- this.keyExchange.SkipServerCertificate();
+ this.keyExchange.SkipServerCredentials();
this.authentication = null;
}
diff --git a/crypto/src/crypto/tls/TlsPskKeyExchange.cs b/crypto/src/crypto/tls/TlsPskKeyExchange.cs
index 24bf433dd..cd13e3438 100644
--- a/crypto/src/crypto/tls/TlsPskKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsPskKeyExchange.cs
@@ -1,68 +1,118 @@
using System;
+using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Tls
{
- internal class TlsPskKeyExchange
- : TlsKeyExchange
+ /// <summary>(D)TLS PSK key exchange (RFC 4279).</summary>
+ public class TlsPskKeyExchange
+ : AbstractTlsKeyExchange
{
- protected TlsContext context;
- protected int keyExchange;
- protected TlsPskIdentity pskIdentity;
+ protected TlsPskIdentity mPskIdentity;
+ protected DHParameters mDHParameters;
+ protected int[] mNamedCurves;
+ protected byte[] mClientECPointFormats, mServerECPointFormats;
- protected byte[] psk_identity_hint = null;
+ protected byte[] mPskIdentityHint = null;
- protected DHPublicKeyParameters dhAgreeServerPublicKey = null;
- protected DHPrivateKeyParameters dhAgreeClientPrivateKey = null;
+ protected DHPrivateKeyParameters mDHAgreePrivateKey = null;
+ protected DHPublicKeyParameters mDHAgreePublicKey = null;
- protected AsymmetricKeyParameter serverPublicKey = null;
- protected RsaKeyParameters rsaServerPublicKey = null;
- protected byte[] premasterSecret;
+ protected AsymmetricKeyParameter mServerPublicKey = null;
+ protected RsaKeyParameters mRsaServerPublicKey = null;
+ protected TlsEncryptionCredentials mServerCredentials = null;
+ protected byte[] mPremasterSecret;
- internal TlsPskKeyExchange(TlsContext context, int keyExchange,
- TlsPskIdentity pskIdentity)
+ public TlsPskKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsPskIdentity pskIdentity,
+ DHParameters dhParameters, int[] namedCurves, byte[] clientECPointFormats, byte[] serverECPointFormats)
+ : base(keyExchange, supportedSignatureAlgorithms)
{
switch (keyExchange)
{
- case KeyExchangeAlgorithm.PSK:
- case KeyExchangeAlgorithm.RSA_PSK:
- case KeyExchangeAlgorithm.DHE_PSK:
- break;
- default:
- throw new ArgumentException("unsupported key exchange algorithm", "keyExchange");
+ case KeyExchangeAlgorithm.DHE_PSK:
+ case KeyExchangeAlgorithm.ECDHE_PSK:
+ case KeyExchangeAlgorithm.PSK:
+ case KeyExchangeAlgorithm.RSA_PSK:
+ break;
+ default:
+ throw new InvalidOperationException("unsupported key exchange algorithm");
}
- this.context = context;
- this.keyExchange = keyExchange;
- this.pskIdentity = pskIdentity;
+ this.mPskIdentity = pskIdentity;
+ this.mDHParameters = dhParameters;
+ this.mNamedCurves = namedCurves;
+ this.mClientECPointFormats = clientECPointFormats;
+ this.mServerECPointFormats = serverECPointFormats;
}
- public virtual void SkipServerCertificate()
+ public override void SkipServerCredentials()
{
- if (keyExchange == KeyExchangeAlgorithm.RSA_PSK)
- {
+ if (mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
}
- public virtual void ProcessServerCertificate(Certificate serverCertificate)
+ public override void ProcessServerCredentials(TlsCredentials serverCredentials)
{
- if (keyExchange != KeyExchangeAlgorithm.RSA_PSK)
+ if (!(serverCredentials is TlsEncryptionCredentials))
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+
+ ProcessServerCertificate(serverCredentials.Certificate);
+
+ this.mServerCredentials = (TlsEncryptionCredentials)serverCredentials;
+ }
+
+ public override byte[] GenerateServerKeyExchange()
+ {
+ // TODO[RFC 4279] Need a server-side PSK API to determine hint and resolve identities to keys
+ this.mPskIdentityHint = null;
+
+ if (this.mPskIdentityHint == null && !RequiresServerKeyExchange)
+ return null;
+
+ MemoryStream buf = new MemoryStream();
+
+ if (this.mPskIdentityHint == null)
{
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ TlsUtilities.WriteOpaque16(TlsUtilities.EmptyBytes, buf);
+ }
+ else
+ {
+ TlsUtilities.WriteOpaque16(this.mPskIdentityHint, buf);
}
+ if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
+ {
+ if (this.mDHParameters == null)
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+
+ this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(context.SecureRandom,
+ this.mDHParameters, buf);
+ }
+ else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
+ {
+ // TODO[RFC 5489]
+ }
+
+ return buf.ToArray();
+ }
+
+ public override void ProcessServerCertificate(Certificate serverCertificate)
+ {
+ if (mKeyExchange != KeyExchangeAlgorithm.RSA_PSK)
+ throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ if (serverCertificate.IsEmpty)
+ throw new TlsFatalAlert(AlertDescription.bad_certificate);
+
X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
- SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
+ SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
try
{
- this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
+ this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo);
}
catch (Exception e)
{
@@ -70,107 +120,92 @@ namespace Org.BouncyCastle.Crypto.Tls
}
// Sanity check the PublicKeyFactory
- if (this.serverPublicKey.IsPrivate)
- {
+ if (this.mServerPublicKey.IsPrivate)
throw new TlsFatalAlert(AlertDescription.internal_error);
- }
- this.rsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.serverPublicKey);
+ this.mRsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.mServerPublicKey);
TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment);
- // TODO
- /*
- * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
- * signing algorithm for the certificate must be the same as the algorithm for the
- * certificate key."
- */
+ base.ProcessServerCertificate(serverCertificate);
}
- public virtual void SkipServerKeyExchange()
+ public override bool RequiresServerKeyExchange
{
- if (keyExchange == KeyExchangeAlgorithm.DHE_PSK)
+ get
{
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ switch (mKeyExchange)
+ {
+ case KeyExchangeAlgorithm.DHE_PSK:
+ case KeyExchangeAlgorithm.ECDHE_PSK:
+ return true;
+ default:
+ return false;
+ }
}
-
- this.psk_identity_hint = TlsUtilities.EmptyBytes;
}
- public virtual void ProcessServerKeyExchange(Stream input)
+ public override void ProcessServerKeyExchange(Stream input)
{
- this.psk_identity_hint = TlsUtilities.ReadOpaque16(input);
+ this.mPskIdentityHint = TlsUtilities.ReadOpaque16(input);
- if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK)
+ if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
{
- byte[] pBytes = TlsUtilities.ReadOpaque16(input);
- byte[] gBytes = TlsUtilities.ReadOpaque16(input);
- byte[] YsBytes = TlsUtilities.ReadOpaque16(input);
+ ServerDHParams serverDHParams = ServerDHParams.Parse(input);
- BigInteger p = new BigInteger(1, pBytes);
- BigInteger g = new BigInteger(1, gBytes);
- BigInteger Ys = new BigInteger(1, YsBytes);
-
- this.dhAgreeServerPublicKey = TlsDHUtilities.ValidateDHPublicKey(
- new DHPublicKeyParameters(Ys, new DHParameters(p, g)));
+ this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(serverDHParams.PublicKey);
}
- else if (this.psk_identity_hint.Length == 0)
+ else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
{
- // TODO Should we enforce that this message should have been skipped if hint is empty?
- //throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ // TODO[RFC 5489]
}
}
- public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
+ public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
- public virtual void SkipClientCredentials()
- {
- // OK
- }
-
- public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
+ public override void ProcessClientCredentials(TlsCredentials clientCredentials)
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
- public virtual void GenerateClientKeyExchange(Stream output)
+ public override void GenerateClientKeyExchange(Stream output)
{
- if (psk_identity_hint == null)
+ if (mPskIdentityHint == null)
{
- pskIdentity.SkipIdentityHint();
+ mPskIdentity.SkipIdentityHint();
}
else
{
- pskIdentity.NotifyIdentityHint(psk_identity_hint);
+ mPskIdentity.NotifyIdentityHint(mPskIdentityHint);
}
- byte[] psk_identity = pskIdentity.GetPskIdentity();
+ byte[] psk_identity = mPskIdentity.GetPskIdentity();
TlsUtilities.WriteOpaque16(psk_identity, output);
- if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK)
+ if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
{
- this.dhAgreeClientPrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(
- context.SecureRandom, this.dhAgreeServerPublicKey.Parameters, output);
+ this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(context.SecureRandom,
+ mDHAgreePublicKey.Parameters, output);
}
- else if (this.keyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
+ else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
{
// TODO[RFC 5489]
throw new TlsFatalAlert(AlertDescription.internal_error);
}
- else if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK)
+ else if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
{
- this.premasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(
- context, this.rsaServerPublicKey, output);
+ this.mPremasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(context,
+ this.mRsaServerPublicKey, output);
}
}
- public virtual byte[] GeneratePremasterSecret()
+ public override byte[] GeneratePremasterSecret()
{
- byte[] psk = pskIdentity.GetPsk();
+ byte[] psk = mPskIdentity.GetPsk();
byte[] other_secret = GenerateOtherSecret(psk.Length);
MemoryStream buf = new MemoryStream(4 + other_secret.Length + psk.Length);
@@ -181,14 +216,25 @@ namespace Org.BouncyCastle.Crypto.Tls
protected virtual byte[] GenerateOtherSecret(int pskLength)
{
- if (this.keyExchange == KeyExchangeAlgorithm.DHE_PSK)
+ if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK)
+ {
+ if (mDHAgreePrivateKey != null)
+ {
+ return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreePublicKey, mDHAgreePrivateKey);
+ }
+
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+ }
+
+ if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK)
{
- return TlsDHUtilities.CalculateDHBasicAgreement(dhAgreeServerPublicKey, dhAgreeClientPrivateKey);
+ // TODO[RFC 5489]
+ throw new TlsFatalAlert(AlertDescription.internal_error);
}
- if (this.keyExchange == KeyExchangeAlgorithm.RSA_PSK)
+ if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK)
{
- return this.premasterSecret;
+ return this.mPremasterSecret;
}
return new byte[pskLength];
@@ -197,12 +243,10 @@ namespace Org.BouncyCastle.Crypto.Tls
protected virtual RsaKeyParameters ValidateRsaPublicKey(RsaKeyParameters key)
{
// TODO What is the minimum bit length required?
- // key.Modulus.BitLength;
+ // key.Modulus.BitLength;
if (!key.Exponent.IsProbablePrime(2))
- {
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
- }
return key;
}
diff --git a/crypto/src/crypto/tls/TlsRsaKeyExchange.cs b/crypto/src/crypto/tls/TlsRsaKeyExchange.cs
index 160afa5c9..3a0a49154 100644
--- a/crypto/src/crypto/tls/TlsRsaKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsRsaKeyExchange.cs
@@ -1,45 +1,57 @@
using System;
+using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// TLS 1.0 RSA key exchange.
- /// </summary>
- internal class TlsRsaKeyExchange
- : TlsKeyExchange
+ /// <summary>(D)TLS and SSLv3 RSA key exchange.</summary>
+ public class TlsRsaKeyExchange
+ : AbstractTlsKeyExchange
{
- protected TlsContext context;
-
protected AsymmetricKeyParameter serverPublicKey = null;
protected RsaKeyParameters rsaServerPublicKey = null;
+ protected TlsEncryptionCredentials serverCredentials = null;
+
protected byte[] premasterSecret;
- internal TlsRsaKeyExchange(TlsContext context)
+ public TlsRsaKeyExchange(IList supportedSignatureAlgorithms)
+ : base(KeyExchangeAlgorithm.RSA, supportedSignatureAlgorithms)
{
- this.context = context;
}
- public virtual void SkipServerCertificate()
+ public override void SkipServerCredentials()
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
- public virtual void ProcessServerCertificate(Certificate serverCertificate)
+ public override void ProcessServerCredentials(TlsCredentials serverCredentials)
+ {
+ if (!(serverCredentials is TlsEncryptionCredentials))
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+
+ ProcessServerCertificate(serverCredentials.Certificate);
+
+ this.serverCredentials = (TlsEncryptionCredentials)serverCredentials;
+ }
+
+ public override void ProcessServerCertificate(Certificate serverCertificate)
{
+ if (serverCertificate.IsEmpty)
+ throw new TlsFatalAlert(AlertDescription.bad_certificate);
+
X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
- SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
+ SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
try
{
this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
@@ -51,111 +63,76 @@ namespace Org.BouncyCastle.Crypto.Tls
// Sanity check the PublicKeyFactory
if (this.serverPublicKey.IsPrivate)
- {
throw new TlsFatalAlert(AlertDescription.internal_error);
- }
this.rsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.serverPublicKey);
TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment);
- // TODO
- /*
- * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
- * signing algorithm for the certificate must be the same as the algorithm for the
- * certificate key."
- */
+ base.ProcessServerCertificate(serverCertificate);
}
- public virtual void SkipServerKeyExchange()
- {
- // OK
- }
-
- public virtual void ProcessServerKeyExchange(Stream input)
- {
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
-
- public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
+ public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
{
byte[] types = certificateRequest.CertificateTypes;
- foreach (byte type in types)
+ for (int i = 0; i < types.Length; ++i)
{
- switch (type)
+ switch (types[i])
{
- case ClientCertificateType.rsa_sign:
- case ClientCertificateType.dss_sign:
- case ClientCertificateType.ecdsa_sign:
- break;
- default:
- throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+ case ClientCertificateType.rsa_sign:
+ case ClientCertificateType.dss_sign:
+ case ClientCertificateType.ecdsa_sign:
+ break;
+ default:
+ throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
}
}
- public virtual void SkipClientCredentials()
+ public override void ProcessClientCredentials(TlsCredentials clientCredentials)
{
- // OK
+ if (!(clientCredentials is TlsSignerCredentials))
+ throw new TlsFatalAlert(AlertDescription.internal_error);
}
- public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
+ public override void GenerateClientKeyExchange(Stream output)
{
- if (!(clientCredentials is TlsSignerCredentials))
- {
- throw new TlsFatalAlert(AlertDescription.internal_error);
- }
+ this.premasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(context, rsaServerPublicKey, output);
}
-
- public virtual void GenerateClientKeyExchange(Stream output)
+
+ public override void ProcessClientKeyExchange(Stream input)
{
- this.premasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(context, this.rsaServerPublicKey, output);
+ byte[] encryptedPreMasterSecret;
+ if (TlsUtilities.IsSsl(context))
+ {
+ // TODO Do any SSLv3 clients actually include the length?
+ encryptedPreMasterSecret = Streams.ReadAll(input);
+ }
+ else
+ {
+ encryptedPreMasterSecret = TlsUtilities.ReadOpaque16(input);
+ }
+
+ this.premasterSecret = serverCredentials.DecryptPreMasterSecret(encryptedPreMasterSecret);
}
- public virtual byte[] GeneratePremasterSecret()
+ public override byte[] GeneratePremasterSecret()
{
+ if (this.premasterSecret == null)
+ throw new TlsFatalAlert(AlertDescription.internal_error);
+
byte[] tmp = this.premasterSecret;
this.premasterSecret = null;
return tmp;
}
- // Would be needed to process RSA_EXPORT server key exchange
-// protected virtual void ProcessRsaServerKeyExchange(Stream input, ISigner signer)
-// {
-// Stream sigIn = input;
-// if (signer != null)
-// {
-// sigIn = new SignerStream(input, signer, null);
-// }
-//
-// byte[] modulusBytes = TlsUtilities.ReadOpaque16(sigIn);
-// byte[] exponentBytes = TlsUtilities.ReadOpaque16(sigIn);
-//
-// if (signer != null)
-// {
-// byte[] sigByte = TlsUtilities.ReadOpaque16(input);
-//
-// if (!signer.VerifySignature(sigByte))
-// {
-// handler.FailWithError(AlertLevel.fatal, AlertDescription.decrypt_error);
-// }
-// }
-//
-// BigInteger modulus = new BigInteger(1, modulusBytes);
-// BigInteger exponent = new BigInteger(1, exponentBytes);
-//
-// this.rsaServerPublicKey = ValidateRSAPublicKey(new RsaKeyParameters(false, modulus, exponent));
-// }
-
protected virtual RsaKeyParameters ValidateRsaPublicKey(RsaKeyParameters key)
{
// TODO What is the minimum bit length required?
-// key.Modulus.BitLength;
+ // key.Modulus.BitLength;
if (!key.Exponent.IsProbablePrime(2))
- {
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
- }
return key;
}
diff --git a/crypto/src/crypto/tls/TlsSrpKeyExchange.cs b/crypto/src/crypto/tls/TlsSrpKeyExchange.cs
index ff1bdac86..f42f7456d 100644
--- a/crypto/src/crypto/tls/TlsSrpKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsSrpKeyExchange.cs
@@ -1,189 +1,175 @@
using System;
+using System.Collections;
using System.IO;
-using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Agreement;
using Org.BouncyCastle.Crypto.Agreement.Srp;
-using Org.BouncyCastle.Crypto.Digests;
-using Org.BouncyCastle.Crypto.IO;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Crypto.Tls
{
- /// <summary>
- /// TLS 1.1 SRP key exchange.
- /// </summary>
- internal class TlsSrpKeyExchange
- : TlsKeyExchange
+ /// <summary>(D)TLS SRP key exchange (RFC 5054).</summary>
+ public class TlsSrpKeyExchange
+ : AbstractTlsKeyExchange
{
- protected TlsContext context;
- protected int keyExchange;
- protected TlsSigner tlsSigner;
- protected byte[] identity;
- protected byte[] password;
+ protected TlsSigner mTlsSigner;
+ protected byte[] mIdentity;
+ protected byte[] mPassword;
- protected AsymmetricKeyParameter serverPublicKey = null;
+ protected AsymmetricKeyParameter mServerPublicKey = null;
- protected byte[] s = null;
- protected BigInteger B = null;
- protected Srp6Client srpClient = new Srp6Client();
+ protected byte[] mS = null;
+ protected BigInteger mB = null;
+ protected Srp6Client mSrpClient = new Srp6Client();
- internal TlsSrpKeyExchange(TlsContext context, int keyExchange,
- byte[] identity, byte[] password)
+ public TlsSrpKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, byte[] identity, byte[] password)
+ : base(keyExchange, supportedSignatureAlgorithms)
{
switch (keyExchange)
{
- case KeyExchangeAlgorithm.SRP:
- this.tlsSigner = null;
- break;
- case KeyExchangeAlgorithm.SRP_RSA:
- this.tlsSigner = new TlsRsaSigner();
- break;
- case KeyExchangeAlgorithm.SRP_DSS:
- this.tlsSigner = new TlsDssSigner();
- break;
- default:
- throw new ArgumentException("unsupported key exchange algorithm", "keyExchange");
+ case KeyExchangeAlgorithm.SRP:
+ this.mTlsSigner = null;
+ break;
+ case KeyExchangeAlgorithm.SRP_RSA:
+ this.mTlsSigner = new TlsRsaSigner();
+ break;
+ case KeyExchangeAlgorithm.SRP_DSS:
+ this.mTlsSigner = new TlsDssSigner();
+ break;
+ default:
+ throw new InvalidOperationException("unsupported key exchange algorithm");
}
- this.context = context;
- this.keyExchange = keyExchange;
- this.identity = identity;
- this.password = password;
+ this.mIdentity = identity;
+ this.mPassword = password;
}
- public virtual void SkipServerCertificate()
+ public override void Init(TlsContext context)
{
- if (tlsSigner != null)
+ base.Init(context);
+
+ if (this.mTlsSigner != null)
{
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ this.mTlsSigner.Init(context);
}
}
- public virtual void ProcessServerCertificate(Certificate serverCertificate)
+ public override void SkipServerCredentials()
{
- if (tlsSigner == null)
- {
+ if (mTlsSigner != null)
throw new TlsFatalAlert(AlertDescription.unexpected_message);
- }
+ }
+
+ public override void ProcessServerCertificate(Certificate serverCertificate)
+ {
+ if (mTlsSigner == null)
+ throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ if (serverCertificate.IsEmpty)
+ throw new TlsFatalAlert(AlertDescription.bad_certificate);
X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0);
- SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
+ SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
try
{
- this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
+ this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo);
}
catch (Exception e)
{
throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e);
}
- if (!tlsSigner.IsValidPublicKey(this.serverPublicKey))
- {
+ if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey))
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
- }
TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature);
- // TODO
- /*
- * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
- * signing algorithm for the certificate must be the same as the algorithm for the
- * certificate key."
- */
+ base.ProcessServerCertificate(serverCertificate);
}
- public virtual void SkipServerKeyExchange()
+ public override bool RequiresServerKeyExchange
{
- throw new TlsFatalAlert(AlertDescription.unexpected_message);
+ get { return true; }
}
- public virtual void ProcessServerKeyExchange(Stream input)
+ public override void ProcessServerKeyExchange(Stream input)
{
SecurityParameters securityParameters = context.SecurityParameters;
- Stream sigIn = input;
- ISigner signer = null;
+ SignerInputBuffer buf = null;
+ Stream teeIn = input;
- if (tlsSigner != null)
+ if (mTlsSigner != null)
{
- signer = InitSigner(tlsSigner, securityParameters);
- sigIn = new SignerStream(input, signer, null);
+ buf = new SignerInputBuffer();
+ teeIn = new TeeInputStream(input, buf);
}
- byte[] NBytes = TlsUtilities.ReadOpaque16(sigIn);
- byte[] gBytes = TlsUtilities.ReadOpaque16(sigIn);
- byte[] sBytes = TlsUtilities.ReadOpaque8(sigIn);
- byte[] BBytes = TlsUtilities.ReadOpaque16(sigIn);
+ byte[] NBytes = TlsUtilities.ReadOpaque16(teeIn);
+ byte[] gBytes = TlsUtilities.ReadOpaque16(teeIn);
+ byte[] sBytes = TlsUtilities.ReadOpaque8(teeIn);
+ byte[] BBytes = TlsUtilities.ReadOpaque16(teeIn);
- if (signer != null)
+ if (buf != null)
{
- byte[] sigByte = TlsUtilities.ReadOpaque16(input);
+ DigitallySigned signed_params = DigitallySigned.Parse(context, input);
- if (!signer.VerifySignature(sigByte))
- {
+ ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters);
+ buf.UpdateSigner(signer);
+ if (!signer.VerifySignature(signed_params.Signature))
throw new TlsFatalAlert(AlertDescription.decrypt_error);
- }
}
BigInteger N = new BigInteger(1, NBytes);
BigInteger g = new BigInteger(1, gBytes);
// TODO Validate group parameters (see RFC 5054)
- //throw new TlsFatalAlert(AlertDescription.insufficient_security);
+ // throw new TlsFatalAlert(AlertDescription.insufficient_security);
- this.s = sBytes;
+ this.mS = sBytes;
/*
- * RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter"
- * alert if B % N = 0.
- */
+ * RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if
+ * B % N = 0.
+ */
try
{
- this.B = Srp6Utilities.ValidatePublicValue(N, new BigInteger(1, BBytes));
+ this.mB = Srp6Utilities.ValidatePublicValue(N, new BigInteger(1, BBytes));
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter, e);
}
- this.srpClient.Init(N, g, new Sha1Digest(), context.SecureRandom);
+ this.mSrpClient.Init(N, g, TlsUtilities.CreateHash(HashAlgorithm.sha1), context.SecureRandom);
}
- public virtual void ValidateCertificateRequest(CertificateRequest certificateRequest)
+ public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
- public virtual void SkipClientCredentials()
- {
- // OK
- }
-
- public virtual void ProcessClientCredentials(TlsCredentials clientCredentials)
+ public override void ProcessClientCredentials(TlsCredentials clientCredentials)
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
- public virtual void GenerateClientKeyExchange(Stream output)
+ public override void GenerateClientKeyExchange(Stream output)
{
- byte[] keData = BigIntegers.AsUnsignedByteArray(srpClient.GenerateClientCredentials(s,
- this.identity, this.password));
- TlsUtilities.WriteOpaque16(keData, output);
+ BigInteger A = mSrpClient.GenerateClientCredentials(mS, this.mIdentity, this.mPassword);
+ TlsUtilities.WriteOpaque16(BigIntegers.AsUnsignedByteArray(A), output);
}
- public virtual byte[] GeneratePremasterSecret()
+ public override byte[] GeneratePremasterSecret()
{
try
{
// TODO Check if this needs to be a fixed size
- return BigIntegers.AsUnsignedByteArray(srpClient.CalculateSecret(B));
+ return BigIntegers.AsUnsignedByteArray(mSrpClient.CalculateSecret(mB));
}
catch (CryptoException e)
{
@@ -191,9 +177,10 @@ namespace Org.BouncyCastle.Crypto.Tls
}
}
- protected virtual ISigner InitSigner(TlsSigner tlsSigner, SecurityParameters securityParameters)
+ protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm,
+ SecurityParameters securityParameters)
{
- ISigner signer = tlsSigner.CreateVerifyer(this.serverPublicKey);
+ ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey);
signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
return signer;
|