Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost')
-rw-r--r--prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey.java359
-rw-r--r--prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.java454
-rw-r--r--prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/KeyFactorySpi.java128
-rw-r--r--prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/KeyPairGeneratorSpi.java144
-rw-r--r--prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java219
5 files changed, 1304 insertions, 0 deletions
diff --git a/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey.java b/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey.java
new file mode 100644
index 00000000..d322a172
--- /dev/null
+++ b/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey.java
@@ -0,0 +1,359 @@
+package org.spongycastle.jcajce.provider.asymmetric.ecgost;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.sec.ECPrivateKeyStructure;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X962Parameters;
+import org.spongycastle.asn1.x9.X9ECParameters;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.crypto.params.ECDomainParameters;
+import org.spongycastle.crypto.params.ECPrivateKeyParameters;
+import org.spongycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.spongycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import org.spongycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import org.spongycastle.jce.interfaces.ECPointEncoder;
+import org.spongycastle.jce.interfaces.ECPrivateKey;
+import org.spongycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.jce.spec.ECNamedCurveParameterSpec;
+import org.spongycastle.jce.spec.ECParameterSpec;
+import org.spongycastle.jce.spec.ECPrivateKeySpec;
+import org.spongycastle.math.ec.ECCurve;
+import org.spongycastle.math.ec.ECPoint;
+
+public class BCECGOST3410PrivateKey
+ implements ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder
+{
+ private String algorithm = "ECGOST3410";
+ private boolean withCompression;
+
+ private transient BigInteger d;
+ private transient ECParameterSpec ecSpec;
+ private transient DERBitString publicKey;
+ private transient PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl();
+
+ protected BCECGOST3410PrivateKey()
+ {
+ }
+
+ BCECGOST3410PrivateKey(
+ ECPrivateKey key)
+ {
+ this.d = key.getD();
+ this.algorithm = key.getAlgorithm();
+ this.ecSpec = key.getParameters();
+ }
+
+ public BCECGOST3410PrivateKey(
+ ECPrivateKeySpec spec)
+ {
+ this.d = spec.getD();
+ this.ecSpec = spec.getParams();
+ }
+
+ public BCECGOST3410PrivateKey(
+ String algorithm,
+ ECPrivateKeyParameters params,
+ BCECGOST3410PublicKey pubKey,
+ ECParameterSpec spec)
+ {
+ ECDomainParameters dp = params.getParameters();
+
+ this.algorithm = algorithm;
+ this.d = params.getD();
+
+ if (spec == null)
+ {
+ this.ecSpec = new ECParameterSpec(
+ dp.getCurve(),
+ dp.getG(),
+ dp.getN(),
+ dp.getH(),
+ dp.getSeed());
+ }
+ else
+ {
+ this.ecSpec = spec;
+ }
+
+ publicKey = getPublicKeyDetails(pubKey);
+ }
+
+ public BCECGOST3410PrivateKey(
+ String algorithm,
+ ECPrivateKeyParameters params)
+ {
+ this.algorithm = algorithm;
+ this.d = params.getD();
+ this.ecSpec = null;
+ }
+
+ public BCECGOST3410PrivateKey(
+ String algorithm,
+ BCECGOST3410PrivateKey key)
+ {
+ this.algorithm = algorithm;
+ this.d = key.d;
+ this.ecSpec = key.ecSpec;
+ this.withCompression = key.withCompression;
+ this.publicKey = key.publicKey;
+ this.attrCarrier = key.attrCarrier;
+ }
+
+ BCECGOST3410PrivateKey(
+ PrivateKeyInfo info)
+ {
+ populateFromPrivKeyInfo(info);
+ }
+
+ private void populateFromPrivKeyInfo(PrivateKeyInfo info)
+ {
+ X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters());
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
+ ECDomainParameters ecP = ECGOST3410NamedCurves.getByOID(oid);
+
+ ecSpec = new ECNamedCurveParameterSpec(
+ ECUtil.getCurveName(oid),
+ ecP.getCurve(),
+ ecP.getG(),
+ ecP.getN(),
+ ecP.getH(),
+ ecP.getSeed());
+ }
+ else if (params.isImplicitlyCA())
+ {
+ ecSpec = null;
+ }
+ else
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+ ecSpec = new ECParameterSpec(ecP.getCurve(),
+ ecP.getG(),
+ ecP.getN(),
+ ecP.getH(),
+ ecP.getSeed());
+ }
+
+ if (info.getPrivateKey() instanceof ASN1Integer)
+ {
+ ASN1Integer derD = ASN1Integer.getInstance(info.getPrivateKey());
+
+ this.d = derD.getValue();
+ }
+ else
+ {
+ ECPrivateKeyStructure ec = new ECPrivateKeyStructure((ASN1Sequence)info.getPrivateKey());
+
+ this.d = ec.getKey();
+ this.publicKey = ec.getPublicKey();
+ }
+ }
+
+ public String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ /**
+ * return the encoding format we produce in getEncoded().
+ *
+ * @return the string "PKCS#8"
+ */
+ public String getFormat()
+ {
+ return "PKCS#8";
+ }
+
+ /**
+ * Return a PKCS8 representation of the key. The sequence returned
+ * represents a full PrivateKeyInfo object.
+ *
+ * @return a PKCS8 representation of the key.
+ */
+ public byte[] getEncoded()
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ DEROutputStream dOut = new DEROutputStream(bOut);
+ X962Parameters params = null;
+
+ if (ecSpec instanceof ECNamedCurveParameterSpec)
+ {
+ ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveParameterSpec)ecSpec).getName());
+
+ params = new X962Parameters(curveOid);
+ }
+ else if (ecSpec == null)
+ {
+ params = new X962Parameters(DERNull.INSTANCE);
+ }
+ else
+ {
+ ECParameterSpec p = (ECParameterSpec)ecSpec;
+
+ ECPoint pG = p.getG().normalize();
+ ECPoint g = pG.getCurve().createPoint(pG.getAffineXCoord().toBigInteger(), pG.getAffineYCoord().toBigInteger());
+
+ X9ECParameters ecP = new X9ECParameters(
+ p.getCurve(),
+ g,
+ p.getN(),
+ p.getH(),
+ p.getSeed());
+
+ params = new X962Parameters(ecP);
+ }
+
+ PrivateKeyInfo info;
+ ECPrivateKeyStructure keyStructure;
+
+ if (publicKey != null)
+ {
+ keyStructure = new ECPrivateKeyStructure(this.getD(), publicKey, params);
+ }
+ else
+ {
+ keyStructure = new ECPrivateKeyStructure(this.getD(), params);
+ }
+
+ try
+ {
+ if (algorithm.equals("ECGOST3410"))
+ {
+ info = new PrivateKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params), keyStructure);
+ }
+ else
+ {
+ info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure);
+ }
+
+ return KeyUtil.getEncodedPrivateKeyInfo(info);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return (ECParameterSpec)ecSpec;
+ }
+
+ public ECParameterSpec getParameters()
+ {
+ return (ECParameterSpec)ecSpec;
+ }
+
+ public BigInteger getD()
+ {
+ return d;
+ }
+
+ public void setBagAttribute(
+ ASN1ObjectIdentifier oid,
+ ASN1Encodable attribute)
+ {
+ attrCarrier.setBagAttribute(oid, attribute);
+ }
+
+ public ASN1Encodable getBagAttribute(
+ ASN1ObjectIdentifier oid)
+ {
+ return attrCarrier.getBagAttribute(oid);
+ }
+
+ public Enumeration getBagAttributeKeys()
+ {
+ return attrCarrier.getBagAttributeKeys();
+ }
+
+ public void setPointFormat(String style)
+ {
+ withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ }
+
+ ECParameterSpec engineGetSpec()
+ {
+ if (ecSpec != null)
+ {
+ return ecSpec;
+ }
+
+ return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof BCECGOST3410PrivateKey))
+ {
+ return false;
+ }
+
+ BCECGOST3410PrivateKey other = (BCECGOST3410PrivateKey)o;
+
+ return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec()));
+ }
+
+ public int hashCode()
+ {
+ return getD().hashCode() ^ engineGetSpec().hashCode();
+ }
+
+ private DERBitString getPublicKeyDetails(BCECGOST3410PublicKey pub)
+ {
+ try
+ {
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded()));
+
+ return info.getPublicKeyData();
+ }
+ catch (IOException e)
+ { // should never happen
+ return null;
+ }
+ }
+
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ byte[] enc = (byte[])in.readObject();
+
+ populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
+
+ this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeObject(this.getEncoded());
+ }
+}
diff --git a/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.java b/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.java
new file mode 100644
index 00000000..75e6e115
--- /dev/null
+++ b/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey.java
@@ -0,0 +1,454 @@
+package org.spongycastle.jcajce.provider.asymmetric.ecgost;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+import org.spongycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X962Parameters;
+import org.spongycastle.asn1.x9.X9ECParameters;
+import org.spongycastle.asn1.x9.X9ECPoint;
+import org.spongycastle.asn1.x9.X9IntegerConverter;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.crypto.params.ECDomainParameters;
+import org.spongycastle.crypto.params.ECPublicKeyParameters;
+import org.spongycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.spongycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import org.spongycastle.jce.ECGOST3410NamedCurveTable;
+import org.spongycastle.jce.interfaces.ECPointEncoder;
+import org.spongycastle.jce.interfaces.ECPublicKey;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.jce.spec.ECNamedCurveParameterSpec;
+import org.spongycastle.jce.spec.ECParameterSpec;
+import org.spongycastle.jce.spec.ECPublicKeySpec;
+import org.spongycastle.math.ec.ECCurve;
+import org.spongycastle.math.ec.ECPoint;
+
+public class BCECGOST3410PublicKey
+ implements ECPublicKey, ECPointEncoder
+{
+ private String algorithm = "ECGOST3410";
+ private boolean withCompression;
+
+ private transient org.spongycastle.math.ec.ECPoint q;
+ private transient ECParameterSpec ecSpec;
+ private transient GOST3410PublicKeyAlgParameters gostParams;
+
+ public BCECGOST3410PublicKey(
+ String algorithm,
+ BCECGOST3410PublicKey key)
+ {
+ this.algorithm = algorithm;
+ this.q = key.q;
+ this.ecSpec = key.ecSpec;
+ this.withCompression = key.withCompression;
+ this.gostParams = key.gostParams;
+ }
+
+ public BCECGOST3410PublicKey(
+ ECPublicKeySpec spec)
+ {
+ this.q = spec.getQ();
+
+ if (spec.getParams() != null)
+ {
+ this.ecSpec = spec.getParams();
+ }
+ else
+ {
+ if (q.getCurve() == null)
+ {
+ org.spongycastle.jce.spec.ECParameterSpec s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+
+ q = s.getCurve().createPoint(q.getX().toBigInteger(), q.getY().toBigInteger(), false);
+ }
+ this.ecSpec = null;
+ }
+ }
+
+ public BCECGOST3410PublicKey(
+ String algorithm,
+ ECPublicKeyParameters params,
+ ECParameterSpec spec)
+ {
+ ECDomainParameters dp = params.getParameters();
+
+ this.algorithm = algorithm;
+ this.q = params.getQ();
+
+ if (spec == null)
+ {
+ this.ecSpec = new ECParameterSpec(
+ dp.getCurve(),
+ dp.getG(),
+ dp.getN(),
+ dp.getH(),
+ dp.getSeed());
+ }
+ else
+ {
+ this.ecSpec = spec;
+ }
+ }
+
+ public BCECGOST3410PublicKey(
+ String algorithm,
+ ECPublicKeyParameters params)
+ {
+ this.algorithm = algorithm;
+ this.q = params.getQ();
+ this.ecSpec = null;
+ }
+
+ BCECGOST3410PublicKey(
+ ECPublicKey key)
+ {
+ this.q = key.getQ();
+ this.algorithm = key.getAlgorithm();
+ this.ecSpec = key.getParameters();
+ }
+
+ BCECGOST3410PublicKey(
+ String algorithm,
+ ECPoint q,
+ ECParameterSpec ecSpec)
+ {
+ this.algorithm = algorithm;
+ this.q = q;
+ this.ecSpec = ecSpec;
+ }
+
+ BCECGOST3410PublicKey(
+ SubjectPublicKeyInfo info)
+ {
+ populateFromPubKeyInfo(info);
+ }
+
+ private void populateFromPubKeyInfo(SubjectPublicKeyInfo info)
+ {
+ if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001))
+ {
+ DERBitString bits = info.getPublicKeyData();
+ ASN1OctetString key;
+ this.algorithm = "ECGOST3410";
+
+ try
+ {
+ key = (ASN1OctetString)ASN1Primitive.fromByteArray(bits.getBytes());
+ }
+ catch (IOException ex)
+ {
+ throw new IllegalArgumentException("error recovering public key");
+ }
+
+ byte[] keyEnc = key.getOctets();
+ byte[] x = new byte[32];
+ byte[] y = new byte[32];
+
+ for (int i = 0; i != x.length; i++)
+ {
+ x[i] = keyEnc[32 - 1 - i];
+ }
+
+ for (int i = 0; i != y.length; i++)
+ {
+ y[i] = keyEnc[64 - 1 - i];
+ }
+
+ gostParams = new GOST3410PublicKeyAlgParameters((ASN1Sequence)info.getAlgorithmId().getParameters());
+
+ ECNamedCurveParameterSpec spec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(gostParams.getPublicKeyParamSet()));
+
+ ecSpec = spec;
+
+ this.q = spec.getCurve().createPoint(new BigInteger(1, x), new BigInteger(1, y), false);
+ }
+ else
+ {
+ X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters());
+ ECCurve curve;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
+ X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+
+ ecSpec = new ECNamedCurveParameterSpec(
+ ECUtil.getCurveName(oid),
+ ecP.getCurve(),
+ ecP.getG(),
+ ecP.getN(),
+ ecP.getH(),
+ ecP.getSeed());
+ curve = ((ECParameterSpec)ecSpec).getCurve();
+ }
+ else if (params.isImplicitlyCA())
+ {
+ ecSpec = null;
+ curve = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve();
+ }
+ else
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+ ecSpec = new ECParameterSpec(
+ ecP.getCurve(),
+ ecP.getG(),
+ ecP.getN(),
+ ecP.getH(),
+ ecP.getSeed());
+ curve = ((ECParameterSpec)ecSpec).getCurve();
+ }
+
+ DERBitString bits = info.getPublicKeyData();
+ byte[] data = bits.getBytes();
+ ASN1OctetString key = new DEROctetString(data);
+
+ //
+ // extra octet string - one of our old certs...
+ //
+ if (data[0] == 0x04 && data[1] == data.length - 2
+ && (data[2] == 0x02 || data[2] == 0x03))
+ {
+ int qLength = new X9IntegerConverter().getByteLength(curve);
+
+ if (qLength >= data.length - 3)
+ {
+ try
+ {
+ key = (ASN1OctetString)ASN1Primitive.fromByteArray(data);
+ }
+ catch (IOException ex)
+ {
+ throw new IllegalArgumentException("error recovering public key");
+ }
+ }
+ }
+
+ X9ECPoint derQ = new X9ECPoint(curve, key);
+
+ this.q = derQ.getPoint();
+ }
+ }
+
+ public String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public String getFormat()
+ {
+ return "X.509";
+ }
+
+ public byte[] getEncoded()
+ {
+ SubjectPublicKeyInfo info;
+
+ if (algorithm.equals("ECGOST3410"))
+ {
+ ASN1Encodable params = null;
+ if (gostParams != null)
+ {
+ params = gostParams;
+ }
+ else if (ecSpec instanceof ECNamedCurveParameterSpec)
+ {
+ params = new GOST3410PublicKeyAlgParameters(
+ ECGOST3410NamedCurves.getOID(((ECNamedCurveParameterSpec)ecSpec).getName()),
+ CryptoProObjectIdentifiers.gostR3411_94_CryptoProParamSet);
+ }
+ else
+ {
+ ECParameterSpec p = (ECParameterSpec)ecSpec;
+
+ ECCurve curve = p.getG().getCurve();
+ ECPoint generator = curve.createPoint(p.getG().getX().toBigInteger(), p.getG().getY().toBigInteger(), withCompression);
+
+ X9ECParameters ecP = new X9ECParameters(
+ p.getCurve(), generator, p.getN(), p.getH(), p.getSeed());
+
+ params = new X962Parameters(ecP);
+ }
+
+ ECPoint qq = this.getQ();
+ ECPoint point = qq.getCurve().createPoint(qq.getX().toBigInteger(), qq.getY().toBigInteger(), false);
+ ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(point));
+
+ BigInteger bX = this.q.getX().toBigInteger();
+ BigInteger bY = this.q.getY().toBigInteger();
+ byte[] encKey = new byte[64];
+
+ byte[] val = bX.toByteArray();
+
+ for (int i = 0; i != 32; i++)
+ {
+ encKey[i] = val[val.length - 1 - i];
+ }
+
+ val = bY.toByteArray();
+
+ for (int i = 0; i != 32; i++)
+ {
+ encKey[32 + i] = val[val.length - 1 - i];
+ }
+
+ try
+ {
+ info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params), new DEROctetString(encKey));
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+ else
+ {
+ X962Parameters params = null;
+ if (ecSpec instanceof ECNamedCurveParameterSpec)
+ {
+ ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveParameterSpec)ecSpec).getName());
+
+ if (curveOid == null)
+ {
+ curveOid = new ASN1ObjectIdentifier(((ECNamedCurveParameterSpec)ecSpec).getName());
+ }
+ params = new X962Parameters(curveOid);
+ }
+ else if (ecSpec == null)
+ {
+ params = new X962Parameters(DERNull.INSTANCE);
+ }
+ else
+ {
+ ECParameterSpec p = (ECParameterSpec)ecSpec;
+
+ ECCurve curve = p.getG().getCurve();
+ ECPoint generator = curve.createPoint(p.getG().getX().toBigInteger(), p.getG().getY().toBigInteger(), withCompression);
+
+ X9ECParameters ecP = new X9ECParameters(
+ p.getCurve(), generator, p.getN(), p.getH(), p.getSeed());
+
+ params = new X962Parameters(ecP);
+ }
+
+ ECCurve curve = this.engineGetQ().getCurve();
+ ECPoint point = curve.createPoint(this.getQ().getX().toBigInteger(), this.getQ().getY().toBigInteger(), withCompression);
+ ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(point));
+
+ info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets());
+ }
+
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return (ECParameterSpec)ecSpec;
+ }
+
+ public ECParameterSpec getParameters()
+ {
+ return (ECParameterSpec)ecSpec;
+ }
+
+ public org.spongycastle.math.ec.ECPoint getQ()
+ {
+ if (ecSpec == null)
+ {
+ if (q instanceof org.spongycastle.math.ec.ECPoint.Fp)
+ {
+ return new org.spongycastle.math.ec.ECPoint.Fp(null, q.getX(), q.getY());
+ }
+ else
+ {
+ return new org.spongycastle.math.ec.ECPoint.F2m(null, q.getX(), q.getY());
+ }
+ }
+
+ return q;
+ }
+
+ public org.spongycastle.math.ec.ECPoint engineGetQ()
+ {
+ return q;
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ String nl = System.getProperty("line.separator");
+
+ buf.append("EC Public Key").append(nl);
+ buf.append(" X: ").append(this.getQ().getX().toBigInteger().toString(16)).append(nl);
+ buf.append(" Y: ").append(this.getQ().getY().toBigInteger().toString(16)).append(nl);
+
+ return buf.toString();
+
+ }
+
+ public void setPointFormat(String style)
+ {
+ withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
+ }
+
+ ECParameterSpec engineGetSpec()
+ {
+ if (ecSpec != null)
+ {
+ return (ECParameterSpec)ecSpec;
+ }
+
+ return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof BCECGOST3410PublicKey))
+ {
+ return false;
+ }
+
+ BCECGOST3410PublicKey other = (BCECGOST3410PublicKey)o;
+
+ return getQ().equals(other.getQ()) && (engineGetSpec().equals(other.engineGetSpec()));
+ }
+
+ public int hashCode()
+ {
+ return getQ().hashCode() ^ engineGetSpec().hashCode();
+ }
+
+ private void readObject(
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ byte[] enc = (byte[])in.readObject();
+
+ populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeObject(this.getEncoded());
+ }
+}
diff --git a/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/KeyFactorySpi.java b/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/KeyFactorySpi.java
new file mode 100644
index 00000000..36847af2
--- /dev/null
+++ b/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/KeyFactorySpi.java
@@ -0,0 +1,128 @@
+package org.spongycastle.jcajce.provider.asymmetric.ecgost;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import org.spongycastle.jce.interfaces.ECPrivateKey;
+import org.spongycastle.jce.interfaces.ECPublicKey;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.jce.spec.ECParameterSpec;
+import org.spongycastle.jce.spec.ECPrivateKeySpec;
+import org.spongycastle.jce.spec.ECPublicKeySpec;
+
+public class KeyFactorySpi
+ extends BaseKeyFactorySpi
+{
+ public KeyFactorySpi()
+ {
+ }
+
+ protected KeySpec engineGetKeySpec(
+ Key key,
+ Class spec)
+ throws InvalidKeySpecException
+ {
+ if (spec.isAssignableFrom(org.spongycastle.jce.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey)
+ {
+ ECPublicKey k = (ECPublicKey)key;
+ if (k.getParams() != null)
+ {
+ return new org.spongycastle.jce.spec.ECPublicKeySpec(k.getQ(), k.getParameters());
+ }
+ else
+ {
+ ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+
+ return new org.spongycastle.jce.spec.ECPublicKeySpec(k.getQ(), implicitSpec);
+ }
+ }
+ else if (spec.isAssignableFrom(org.spongycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey)
+ {
+ ECPrivateKey k = (ECPrivateKey)key;
+
+ if (k.getParams() != null)
+ {
+ return new org.spongycastle.jce.spec.ECPrivateKeySpec(k.getD(), k.getParameters());
+ }
+ else
+ {
+ ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+
+ return new org.spongycastle.jce.spec.ECPrivateKeySpec(k.getD(), implicitSpec);
+ }
+ }
+
+ return super.engineGetKeySpec(key, spec);
+ }
+
+ protected Key engineTranslateKey(
+ Key key)
+ throws InvalidKeyException
+ {
+ throw new InvalidKeyException("key type unknown");
+ }
+
+ protected PrivateKey engineGeneratePrivate(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof ECPrivateKeySpec)
+ {
+ return new BCECGOST3410PrivateKey((ECPrivateKeySpec)keySpec);
+ }
+
+ return super.engineGeneratePrivate(keySpec);
+ }
+
+ protected PublicKey engineGeneratePublic(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof ECPublicKeySpec)
+ {
+ return new BCECGOST3410PublicKey((ECPublicKeySpec)keySpec);
+ }
+
+ return super.engineGeneratePublic(keySpec);
+ }
+
+ public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm();
+
+ if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001))
+ {
+ return new BCECGOST3410PrivateKey(keyInfo);
+ }
+ else
+ {
+ throw new IOException("algorithm identifier " + algOid + " in key not recognised");
+ }
+ }
+
+ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
+ throws IOException
+ {
+ ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm();
+
+ if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001))
+ {
+ return new BCECGOST3410PublicKey(keyInfo);
+ }
+ else
+ {
+ throw new IOException("algorithm identifier " + algOid + " in key not recognised");
+ }
+ }
+}
diff --git a/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/KeyPairGeneratorSpi.java b/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/KeyPairGeneratorSpi.java
new file mode 100644
index 00000000..f950260e
--- /dev/null
+++ b/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/KeyPairGeneratorSpi.java
@@ -0,0 +1,144 @@
+package org.spongycastle.jcajce.provider.asymmetric.ecgost;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.spongycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+import org.spongycastle.crypto.AsymmetricCipherKeyPair;
+import org.spongycastle.crypto.generators.ECKeyPairGenerator;
+import org.spongycastle.crypto.params.ECDomainParameters;
+import org.spongycastle.crypto.params.ECKeyGenerationParameters;
+import org.spongycastle.crypto.params.ECPrivateKeyParameters;
+import org.spongycastle.crypto.params.ECPublicKeyParameters;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.jce.spec.ECNamedCurveGenParameterSpec;
+import org.spongycastle.jce.spec.ECNamedCurveParameterSpec;
+import org.spongycastle.jce.spec.ECParameterSpec;
+
+public class KeyPairGeneratorSpi
+ extends java.security.KeyPairGenerator
+{
+ ECParameterSpec ecParams = null;
+ ECKeyPairGenerator engine = new ECKeyPairGenerator();
+
+ String algorithm = "ECGOST3410";
+ ECKeyGenerationParameters param;
+ int strength = 239;
+ SecureRandom random = null;
+ boolean initialised = false;
+
+ public KeyPairGeneratorSpi()
+ {
+ super("ECGOST3410");
+ }
+
+ public void initialize(
+ int strength,
+ SecureRandom random)
+ {
+ this.strength = strength;
+ this.random = random;
+
+ if (ecParams != null)
+ {
+ param = new ECKeyGenerationParameters(new ECDomainParameters(ecParams.getCurve(), ecParams.getG(), ecParams.getN()), random);
+
+ engine.init(param);
+ initialised = true;
+ }
+ else
+ {
+ throw new InvalidParameterException("unknown key size.");
+ }
+ }
+
+ public void initialize(
+ AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidAlgorithmParameterException
+ {
+ if (params instanceof ECParameterSpec)
+ {
+ ECParameterSpec p = (ECParameterSpec)params;
+ this.ecParams = p;
+
+ param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random);
+
+ engine.init(param);
+ initialised = true;
+ }
+ else if (params instanceof ECNamedCurveGenParameterSpec)
+ {
+ String curveName;
+
+ curveName = ((ECNamedCurveGenParameterSpec)params).getName();
+
+ ECDomainParameters ecP = ECGOST3410NamedCurves.getByName(curveName);
+ if (ecP == null)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
+ }
+
+ this.ecParams = new ECNamedCurveParameterSpec(
+ curveName,
+ ecP.getCurve(),
+ ecP.getG(),
+ ecP.getN(),
+ ecP.getH(),
+ ecP.getSeed());
+
+ param = new ECKeyGenerationParameters(new ECDomainParameters(ecParams.getCurve(), ecParams.getG(), ecParams.getN()), random);
+
+ engine.init(param);
+ initialised = true;
+ }
+ else if (params == null && BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa() != null)
+ {
+ ECParameterSpec p = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+ this.ecParams = null;
+
+ param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random);
+
+ engine.init(param);
+ initialised = true;
+ }
+ else if (params == null && BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa() == null)
+ {
+ throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set");
+ }
+ else
+ {
+ throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec: " + params.getClass().getName());
+ }
+ }
+
+ public KeyPair generateKeyPair()
+ {
+ if (!initialised)
+ {
+ throw new IllegalStateException("EC Key Pair Generator not initialised");
+ }
+
+ AsymmetricCipherKeyPair pair = engine.generateKeyPair();
+ ECPublicKeyParameters pub = (ECPublicKeyParameters)pair.getPublic();
+ ECPrivateKeyParameters priv = (ECPrivateKeyParameters)pair.getPrivate();
+
+ if (ecParams == null)
+ {
+ return new KeyPair(new BCECGOST3410PublicKey(algorithm, pub),
+ new BCECGOST3410PrivateKey(algorithm, priv));
+ }
+ else
+ {
+ ECParameterSpec p = (ECParameterSpec)ecParams;
+
+ BCECGOST3410PublicKey pubKey = new BCECGOST3410PublicKey(algorithm, pub, p);
+ return new KeyPair(pubKey,
+ new BCECGOST3410PrivateKey(algorithm, priv, pubKey, p));
+ }
+ }
+}
+
diff --git a/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java b/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java
new file mode 100644
index 00000000..c3660fb1
--- /dev/null
+++ b/prov/src/main/jdk1.4/org/spongycastle/jcajce/provider/asymmetric/ecgost/SignatureSpi.java
@@ -0,0 +1,219 @@
+package org.spongycastle.jcajce.provider.asymmetric.ecgost;
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.X509ObjectIdentifiers;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.DSA;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.digests.GOST3411Digest;
+import org.spongycastle.crypto.params.ParametersWithRandom;
+import org.spongycastle.crypto.signers.ECGOST3410Signer;
+import org.spongycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.spongycastle.jce.interfaces.ECKey;
+import org.spongycastle.jce.interfaces.ECPublicKey;
+import org.spongycastle.jce.interfaces.GOST3410Key;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.jcajce.provider.asymmetric.util.GOST3410Util;
+
+public class SignatureSpi
+ extends java.security.Signature
+ implements PKCSObjectIdentifiers, X509ObjectIdentifiers
+{
+ private Digest digest;
+ private DSA signer;
+
+ public SignatureSpi()
+ {
+ super("ECGOST3410");
+ this.digest = new GOST3411Digest();
+ this.signer = new ECGOST3410Signer();
+ }
+
+ protected void engineInitVerify(
+ PublicKey publicKey)
+ throws InvalidKeyException
+ {
+ CipherParameters param;
+
+ if (publicKey instanceof ECPublicKey)
+ {
+ param = ECUtil.generatePublicKeyParameter(publicKey);
+ }
+ else if (publicKey instanceof GOST3410Key)
+ {
+ param = GOST3410Util.generatePublicKeyParameter(publicKey);
+ }
+ else
+ {
+ try
+ {
+ byte[] bytes = publicKey.getEncoded();
+
+ publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes));
+
+ if (publicKey instanceof ECPublicKey)
+ {
+ param = ECUtil.generatePublicKeyParameter(publicKey);
+ }
+ else
+ {
+ throw new InvalidKeyException("can't recognise key type in DSA based signer");
+ }
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("can't recognise key type in DSA based signer");
+ }
+ }
+
+ digest.reset();
+ signer.init(false, param);
+ }
+
+ protected void engineInitSign(
+ PrivateKey privateKey)
+ throws InvalidKeyException
+ {
+ CipherParameters param;
+
+ if (privateKey instanceof ECKey)
+ {
+ param = ECUtil.generatePrivateKeyParameter(privateKey);
+ }
+ else
+ {
+ param = GOST3410Util.generatePrivateKeyParameter(privateKey);
+ }
+
+ digest.reset();
+
+ if (appRandom != null)
+ {
+ signer.init(true, new ParametersWithRandom(param, appRandom));
+ }
+ else
+ {
+ signer.init(true, param);
+ }
+ }
+
+ protected void engineUpdate(
+ byte b)
+ throws SignatureException
+ {
+ digest.update(b);
+ }
+
+ protected void engineUpdate(
+ byte[] b,
+ int off,
+ int len)
+ throws SignatureException
+ {
+ digest.update(b, off, len);
+ }
+
+ protected byte[] engineSign()
+ throws SignatureException
+ {
+ byte[] hash = new byte[digest.getDigestSize()];
+
+ digest.doFinal(hash, 0);
+
+ try
+ {
+ byte[] sigBytes = new byte[64];
+ BigInteger[] sig = signer.generateSignature(hash);
+ byte[] r = sig[0].toByteArray();
+ byte[] s = sig[1].toByteArray();
+
+ if (s[0] != 0)
+ {
+ System.arraycopy(s, 0, sigBytes, 32 - s.length, s.length);
+ }
+ else
+ {
+ System.arraycopy(s, 1, sigBytes, 32 - (s.length - 1), s.length - 1);
+ }
+
+ if (r[0] != 0)
+ {
+ System.arraycopy(r, 0, sigBytes, 64 - r.length, r.length);
+ }
+ else
+ {
+ System.arraycopy(r, 1, sigBytes, 64 - (r.length - 1), r.length - 1);
+ }
+
+ return sigBytes;
+ }
+ catch (Exception e)
+ {
+ throw new SignatureException(e.toString());
+ }
+ }
+
+ protected boolean engineVerify(
+ byte[] sigBytes)
+ throws SignatureException
+ {
+ byte[] hash = new byte[digest.getDigestSize()];
+
+ digest.doFinal(hash, 0);
+
+ BigInteger[] sig;
+
+ try
+ {
+ byte[] r = new byte[32];
+ byte[] s = new byte[32];
+
+ System.arraycopy(sigBytes, 0, s, 0, 32);
+
+ System.arraycopy(sigBytes, 32, r, 0, 32);
+
+ sig = new BigInteger[2];
+ sig[0] = new BigInteger(1, r);
+ sig[1] = new BigInteger(1, s);
+ }
+ catch (Exception e)
+ {
+ throw new SignatureException("error decoding signature bytes.");
+ }
+
+ return signer.verifySignature(hash, sig[0], sig[1]);
+ }
+
+ protected void engineSetParameter(
+ AlgorithmParameterSpec params)
+ {
+ throw new UnsupportedOperationException("engineSetParameter unsupported");
+ }
+
+ /**
+ * @deprecated replaced with <a href = "#engineSetParameter(java.security.spec.AlgorithmParameterSpec)">
+ */
+ protected void engineSetParameter(
+ String param,
+ Object value)
+ {
+ throw new UnsupportedOperationException("engineSetParameter unsupported");
+ }
+
+ /**
+ * @deprecated
+ */
+ protected Object engineGetParameter(
+ String param)
+ {
+ throw new UnsupportedOperationException("engineSetParameter unsupported");
+ }
+}