• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.jce;
2 
3 import java.io.IOException;
4 import java.security.AlgorithmParameters;
5 import java.security.GeneralSecurityException;
6 import java.security.InvalidKeyException;
7 import java.security.KeyFactory;
8 import java.security.NoSuchAlgorithmException;
9 import java.security.NoSuchProviderException;
10 import java.security.PrivateKey;
11 import java.security.PublicKey;
12 import java.security.Signature;
13 import java.security.SignatureException;
14 import java.security.spec.InvalidKeySpecException;
15 import java.security.spec.PSSParameterSpec;
16 import java.security.spec.X509EncodedKeySpec;
17 import java.util.HashSet;
18 import java.util.Hashtable;
19 import java.util.Set;
20 
21 import javax.security.auth.x500.X500Principal;
22 
23 import org.bouncycastle.asn1.ASN1Encodable;
24 import org.bouncycastle.asn1.ASN1Encoding;
25 import org.bouncycastle.asn1.ASN1InputStream;
26 import org.bouncycastle.asn1.ASN1Integer;
27 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
28 import org.bouncycastle.asn1.ASN1Primitive;
29 import org.bouncycastle.asn1.ASN1Sequence;
30 import org.bouncycastle.asn1.ASN1Set;
31 import org.bouncycastle.asn1.DERBitString;
32 import org.bouncycastle.asn1.DERNull;
33 // BEGIN android-removed
34 // import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
35 // END android-removed
36 import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
37 import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
38 import org.bouncycastle.asn1.pkcs.CertificationRequest;
39 import org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
40 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
41 import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
42 // BEGIN android-removed
43 // import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
44 // END android-removed
45 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
46 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
47 import org.bouncycastle.asn1.x509.X509Name;
48 import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
49 import org.bouncycastle.jce.provider.BouncyCastleProvider;
50 import org.bouncycastle.util.Strings;
51 
52 /**
53  * A class for verifying and creating PKCS10 Certification requests.
54  * <pre>
55  * CertificationRequest ::= SEQUENCE {
56  *   certificationRequestInfo  CertificationRequestInfo,
57  *   signatureAlgorithm        AlgorithmIdentifier{{ SignatureAlgorithms }},
58  *   signature                 BIT STRING
59  * }
60  *
61  * CertificationRequestInfo ::= SEQUENCE {
62  *   version             INTEGER { v1(0) } (v1,...),
63  *   subject             Name,
64  *   subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
65  *   attributes          [0] Attributes{{ CRIAttributes }}
66  *  }
67  *
68  *  Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
69  *
70  *  Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
71  *    type    ATTRIBUTE.&id({IOSet}),
72  *    values  SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
73  *  }
74  * </pre>
75  * @deprecated use classes in org.bouncycastle.pkcs.
76  */
77 public class PKCS10CertificationRequest
78     extends CertificationRequest
79 {
80     private static Hashtable            algorithms = new Hashtable();
81     private static Hashtable            params = new Hashtable();
82     private static Hashtable            keyAlgorithms = new Hashtable();
83     private static Hashtable            oids = new Hashtable();
84     private static Set                  noParams = new HashSet();
85 
86     static
87     {
88         // BEGIN android-removed
89         // Dropping MD2
90         // algorithms.put("MD2WITHRSAENCRYPTION", new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"));
91         // algorithms.put("MD2WITHRSA", new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"));
92         // END android-removed
93         algorithms.put("MD5WITHRSAENCRYPTION", new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"));
94         algorithms.put("MD5WITHRSA", new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"));
95         algorithms.put("RSAWITHMD5", new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"));
96         algorithms.put("SHA1WITHRSAENCRYPTION", new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"));
97         algorithms.put("SHA1WITHRSA", new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"));
98         algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption);
99         algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption);
100         algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption);
101         algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption);
102         algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption);
103         algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption);
104         algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption);
105         algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption);
106         algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
107         algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
108         algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
109         algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
110         algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
111         algorithms.put("RSAWITHSHA1", new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"));
112         // BEGIN android-removed
113         // algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
114         // algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
115         // algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
116         // algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
117         // algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
118         // algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
119         // END android-removed
120         algorithms.put("SHA1WITHDSA", new ASN1ObjectIdentifier("1.2.840.10040.4.3"));
121         algorithms.put("DSAWITHSHA1", new ASN1ObjectIdentifier("1.2.840.10040.4.3"));
122         algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224);
123         algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256);
124         algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384);
125         algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512);
126         algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1);
127         algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224);
128         algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256);
129         algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384);
130         algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512);
131         algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1);
132         // BEGIN android-removed
133         // algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
134         // algorithms.put("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
135         // algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
136         // algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
137         // algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
138         // END android-removed
139 
140         //
141         // reverse mappings
142         //
oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA")143         oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA");
oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA")144         oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA");
oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA")145         oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA");
oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA")146         oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA");
oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA")147         oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA");
148         // BEGIN android-removed
149         // oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
150         // oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
151         // END android-removed
152 
oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA")153         oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA");
154         // BEGIN android-removed
155         // oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA");
156         // END android-removed
oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA")157         oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA")158         oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA")159         oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA")160         oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA")161         oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA")162         oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA");
oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA")163         oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA")164         oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA");
oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA")165         oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA");
oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA")166         oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
167 
168         //
169         // key types
170         //
keyAlgorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA")171         keyAlgorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA");
keyAlgorithms.put(X9ObjectIdentifiers.id_dsa, "DSA")172         keyAlgorithms.put(X9ObjectIdentifiers.id_dsa, "DSA");
173 
174         //
175         // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
176         // The parameters field SHALL be NULL for RSA based signature algorithms.
177         //
178         noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1);
179         noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224);
180         noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256);
181         noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384);
182         noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512);
183         noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1);
184         noParams.add(NISTObjectIdentifiers.dsa_with_sha224);
185         noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
186 
187         //
188         // RFC 4491
189         //
190         // BEGIN android-removed
191         // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
192         // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
193         // END android-removed
194         //
195         // explicit params
196         //
197         AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
198         params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20));
199 
200         AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE);
201         params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28));
202 
203         AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);
204         params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32));
205 
206         AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE);
207         params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48));
208 
209         AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE);
210         params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64));
211     }
212 
creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize)213     private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize)
214     {
215         return new RSASSAPSSparams(
216             hashAlgId,
217             new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId),
218             new ASN1Integer(saltSize),
219             new ASN1Integer(1));
220     }
221 
toDERSequence( byte[] bytes)222     private static ASN1Sequence toDERSequence(
223         byte[]  bytes)
224     {
225         try
226         {
227             ASN1InputStream         dIn = new ASN1InputStream(bytes);
228 
229             return (ASN1Sequence)dIn.readObject();
230         }
231         catch (Exception e)
232         {
233             throw new IllegalArgumentException("badly encoded request");
234         }
235     }
236 
237     /**
238      * construct a PKCS10 certification request from a DER encoded
239      * byte stream.
240      */
PKCS10CertificationRequest( byte[] bytes)241     public PKCS10CertificationRequest(
242         byte[]  bytes)
243     {
244         super(toDERSequence(bytes));
245     }
246 
PKCS10CertificationRequest( ASN1Sequence sequence)247     public PKCS10CertificationRequest(
248         ASN1Sequence  sequence)
249     {
250         super(sequence);
251     }
252 
253     /**
254      * create a PKCS10 certfication request using the BC provider.
255      */
PKCS10CertificationRequest( String signatureAlgorithm, X509Name subject, PublicKey key, ASN1Set attributes, PrivateKey signingKey)256     public PKCS10CertificationRequest(
257         String              signatureAlgorithm,
258         X509Name            subject,
259         PublicKey           key,
260         ASN1Set             attributes,
261         PrivateKey          signingKey)
262         throws NoSuchAlgorithmException, NoSuchProviderException,
263                 InvalidKeyException, SignatureException
264     {
265         this(signatureAlgorithm, subject, key, attributes, signingKey, BouncyCastleProvider.PROVIDER_NAME);
266     }
267 
convertName( X500Principal name)268     private static X509Name convertName(
269         X500Principal    name)
270     {
271         try
272         {
273             return new X509Principal(name.getEncoded());
274         }
275         catch (IOException e)
276         {
277             throw new IllegalArgumentException("can't convert name");
278         }
279     }
280 
281     /**
282      * create a PKCS10 certfication request using the BC provider.
283      */
PKCS10CertificationRequest( String signatureAlgorithm, X500Principal subject, PublicKey key, ASN1Set attributes, PrivateKey signingKey)284     public PKCS10CertificationRequest(
285         String              signatureAlgorithm,
286         X500Principal       subject,
287         PublicKey           key,
288         ASN1Set             attributes,
289         PrivateKey          signingKey)
290         throws NoSuchAlgorithmException, NoSuchProviderException,
291                 InvalidKeyException, SignatureException
292     {
293         this(signatureAlgorithm, convertName(subject), key, attributes, signingKey, BouncyCastleProvider.PROVIDER_NAME);
294     }
295 
296     /**
297      * create a PKCS10 certfication request using the named provider.
298      */
PKCS10CertificationRequest( String signatureAlgorithm, X500Principal subject, PublicKey key, ASN1Set attributes, PrivateKey signingKey, String provider)299     public PKCS10CertificationRequest(
300         String              signatureAlgorithm,
301         X500Principal       subject,
302         PublicKey           key,
303         ASN1Set             attributes,
304         PrivateKey          signingKey,
305         String              provider)
306         throws NoSuchAlgorithmException, NoSuchProviderException,
307                 InvalidKeyException, SignatureException
308     {
309         this(signatureAlgorithm, convertName(subject), key, attributes, signingKey, provider);
310     }
311 
312     /**
313      * create a PKCS10 certfication request using the named provider.
314      */
PKCS10CertificationRequest( String signatureAlgorithm, X509Name subject, PublicKey key, ASN1Set attributes, PrivateKey signingKey, String provider)315     public PKCS10CertificationRequest(
316         String              signatureAlgorithm,
317         X509Name            subject,
318         PublicKey           key,
319         ASN1Set             attributes,
320         PrivateKey          signingKey,
321         String              provider)
322         throws NoSuchAlgorithmException, NoSuchProviderException,
323                 InvalidKeyException, SignatureException
324     {
325         String algorithmName = Strings.toUpperCase(signatureAlgorithm);
326         ASN1ObjectIdentifier sigOID = (ASN1ObjectIdentifier)algorithms.get(algorithmName);
327 
328         if (sigOID == null)
329         {
330             try
331             {
332                 sigOID = new ASN1ObjectIdentifier(algorithmName);
333             }
334             catch (Exception e)
335             {
336                 throw new IllegalArgumentException("Unknown signature type requested");
337             }
338         }
339 
340         if (subject == null)
341         {
342             throw new IllegalArgumentException("subject must not be null");
343         }
344 
345         if (key == null)
346         {
347             throw new IllegalArgumentException("public key must not be null");
348         }
349 
350         if (noParams.contains(sigOID))
351         {
352             this.sigAlgId = new AlgorithmIdentifier(sigOID);
353         }
354         else if (params.containsKey(algorithmName))
355         {
356             this.sigAlgId = new AlgorithmIdentifier(sigOID, (ASN1Encodable)params.get(algorithmName));
357         }
358         else
359         {
360             this.sigAlgId = new AlgorithmIdentifier(sigOID, DERNull.INSTANCE);
361         }
362 
363         try
364         {
365             ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(key.getEncoded());
366             this.reqInfo = new CertificationRequestInfo(subject, SubjectPublicKeyInfo.getInstance(seq), attributes);
367         }
368         catch (IOException e)
369         {
370             throw new IllegalArgumentException("can't encode public key");
371         }
372 
373         Signature sig;
374         if (provider == null)
375         {
376             sig = Signature.getInstance(signatureAlgorithm);
377         }
378         else
379         {
380             sig = Signature.getInstance(signatureAlgorithm, provider);
381         }
382 
383         sig.initSign(signingKey);
384 
385         try
386         {
387             sig.update(reqInfo.getEncoded(ASN1Encoding.DER));
388         }
389         catch (Exception e)
390         {
391             throw new IllegalArgumentException("exception encoding TBS cert request - " + e);
392         }
393 
394         this.sigBits = new DERBitString(sig.sign());
395     }
396 
397     /**
398      * return the public key associated with the certification request -
399      * the public key is created using the BC provider.
400      */
getPublicKey()401     public PublicKey getPublicKey()
402         throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException
403     {
404         return getPublicKey(BouncyCastleProvider.PROVIDER_NAME);
405     }
406 
getPublicKey( String provider)407     public PublicKey getPublicKey(
408         String  provider)
409         throws NoSuchAlgorithmException, NoSuchProviderException,
410                 InvalidKeyException
411     {
412         SubjectPublicKeyInfo    subjectPKInfo = reqInfo.getSubjectPublicKeyInfo();
413 
414 
415         try
416         {
417             X509EncodedKeySpec      xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getOctets());
418             AlgorithmIdentifier     keyAlg = subjectPKInfo.getAlgorithm();
419             try
420             {
421                 if (provider == null)
422                 {
423                     return KeyFactory.getInstance(keyAlg.getAlgorithm().getId()).generatePublic(xspec);
424                 }
425                 else
426                 {
427                     return KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), provider).generatePublic(xspec);
428                 }
429             }
430             catch (NoSuchAlgorithmException e)
431             {
432                 //
433                 // try an alternate
434                 //
435                 if (keyAlgorithms.get(keyAlg.getAlgorithm()) != null)
436                 {
437                     String  keyAlgorithm = (String)keyAlgorithms.get(keyAlg.getAlgorithm());
438 
439                     if (provider == null)
440                     {
441                         return KeyFactory.getInstance(keyAlgorithm).generatePublic(xspec);
442                     }
443                     else
444                     {
445                         return KeyFactory.getInstance(keyAlgorithm, provider).generatePublic(xspec);
446                     }
447                 }
448 
449                 throw e;
450             }
451         }
452         catch (InvalidKeySpecException e)
453         {
454             throw new InvalidKeyException("error decoding public key");
455         }
456         catch (IOException e)
457         {
458             throw new InvalidKeyException("error decoding public key");
459         }
460     }
461 
462     /**
463      * verify the request using the BC provider.
464      */
verify()465     public boolean verify()
466         throws NoSuchAlgorithmException, NoSuchProviderException,
467                 InvalidKeyException, SignatureException
468     {
469         return verify(BouncyCastleProvider.PROVIDER_NAME);
470     }
471 
472     /**
473      * verify the request using the passed in provider.
474      */
verify( String provider)475     public boolean verify(
476         String provider)
477         throws NoSuchAlgorithmException, NoSuchProviderException,
478                 InvalidKeyException, SignatureException
479     {
480         return verify(this.getPublicKey(provider), provider);
481     }
482 
483     /**
484      * verify the request using the passed in public key and the provider..
485      */
verify( PublicKey pubKey, String provider)486     public boolean verify(
487         PublicKey pubKey,
488         String provider)
489         throws NoSuchAlgorithmException, NoSuchProviderException,
490                 InvalidKeyException, SignatureException
491     {
492         Signature   sig;
493 
494         try
495         {
496             if (provider == null)
497             {
498                 sig = Signature.getInstance(getSignatureName(sigAlgId));
499             }
500             else
501             {
502                 sig = Signature.getInstance(getSignatureName(sigAlgId), provider);
503             }
504         }
505         catch (NoSuchAlgorithmException e)
506         {
507             //
508             // try an alternate
509             //
510             if (oids.get(sigAlgId.getAlgorithm()) != null)
511             {
512                 String  signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm());
513 
514                 if (provider == null)
515                 {
516                     sig = Signature.getInstance(signatureAlgorithm);
517                 }
518                 else
519                 {
520                     sig = Signature.getInstance(signatureAlgorithm, provider);
521                 }
522             }
523             else
524             {
525                 throw e;
526             }
527         }
528 
529         setSignatureParameters(sig, sigAlgId.getParameters());
530 
531         sig.initVerify(pubKey);
532 
533         try
534         {
535             sig.update(reqInfo.getEncoded(ASN1Encoding.DER));
536         }
537         catch (Exception e)
538         {
539             throw new SignatureException("exception encoding TBS cert request - " + e);
540         }
541 
542         return sig.verify(sigBits.getOctets());
543     }
544 
545     /**
546      * return a DER encoded byte array representing this object
547      */
getEncoded()548     public byte[] getEncoded()
549     {
550         try
551         {
552             return this.getEncoded(ASN1Encoding.DER);
553         }
554         catch (IOException e)
555         {
556             throw new RuntimeException(e.toString());
557         }
558     }
559 
setSignatureParameters( Signature signature, ASN1Encodable params)560     private void setSignatureParameters(
561         Signature signature,
562         ASN1Encodable params)
563         throws NoSuchAlgorithmException, SignatureException, InvalidKeyException
564     {
565         if (params != null && !DERNull.INSTANCE.equals(params))
566         {
567             AlgorithmParameters sigParams = AlgorithmParameters.getInstance(signature.getAlgorithm(), signature.getProvider());
568 
569             try
570             {
571                 sigParams.init(params.toASN1Primitive().getEncoded(ASN1Encoding.DER));
572             }
573             catch (IOException e)
574             {
575                 throw new SignatureException("IOException decoding parameters: " + e.getMessage());
576             }
577 
578             if (signature.getAlgorithm().endsWith("MGF1"))
579             {
580                 try
581                 {
582                     signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class));
583                 }
584                 catch (GeneralSecurityException e)
585                 {
586                     throw new SignatureException("Exception extracting parameters: " + e.getMessage());
587                 }
588             }
589         }
590     }
591 
getSignatureName( AlgorithmIdentifier sigAlgId)592     static String getSignatureName(
593         AlgorithmIdentifier sigAlgId)
594     {
595         ASN1Encodable params = sigAlgId.getParameters();
596 
597         if (params != null && !DERNull.INSTANCE.equals(params))
598         {
599             if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
600             {
601                 RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
602                 return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1";
603             }
604         }
605 
606         return sigAlgId.getAlgorithm().getId();
607     }
608 
getDigestAlgName( ASN1ObjectIdentifier digestAlgOID)609     private static String getDigestAlgName(
610         ASN1ObjectIdentifier digestAlgOID)
611     {
612         if (PKCSObjectIdentifiers.md5.equals(digestAlgOID))
613         {
614             return "MD5";
615         }
616         else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID))
617         {
618             return "SHA1";
619         }
620         else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID))
621         {
622             return "SHA224";
623         }
624         else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID))
625         {
626             return "SHA256";
627         }
628         else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID))
629         {
630             return "SHA384";
631         }
632         else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID))
633         {
634             return "SHA512";
635         }
636         // BEGIN android-removed
637         // else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID))
638         // {
639         //     return "RIPEMD128";
640         // }
641         // else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID))
642         // {
643         //     return "RIPEMD160";
644         // }
645         // else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID))
646         // {
647         //     return "RIPEMD256";
648         // }
649         // else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID))
650         // {
651         //     return "GOST3411";
652         // }
653         // END android-removed
654         else
655         {
656             return digestAlgOID.getId();
657         }
658     }
659 }
660