1package org.bouncycastle.cms; 2 3import java.util.ArrayList; 4import java.util.HashMap; 5import java.util.HashSet; 6import java.util.Iterator; 7import java.util.List; 8import java.util.Map; 9import java.util.Set; 10 11import org.bouncycastle.asn1.ASN1Encodable; 12import org.bouncycastle.asn1.ASN1ObjectIdentifier; 13import org.bouncycastle.asn1.DERTaggedObject; 14import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; 15// BEGIN android-removed 16// import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; 17// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; 18// END android-removed 19import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; 20import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; 21import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 22import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; 23import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 24import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 25import org.bouncycastle.cert.X509AttributeCertificateHolder; 26import org.bouncycastle.cert.X509CRLHolder; 27import org.bouncycastle.cert.X509CertificateHolder; 28import org.bouncycastle.util.Arrays; 29import org.bouncycastle.util.Store; 30 31public class CMSSignedGenerator 32{ 33 /** 34 * Default type for the signed data. 35 */ 36 public static final String DATA = CMSObjectIdentifiers.data.getId(); 37 38 public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); 39 public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); 40 public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); 41 public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); 42 public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); 43 public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); 44 // BEGIN android-removed 45 // public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); 46 // public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); 47 // public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); 48 // public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); 49 // END android-removed 50 51 public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); 52 public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); 53 public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); 54 public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); 55 // BEGIN android-removed 56 // public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); 57 // public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); 58 // END android-removed 59 60 private static final String ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); 61 private static final String ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224.getId(); 62 private static final String ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256.getId(); 63 private static final String ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384.getId(); 64 private static final String ENCRYPTION_ECDSA_WITH_SHA512 = X9ObjectIdentifiers.ecdsa_with_SHA512.getId(); 65 66 private static final Set NO_PARAMS = new HashSet(); 67 private static final Map EC_ALGORITHMS = new HashMap(); 68 69 static 70 { 71 NO_PARAMS.add(ENCRYPTION_DSA); 72 NO_PARAMS.add(ENCRYPTION_ECDSA); 73 NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1); 74 NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224); 75 NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256); 76 NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384); 77 NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA512); 78 79 EC_ALGORITHMS.put(DIGEST_SHA1, ENCRYPTION_ECDSA_WITH_SHA1); 80 EC_ALGORITHMS.put(DIGEST_SHA224, ENCRYPTION_ECDSA_WITH_SHA224); 81 EC_ALGORITHMS.put(DIGEST_SHA256, ENCRYPTION_ECDSA_WITH_SHA256); 82 EC_ALGORITHMS.put(DIGEST_SHA384, ENCRYPTION_ECDSA_WITH_SHA384); 83 EC_ALGORITHMS.put(DIGEST_SHA512, ENCRYPTION_ECDSA_WITH_SHA512); 84 } 85 86 protected List certs = new ArrayList(); 87 protected List crls = new ArrayList(); 88 protected List _signers = new ArrayList(); 89 protected List signerGens = new ArrayList(); 90 protected Map digests = new HashMap(); 91 92 /** 93 * base constructor 94 */ 95 protected CMSSignedGenerator() 96 { 97 } 98 99 protected Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash) 100 { 101 Map param = new HashMap(); 102 param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); 103 param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); 104 param.put(CMSAttributeTableGenerator.DIGEST, Arrays.clone(hash)); 105 return param; 106 } 107 108 /** 109 * Add a certificate to the certificate set to be included with the generated SignedData message. 110 * 111 * @param certificate the certificate to be included. 112 * @throws CMSException if the certificate cannot be encoded for adding. 113 */ 114 public void addCertificate( 115 X509CertificateHolder certificate) 116 throws CMSException 117 { 118 certs.add(certificate.toASN1Structure()); 119 } 120 121 /** 122 * Add the certificates in certStore to the certificate set to be included with the generated SignedData message. 123 * 124 * @param certStore the store containing the certificates to be included. 125 * @throws CMSException if the certificates cannot be encoded for adding. 126 */ 127 public void addCertificates( 128 Store certStore) 129 throws CMSException 130 { 131 certs.addAll(CMSUtils.getCertificatesFromStore(certStore)); 132 } 133 134 /** 135 * Add a CRL to the CRL set to be included with the generated SignedData message. 136 * 137 * @param crl the CRL to be included. 138 */ 139 public void addCRL(X509CRLHolder crl) 140 { 141 crls.add(crl.toASN1Structure()); 142 } 143 144 /** 145 * Add the CRLs in crlStore to the CRL set to be included with the generated SignedData message. 146 * 147 * @param crlStore the store containing the CRLs to be included. 148 * @throws CMSException if the CRLs cannot be encoded for adding. 149 */ 150 public void addCRLs( 151 Store crlStore) 152 throws CMSException 153 { 154 crls.addAll(CMSUtils.getCRLsFromStore(crlStore)); 155 } 156 157 /** 158 * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message. 159 * 160 * @param attrCert the store containing the certificates to be included. 161 * @throws CMSException if the attribute certificate cannot be encoded for adding. 162 */ 163 public void addAttributeCertificate( 164 X509AttributeCertificateHolder attrCert) 165 throws CMSException 166 { 167 certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); 168 } 169 170 /** 171 * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message. 172 * 173 * @param attrStore the store containing the certificates to be included. 174 * @throws CMSException if the attribute certificate cannot be encoded for adding. 175 */ 176 public void addAttributeCertificates( 177 Store attrStore) 178 throws CMSException 179 { 180 certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrStore)); 181 } 182 183 // BEGIN android-removed 184 // /** 185 // * Add a single instance of otherRevocationData to the CRL set to be included with the generated SignedData message. 186 // * 187 // * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data. 188 // * @param otherRevocationInfo the otherRevocationInfo ASN.1 structure. 189 // */ 190 // public void addOtherRevocationInfo( 191 // ASN1ObjectIdentifier otherRevocationInfoFormat, 192 // ASN1Encodable otherRevocationInfo) 193 // { 194 // crls.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, otherRevocationInfo))); 195 // } 196 // 197 // /** 198 // * Add a Store of otherRevocationData to the CRL set to be included with the generated SignedData message. 199 // * 200 // * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data. 201 // * @param otherRevocationInfos a Store of otherRevocationInfo data to add. 202 // */ 203 // public void addOtherRevocationInfo( 204 // ASN1ObjectIdentifier otherRevocationInfoFormat, 205 // Store otherRevocationInfos) 206 // { 207 // crls.addAll(CMSUtils.getOthersFromStore(otherRevocationInfoFormat, otherRevocationInfos)); 208 // } 209 // END android-removed 210 211 /** 212 * Add a store of pre-calculated signers to the generator. 213 * 214 * @param signerStore store of signers 215 */ 216 public void addSigners( 217 SignerInformationStore signerStore) 218 { 219 Iterator it = signerStore.getSigners().iterator(); 220 221 while (it.hasNext()) 222 { 223 _signers.add(it.next()); 224 } 225 } 226 227 /** 228 * Add a generator for a particular signer to this CMS SignedData generator. 229 * 230 * @param infoGen the generator representing the particular signer. 231 */ 232 public void addSignerInfoGenerator(SignerInfoGenerator infoGen) 233 { 234 signerGens.add(infoGen); 235 } 236 237 /** 238 * Return a map of oids and byte arrays representing the digests calculated on the content during 239 * the last generate. 240 * 241 * @return a map of oids (as String objects) and byte[] representing digests. 242 */ 243 public Map getGeneratedDigests() 244 { 245 return new HashMap(digests); 246 } 247} 248