diff options
-rw-r--r-- | crypto/src/asn1/pkcs/PBKDF2Params.cs | 196 | ||||
-rw-r--r-- | crypto/src/crypto/tls/DefaultTlsServer.cs | 2 | ||||
-rw-r--r-- | crypto/src/crypto/tls/PskTlsServer.cs | 2 | ||||
-rw-r--r-- | crypto/src/crypto/tls/TlsDHKeyExchange.cs | 22 | ||||
-rw-r--r-- | crypto/src/crypto/tls/TlsDHUtilities.cs | 24 | ||||
-rw-r--r-- | crypto/src/crypto/tls/TlsDheKeyExchange.cs | 2 |
6 files changed, 162 insertions, 86 deletions
diff --git a/crypto/src/asn1/pkcs/PBKDF2Params.cs b/crypto/src/asn1/pkcs/PBKDF2Params.cs index 1351b94cf..5d1e9854f 100644 --- a/crypto/src/asn1/pkcs/PBKDF2Params.cs +++ b/crypto/src/asn1/pkcs/PBKDF2Params.cs @@ -1,50 +1,73 @@ using System; - +using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; namespace Org.BouncyCastle.Asn1.Pkcs { - public class Pbkdf2Params - : Asn1Encodable - { - private readonly Asn1OctetString octStr; - private readonly DerInteger iterationCount; - private readonly DerInteger keyLength; - - public static Pbkdf2Params GetInstance( - object obj) - { - if (obj == null || obj is Pbkdf2Params) - return (Pbkdf2Params)obj; - - if (obj is Asn1Sequence) - return new Pbkdf2Params((Asn1Sequence)obj); - - throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); - } - - public Pbkdf2Params( - Asn1Sequence seq) - { - if (seq.Count < 2 || seq.Count > 3) - throw new ArgumentException("Wrong number of elements in sequence", "seq"); - - octStr = (Asn1OctetString)seq[0]; - iterationCount = (DerInteger)seq[1]; - - if (seq.Count > 2) - { - keyLength = (DerInteger)seq[2]; - } - } - - public Pbkdf2Params( - byte[] salt, - int iterationCount) - { - this.octStr = new DerOctetString(salt); - this.iterationCount = new DerInteger(iterationCount); - } + public class Pbkdf2Params + : Asn1Encodable + { + private static AlgorithmIdentifier algid_hmacWithSHA1 = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdHmacWithSha1, DerNull.Instance); + + private readonly Asn1OctetString octStr; + private readonly DerInteger iterationCount, keyLength; + private readonly AlgorithmIdentifier prf; + + public static Pbkdf2Params GetInstance( + object obj) + { + if (obj == null || obj is Pbkdf2Params) + return (Pbkdf2Params)obj; + + if (obj is Asn1Sequence) + return new Pbkdf2Params((Asn1Sequence)obj); + + throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); + } + + public Pbkdf2Params( + Asn1Sequence seq) + { + if (seq.Count < 2 || seq.Count > 4) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.octStr = (Asn1OctetString)seq[0]; + this.iterationCount = (DerInteger)seq[1]; + + Asn1Encodable kl = null, d = null; + if (seq.Count > 3) + { + kl = seq[2]; + d = seq[3]; + } + else if (seq.Count > 2) + { + if (seq[2] is DerInteger) + { + kl = seq[2]; + } + else + { + d = seq[2]; + } + } + if (kl != null) + { + keyLength = (DerInteger)kl; + } + if (d != null) + { + prf = AlgorithmIdentifier.GetInstance(d); + } + } + + public Pbkdf2Params( + byte[] salt, + int iterationCount) + { + this.octStr = new DerOctetString(salt); + this.iterationCount = new DerInteger(iterationCount); + } public Pbkdf2Params( byte[] salt, @@ -55,32 +78,65 @@ namespace Org.BouncyCastle.Asn1.Pkcs this.keyLength = new DerInteger(keyLength); } - public byte[] GetSalt() - { - return octStr.GetOctets(); - } - - public BigInteger IterationCount - { - get { return iterationCount.Value; } - } - - public BigInteger KeyLength - { - get { return keyLength == null ? null : keyLength.Value; } - } - - public override Asn1Object ToAsn1Object() - { - Asn1EncodableVector v = new Asn1EncodableVector( - octStr, iterationCount); - - if (keyLength != null) - { - v.Add(keyLength); - } - - return new DerSequence(v); - } - } + public Pbkdf2Params( + byte[] salt, + int iterationCount, + int keyLength, + AlgorithmIdentifier prf) + : this(salt, iterationCount, keyLength) + { + this.prf = prf; + } + + public Pbkdf2Params( + byte[] salt, + int iterationCount, + AlgorithmIdentifier prf) + : this(salt, iterationCount) + { + this.prf = prf; + } + + public byte[] GetSalt() + { + return octStr.GetOctets(); + } + + public BigInteger IterationCount + { + get { return iterationCount.Value; } + } + + public BigInteger KeyLength + { + get { return keyLength == null ? null : keyLength.Value; } + } + + public bool IsDefaultPrf + { + get { return prf == null || prf.Equals(algid_hmacWithSHA1); } + } + + public AlgorithmIdentifier Prf + { + get { return prf != null ? prf : algid_hmacWithSHA1; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + octStr, iterationCount); + + if (keyLength != null) + { + v.Add(keyLength); + } + if (!IsDefaultPrf) + { + v.Add(prf); + } + + return new DerSequence(v); + } + } } diff --git a/crypto/src/crypto/tls/DefaultTlsServer.cs b/crypto/src/crypto/tls/DefaultTlsServer.cs index b12c43e1c..77cd5f1cc 100644 --- a/crypto/src/crypto/tls/DefaultTlsServer.cs +++ b/crypto/src/crypto/tls/DefaultTlsServer.cs @@ -42,7 +42,7 @@ namespace Org.BouncyCastle.Crypto.Tls protected virtual DHParameters GetDHParameters() { - return DHStandardGroups.rfc5114_1024_160; + return DHStandardGroups.rfc5114_2048_256; } protected override int[] GetCipherSuites() diff --git a/crypto/src/crypto/tls/PskTlsServer.cs b/crypto/src/crypto/tls/PskTlsServer.cs index 27d2b8119..85f3055fb 100644 --- a/crypto/src/crypto/tls/PskTlsServer.cs +++ b/crypto/src/crypto/tls/PskTlsServer.cs @@ -28,7 +28,7 @@ namespace Org.BouncyCastle.Crypto.Tls protected virtual DHParameters GetDHParameters() { - return DHStandardGroups.rfc5114_1024_160; + return DHStandardGroups.rfc5114_2048_256; } protected override int[] GetCipherSuites() diff --git a/crypto/src/crypto/tls/TlsDHKeyExchange.cs b/crypto/src/crypto/tls/TlsDHKeyExchange.cs index 211249fcc..93ef1fa4a 100644 --- a/crypto/src/crypto/tls/TlsDHKeyExchange.cs +++ b/crypto/src/crypto/tls/TlsDHKeyExchange.cs @@ -81,6 +81,7 @@ namespace Org.BouncyCastle.Crypto.Tls try { this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey((DHPublicKeyParameters)this.mServerPublicKey); + this.mDHParameters = ValidateDHParameters(mDHAgreePublicKey.Parameters); } catch (InvalidCastException e) { @@ -171,8 +172,12 @@ namespace Org.BouncyCastle.Crypto.Tls public override void ProcessClientCertificate(Certificate clientCertificate) { - // TODO Extract the public key - // TODO If the certificate is 'fixed', take the public key as dhAgreeClientPublicKey + // TODO Extract the public key and validate + + /* + * TODO If the certificate is 'fixed', take the public key as dhAgreePublicKey and check + * that the parameters match the server's (see 'areCompatibleParameters'). + */ } public override void ProcessClientKeyExchange(Stream input) @@ -202,5 +207,18 @@ namespace Org.BouncyCastle.Crypto.Tls throw new TlsFatalAlert(AlertDescription.internal_error); } + + protected virtual int MinimumPrimeBits + { + get { return 1024; } + } + + protected virtual DHParameters ValidateDHParameters(DHParameters parameters) + { + if (parameters.P.BitLength < MinimumPrimeBits) + throw new TlsFatalAlert(AlertDescription.insufficient_security); + + return TlsDHUtilities.ValidateDHParameters(parameters); + } } } diff --git a/crypto/src/crypto/tls/TlsDHUtilities.cs b/crypto/src/crypto/tls/TlsDHUtilities.cs index b29f75e30..727587135 100644 --- a/crypto/src/crypto/tls/TlsDHUtilities.cs +++ b/crypto/src/crypto/tls/TlsDHUtilities.cs @@ -435,26 +435,28 @@ namespace Org.BouncyCastle.Crypto.Tls return (DHPrivateKeyParameters)kp.Private; } - - public static DHPublicKeyParameters ValidateDHPublicKey(DHPublicKeyParameters key) + + public static DHParameters ValidateDHParameters(DHParameters parameters) { - BigInteger Y = key.Y; - DHParameters parameters = key.Parameters; BigInteger p = parameters.P; BigInteger g = parameters.G; if (!p.IsProbablePrime(2)) - { throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } if (g.CompareTo(Two) < 0 || g.CompareTo(p.Subtract(Two)) > 0) - { throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } - if (Y.CompareTo(Two) < 0 || Y.CompareTo(p.Subtract(Two)) > 0) - { + + + return parameters; + } + + public static DHPublicKeyParameters ValidateDHPublicKey(DHPublicKeyParameters key) + { + DHParameters parameters = ValidateDHParameters(key.Parameters); + + BigInteger Y = key.Y; + if (Y.CompareTo(Two) < 0 || Y.CompareTo(parameters.P.Subtract(Two)) > 0) throw new TlsFatalAlert(AlertDescription.illegal_parameter); - } // TODO See RFC 2631 for more discussion of Diffie-Hellman validation diff --git a/crypto/src/crypto/tls/TlsDheKeyExchange.cs b/crypto/src/crypto/tls/TlsDheKeyExchange.cs index 419d4e442..9831e8cd7 100644 --- a/crypto/src/crypto/tls/TlsDheKeyExchange.cs +++ b/crypto/src/crypto/tls/TlsDheKeyExchange.cs @@ -79,7 +79,7 @@ namespace Org.BouncyCastle.Crypto.Tls throw new TlsFatalAlert(AlertDescription.decrypt_error); this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(dhParams.PublicKey); - this.mDHParameters = mDHAgreePublicKey.Parameters; + this.mDHParameters = ValidateDHParameters(mDHAgreePublicKey.Parameters); } protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, |