1package org.bouncycastle.crypto.util;
2
3import org.bouncycastle.asn1.ASN1InputStream;
4import org.bouncycastle.asn1.ASN1Object;
5import org.bouncycastle.asn1.ASN1Sequence;
6import org.bouncycastle.asn1.DEREncodable;
7import org.bouncycastle.asn1.DERInteger;
8import org.bouncycastle.asn1.DERObject;
9import org.bouncycastle.asn1.DERObjectIdentifier;
10// BEGIN android-removed
11// import org.bouncycastle.asn1.nist.NISTNamedCurves;
12// import org.bouncycastle.asn1.oiw.ElGamalParameter;
13// END android-removed
14import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
15import org.bouncycastle.asn1.pkcs.DHParameter;
16import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
17import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
18import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
19// BEGIN android-removed
20// import org.bouncycastle.asn1.sec.ECPrivateKeyStructure;
21// import org.bouncycastle.asn1.sec.SECNamedCurves;
22// import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
23// END android-removed
24import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
25import org.bouncycastle.asn1.x509.DSAParameter;
26// BEGIN android-removed
27// import org.bouncycastle.asn1.x9.X962NamedCurves;
28// import org.bouncycastle.asn1.x9.X962Parameters;
29// import org.bouncycastle.asn1.x9.X9ECParameters;
30// import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
31// END android-removed
32import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
33import org.bouncycastle.crypto.params.DHParameters;
34import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
35import org.bouncycastle.crypto.params.DSAParameters;
36import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
37// BEGIN android-removed
38// import org.bouncycastle.crypto.params.ECDomainParameters;
39// import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
40// import org.bouncycastle.crypto.params.ElGamalParameters;
41// import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters;
42// END android-removed
43import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
44
45import java.io.IOException;
46import java.io.InputStream;
47import java.math.BigInteger;
48
49/**
50 * Factory for creating private key objects from PKCS8 PrivateKeyInfo objects.
51 */
52public class PrivateKeyFactory
53{
54    /**
55     * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding.
56     *
57     * @param privateKeyInfoData the PrivateKeyInfo encoding
58     * @return a suitable private key parameter
59     * @throws IOException on an error decoding the key
60     */
61    public static AsymmetricKeyParameter createKey(
62        byte[] privateKeyInfoData)
63        throws IOException
64    {
65        return createKey(
66            PrivateKeyInfo.getInstance(
67                ASN1Object.fromByteArray(privateKeyInfoData)));
68    }
69
70    /**
71     * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding read from a stream.
72     *
73     * @param inStr the stream to read the PrivateKeyInfo encoding from
74     * @return a suitable private key parameter
75     * @throws IOException on an error decoding the key
76     */
77    public static AsymmetricKeyParameter createKey(
78        InputStream inStr)
79        throws IOException
80    {
81        return createKey(
82            PrivateKeyInfo.getInstance(
83                new ASN1InputStream(inStr).readObject()));
84    }
85
86    /**
87     * Create a private key parameter from the passed in PKCS8 PrivateKeyInfo object.
88     *
89     * @param keyInfo the PrivateKeyInfo object containing the key material
90     * @return a suitable private key parameter
91     * @throws IOException on an error decoding the key
92     */
93    public static AsymmetricKeyParameter createKey(
94        PrivateKeyInfo    keyInfo)
95        throws IOException
96    {
97        AlgorithmIdentifier     algId = keyInfo.getAlgorithmId();
98
99        if (algId.getObjectId().equals(PKCSObjectIdentifiers.rsaEncryption))
100        {
101            RSAPrivateKeyStructure  keyStructure = new RSAPrivateKeyStructure((ASN1Sequence)keyInfo.getPrivateKey());
102
103            return new RSAPrivateCrtKeyParameters(
104                                        keyStructure.getModulus(),
105                                        keyStructure.getPublicExponent(),
106                                        keyStructure.getPrivateExponent(),
107                                        keyStructure.getPrime1(),
108                                        keyStructure.getPrime2(),
109                                        keyStructure.getExponent1(),
110                                        keyStructure.getExponent2(),
111                                        keyStructure.getCoefficient());
112        }
113        else if (algId.getObjectId().equals(PKCSObjectIdentifiers.dhKeyAgreement))
114        {
115            DHParameter     params = new DHParameter((ASN1Sequence)keyInfo.getAlgorithmId().getParameters());
116            DERInteger      derX = (DERInteger)keyInfo.getPrivateKey();
117
118            BigInteger lVal = params.getL();
119            int l = lVal == null ? 0 : lVal.intValue();
120            DHParameters dhParams = new DHParameters(params.getP(), params.getG(), null, l);
121
122            return new DHPrivateKeyParameters(derX.getValue(), dhParams);
123        }
124        // BEGIN android-removed
125        // else if (algId.getObjectId().equals(OIWObjectIdentifiers.elGamalAlgorithm))
126        // {
127        //     ElGamalParameter    params = new ElGamalParameter((ASN1Sequence)keyInfo.getAlgorithmId().getParameters());
128        //     DERInteger          derX = (DERInteger)keyInfo.getPrivateKey();
129        //
130        //     return new ElGamalPrivateKeyParameters(derX.getValue(), new ElGamalParameters(params.getP(), params.getG()));
131        // }
132        // else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_dsa))
133        // {
134        //     DERInteger derX = (DERInteger)keyInfo.getPrivateKey();
135        //     DEREncodable de = keyInfo.getAlgorithmId().getParameters();
136        //
137        //     DSAParameters parameters = null;
138        //     if (de != null)
139        //     {
140        //         DSAParameter params = DSAParameter.getInstance(de.getDERObject());
141        //         parameters = new DSAParameters(params.getP(), params.getQ(), params.getG());
142        //     }
143        //
144        //     return new DSAPrivateKeyParameters(derX.getValue(), parameters);
145        // }
146        // else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_ecPublicKey))
147        // {
148        //     X962Parameters      params = new X962Parameters((DERObject)keyInfo.getAlgorithmId().getParameters());
149        //     ECDomainParameters  dParams = null;
150        //
151        //     if (params.isNamedCurve())
152        //     {
153        //         DERObjectIdentifier oid = (DERObjectIdentifier)params.getParameters();
154        //         X9ECParameters      ecP = X962NamedCurves.getByOID(oid);
155        //
156        //         if (ecP == null)
157        //         {
158        //             ecP = SECNamedCurves.getByOID(oid);
159        //
160        //             if (ecP == null)
161        //             {
162        //                 ecP = NISTNamedCurves.getByOID(oid);
163        //
164        //                 if (ecP == null)
165        //                 {
166        //                     ecP = TeleTrusTNamedCurves.getByOID(oid);
167        //                 }
168        //             }
169        //         }
170        //
171        //         dParams = new ECDomainParameters(
172        //                                     ecP.getCurve(),
173        //                                     ecP.getG(),
174        //                                     ecP.getN(),
175        //                                     ecP.getH(),
176        //                                     ecP.getSeed());
177        //     }
178        //     else
179        //     {
180        //         X9ECParameters ecP = new X9ECParameters(
181        //                     (ASN1Sequence)params.getParameters());
182        //         dParams = new ECDomainParameters(
183        //                                     ecP.getCurve(),
184        //                                     ecP.getG(),
185        //                                     ecP.getN(),
186        //                                     ecP.getH(),
187        //                                     ecP.getSeed());
188        //     }
189        //
190        //     ECPrivateKeyStructure   ec = new ECPrivateKeyStructure((ASN1Sequence)keyInfo.getPrivateKey());
191        //
192        //     return new ECPrivateKeyParameters(ec.getKey(), dParams);
193        // }
194        // END android-removed
195        else
196        {
197            throw new RuntimeException("algorithm identifier in key not recognised");
198        }
199    }
200}
201