PublicKeyFactory.java revision 5db505e1f6a68c8d5dfdb0fed0b8607dea7bed96
1524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wupackage org.bouncycastle.crypto.util;
2524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
3524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport java.io.IOException;
4524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport java.io.InputStream;
5524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport java.math.BigInteger;
6524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
7524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1Encodable;
8524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1InputStream;
9524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1Integer;
10524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1ObjectIdentifier;
11524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1OctetString;
12524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1Primitive;
13524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.ASN1Sequence;
14524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.DEROctetString;
15524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// BEGIN android-removed
16524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// import org.bouncycastle.asn1.oiw.ElGamalParameter;
17524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// END android-removed
18524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
19524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.pkcs.DHParameter;
20524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
21524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.pkcs.RSAPublicKey;
22524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x509.AlgorithmIdentifier;
23524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x509.DSAParameter;
24524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
25524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
26524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.DHDomainParameters;
27524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.DHPublicKey;
28524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.DHValidationParms;
29524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.ECNamedCurveTable;
30524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.X962Parameters;
31524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.X9ECParameters;
32524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.asn1.x9.X9ECPoint;
33d38afcd2f286e924e0f9b7f484712ac19e3f98fcChia-I Wuimport org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
34524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.AsymmetricKeyParameter;
35524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.DHParameters;
36524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.DHPublicKeyParameters;
37524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.DHValidationParameters;
38524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.DSAParameters;
39524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.DSAPublicKeyParameters;
40524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.ECDomainParameters;
41524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.ECPublicKeyParameters;
42524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// BEGIN android-removed
43524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// import org.bouncycastle.crypto.params.ElGamalParameters;
44524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters;
45524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu// END android-removed
46524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wuimport org.bouncycastle.crypto.params.RSAKeyParameters;
47524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
48524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu/**
49524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * Factory to create asymmetric public key parameters for asymmetric ciphers from range of
50524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu * ASN.1 encoded SubjectPublicKeyInfo objects.
51524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu */
52524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wupublic class PublicKeyFactory
53d38afcd2f286e924e0f9b7f484712ac19e3f98fcChia-I Wu{
54524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    /**
55524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     * Create a public key from a SubjectPublicKeyInfo encoding
56524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     *
57f141abdc8fdbff41e16b0ce53fa3fa8fba32a7f9Chia-I Wu     * @param keyInfoData the SubjectPublicKeyInfo encoding
58524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     * @return the appropriate key parameter
59f141abdc8fdbff41e16b0ce53fa3fa8fba32a7f9Chia-I Wu     * @throws IOException on an error decoding the key
60f141abdc8fdbff41e16b0ce53fa3fa8fba32a7f9Chia-I Wu     */
61524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    public static AsymmetricKeyParameter createKey(byte[] keyInfoData) throws IOException
62524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    {
63524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        return createKey(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(keyInfoData)));
64524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    }
65524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
66524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    /**
67524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     * Create a public key from a SubjectPublicKeyInfo encoding read from a stream
68524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     *
69524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     * @param inStr the stream to read the SubjectPublicKeyInfo encoding from
70524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     * @return the appropriate key parameter
71524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     * @throws IOException on an error decoding the key
72524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     */
73524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    public static AsymmetricKeyParameter createKey(InputStream inStr) throws IOException
74524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    {
75524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        return createKey(SubjectPublicKeyInfo.getInstance(new ASN1InputStream(inStr).readObject()));
76524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    }
77524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
78524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    /**
79524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     * Create a public key from the passed in SubjectPublicKeyInfo
80524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     *
81524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     * @param keyInfo the SubjectPublicKeyInfo containing the key data
82524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     * @return the appropriate key parameter
83f141abdc8fdbff41e16b0ce53fa3fa8fba32a7f9Chia-I Wu     * @throws IOException on an error decoding the key
84524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu     */
85524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) throws IOException
86524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    {
87524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        AlgorithmIdentifier algId = keyInfo.getAlgorithm();
88524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
89524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption)
90524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            || algId.getAlgorithm().equals(X509ObjectIdentifiers.id_ea_rsa))
91524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        {
92524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            RSAPublicKey pubKey = RSAPublicKey.getInstance(keyInfo.parsePublicKey());
93f141abdc8fdbff41e16b0ce53fa3fa8fba32a7f9Chia-I Wu
94524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            return new RSAKeyParameters(false, pubKey.getModulus(), pubKey.getPublicExponent());
95524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        }
96524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.dhpublicnumber))
97524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        {
98524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            DHPublicKey dhPublicKey = DHPublicKey.getInstance(keyInfo.parsePublicKey());
99524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
100524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            BigInteger y = dhPublicKey.getY().getValue();
101524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
102524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            DHDomainParameters dhParams = DHDomainParameters.getInstance(algId.getParameters());
103524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
104524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            BigInteger p = dhParams.getP().getValue();
105524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            BigInteger g = dhParams.getG().getValue();
106524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            BigInteger q = dhParams.getQ().getValue();
107524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
108524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            BigInteger j = null;
109524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            if (dhParams.getJ() != null)
110524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            {
111524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                j = dhParams.getJ().getValue();
112524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            }
113524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
114524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            DHValidationParameters validation = null;
115524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            DHValidationParms dhValidationParms = dhParams.getValidationParms();
116524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            if (dhValidationParms != null)
117524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            {
118524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                byte[] seed = dhValidationParms.getSeed().getBytes();
119524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                BigInteger pgenCounter = dhValidationParms.getPgenCounter().getValue();
120524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
121524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                // TODO Check pgenCounter size?
122524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
123524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                validation = new DHValidationParameters(seed, pgenCounter.intValue());
124524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            }
125524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
126524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            return new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation));
127524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        }
128524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        else if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.dhKeyAgreement))
129524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        {
130524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            DHParameter params = DHParameter.getInstance(algId.getParameters());
131524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey();
132524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
133524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            BigInteger lVal = params.getL();
134524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            int l = lVal == null ? 0 : lVal.intValue();
135524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            DHParameters dhParams = new DHParameters(params.getP(), params.getG(), null, l);
136524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
137524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            return new DHPublicKeyParameters(derY.getValue(), dhParams);
138524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        }
139524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        // BEGIN android-removed
140524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        // else if (algId.getAlgorithm().equals(OIWObjectIdentifiers.elGamalAlgorithm))
141524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        // {
142524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        //     ElGamalParameter params = new ElGamalParameter((ASN1Sequence)algId.getParameters());
143524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        //     ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey();
144524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        //
145524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        //     return new ElGamalPublicKeyParameters(derY.getValue(), new ElGamalParameters(
146524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        //         params.getP(), params.getG()));
147524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        // }
148524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        // END android-removed
149524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_dsa)
150524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            || algId.getAlgorithm().equals(OIWObjectIdentifiers.dsaWithSHA1))
151524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        {
152524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey();
153524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            ASN1Encodable de = algId.getParameters();
154524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
155524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            DSAParameters parameters = null;
156524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            if (de != null)
157524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            {
158524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive());
159524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                parameters = new DSAParameters(params.getP(), params.getQ(), params.getG());
160524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            }
161524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
162524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            return new DSAPublicKeyParameters(derY.getValue(), parameters);
163524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        }
164524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_ecPublicKey))
165524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        {
166524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            X962Parameters params = X962Parameters.getInstance(algId.getParameters());
167524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
168524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            X9ECParameters x9;
169524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            if (params.isNamedCurve())
170524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            {
171524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
172524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                x9 = ECNamedCurveTable.getByOID(oid);
173524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            }
174524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            else
175524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            {
176524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                x9 = X9ECParameters.getInstance(params.getParameters());
177524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            }
178524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
179524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            ASN1OctetString key = new DEROctetString(keyInfo.getPublicKeyData().getBytes());
180524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            X9ECPoint derQ = new X9ECPoint(x9.getCurve(), key);
181524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
182524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            // TODO We lose any named parameters here
183524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
184524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            ECDomainParameters dParams = new ECDomainParameters(
185524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu                    x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
186524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu
187524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            return new ECPublicKeyParameters(derQ.getPoint(), dParams);
188524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        }
189524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        else
190524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        {
191524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu            throw new RuntimeException("algorithm identifier in key not recognised");
192524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu        }
193524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu    }
194524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu}
195524b2626c2d018f330ae7423c858ef73ea0424b5Chia-I Wu