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.ASN1Encoding;
     25 import org.bouncycastle.asn1.ASN1InputStream;
     26 import org.bouncycastle.asn1.ASN1Integer;
     27 import org.bouncycastle.asn1.ASN1Primitive;
     28 import org.bouncycastle.asn1.ASN1Sequence;
     29 import org.bouncycastle.asn1.ASN1Set;
     30 import org.bouncycastle.asn1.DERBitString;
     31 import org.bouncycastle.asn1.DERNull;
     32 import org.bouncycastle.asn1.DERObjectIdentifier;
     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 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