diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-11-13 22:19:11 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-11-13 22:19:11 +0700 |
commit | cc75817fb374917300d90da724e62598fd065f31 (patch) | |
tree | f8d64cb7142a4ea25dfb5e042c8a8fccb2c7b0d3 | |
parent | Merge branch 'master' of git.bouncycastle.org:bc-csharp into pcl (diff) | |
parent | Update ECPrivateKeyStructure following Java API (diff) | |
download | BouncyCastle.NET-ed25519-cc75817fb374917300d90da724e62598fd065f31.tar.xz |
Merge branch 'master' of git.bouncycastle.org:bc-csharp into pcl
-rw-r--r-- | crypto/src/asn1/cms/OriginatorPublicKey.cs | 23 | ||||
-rw-r--r-- | crypto/src/asn1/pkcs/PrivateKeyInfo.cs | 4 | ||||
-rw-r--r-- | crypto/src/asn1/sec/ECPrivateKeyStructure.cs | 58 | ||||
-rw-r--r-- | crypto/src/crypto/tls/ServerName.cs | 5 | ||||
-rw-r--r-- | crypto/src/openssl/PEMReader.cs | 2 | ||||
-rw-r--r-- | crypto/src/pkcs/PrivateKeyInfoFactory.cs | 33 | ||||
-rw-r--r-- | crypto/src/security/PrivateKeyFactory.cs | 15 | ||||
-rw-r--r-- | crypto/test/src/asn1/test/X9Test.cs | 22 |
8 files changed, 110 insertions, 52 deletions
diff --git a/crypto/src/asn1/cms/OriginatorPublicKey.cs b/crypto/src/asn1/cms/OriginatorPublicKey.cs index aabaf4386..988841aa5 100644 --- a/crypto/src/asn1/cms/OriginatorPublicKey.cs +++ b/crypto/src/asn1/cms/OriginatorPublicKey.cs @@ -8,22 +8,23 @@ namespace Org.BouncyCastle.Asn1.Cms public class OriginatorPublicKey : Asn1Encodable { - private AlgorithmIdentifier algorithm; - private DerBitString publicKey; + private readonly AlgorithmIdentifier mAlgorithm; + private readonly DerBitString mPublicKey; - public OriginatorPublicKey( + public OriginatorPublicKey( AlgorithmIdentifier algorithm, byte[] publicKey) { - this.algorithm = algorithm; - this.publicKey = new DerBitString(publicKey); + this.mAlgorithm = algorithm; + this.mPublicKey = new DerBitString(publicKey); } + [Obsolete("Use 'GetInstance' instead")] public OriginatorPublicKey( Asn1Sequence seq) { - algorithm = AlgorithmIdentifier.GetInstance(seq[0]); - publicKey = (DerBitString) seq[1]; + this.mAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]); + this.mPublicKey = DerBitString.GetInstance(seq[1]); } /** @@ -55,19 +56,19 @@ namespace Org.BouncyCastle.Asn1.Cms return (OriginatorPublicKey)obj; if (obj is Asn1Sequence) - return new OriginatorPublicKey((Asn1Sequence) obj); + return new OriginatorPublicKey(Asn1Sequence.GetInstance(obj)); throw new ArgumentException("Invalid OriginatorPublicKey: " + obj.GetType().Name); } public AlgorithmIdentifier Algorithm { - get { return algorithm; } + get { return mAlgorithm; } } public DerBitString PublicKey { - get { return publicKey; } + get { return mPublicKey; } } /** @@ -81,7 +82,7 @@ namespace Org.BouncyCastle.Asn1.Cms */ public override Asn1Object ToAsn1Object() { - return new DerSequence(algorithm, publicKey); + return new DerSequence(mAlgorithm, mPublicKey); } } } diff --git a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs index 404277ba6..c5be7a315 100644 --- a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs +++ b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs @@ -29,14 +29,14 @@ namespace Org.BouncyCastle.Asn1.Pkcs return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj)); } - public PrivateKeyInfo(AlgorithmIdentifier algID, Asn1Object privateKey) + public PrivateKeyInfo(AlgorithmIdentifier algID, Asn1Encodable privateKey) : this(algID, privateKey, null) { } public PrivateKeyInfo( AlgorithmIdentifier algID, - Asn1Object privateKey, + Asn1Encodable privateKey, Asn1Set attributes) { this.algID = algID; diff --git a/crypto/src/asn1/sec/ECPrivateKeyStructure.cs b/crypto/src/asn1/sec/ECPrivateKeyStructure.cs index 8d805fa30..32e020c0b 100644 --- a/crypto/src/asn1/sec/ECPrivateKeyStructure.cs +++ b/crypto/src/asn1/sec/ECPrivateKeyStructure.cs @@ -23,6 +23,7 @@ namespace Org.BouncyCastle.Asn1.Sec return new ECPrivateKeyStructure(Asn1Sequence.GetInstance(obj)); } + [Obsolete("Use 'GetInstance' instead")] public ECPrivateKeyStructure( Asn1Sequence seq) { @@ -32,6 +33,7 @@ namespace Org.BouncyCastle.Asn1.Sec this.seq = seq; } + [Obsolete("Use constructor which takes 'orderBitLength' instead, to guarantee correct encoding")] public ECPrivateKeyStructure( BigInteger key) { @@ -44,12 +46,30 @@ namespace Org.BouncyCastle.Asn1.Sec } public ECPrivateKeyStructure( + int orderBitLength, + BigInteger key) + { + if (key == null) + throw new ArgumentNullException("key"); + if (orderBitLength < key.BitLength) + throw new ArgumentException("must be >= key bitlength", "orderBitLength"); + + byte[] bytes = BigIntegers.AsUnsignedByteArray((orderBitLength + 7) / 8, key); + + this.seq = new DerSequence( + new DerInteger(1), + new DerOctetString(bytes)); + } + + [Obsolete("Use constructor which takes 'orderBitLength' instead, to guarantee correct encoding")] + public ECPrivateKeyStructure( BigInteger key, Asn1Encodable parameters) : this(key, null, parameters) { } + [Obsolete("Use constructor which takes 'orderBitLength' instead, to guarantee correct encoding")] public ECPrivateKeyStructure( BigInteger key, DerBitString publicKey, @@ -75,6 +95,44 @@ namespace Org.BouncyCastle.Asn1.Sec this.seq = new DerSequence(v); } + public ECPrivateKeyStructure( + int orderBitLength, + BigInteger key, + Asn1Encodable parameters) + : this(orderBitLength, key, null, parameters) + { + } + + public ECPrivateKeyStructure( + int orderBitLength, + BigInteger key, + DerBitString publicKey, + Asn1Encodable parameters) + { + if (key == null) + throw new ArgumentNullException("key"); + if (orderBitLength < key.BitLength) + throw new ArgumentException("must be >= key bitlength", "orderBitLength"); + + byte[] bytes = BigIntegers.AsUnsignedByteArray((orderBitLength + 7) / 8, key); + + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger(1), + new DerOctetString(bytes)); + + if (parameters != null) + { + v.Add(new DerTaggedObject(true, 0, parameters)); + } + + if (publicKey != null) + { + v.Add(new DerTaggedObject(true, 1, publicKey)); + } + + this.seq = new DerSequence(v); + } + public virtual BigInteger GetKey() { Asn1OctetString octs = (Asn1OctetString) seq[1]; diff --git a/crypto/src/crypto/tls/ServerName.cs b/crypto/src/crypto/tls/ServerName.cs index d42055b78..508c2ddbc 100644 --- a/crypto/src/crypto/tls/ServerName.cs +++ b/crypto/src/crypto/tls/ServerName.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Text; using Org.BouncyCastle.Utilities; @@ -52,7 +51,7 @@ namespace Org.BouncyCastle.Crypto.Tls switch (mNameType) { case Tls.NameType.host_name: - byte[] asciiEncoding = Encoding.ASCII.GetBytes((string)mName); + byte[] asciiEncoding = Strings.ToAsciiByteArray((string)mName); if (asciiEncoding.Length < 1) throw new TlsFatalAlert(AlertDescription.internal_error); TlsUtilities.WriteOpaque16(asciiEncoding, output); @@ -82,7 +81,7 @@ namespace Org.BouncyCastle.Crypto.Tls byte[] asciiEncoding = TlsUtilities.ReadOpaque16(input); if (asciiEncoding.Length < 1) throw new TlsFatalAlert(AlertDescription.decode_error); - name = Encoding.ASCII.GetString(asciiEncoding); + name = Strings.FromAsciiByteArray(asciiEncoding); break; } default: diff --git a/crypto/src/openssl/PEMReader.cs b/crypto/src/openssl/PEMReader.cs index 987f4471c..9a5f99b1a 100644 --- a/crypto/src/openssl/PEMReader.cs +++ b/crypto/src/openssl/PEMReader.cs @@ -311,7 +311,7 @@ namespace Org.BouncyCastle.OpenSsl case "EC": { - ECPrivateKeyStructure pKey = new ECPrivateKeyStructure(seq); + ECPrivateKeyStructure pKey = ECPrivateKeyStructure.GetInstance(seq); AlgorithmIdentifier algId = new AlgorithmIdentifier( X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters()); diff --git a/crypto/src/pkcs/PrivateKeyInfoFactory.cs b/crypto/src/pkcs/PrivateKeyInfoFactory.cs index c6aab4884..aafc4c292 100644 --- a/crypto/src/pkcs/PrivateKeyInfoFactory.cs +++ b/crypto/src/pkcs/PrivateKeyInfoFactory.cs @@ -106,49 +106,46 @@ namespace Org.BouncyCastle.Pkcs if (key is ECPrivateKeyParameters) { - ECPrivateKeyParameters _key = (ECPrivateKeyParameters)key; + ECPrivateKeyParameters priv = (ECPrivateKeyParameters)key; + ECDomainParameters dp = priv.Parameters; + int orderBitLength = dp.N.BitLength; + AlgorithmIdentifier algID; ECPrivateKeyStructure ec; - if (_key.AlgorithmName == "ECGOST3410") + if (priv.AlgorithmName == "ECGOST3410") { - if (_key.PublicKeyParamSet == null) + if (priv.PublicKeyParamSet == null) throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( - _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); + priv.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); - algID = new AlgorithmIdentifier( - CryptoProObjectIdentifiers.GostR3410x2001, - gostParams.ToAsn1Object()); + algID = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x2001, gostParams); // TODO Do we need to pass any parameters here? - ec = new ECPrivateKeyStructure(_key.D); + ec = new ECPrivateKeyStructure(orderBitLength, priv.D); } else { X962Parameters x962; - if (_key.PublicKeyParamSet == null) + if (priv.PublicKeyParamSet == null) { - ECDomainParameters kp = _key.Parameters; - X9ECParameters ecP = new X9ECParameters(kp.Curve, kp.G, kp.N, kp.H, kp.GetSeed()); - + X9ECParameters ecP = new X9ECParameters(dp.Curve, dp.G, dp.N, dp.H, dp.GetSeed()); x962 = new X962Parameters(ecP); } else { - x962 = new X962Parameters(_key.PublicKeyParamSet); + x962 = new X962Parameters(priv.PublicKeyParamSet); } - Asn1Object x962Object = x962.ToAsn1Object(); - // TODO Possible to pass the publicKey bitstring here? - ec = new ECPrivateKeyStructure(_key.D, x962Object); + ec = new ECPrivateKeyStructure(orderBitLength, priv.D, x962); - algID = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, x962Object); + algID = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, x962); } - return new PrivateKeyInfo(algID, ec.ToAsn1Object()); + return new PrivateKeyInfo(algID, ec); } if (key is Gost3410PrivateKeyParameters) diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs index b9538b33d..8c2ecfdb0 100644 --- a/crypto/src/security/PrivateKeyFactory.cs +++ b/crypto/src/security/PrivateKeyFactory.cs @@ -117,8 +117,7 @@ namespace Org.BouncyCastle.Security x9 = new X9ECParameters((Asn1Sequence)para.Parameters); } - ECPrivateKeyStructure ec = new ECPrivateKeyStructure( - Asn1Sequence.GetInstance(keyInfo.ParsePrivateKey())); + ECPrivateKeyStructure ec = ECPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey()); BigInteger d = ec.GetKey(); if (para.IsNamedCurve) @@ -134,24 +133,24 @@ namespace Org.BouncyCastle.Security Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object())); + ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet); + + if (ecP == null) + throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key"); + Asn1Object privKey = keyInfo.ParsePrivateKey(); ECPrivateKeyStructure ec; if (privKey is DerInteger) { // TODO Do we need to pass any parameters here? - ec = new ECPrivateKeyStructure(((DerInteger)privKey).Value); + ec = new ECPrivateKeyStructure(ecP.N.BitLength, ((DerInteger)privKey).Value); } else { ec = ECPrivateKeyStructure.GetInstance(privKey); } - ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet); - - if (ecP == null) - throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key"); - return new ECPrivateKeyParameters("ECGOST3410", ec.GetKey(), gostParams.PublicKeyParamSet); } else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94)) diff --git a/crypto/test/src/asn1/test/X9Test.cs b/crypto/test/src/asn1/test/X9Test.cs index e310811ea..db2541f7c 100644 --- a/crypto/test/src/asn1/test/X9Test.cs +++ b/crypto/test/src/asn1/test/X9Test.cs @@ -27,13 +27,13 @@ namespace Org.BouncyCastle.Asn1.Tests + "yUmqLG2UhT0OZgu/hUsclQX+laAh5///////////////9///+XXetBs6YFfDxDIUZSZVECAQED" + "IAADG5xRI+Iki/JrvL20hoDUa7Cggzorv5B9yyqSMjYu"); - private static readonly byte[] namedPriv = Base64.Decode("MCICAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQEECDAGAgEBBAEK"); + private static readonly byte[] namedPriv = Base64.Decode("MDkCAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQEEHzAdAgEBBBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo="); private static readonly byte[] expPriv = Base64.Decode( - "MIHnAgEAMIHXBgcqhkjOPQIBMIHLAgEBMCkGByqGSM49AQECHn///////////////3///////4" - + "AAAAAAAH///////zBXBB5///////////////9///////+AAAAAAAB///////wEHiVXBfoqMGZU" - + "sfTLA9anUKMMJQEC1JiHF9m6FattPgMVAH1zdBaP/jRxtgqFdoahlHXTv6L/BB8DZ2iujhi7ks" - + "/PAFyUmqLG2UhT0OZgu/hUsclQX+laAh5///////////////9///+XXetBs6YFfDxDIUZSZVEC" - + "AQEECDAGAgEBBAEU"); + "MIIBBAIBADCB1wYHKoZIzj0CATCBywIBATApBgcqhkjOPQEBAh5///////////////9///////" + + "+AAAAAAAB///////8wVwQef///////////////f///////gAAAAAAAf//////8BB4lVwX6KjBmVL" + + "H0ywPWp1CjDCUBAtSYhxfZuhWrbT4DFQB9c3QWj/40cbYKhXaGoZR107+i/wQfA2doro4Yu5LPzw" + + "BclJqixtlIU9DmYLv4VLHJUF/pWgIef///////////////f///l13rQbOmBXw8QyFGUmVRAgEBBC" + + "UwIwIBAQQeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU"); private void EncodePublicKey() { @@ -99,14 +99,15 @@ namespace Org.BouncyCastle.Asn1.Tests private void EncodePrivateKey() { - X9ECParameters ecP = X962NamedCurves.GetByOid(X9ObjectIdentifiers.Prime239v3); + X9ECParameters ecP = X962NamedCurves.GetByOid(X9ObjectIdentifiers.Prime192v1); // // named curve // X962Parameters _params = new X962Parameters(X9ObjectIdentifiers.Prime192v1); - PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, _params), new ECPrivateKeyStructure(BigInteger.Ten).ToAsn1Object()); + PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, _params), + new ECPrivateKeyStructure(ecP.N.BitLength, BigInteger.Ten).ToAsn1Object()); if (!Arrays.AreEqual(info.GetEncoded(), namedPriv)) { @@ -123,9 +124,12 @@ namespace Org.BouncyCastle.Asn1.Tests // // explicit curve parameters // + ecP = X962NamedCurves.GetByOid(X9ObjectIdentifiers.Prime239v3); + _params = new X962Parameters(ecP); - info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, _params), new ECPrivateKeyStructure(BigInteger.ValueOf(20)).ToAsn1Object()); + info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, _params), + new ECPrivateKeyStructure(ecP.N.BitLength, BigInteger.ValueOf(20)).ToAsn1Object()); if (!Arrays.AreEqual(info.GetEncoded(), expPriv)) { |