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