| package org.bouncycastle.cms; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.security.InvalidAlgorithmParameterException; |
| import java.security.NoSuchAlgorithmException; |
| import java.security.Provider; |
| import java.security.cert.CRLException; |
| import java.security.cert.CertStore; |
| import java.security.cert.CertificateException; |
| import java.security.cert.CertificateFactory; |
| import java.security.cert.CollectionCertStoreParameters; |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.bouncycastle.asn1.ASN1Encodable; |
| import org.bouncycastle.asn1.ASN1Primitive; |
| import org.bouncycastle.asn1.ASN1Sequence; |
| import org.bouncycastle.asn1.ASN1Set; |
| import org.bouncycastle.asn1.ASN1TaggedObject; |
| import org.bouncycastle.asn1.DERNull; |
| import org.bouncycastle.asn1.DERObjectIdentifier; |
| // BEGIN android-removed |
| // import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; |
| // END android-removed |
| import org.bouncycastle.asn1.eac.EACObjectIdentifiers; |
| import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; |
| import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; |
| import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; |
| import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; |
| import org.bouncycastle.asn1.x509.AlgorithmIdentifier; |
| import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; |
| import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; |
| import org.bouncycastle.x509.NoSuchStoreException; |
| import org.bouncycastle.x509.X509CollectionStoreParameters; |
| import org.bouncycastle.x509.X509Store; |
| import org.bouncycastle.x509.X509V2AttributeCertificate; |
| |
| class CMSSignedHelper |
| { |
| static final CMSSignedHelper INSTANCE = new CMSSignedHelper(); |
| |
| private static final Map encryptionAlgs = new HashMap(); |
| private static final Map digestAlgs = new HashMap(); |
| private static final Map digestAliases = new HashMap(); |
| |
| private static void addEntries(DERObjectIdentifier alias, String digest, String encryption) |
| { |
| digestAlgs.put(alias.getId(), digest); |
| encryptionAlgs.put(alias.getId(), encryption); |
| } |
| |
| static |
| { |
| // BEGIN android-removed |
| // addEntries(NISTObjectIdentifiers.dsa_with_sha224, "SHA224", "DSA"); |
| // END android-removed |
| addEntries(NISTObjectIdentifiers.dsa_with_sha256, "SHA256", "DSA"); |
| addEntries(NISTObjectIdentifiers.dsa_with_sha384, "SHA384", "DSA"); |
| addEntries(NISTObjectIdentifiers.dsa_with_sha512, "SHA512", "DSA"); |
| addEntries(OIWObjectIdentifiers.dsaWithSHA1, "SHA1", "DSA"); |
| // BEGIN android-removed |
| // addEntries(OIWObjectIdentifiers.md4WithRSA, "MD4", "RSA"); |
| // addEntries(OIWObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); |
| // END android-removed |
| addEntries(OIWObjectIdentifiers.md5WithRSA, "MD5", "RSA"); |
| addEntries(OIWObjectIdentifiers.sha1WithRSA, "SHA1", "RSA"); |
| // BEGIN android-removed |
| // addEntries(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2", "RSA"); |
| // addEntries(PKCSObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); |
| // END android-removed |
| addEntries(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5", "RSA"); |
| addEntries(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1", "RSA"); |
| // BEGIN android-removed |
| // addEntries(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224", "RSA"); |
| // END android-removed |
| addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256", "RSA"); |
| addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384", "RSA"); |
| addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512", "RSA"); |
| addEntries(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1", "ECDSA"); |
| // BEGIN android-removed |
| // addEntries(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224", "ECDSA"); |
| // END android-removed |
| addEntries(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256", "ECDSA"); |
| addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384", "ECDSA"); |
| addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512", "ECDSA"); |
| addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1", "DSA"); |
| addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA"); |
| // BEGIN android-removed |
| // addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA"); |
| // END android-removed |
| addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA"); |
| addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384", "ECDSA"); |
| addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512", "ECDSA"); |
| addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1", "RSA"); |
| addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA"); |
| addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1"); |
| addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1"); |
| |
| encryptionAlgs.put(X9ObjectIdentifiers.id_dsa.getId(), "DSA"); |
| encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption.getId(), "RSA"); |
| encryptionAlgs.put(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA"); |
| encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa.getId(), "RSA"); |
| // BEGIN android-removed |
| // encryptionAlgs.put(CMSSignedDataGenerator.ENCRYPTION_RSA_PSS, "RSAandMGF1"); |
| // encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94.getId(), "GOST3410"); |
| // encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001.getId(), "ECGOST3410"); |
| // encryptionAlgs.put("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410"); |
| // encryptionAlgs.put("1.3.6.1.4.1.5849.1.1.5", "GOST3410"); |
| // encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001.getId(), "ECGOST3410"); |
| // encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94.getId(), "GOST3410"); |
| // |
| // digestAlgs.put(PKCSObjectIdentifiers.md2.getId(), "MD2"); |
| // digestAlgs.put(PKCSObjectIdentifiers.md4.getId(), "MD4"); |
| // END android-removed |
| digestAlgs.put(PKCSObjectIdentifiers.md5.getId(), "MD5"); |
| digestAlgs.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1"); |
| // BEGIN android-removed |
| // digestAlgs.put(NISTObjectIdentifiers.id_sha224.getId(), "SHA224"); |
| // END android-removed |
| digestAlgs.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256"); |
| digestAlgs.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384"); |
| digestAlgs.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512"); |
| // BEGIN android-removed |
| // digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), "RIPEMD128"); |
| // digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), "RIPEMD160"); |
| // digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), "RIPEMD256"); |
| // digestAlgs.put(CryptoProObjectIdentifiers.gostR3411.getId(), "GOST3411"); |
| // digestAlgs.put("1.3.6.1.4.1.5849.1.2.1", "GOST3411"); |
| // END android-removed |
| |
| digestAliases.put("SHA1", new String[] { "SHA-1" }); |
| // BEGIN android-removed |
| // digestAliases.put("SHA224", new String[] { "SHA-224" }); |
| // END android-removed |
| digestAliases.put("SHA256", new String[] { "SHA-256" }); |
| digestAliases.put("SHA384", new String[] { "SHA-384" }); |
| digestAliases.put("SHA512", new String[] { "SHA-512" }); |
| } |
| |
| /** |
| * Return the digest algorithm using one of the standard JCA string |
| * representations rather than the algorithm identifier (if possible). |
| */ |
| String getDigestAlgName( |
| String digestAlgOID) |
| { |
| String algName = (String)digestAlgs.get(digestAlgOID); |
| |
| if (algName != null) |
| { |
| return algName; |
| } |
| |
| return digestAlgOID; |
| } |
| |
| /** |
| * Return the digest encryption algorithm using one of the standard |
| * JCA string representations rather the the algorithm identifier (if |
| * possible). |
| */ |
| String getEncryptionAlgName( |
| String encryptionAlgOID) |
| { |
| String algName = (String)encryptionAlgs.get(encryptionAlgOID); |
| |
| if (algName != null) |
| { |
| return algName; |
| } |
| |
| return encryptionAlgOID; |
| } |
| |
| |
| X509Store createAttributeStore( |
| String type, |
| Provider provider, |
| ASN1Set certSet) |
| throws NoSuchStoreException, CMSException |
| { |
| List certs = new ArrayList(); |
| |
| if (certSet != null) |
| { |
| Enumeration e = certSet.getObjects(); |
| |
| while (e.hasMoreElements()) |
| { |
| try |
| { |
| ASN1Primitive obj = ((ASN1Encodable)e.nextElement()).toASN1Primitive(); |
| |
| if (obj instanceof ASN1TaggedObject) |
| { |
| ASN1TaggedObject tagged = (ASN1TaggedObject)obj; |
| |
| if (tagged.getTagNo() == 2) |
| { |
| certs.add(new X509V2AttributeCertificate(ASN1Sequence.getInstance(tagged, false).getEncoded())); |
| } |
| } |
| } |
| catch (IOException ex) |
| { |
| throw new CMSException( |
| "can't re-encode attribute certificate!", ex); |
| } |
| } |
| } |
| |
| try |
| { |
| return X509Store.getInstance( |
| "AttributeCertificate/" +type, new X509CollectionStoreParameters(certs), provider); |
| } |
| catch (IllegalArgumentException e) |
| { |
| throw new CMSException("can't setup the X509Store", e); |
| } |
| } |
| |
| X509Store createCertificateStore( |
| String type, |
| Provider provider, |
| ASN1Set certSet) |
| throws NoSuchStoreException, CMSException |
| { |
| List certs = new ArrayList(); |
| |
| if (certSet != null) |
| { |
| addCertsFromSet(certs, certSet, provider); |
| } |
| |
| try |
| { |
| return X509Store.getInstance( |
| "Certificate/" +type, new X509CollectionStoreParameters(certs), provider); |
| } |
| catch (IllegalArgumentException e) |
| { |
| throw new CMSException("can't setup the X509Store", e); |
| } |
| } |
| |
| X509Store createCRLsStore( |
| String type, |
| Provider provider, |
| ASN1Set crlSet) |
| throws NoSuchStoreException, CMSException |
| { |
| List crls = new ArrayList(); |
| |
| if (crlSet != null) |
| { |
| addCRLsFromSet(crls, crlSet, provider); |
| } |
| |
| try |
| { |
| return X509Store.getInstance( |
| "CRL/" +type, new X509CollectionStoreParameters(crls), provider); |
| } |
| catch (IllegalArgumentException e) |
| { |
| throw new CMSException("can't setup the X509Store", e); |
| } |
| } |
| |
| CertStore createCertStore( |
| String type, |
| Provider provider, |
| ASN1Set certSet, |
| ASN1Set crlSet) |
| throws CMSException, NoSuchAlgorithmException |
| { |
| List certsAndcrls = new ArrayList(); |
| |
| // |
| // load the certificates and revocation lists if we have any |
| // |
| |
| if (certSet != null) |
| { |
| addCertsFromSet(certsAndcrls, certSet, provider); |
| } |
| |
| if (crlSet != null) |
| { |
| addCRLsFromSet(certsAndcrls, crlSet, provider); |
| } |
| |
| try |
| { |
| if (provider != null) |
| { |
| return CertStore.getInstance(type, new CollectionCertStoreParameters(certsAndcrls), provider); |
| } |
| else |
| { |
| return CertStore.getInstance(type, new CollectionCertStoreParameters(certsAndcrls)); |
| } |
| } |
| catch (InvalidAlgorithmParameterException e) |
| { |
| throw new CMSException("can't setup the CertStore", e); |
| } |
| } |
| |
| private void addCertsFromSet(List certs, ASN1Set certSet, Provider provider) |
| throws CMSException |
| { |
| CertificateFactory cf; |
| |
| try |
| { |
| if (provider != null) |
| { |
| cf = CertificateFactory.getInstance("X.509", provider); |
| } |
| else |
| { |
| cf = CertificateFactory.getInstance("X.509"); |
| } |
| } |
| catch (CertificateException ex) |
| { |
| throw new CMSException("can't get certificate factory.", ex); |
| } |
| Enumeration e = certSet.getObjects(); |
| |
| while (e.hasMoreElements()) |
| { |
| try |
| { |
| ASN1Primitive obj = ((ASN1Encodable)e.nextElement()).toASN1Primitive(); |
| |
| if (obj instanceof ASN1Sequence) |
| { |
| certs.add(cf.generateCertificate( |
| new ByteArrayInputStream(obj.getEncoded()))); |
| } |
| } |
| catch (IOException ex) |
| { |
| throw new CMSException( |
| "can't re-encode certificate!", ex); |
| } |
| catch (CertificateException ex) |
| { |
| throw new CMSException( |
| "can't re-encode certificate!", ex); |
| } |
| } |
| } |
| |
| private void addCRLsFromSet(List crls, ASN1Set certSet, Provider provider) |
| throws CMSException |
| { |
| CertificateFactory cf; |
| |
| try |
| { |
| if (provider != null) |
| { |
| cf = CertificateFactory.getInstance("X.509", provider); |
| } |
| else |
| { |
| cf = CertificateFactory.getInstance("X.509"); |
| } |
| } |
| catch (CertificateException ex) |
| { |
| throw new CMSException("can't get certificate factory.", ex); |
| } |
| Enumeration e = certSet.getObjects(); |
| |
| while (e.hasMoreElements()) |
| { |
| try |
| { |
| ASN1Primitive obj = ((ASN1Encodable)e.nextElement()).toASN1Primitive(); |
| |
| crls.add(cf.generateCRL( |
| new ByteArrayInputStream(obj.getEncoded()))); |
| } |
| catch (IOException ex) |
| { |
| throw new CMSException("can't re-encode CRL!", ex); |
| } |
| catch (CRLException ex) |
| { |
| throw new CMSException("can't re-encode CRL!", ex); |
| } |
| } |
| } |
| |
| AlgorithmIdentifier fixAlgID(AlgorithmIdentifier algId) |
| { |
| if (algId.getParameters() == null) |
| { |
| return new AlgorithmIdentifier(algId.getObjectId(), DERNull.INSTANCE); |
| } |
| |
| return algId; |
| } |
| |
| void setSigningEncryptionAlgorithmMapping(DERObjectIdentifier oid, String algorithmName) |
| { |
| encryptionAlgs.put(oid.getId(), algorithmName); |
| } |
| |
| void setSigningDigestAlgorithmMapping(DERObjectIdentifier oid, String algorithmName) |
| { |
| digestAlgs.put(oid.getId(), algorithmName); |
| } |
| } |