Home | History | Annotate | Download | only in cms
      1 package org.bouncycastle.cms;
      2 
      3 import java.io.IOException;
      4 import java.security.PrivateKey;
      5 import java.security.SecureRandom;
      6 import java.security.cert.CertStore;
      7 import java.security.cert.CertStoreException;
      8 import java.security.interfaces.DSAPrivateKey;
      9 import java.security.interfaces.RSAPrivateKey;
     10 import java.util.ArrayList;
     11 import java.util.HashMap;
     12 import java.util.HashSet;
     13 import java.util.Iterator;
     14 import java.util.List;
     15 import java.util.Map;
     16 import java.util.Set;
     17 
     18 import org.bouncycastle.asn1.ASN1Primitive;
     19 import org.bouncycastle.asn1.ASN1Set;
     20 import org.bouncycastle.asn1.DERObjectIdentifier;
     21 import org.bouncycastle.asn1.DERSet;
     22 import org.bouncycastle.asn1.DERTaggedObject;
     23 import org.bouncycastle.asn1.cms.AttributeTable;
     24 import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
     25 // BEGIN android-removed
     26 // import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
     27 // END android-removed
     28 import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
     29 import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
     30 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
     31 import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
     32 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
     33 import org.bouncycastle.asn1.x509.AttributeCertificate;
     34 import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
     35 // BEGIN android-removed
     36 // import org.bouncycastle.jce.interfaces.GOST3410PrivateKey;
     37 // END android-removed
     38 import org.bouncycastle.util.Store;
     39 import org.bouncycastle.x509.X509AttributeCertificate;
     40 import org.bouncycastle.x509.X509Store;
     41 
     42 public class CMSSignedGenerator
     43 {
     44     /**
     45      * Default type for the signed data.
     46      */
     47     public static final String  DATA = CMSObjectIdentifiers.data.getId();
     48 
     49     public static final String  DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId();
     50     // BEGIN android-removed
     51     // public static final String  DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId();
     52     // END android-removed
     53     public static final String  DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId();
     54     public static final String  DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId();
     55     public static final String  DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId();
     56     public static final String  DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId();
     57     // BEGIN android-removed
     58     // public static final String  DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId();
     59     // public static final String  DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId();
     60     // public static final String  DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId();
     61     // public static final String  DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId();
     62     // END android-removed
     63 
     64     public static final String  ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId();
     65     public static final String  ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId();
     66     public static final String  ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId();
     67     public static final String  ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId();
     68     // BEGIN android-removed
     69     // public static final String  ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId();
     70     // public static final String  ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId();
     71     // END android-removed
     72 
     73     private static final String  ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1.getId();
     74     // BEGIN android-removed
     75     // private static final String  ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224.getId();
     76     // END android-removed
     77     private static final String  ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256.getId();
     78     private static final String  ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384.getId();
     79     private static final String  ENCRYPTION_ECDSA_WITH_SHA512 = X9ObjectIdentifiers.ecdsa_with_SHA512.getId();
     80 
     81     private static final Set NO_PARAMS = new HashSet();
     82     private static final Map EC_ALGORITHMS = new HashMap();
     83 
     84     static
     85     {
     86         NO_PARAMS.add(ENCRYPTION_DSA);
     87         NO_PARAMS.add(ENCRYPTION_ECDSA);
     88         NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1);
     89         // BEGIN android-removed
     90         // NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224);
     91         // END android-removed
     92         NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256);
     93         NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384);
     94         NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA512);
     95 
     96         EC_ALGORITHMS.put(DIGEST_SHA1, ENCRYPTION_ECDSA_WITH_SHA1);
     97         // BEGIN android-removed
     98         // EC_ALGORITHMS.put(DIGEST_SHA224, ENCRYPTION_ECDSA_WITH_SHA224);
     99         // END android-removed
    100         EC_ALGORITHMS.put(DIGEST_SHA256, ENCRYPTION_ECDSA_WITH_SHA256);
    101         EC_ALGORITHMS.put(DIGEST_SHA384, ENCRYPTION_ECDSA_WITH_SHA384);
    102         EC_ALGORITHMS.put(DIGEST_SHA512, ENCRYPTION_ECDSA_WITH_SHA512);
    103     }
    104 
    105     protected List certs = new ArrayList();
    106     protected List crls = new ArrayList();
    107     protected List _signers = new ArrayList();
    108     protected List signerGens = new ArrayList();
    109     protected Map digests = new HashMap();
    110 
    111     protected final SecureRandom rand;
    112 
    113     /**
    114      * base constructor
    115      */
    116     protected CMSSignedGenerator()
    117     {
    118         this(new SecureRandom());
    119     }
    120 
    121     /**
    122      * constructor allowing specific source of randomness
    123      * @param rand instance of SecureRandom to use
    124      */
    125     protected CMSSignedGenerator(
    126         SecureRandom rand)
    127     {
    128         this.rand = rand;
    129     }
    130 
    131     protected String getEncOID(
    132         PrivateKey key,
    133         String     digestOID)
    134     {
    135         String encOID = null;
    136 
    137         if (key instanceof RSAPrivateKey || "RSA".equalsIgnoreCase(key.getAlgorithm()))
    138         {
    139             encOID = ENCRYPTION_RSA;
    140         }
    141         else if (key instanceof DSAPrivateKey || "DSA".equalsIgnoreCase(key.getAlgorithm()))
    142         {
    143             encOID = ENCRYPTION_DSA;
    144             if (!digestOID.equals(DIGEST_SHA1))
    145             {
    146                 throw new IllegalArgumentException("can't mix DSA with anything but SHA1");
    147             }
    148         }
    149         else if ("ECDSA".equalsIgnoreCase(key.getAlgorithm()) || "EC".equalsIgnoreCase(key.getAlgorithm()))
    150         {
    151             encOID = (String)EC_ALGORITHMS.get(digestOID);
    152             if (encOID == null)
    153             {
    154                 throw new IllegalArgumentException("can't mix ECDSA with anything but SHA family digests");
    155             }
    156         }
    157         // BEGIN android-removed
    158         // else if (key instanceof GOST3410PrivateKey || "GOST3410".equalsIgnoreCase(key.getAlgorithm()))
    159         // {
    160         //     encOID = ENCRYPTION_GOST3410;
    161         // }
    162         // else if ("ECGOST3410".equalsIgnoreCase(key.getAlgorithm()))
    163         // {
    164         //     encOID = ENCRYPTION_ECGOST3410;
    165         // }
    166         // END android-removed
    167 
    168         return encOID;
    169     }
    170 
    171     protected Map getBaseParameters(DERObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
    172     {
    173         Map param = new HashMap();
    174         param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType);
    175         param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId);
    176         param.put(CMSAttributeTableGenerator.DIGEST,  hash.clone());
    177         return param;
    178     }
    179 
    180     protected ASN1Set getAttributeSet(
    181         AttributeTable attr)
    182     {
    183         if (attr != null)
    184         {
    185             return new DERSet(attr.toASN1EncodableVector());
    186         }
    187 
    188         return null;
    189     }
    190 
    191     /**
    192      * add the certificates and CRLs contained in the given CertStore
    193      * to the pool that will be included in the encoded signature block.
    194      * <p>
    195      * Note: this assumes the CertStore will support null in the get
    196      * methods.
    197      * @param certStore CertStore containing the public key certificates and CRLs
    198      * @throws java.security.cert.CertStoreException  if an issue occurs processing the CertStore
    199      * @throws CMSException  if an issue occurse transforming data from the CertStore into the message
    200      * @deprecated use addCertificates and addCRLs
    201      */
    202     public void addCertificatesAndCRLs(
    203         CertStore certStore)
    204         throws CertStoreException, CMSException
    205     {
    206         certs.addAll(CMSUtils.getCertificatesFromStore(certStore));
    207         crls.addAll(CMSUtils.getCRLsFromStore(certStore));
    208     }
    209 
    210     public void addCertificates(
    211         Store certStore)
    212         throws CMSException
    213     {
    214         certs.addAll(CMSUtils.getCertificatesFromStore(certStore));
    215     }
    216 
    217     public void addCRLs(
    218         Store crlStore)
    219         throws CMSException
    220     {
    221         crls.addAll(CMSUtils.getCRLsFromStore(crlStore));
    222     }
    223 
    224     public void addAttributeCertificates(
    225         Store attrStore)
    226         throws CMSException
    227     {
    228         certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrStore));
    229     }
    230 
    231     /**
    232      * Add the attribute certificates contained in the passed in store to the
    233      * generator.
    234      *
    235      * @param store a store of Version 2 attribute certificates
    236      * @throws CMSException if an error occurse processing the store.
    237      * @deprecated use basic Store method
    238      */
    239     public void addAttributeCertificates(
    240         X509Store store)
    241         throws CMSException
    242     {
    243         try
    244         {
    245             for (Iterator it = store.getMatches(null).iterator(); it.hasNext();)
    246             {
    247                 X509AttributeCertificate attrCert = (X509AttributeCertificate)it.next();
    248 
    249                 certs.add(new DERTaggedObject(false, 2,
    250                              AttributeCertificate.getInstance(ASN1Primitive.fromByteArray(attrCert.getEncoded()))));
    251             }
    252         }
    253         catch (IllegalArgumentException e)
    254         {
    255             throw new CMSException("error processing attribute certs", e);
    256         }
    257         catch (IOException e)
    258         {
    259             throw new CMSException("error processing attribute certs", e);
    260         }
    261     }
    262 
    263 
    264     /**
    265      * Add a store of precalculated signers to the generator.
    266      *
    267      * @param signerStore store of signers
    268      */
    269     public void addSigners(
    270         SignerInformationStore    signerStore)
    271     {
    272         Iterator    it = signerStore.getSigners().iterator();
    273 
    274         while (it.hasNext())
    275         {
    276             _signers.add(it.next());
    277         }
    278     }
    279 
    280     public void addSignerInfoGenerator(SignerInfoGenerator infoGen)
    281     {
    282          signerGens.add(infoGen);
    283     }
    284 
    285     /**
    286      * Return a map of oids and byte arrays representing the digests calculated on the content during
    287      * the last generate.
    288      *
    289      * @return a map of oids (as String objects) and byte[] representing digests.
    290      */
    291     public Map getGeneratedDigests()
    292     {
    293         return new HashMap(digests);
    294     }
    295 }
    296