summaryrefslogtreecommitdiffstats
path: root/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec
diff options
context:
space:
mode:
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java52
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java169
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java145
4 files changed, 212 insertions, 170 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
index 0eaae1d..ac0ddf5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
@@ -34,6 +34,8 @@ import org.bouncycastle.jce.interfaces.ECPointEncoder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.custom.sec.SecP256K1Point;
+import org.bouncycastle.math.ec.custom.sec.SecP256R1Point;
public class BCECPublicKey
implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder
@@ -82,6 +84,8 @@ public class BCECPublicKey
ECCurve curve = spec.getParams().getCurve();
EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed());
+ // this may seem a little long-winded but it's how we pick up the custom curve.
+ this.q = EC5Util.convertCurve(ellipticCurve).createPoint(spec.getQ().getAffineXCoord().toBigInteger(), spec.getQ().getAffineYCoord().toBigInteger());
this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams());
}
else
@@ -132,7 +136,6 @@ public class BCECPublicKey
ECDomainParameters dp = params.getParameters();
this.algorithm = algorithm;
- this.q = params.getQ();
if (spec == null)
{
@@ -147,6 +150,8 @@ public class BCECPublicKey
this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec);
}
+ this.q = EC5Util.convertCurve(ecSpec.getCurve()).createPoint(params.getQ().getAffineXCoord().toBigInteger(), params.getQ().getAffineYCoord().toBigInteger());
+
this.configuration = configuration;
}
@@ -369,14 +374,7 @@ public class BCECPublicKey
{
if (ecSpec == null)
{
- if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp)
- {
- return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getAffineXCoord(), q.getAffineYCoord());
- }
- else
- {
- return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getAffineXCoord(), q.getAffineYCoord());
- }
+ return q.getDetachedPoint();
}
return q;
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
index ea36dfd..3dbe004 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
@@ -17,6 +17,7 @@ import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x9.X9IntegerConverter;
import org.bouncycastle.crypto.BasicAgreement;
@@ -30,6 +31,7 @@ import org.bouncycastle.crypto.agreement.ECDHBasicAgreement;
// import org.bouncycastle.crypto.agreement.kdf.ECDHKEKGenerator;
// END android-removed
import org.bouncycastle.crypto.digests.SHA1Digest;
+import org.bouncycastle.crypto.params.DESParameters;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
@@ -45,6 +47,7 @@ import org.bouncycastle.jce.interfaces.ECPublicKey;
// import org.bouncycastle.jce.interfaces.MQVPublicKey;
// END android-removed
import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Strings;
/**
* Diffie-Hellman key agreement using elliptic curve keys, ala IEEE P1363
@@ -57,9 +60,12 @@ public class KeyAgreementSpi
{
private static final X9IntegerConverter converter = new X9IntegerConverter();
private static final Hashtable algorithms = new Hashtable();
+ private static final Hashtable oids = new Hashtable();
+ private static final Hashtable des = new Hashtable();
static
{
+ Integer i64 = Integers.valueOf(64);
Integer i128 = Integers.valueOf(128);
Integer i192 = Integers.valueOf(192);
Integer i256 = Integers.valueOf(256);
@@ -71,6 +77,18 @@ public class KeyAgreementSpi
algorithms.put(NISTObjectIdentifiers.id_aes192_wrap.getId(), i192);
algorithms.put(NISTObjectIdentifiers.id_aes256_wrap.getId(), i256);
algorithms.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), i192);
+ algorithms.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), i192);
+ algorithms.put(OIWObjectIdentifiers.desCBC.getId(), i64);
+
+ oids.put("DESEDE", PKCSObjectIdentifiers.des_EDE3_CBC);
+ oids.put("AES", NISTObjectIdentifiers.id_aes256_CBC);
+ oids.put("DES", OIWObjectIdentifiers.desCBC);
+
+ des.put("DES", "DES");
+ des.put("DESEDE", "DES");
+ des.put(OIWObjectIdentifiers.desCBC.getId(), "DES");
+ des.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), "DES");
+ des.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), "DES");
}
private String kaAlgorithm;
@@ -84,7 +102,7 @@ public class KeyAgreementSpi
private byte[] bigIntToBytes(
BigInteger r)
{
- return converter.integerToBytes(r, converter.getByteLength(parameters.getG().getAffineXCoord()));
+ return converter.integerToBytes(r, converter.getByteLength(parameters.getCurve()));
}
protected KeyAgreementSpi(
@@ -189,18 +207,25 @@ public class KeyAgreementSpi
throws NoSuchAlgorithmException
{
byte[] secret = bigIntToBytes(result);
+ String algKey = Strings.toUpperCase(algorithm);
+ String oidAlgorithm = algorithm;
+
+ if (oids.containsKey(algKey))
+ {
+ oidAlgorithm = ((ASN1ObjectIdentifier)oids.get(algKey)).getId();
+ }
// BEGIN android-removed
// if (kdf != null)
// {
- // if (!algorithms.containsKey(algorithm))
+ // if (!algorithms.containsKey(oidAlgorithm))
// {
// throw new NoSuchAlgorithmException("unknown algorithm encountered: " + algorithm);
// }
//
- // int keySize = ((Integer)algorithms.get(algorithm)).intValue();
+ // int keySize = ((Integer)algorithms.get(oidAlgorithm)).intValue();
//
- // DHKDFParameters params = new DHKDFParameters(new ASN1ObjectIdentifier(algorithm), keySize, secret);
+ // DHKDFParameters params = new DHKDFParameters(new ASN1ObjectIdentifier(oidAlgorithm), keySize, secret);
//
// byte[] keyBytes = new byte[keySize / 8];
// kdf.init(params);
@@ -210,7 +235,21 @@ public class KeyAgreementSpi
// else
// END android-removed
{
- // TODO Should we be ensuring the key is the right length?
+ if (algorithms.containsKey(oidAlgorithm))
+ {
+ Integer length = (Integer)algorithms.get(oidAlgorithm);
+
+ byte[] key = new byte[length.intValue() / 8];
+
+ System.arraycopy(secret, 0, key, 0, key.length);
+
+ secret = key;
+ }
+ }
+
+ if (des.containsKey(oidAlgorithm))
+ {
+ DESParameters.setOddParity(secret);
}
return new SecretKeySpec(secret, algorithm);
@@ -222,12 +261,11 @@ public class KeyAgreementSpi
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
- // BEGIN android-added
if (params != null)
{
throw new InvalidAlgorithmParameterException("No algorithm parameters supported");
}
- // END android-added
+
initFromKey(key);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
index 42bb895..1239609 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
@@ -91,22 +91,20 @@ public abstract class KeyPairGeneratorSpi
// BEGIN android-added
}
// END android-added
+
ECGenParameterSpec ecParams = (ECGenParameterSpec)ecParameters.get(Integers.valueOf(strength));
+ if (ecParams == null)
+ {
+ throw new InvalidParameterException("unknown key size.");
+ }
- if (ecParams != null)
+ try
{
- try
- {
- initialize(ecParams, random);
- }
- catch (InvalidAlgorithmParameterException e)
- {
- throw new InvalidParameterException("key size not configurable.");
- }
+ initialize(ecParams, random);
}
- else
+ catch (InvalidAlgorithmParameterException e)
{
- throw new InvalidParameterException("unknown key size.");
+ throw new InvalidParameterException("key size not configurable.");
}
}
@@ -120,97 +118,42 @@ public abstract class KeyPairGeneratorSpi
random = this.random;
}
// END android-added
- if (params instanceof ECParameterSpec)
+ if (params == null)
{
- ECParameterSpec p = (ECParameterSpec)params;
- this.ecParams = params;
-
- param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random);
+ ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
+ if (implicitCA == null)
+ {
+ throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set");
+ }
- engine.init(param);
- initialised = true;
+ this.ecParams = null;
+ this.param = createKeyGenParamsBC(implicitCA, random);
}
- else if (params instanceof java.security.spec.ECParameterSpec)
+ else if (params instanceof ECParameterSpec)
{
- java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)params;
this.ecParams = params;
-
- ECCurve curve = EC5Util.convertCurve(p.getCurve());
- ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false);
-
- param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random);
-
- engine.init(param);
- initialised = true;
+ this.param = createKeyGenParamsBC((ECParameterSpec)params, random);
}
- else if (params instanceof ECGenParameterSpec || params instanceof ECNamedCurveGenParameterSpec)
+ else if (params instanceof java.security.spec.ECParameterSpec)
{
- String curveName;
-
- if (params instanceof ECGenParameterSpec)
- {
- curveName = ((ECGenParameterSpec)params).getName();
- }
- else
- {
- curveName = ((ECNamedCurveGenParameterSpec)params).getName();
- }
-
- X9ECParameters ecP = ECNamedCurveTable.getByName(curveName);
- if (ecP == null)
- {
- // See if it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug)
- try
- {
- ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(curveName);
- ecP = ECNamedCurveTable.getByOID(oid);
- if (ecP == null)
- {
- throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName);
- }
- }
- catch (IllegalArgumentException ex)
- {
- throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
- }
- }
-
- this.ecParams = new ECNamedCurveSpec(
- curveName,
- ecP.getCurve(),
- ecP.getG(),
- ecP.getN(),
- ecP.getH(),
- null); // ecP.getSeed()); Work-around JDK bug -- it won't look up named curves properly if seed is present
-
- java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams;
-
- ECCurve curve = EC5Util.convertCurve(p.getCurve());
- ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false);
-
- param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random);
-
- engine.init(param);
- initialised = true;
+ this.ecParams = params;
+ this.param = createKeyGenParamsJCE((java.security.spec.ECParameterSpec)params, random);
}
- else if (params == null && configuration.getEcImplicitlyCa() != null)
+ else if (params instanceof ECGenParameterSpec)
{
- ECParameterSpec p = configuration.getEcImplicitlyCa();
- this.ecParams = params;
-
- param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random);
-
- engine.init(param);
- initialised = true;
+ initializeNamedCurve(((ECGenParameterSpec)params).getName(), random);
}
- else if (params == null && configuration.getEcImplicitlyCa() == null)
+ else if (params instanceof ECNamedCurveGenParameterSpec)
{
- throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set");
+ initializeNamedCurve(((ECNamedCurveGenParameterSpec)params).getName(), random);
}
else
{
throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec");
}
+
+ engine.init(param);
+ initialised = true;
}
public KeyPair generateKeyPair()
@@ -246,6 +189,58 @@ public abstract class KeyPairGeneratorSpi
return new KeyPair(pubKey, new BCECPrivateKey(algorithm, priv, pubKey, p, configuration));
}
}
+
+ protected ECKeyGenerationParameters createKeyGenParamsBC(ECParameterSpec p, SecureRandom r)
+ {
+ return new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), r);
+ }
+
+ protected ECKeyGenerationParameters createKeyGenParamsJCE(java.security.spec.ECParameterSpec p, SecureRandom r)
+ {
+ ECCurve curve = EC5Util.convertCurve(p.getCurve());
+ ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false);
+ BigInteger n = p.getOrder();
+ BigInteger h = BigInteger.valueOf(p.getCofactor());
+ ECDomainParameters dp = new ECDomainParameters(curve, g, n, h);
+ return new ECKeyGenerationParameters(dp, r);
+ }
+
+ protected ECNamedCurveSpec createNamedCurveSpec(String curveName)
+ throws InvalidAlgorithmParameterException
+ {
+ // NOTE: Don't bother with custom curves here as the curve will be converted to JCE type shortly
+
+ X9ECParameters p = ECNamedCurveTable.getByName(curveName);
+ if (p == null)
+ {
+ try
+ {
+ // Check whether it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug)
+ p = ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(curveName));
+ if (p == null)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName);
+ }
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
+ }
+ }
+
+ // Work-around for JDK bug -- it won't look up named curves properly if seed is present
+ byte[] seed = null; //p.getSeed();
+
+ return new ECNamedCurveSpec(curveName, p.getCurve(), p.getG(), p.getN(), p.getH(), seed);
+ }
+
+ protected void initializeNamedCurve(String curveName, SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ ECNamedCurveSpec namedCurve = createNamedCurveSpec(curveName);
+ this.ecParams = namedCurve;
+ this.param = createKeyGenParamsJCE(namedCurve, random);
+ }
}
public static class ECDSA
@@ -283,4 +278,4 @@ public abstract class KeyPairGeneratorSpi
super("ECMQV", BouncyCastleProvider.CONFIGURATION);
}
}
-} \ No newline at end of file
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
index 3757229..26811d1 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
@@ -249,7 +249,7 @@ public class SignatureSpi
// {
// public ecCVCDSA()
// {
- // super(new SHA1Digest(), new ECDSASigner(), new CVCDSAEncoder());
+ // super(new SHA1Digest(), new ECDSASigner(), new PlainDSAEncoder());
// }
// }
//
@@ -258,7 +258,7 @@ public class SignatureSpi
// {
// public ecCVCDSA224()
// {
- // super(new SHA224Digest(), new ECDSASigner(), new CVCDSAEncoder());
+ // super(new SHA224Digest(), new ECDSASigner(), new PlainDSAEncoder());
// }
// }
//
@@ -267,7 +267,7 @@ public class SignatureSpi
// {
// public ecCVCDSA256()
// {
- // super(new SHA256Digest(), new ECDSASigner(), new CVCDSAEncoder());
+ // super(new SHA256Digest(), new ECDSASigner(), new PlainDSAEncoder());
// }
// }
//
@@ -276,7 +276,7 @@ public class SignatureSpi
// {
// public ecCVCDSA384()
// {
- // super(new SHA384Digest(), new ECDSASigner(), new CVCDSAEncoder());
+ // super(new SHA384Digest(), new ECDSASigner(), new PlainDSAEncoder());
// }
// }
//
@@ -285,7 +285,16 @@ public class SignatureSpi
// {
// public ecCVCDSA512()
// {
- // super(new SHA512Digest(), new ECDSASigner(), new CVCDSAEncoder());
+ // super(new SHA512Digest(), new ECDSASigner(), new PlainDSAEncoder());
+ // }
+ // }
+ //
+ // static public class ecPlainDSARP160
+ // extends SignatureSpi
+ // {
+ // public ecPlainDSARP160()
+ // {
+ // super(new RIPEMD160Digest(), new ECDSASigner(), new PlainDSAEncoder());
// }
// }
// END android-removed
@@ -320,66 +329,68 @@ public class SignatureSpi
}
}
- private static class CVCDSAEncoder
- implements DSAEncoder
- {
- public byte[] encode(
- BigInteger r,
- BigInteger s)
- throws IOException
- {
- byte[] first = makeUnsigned(r);
- byte[] second = makeUnsigned(s);
- byte[] res;
-
- if (first.length > second.length)
- {
- res = new byte[first.length * 2];
- }
- else
- {
- res = new byte[second.length * 2];
- }
-
- System.arraycopy(first, 0, res, res.length / 2 - first.length, first.length);
- System.arraycopy(second, 0, res, res.length - second.length, second.length);
-
- return res;
- }
-
-
- private byte[] makeUnsigned(BigInteger val)
- {
- byte[] res = val.toByteArray();
-
- if (res[0] == 0)
- {
- byte[] tmp = new byte[res.length - 1];
-
- System.arraycopy(res, 1, tmp, 0, tmp.length);
-
- return tmp;
- }
-
- return res;
- }
-
- public BigInteger[] decode(
- byte[] encoding)
- throws IOException
- {
- BigInteger[] sig = new BigInteger[2];
-
- byte[] first = new byte[encoding.length / 2];
- byte[] second = new byte[encoding.length / 2];
-
- System.arraycopy(encoding, 0, first, 0, first.length);
- System.arraycopy(encoding, first.length, second, 0, second.length);
-
- sig[0] = new BigInteger(1, first);
- sig[1] = new BigInteger(1, second);
-
- return sig;
- }
- }
+ // BEGIN android-removed
+ // private static class PlainDSAEncoder
+ // implements DSAEncoder
+ // {
+ // public byte[] encode(
+ // BigInteger r,
+ // BigInteger s)
+ // throws IOException
+ // {
+ // byte[] first = makeUnsigned(r);
+ // byte[] second = makeUnsigned(s);
+ // byte[] res;
+ //
+ // if (first.length > second.length)
+ // {
+ // res = new byte[first.length * 2];
+ // }
+ // else
+ // {
+ // res = new byte[second.length * 2];
+ // }
+ //
+ // System.arraycopy(first, 0, res, res.length / 2 - first.length, first.length);
+ // System.arraycopy(second, 0, res, res.length - second.length, second.length);
+ //
+ // return res;
+ // }
+ //
+ //
+ // private byte[] makeUnsigned(BigInteger val)
+ // {
+ // byte[] res = val.toByteArray();
+ //
+ // if (res[0] == 0)
+ // {
+ // byte[] tmp = new byte[res.length - 1];
+ //
+ // System.arraycopy(res, 1, tmp, 0, tmp.length);
+ //
+ // return tmp;
+ // }
+ //
+ // return res;
+ // }
+ //
+ // public BigInteger[] decode(
+ // byte[] encoding)
+ // throws IOException
+ // {
+ // BigInteger[] sig = new BigInteger[2];
+ //
+ // byte[] first = new byte[encoding.length / 2];
+ // byte[] second = new byte[encoding.length / 2];
+ //
+ // System.arraycopy(encoding, 0, first, 0, first.length);
+ // System.arraycopy(encoding, first.length, second, 0, second.length);
+ //
+ // sig[0] = new BigInteger(1, first);
+ // sig[1] = new BigInteger(1, second);
+ //
+ // return sig;
+ // }
+ // }
+ // END android-removed
}