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