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