diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2016-03-01 00:33:24 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2016-03-01 00:33:24 +0700 |
commit | 4d6b202012080ce738f69fc7c6a0b8c9e588d083 (patch) | |
tree | 6e00d6218c4779b9618c2c78fa24bf7e2414fb28 /crypto | |
parent | fixed zero length message bug (diff) | |
download | BouncyCastle.NET-ed25519-4d6b202012080ce738f69fc7c6a0b8c9e588d083.tar.xz |
BMA-147 Support ECDH_anon key exchange in (D)TLS
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/Readme.html | 1 | ||||
-rw-r--r-- | crypto/src/crypto/tls/DefaultTlsClient.cs | 1 | ||||
-rw-r--r-- | crypto/src/crypto/tls/DefaultTlsServer.cs | 6 | ||||
-rw-r--r-- | crypto/src/crypto/tls/TlsECDHKeyExchange.cs | 42 | ||||
-rw-r--r-- | crypto/src/crypto/tls/TlsUtilities.cs | 76 |
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: |