diff options
author | David Hook <dgh@cryptoworkshop.com> | 2014-01-06 13:46:51 +0400 |
---|---|---|
committer | David Hook <dgh@cryptoworkshop.com> | 2014-01-06 13:46:51 +0400 |
commit | 8b361e6c9ebcdbbd53f3ffcf9b9e76b3c1eb0fbf (patch) | |
tree | 6a02567d2abd06e39fdbbf7e7875002d36c0e0fa /core | |
parent | 09d5054567b98654949a14a4a42f3a2ddb16eff8 (diff) |
Further work on custom curve support.
Initial work on RFC 5581
Diffstat (limited to 'core')
6 files changed, 103 insertions, 15 deletions
diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java b/core/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java index eeae0dea..2206a331 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java +++ b/core/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java @@ -44,6 +44,35 @@ public class ECNamedCurveTable } /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static ASN1ObjectIdentifier getOID( + String name) + { + ASN1ObjectIdentifier oid = X962NamedCurves.getOID(name); + + if (oid == null) + { + oid = SECNamedCurves.getOID(name); + } + + if (oid == null) + { + oid = TeleTrusTNamedCurves.getOID(name); + } + + if (oid == null) + { + oid = NISTNamedCurves.getOID(name); + } + + return oid; + } + + /** * return a X9ECParameters object representing the passed in named * curve. * diff --git a/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java new file mode 100644 index 00000000..6350806f --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java @@ -0,0 +1,35 @@ +package org.bouncycastle.crypto.params; + +import java.math.BigInteger; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.math.ec.ECPoint; + +public class ECNamedDomainParameters + extends ECDomainParameters +{ + private final ASN1ObjectIdentifier name; + + public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECCurve curve, ECPoint G, BigInteger n) + { + this(name, curve, G, n, null, null); + } + + public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECCurve curve, ECPoint G, BigInteger n, BigInteger h) + { + this(name, curve, G, n, h, null); + } + + public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECCurve curve, ECPoint G, BigInteger n, BigInteger h, byte[] seed) + { + super(curve, G, n, h, seed); + + this.name = name; + } + + public ASN1ObjectIdentifier getName() + { + return name; + } +} diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java index 6bf3399b..9e342ff9 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java @@ -23,12 +23,14 @@ import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.crypto.ec.CustomNamedCurves; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECNamedDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; @@ -124,24 +126,30 @@ public class PrivateKeyFactory X962Parameters params = new X962Parameters((ASN1Primitive)algId.getParameters()); X9ECParameters x9; + ECDomainParameters dParams; + if (params.isNamedCurve()) { - ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); - x9 = ECNamedCurveTable.getByOID(oid); + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); + + x9 = CustomNamedCurves.getByOID(oid); + if (x9 == null) + { + x9 = ECNamedCurveTable.getByOID(oid); + } + dParams = new ECNamedDomainParameters( + oid, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); } else { x9 = X9ECParameters.getInstance(params.getParameters()); + dParams = new ECDomainParameters( + x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); } ECPrivateKey ec = ECPrivateKey.getInstance(keyInfo.parsePrivateKey()); BigInteger d = ec.getKey(); - // TODO We lose any named parameters here - - ECDomainParameters dParams = new ECDomainParameters( - x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); - return new ECPrivateKeyParameters(d, dParams); } else diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java index 7b06c3fe..9f791f4c 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java @@ -18,6 +18,7 @@ import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECNamedDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; @@ -55,11 +56,14 @@ public class PrivateKeyInfoFactory ECDomainParameters domainParams = priv.getParameters(); ASN1Encodable params; - // TODO: need to handle named curves if (domainParams == null) { params = new X962Parameters(DERNull.INSTANCE); // Implicitly CA } + else if (domainParams instanceof ECNamedDomainParameters) + { + params = new X962Parameters(((ECNamedDomainParameters)domainParams).getName()); + } else { X9ECParameters ecP = new X9ECParameters( diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java index 2d2927b9..b52d9bc0 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java @@ -29,6 +29,7 @@ import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECPoint; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.crypto.ec.CustomNamedCurves; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; @@ -36,6 +37,7 @@ import org.bouncycastle.crypto.params.DHValidationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECNamedDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; @@ -160,24 +162,30 @@ public class PublicKeyFactory X962Parameters params = X962Parameters.getInstance(algId.getParameters()); X9ECParameters x9; + ECDomainParameters dParams; + if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); - x9 = ECNamedCurveTable.getByOID(oid); + + x9 = CustomNamedCurves.getByOID(oid); + if (x9 == null) + { + x9 = ECNamedCurveTable.getByOID(oid); + } + dParams = new ECNamedDomainParameters( + oid, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); } else { x9 = X9ECParameters.getInstance(params.getParameters()); + dParams = new ECDomainParameters( + x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); } ASN1OctetString key = new DEROctetString(keyInfo.getPublicKeyData().getBytes()); X9ECPoint derQ = new X9ECPoint(x9.getCurve(), key); - // TODO We lose any named parameters here - - ECDomainParameters dParams = new ECDomainParameters( - x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); - return new ECPublicKeyParameters(derQ.getPoint(), dParams); } else diff --git a/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java index bdc6cbd1..d2d42037 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java @@ -17,6 +17,7 @@ import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECNamedDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; @@ -52,11 +53,14 @@ public class SubjectPublicKeyInfoFactory ECDomainParameters domainParams = pub.getParameters(); ASN1Encodable params; - // TODO: need to handle named curves if (domainParams == null) { params = new X962Parameters(DERNull.INSTANCE); // Implicitly CA } + else if (domainParams instanceof ECNamedDomainParameters) + { + params = new X962Parameters(((ECNamedDomainParameters)domainParams).getName()); + } else { X9ECParameters ecP = new X9ECParameters( |