PrivateKeyFactory.java revision 5db505e1f6a68c8d5dfdb0fed0b8607dea7bed96
1package org.bouncycastle.crypto.util;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.math.BigInteger;
6
7import org.bouncycastle.asn1.ASN1Encodable;
8import org.bouncycastle.asn1.ASN1InputStream;
9import org.bouncycastle.asn1.ASN1Integer;
10import org.bouncycastle.asn1.ASN1ObjectIdentifier;
11import org.bouncycastle.asn1.ASN1Primitive;
12import org.bouncycastle.asn1.ASN1Sequence;
13// BEGIN android-removed
14// import org.bouncycastle.asn1.oiw.ElGamalParameter;
15// END android-removed
16import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
17import org.bouncycastle.asn1.pkcs.DHParameter;
18import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
19import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
20import org.bouncycastle.asn1.pkcs.RSAPrivateKey;
21import org.bouncycastle.asn1.sec.ECPrivateKey;
22import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
23import org.bouncycastle.asn1.x509.DSAParameter;
24import org.bouncycastle.asn1.x9.ECNamedCurveTable;
25import org.bouncycastle.asn1.x9.X962Parameters;
26import org.bouncycastle.asn1.x9.X9ECParameters;
27import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
28import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
29import org.bouncycastle.crypto.params.DHParameters;
30import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
31import org.bouncycastle.crypto.params.DSAParameters;
32import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
33import org.bouncycastle.crypto.params.ECDomainParameters;
34import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
35// BEGIN android-removed
36// import org.bouncycastle.crypto.params.ElGamalParameters;
37// import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters;
38// END android-removed
39import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
40
41/**
42 * Factory for creating private key objects from PKCS8 PrivateKeyInfo objects.
43 */
44public class PrivateKeyFactory
45{
46    /**
47     * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding.
48     *
49     * @param privateKeyInfoData the PrivateKeyInfo encoding
50     * @return a suitable private key parameter
51     * @throws IOException on an error decoding the key
52     */
53    public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData) throws IOException
54    {
55        return createKey(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privateKeyInfoData)));
56    }
57
58    /**
59     * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding read from a
60     * stream.
61     *
62     * @param inStr the stream to read the PrivateKeyInfo encoding from
63     * @return a suitable private key parameter
64     * @throws IOException on an error decoding the key
65     */
66    public static AsymmetricKeyParameter createKey(InputStream inStr) throws IOException
67    {
68        return createKey(PrivateKeyInfo.getInstance(new ASN1InputStream(inStr).readObject()));
69    }
70
71    /**
72     * Create a private key parameter from the passed in PKCS8 PrivateKeyInfo object.
73     *
74     * @param keyInfo the PrivateKeyInfo object containing the key material
75     * @return a suitable private key parameter
76     * @throws IOException on an error decoding the key
77     */
78    public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) throws IOException
79    {
80        AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm();
81
82        if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
83        {
84            RSAPrivateKey keyStructure = RSAPrivateKey.getInstance(keyInfo.parsePrivateKey());
85
86            return new RSAPrivateCrtKeyParameters(keyStructure.getModulus(),
87                keyStructure.getPublicExponent(), keyStructure.getPrivateExponent(),
88                keyStructure.getPrime1(), keyStructure.getPrime2(), keyStructure.getExponent1(),
89                keyStructure.getExponent2(), keyStructure.getCoefficient());
90        }
91        // TODO?
92//      else if (algId.getObjectId().equals(X9ObjectIdentifiers.dhpublicnumber))
93        else if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.dhKeyAgreement))
94        {
95            DHParameter params = DHParameter.getInstance(algId.getParameters());
96            ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
97
98            BigInteger lVal = params.getL();
99            int l = lVal == null ? 0 : lVal.intValue();
100            DHParameters dhParams = new DHParameters(params.getP(), params.getG(), null, l);
101
102            return new DHPrivateKeyParameters(derX.getValue(), dhParams);
103        }
104        // BEGIN android-removed
105        // else if (algId.getAlgorithm().equals(OIWObjectIdentifiers.elGamalAlgorithm))
106        // {
107        //     ElGamalParameter params = new ElGamalParameter((ASN1Sequence)algId.getParameters());
108        //     ASN1Integer = (ASN1Integer)keyInfo.parsePrivateKey();
109        //
110        //     return new ElGamalPrivateKeyParameters(derX.getValue(), new ElGamalParameters(
111        //         params.getP(), params.getG()));
112        // }
113        // END android-removed
114        else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_dsa))
115        {
116            ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey();
117            ASN1Encodable de = algId.getParameters();
118
119            DSAParameters parameters = null;
120            if (de != null)
121            {
122                DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive());
123                parameters = new DSAParameters(params.getP(), params.getQ(), params.getG());
124            }
125
126            return new DSAPrivateKeyParameters(derX.getValue(), parameters);
127        }
128        else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_ecPublicKey))
129        {
130            X962Parameters params = new X962Parameters((ASN1Primitive)algId.getParameters());
131
132            X9ECParameters x9;
133            if (params.isNamedCurve())
134            {
135                ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
136                x9 = ECNamedCurveTable.getByOID(oid);
137            }
138            else
139            {
140                x9 = X9ECParameters.getInstance(params.getParameters());
141            }
142
143            ECPrivateKey ec = ECPrivateKey.getInstance(keyInfo.parsePrivateKey());
144            BigInteger d = ec.getKey();
145
146            // TODO We lose any named parameters here
147
148            ECDomainParameters dParams = new ECDomainParameters(
149                    x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
150
151            return new ECPrivateKeyParameters(d, dParams);
152        }
153        else
154        {
155            throw new RuntimeException("algorithm identifier in key not recognised");
156        }
157    }
158}
159