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