summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2016-03-01 00:33:24 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2016-03-01 00:33:24 +0700
commit4d6b202012080ce738f69fc7c6a0b8c9e588d083 (patch)
tree6e00d6218c4779b9618c2c78fa24bf7e2414fb28
parentfixed zero length message bug (diff)
downloadBouncyCastle.NET-ed25519-4d6b202012080ce738f69fc7c6a0b8c9e588d083.tar.xz
BMA-147 Support ECDH_anon key exchange in (D)TLS
-rw-r--r--crypto/Readme.html1
-rw-r--r--crypto/src/crypto/tls/DefaultTlsClient.cs1
-rw-r--r--crypto/src/crypto/tls/DefaultTlsServer.cs6
-rw-r--r--crypto/src/crypto/tls/TlsECDHKeyExchange.cs42
-rw-r--r--crypto/src/crypto/tls/TlsUtilities.cs76
5 files changed, 89 insertions, 37 deletions
diff --git a/crypto/Readme.html b/crypto/Readme.html
index a8401c198..7af1bbaf0 100644
--- a/crypto/Readme.html
+++ b/crypto/Readme.html
@@ -297,6 +297,7 @@ We state, where EC MQV has not otherwise been disabled or removed:
         <h5>Additional Features and Functionality</h5>
         <ul>
             <li>TLS: support for ClientHello Padding Extension (RFC 7685).</li>
+            <li>TLS: support for ECDH_anon key exchange.</li>
             <li>BCrypt implementation added.</li>
         </ul>
 
diff --git a/crypto/src/crypto/tls/DefaultTlsClient.cs b/crypto/src/crypto/tls/DefaultTlsClient.cs
index ff7e6da85..7dadf8a1a 100644
--- a/crypto/src/crypto/tls/DefaultTlsClient.cs
+++ b/crypto/src/crypto/tls/DefaultTlsClient.cs
@@ -60,6 +60,7 @@ namespace Org.BouncyCastle.Crypto.Tls
             case KeyExchangeAlgorithm.DHE_RSA:
                 return CreateDheKeyExchange(keyExchangeAlgorithm);
 
+            case KeyExchangeAlgorithm.ECDH_anon:
             case KeyExchangeAlgorithm.ECDH_ECDSA:
             case KeyExchangeAlgorithm.ECDH_RSA:
                 return CreateECDHKeyExchange(keyExchangeAlgorithm);
diff --git a/crypto/src/crypto/tls/DefaultTlsServer.cs b/crypto/src/crypto/tls/DefaultTlsServer.cs
index 77cd5f1cc..44ceb30e3 100644
--- a/crypto/src/crypto/tls/DefaultTlsServer.cs
+++ b/crypto/src/crypto/tls/DefaultTlsServer.cs
@@ -76,11 +76,12 @@ namespace Org.BouncyCastle.Crypto.Tls
 
             switch (keyExchangeAlgorithm)
             {
-                case KeyExchangeAlgorithm.DH_DSS:
                 case KeyExchangeAlgorithm.DHE_DSS:
                     return GetDsaSignerCredentials();
 
-                case KeyExchangeAlgorithm.ECDH_ECDSA:
+                case KeyExchangeAlgorithm.ECDH_anon:
+                    return null;
+
                 case KeyExchangeAlgorithm.ECDHE_ECDSA:
                     return GetECDsaSignerCredentials();
 
@@ -111,6 +112,7 @@ namespace Org.BouncyCastle.Crypto.Tls
             case KeyExchangeAlgorithm.DHE_RSA:
                 return CreateDheKeyExchange(keyExchangeAlgorithm);
 
+            case KeyExchangeAlgorithm.ECDH_anon:
             case KeyExchangeAlgorithm.ECDH_ECDSA:
             case KeyExchangeAlgorithm.ECDH_RSA:
                 return CreateECDHKeyExchange(keyExchangeAlgorithm);
diff --git a/crypto/src/crypto/tls/TlsECDHKeyExchange.cs b/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
index 992be4aca..03c162904 100644
--- a/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
+++ b/crypto/src/crypto/tls/TlsECDHKeyExchange.cs
@@ -34,6 +34,7 @@ namespace Org.BouncyCastle.Crypto.Tls
             case KeyExchangeAlgorithm.ECDHE_ECDSA:
                 this.mTlsSigner = new TlsECDsaSigner();
                 break;
+            case KeyExchangeAlgorithm.ECDH_anon:
             case KeyExchangeAlgorithm.ECDH_RSA:
             case KeyExchangeAlgorithm.ECDH_ECDSA:
                 this.mTlsSigner = null;
@@ -59,11 +60,14 @@ namespace Org.BouncyCastle.Crypto.Tls
 
         public override void SkipServerCredentials()
         {
-            throw new TlsFatalAlert(AlertDescription.unexpected_message);
+            if (mKeyExchange != KeyExchangeAlgorithm.ECDH_anon)
+                throw new TlsFatalAlert(AlertDescription.unexpected_message);
         }
 
         public override void ProcessServerCertificate(Certificate serverCertificate)
         {
+            if (mKeyExchange == KeyExchangeAlgorithm.ECDH_anon)
+                throw new TlsFatalAlert(AlertDescription.unexpected_message);
             if (serverCertificate.IsEmpty)
                 throw new TlsFatalAlert(AlertDescription.bad_certificate);
 
@@ -109,9 +113,9 @@ namespace Org.BouncyCastle.Crypto.Tls
             {
                 switch (mKeyExchange)
                 {
+                case KeyExchangeAlgorithm.ECDH_anon:
                 case KeyExchangeAlgorithm.ECDHE_ECDSA:
                 case KeyExchangeAlgorithm.ECDHE_RSA:
-                case KeyExchangeAlgorithm.ECDH_anon:
                     return true;
                 default:
                     return false;
@@ -119,6 +123,34 @@ namespace Org.BouncyCastle.Crypto.Tls
             }
         }
 
+        public override byte[] GenerateServerKeyExchange()
+        {
+            if (!RequiresServerKeyExchange)
+                return null;
+
+            // ECDH_anon is handled here, ECDHE_* in a subclass
+
+            MemoryStream buf = new MemoryStream();
+            this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves,
+                mClientECPointFormats, buf);
+            return buf.ToArray();
+        }
+
+        public override void ProcessServerKeyExchange(Stream input)
+        {
+            if (!RequiresServerKeyExchange)
+                throw new TlsFatalAlert(AlertDescription.unexpected_message);
+
+            // ECDH_anon is handled here, ECDHE_* in a subclass
+
+            ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, input);
+
+            byte[] point = TlsUtilities.ReadOpaque8(input);
+
+            this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(
+                mClientECPointFormats, curve_params, point));
+        }
+
         public override void ValidateCertificateRequest(CertificateRequest certificateRequest)
         {
             /*
@@ -146,6 +178,9 @@ namespace Org.BouncyCastle.Crypto.Tls
 
         public override void ProcessClientCredentials(TlsCredentials clientCredentials)
         {
+            if (mKeyExchange == KeyExchangeAlgorithm.ECDH_anon)
+                throw new TlsFatalAlert(AlertDescription.internal_error);
+
             if (clientCredentials is TlsAgreementCredentials)
             {
                 // TODO Validate client cert has matching parameters (see 'TlsEccUtilities.AreOnSameCurve')?
@@ -173,6 +208,9 @@ namespace Org.BouncyCastle.Crypto.Tls
 
         public override void ProcessClientCertificate(Certificate clientCertificate)
         {
+            if (mKeyExchange == KeyExchangeAlgorithm.ECDH_anon)
+                throw new TlsFatalAlert(AlertDescription.unexpected_message);
+
             // TODO Extract the public key
             // TODO If the certificate is 'fixed', take the public key as mECAgreeClientPublicKey
         }
diff --git a/crypto/src/crypto/tls/TlsUtilities.cs b/crypto/src/crypto/tls/TlsUtilities.cs
index 0e32f866a..25908d163 100644
--- a/crypto/src/crypto/tls/TlsUtilities.cs
+++ b/crypto/src/crypto/tls/TlsUtilities.cs
@@ -1264,6 +1264,7 @@ namespace Org.BouncyCastle.Crypto.Tls
             case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
             case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
             case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
             case CipherSuite.TLS_ECDH_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:
@@ -1278,38 +1279,37 @@ namespace Org.BouncyCastle.Crypto.Tls
                 return EncryptionAlgorithm.cls_3DES_EDE_CBC;
 
             case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+            case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
             case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
-            case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+            case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
             case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA:
             case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA:
             case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA:
                 return EncryptionAlgorithm.AES_128_CBC;
 
-            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_PSK_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_PSK_WITH_AES_128_CBC_SHA256:
-            case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
-            case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256:
-            case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
-            case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
-                return EncryptionAlgorithm.AES_128_CBC;
-
             case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
             case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
@@ -1347,40 +1347,37 @@ namespace Org.BouncyCastle.Crypto.Tls
                 return EncryptionAlgorithm.AES_128_OCB_TAGLEN96;
 
             case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
             case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_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_PSK_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
             case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+            case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
             case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
             case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
             case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
             case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
             case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
             case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
             case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
             case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA:
             case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA:
             case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA:
                 return EncryptionAlgorithm.AES_256_CBC;
 
-            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 EncryptionAlgorithm.AES_256_CBC;
-
-            case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
-            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_PSK_WITH_AES_256_CBC_SHA384:
-            case CipherSuite.TLS_ECDHE_RSA_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 EncryptionAlgorithm.AES_256_CBC;
-
             case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
             case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
@@ -1504,6 +1501,7 @@ namespace Org.BouncyCastle.Crypto.Tls
                 return EncryptionAlgorithm.NULL;
 
             case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA:
             case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA:
             case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA:
             case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
@@ -1654,6 +1652,13 @@ namespace Org.BouncyCastle.Crypto.Tls
             case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
                 return KeyExchangeAlgorithm.DHE_RSA;
 
+            case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA:
+                return KeyExchangeAlgorithm.ECDH_anon;
+
             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:
@@ -1953,6 +1958,11 @@ namespace Org.BouncyCastle.Crypto.Tls
             case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
             case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
             case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA:
+            case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA:
             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_256_CBC_SHA: