001: package org.bouncycastle.cms;
002:
003: import org.bouncycastle.asn1.ASN1Object;
004: import org.bouncycastle.asn1.ASN1Set;
005: import org.bouncycastle.asn1.DERNull;
006: import org.bouncycastle.asn1.DERObjectIdentifier;
007: import org.bouncycastle.asn1.DERSet;
008: import org.bouncycastle.asn1.DERTaggedObject;
009: import org.bouncycastle.asn1.cms.AttributeTable;
010: import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
011: import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
012: import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
013: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
014: import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
015: import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
016: import org.bouncycastle.asn1.x509.AttributeCertificate;
017: import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
018: import org.bouncycastle.jce.interfaces.GOST3410PrivateKey;
019: import org.bouncycastle.x509.X509AttributeCertificate;
020: import org.bouncycastle.x509.X509Store;
021:
022: import java.io.IOException;
023: import java.security.PrivateKey;
024: import java.security.cert.CertStore;
025: import java.security.cert.CertStoreException;
026: import java.security.interfaces.DSAPrivateKey;
027: import java.security.interfaces.RSAPrivateKey;
028: import java.util.ArrayList;
029: import java.util.HashMap;
030: import java.util.HashSet;
031: import java.util.Iterator;
032: import java.util.List;
033: import java.util.Map;
034: import java.util.Set;
035:
036: public class CMSSignedGenerator {
037: /**
038: * Default type for the signed data.
039: */
040: public static final String DATA = PKCSObjectIdentifiers.data
041: .getId();
042:
043: public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1
044: .getId();
045: public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224
046: .getId();
047: public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256
048: .getId();
049: public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384
050: .getId();
051: public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512
052: .getId();
053: public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5
054: .getId();
055: public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411
056: .getId();
057: public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128
058: .getId();
059: public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160
060: .getId();
061: public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256
062: .getId();
063:
064: public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption
065: .getId();
066: public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1
067: .getId();
068: public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1
069: .getId();
070: public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS
071: .getId();
072: public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94
073: .getId();
074: public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001
075: .getId();
076:
077: private static final String ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1
078: .getId();
079: private static final String ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224
080: .getId();
081: private static final String ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256
082: .getId();
083: private static final String ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384
084: .getId();
085: private static final String ENCRYPTION_ECDSA_WITH_SHA512 = X9ObjectIdentifiers.ecdsa_with_SHA512
086: .getId();
087:
088: private static final Set NO_PARAMS = new HashSet();
089: private static final Map EC_ALGORITHMS = new HashMap();
090:
091: static {
092: NO_PARAMS.add(ENCRYPTION_DSA);
093: NO_PARAMS.add(ENCRYPTION_ECDSA);
094: NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1);
095: NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224);
096: NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256);
097: NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384);
098: NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA512);
099:
100: EC_ALGORITHMS.put(DIGEST_SHA1, ENCRYPTION_ECDSA_WITH_SHA1);
101: EC_ALGORITHMS.put(DIGEST_SHA224, ENCRYPTION_ECDSA_WITH_SHA224);
102: EC_ALGORITHMS.put(DIGEST_SHA256, ENCRYPTION_ECDSA_WITH_SHA256);
103: EC_ALGORITHMS.put(DIGEST_SHA384, ENCRYPTION_ECDSA_WITH_SHA384);
104: EC_ALGORITHMS.put(DIGEST_SHA512, ENCRYPTION_ECDSA_WITH_SHA512);
105: }
106:
107: protected List _certs = new ArrayList();
108: protected List _crls = new ArrayList();
109: protected List _signers = new ArrayList();
110: protected Map _digests = new HashMap();
111:
112: protected CMSSignedGenerator() {
113:
114: }
115:
116: protected String getEncOID(PrivateKey key, String digestOID) {
117: String encOID = null;
118:
119: if (key instanceof RSAPrivateKey
120: || "RSA".equalsIgnoreCase(key.getAlgorithm())) {
121: encOID = ENCRYPTION_RSA;
122: } else if (key instanceof DSAPrivateKey
123: || "DSA".equalsIgnoreCase(key.getAlgorithm())) {
124: encOID = ENCRYPTION_DSA;
125: if (!digestOID.equals(DIGEST_SHA1)) {
126: throw new IllegalArgumentException(
127: "can't mix DSA with anything but SHA1");
128: }
129: } else if ("ECDSA".equalsIgnoreCase(key.getAlgorithm())
130: || "EC".equalsIgnoreCase(key.getAlgorithm())) {
131: encOID = (String) EC_ALGORITHMS.get(digestOID);
132: if (encOID == null) {
133: throw new IllegalArgumentException(
134: "can't mix ECDSA with anything but SHA family digests");
135: }
136: } else if (key instanceof GOST3410PrivateKey
137: || "GOST3410".equalsIgnoreCase(key.getAlgorithm())) {
138: encOID = ENCRYPTION_GOST3410;
139: } else if ("ECGOST3410".equalsIgnoreCase(key.getAlgorithm())) {
140: encOID = ENCRYPTION_ECGOST3410;
141: }
142:
143: return encOID;
144: }
145:
146: protected AlgorithmIdentifier getEncAlgorithmIdentifier(
147: String encOid) {
148: if (NO_PARAMS.contains(encOid)) {
149: return new AlgorithmIdentifier(new DERObjectIdentifier(
150: encOid));
151: } else {
152: return new AlgorithmIdentifier(new DERObjectIdentifier(
153: encOid), new DERNull());
154: }
155: }
156:
157: protected Map getBaseParameters(DERObjectIdentifier contentType,
158: AlgorithmIdentifier digAlgId, byte[] hash) {
159: Map param = new HashMap();
160:
161: param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType);
162: param.put(
163: CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER,
164: digAlgId);
165:
166: if (hash != null) {
167: param.put(CMSAttributeTableGenerator.DIGEST, hash.clone());
168: }
169:
170: return param;
171: }
172:
173: protected ASN1Set getAttributeSet(AttributeTable attr) {
174: if (attr != null) {
175: return new DERSet(attr.toASN1EncodableVector());
176: }
177:
178: return null;
179: }
180:
181: /**
182: * add the certificates and CRLs contained in the given CertStore
183: * to the pool that will be included in the encoded signature block.
184: * <p>
185: * Note: this assumes the CertStore will support null in the get
186: * methods.
187: * @param certStore CertStore containing the public key certificates and CRLs
188: * @throws java.security.cert.CertStoreException if an issue occurs processing the CertStore
189: * @throws CMSException if an issue occurse transforming data from the CertStore into the message
190: */
191: public void addCertificatesAndCRLs(CertStore certStore)
192: throws CertStoreException, CMSException {
193: _certs.addAll(CMSUtils.getCertificatesFromStore(certStore));
194: _crls.addAll(CMSUtils.getCRLsFromStore(certStore));
195: }
196:
197: /**
198: * Add the attribute certificates contained in the passed in store to the
199: * generator.
200: *
201: * @param store a store of Version 2 attribute certificates
202: * @throws CMSException if an error occurse processing the store.
203: */
204: public void addAttributeCertificates(X509Store store)
205: throws CMSException {
206: try {
207: for (Iterator it = store.getMatches(null).iterator(); it
208: .hasNext();) {
209: X509AttributeCertificate attrCert = (X509AttributeCertificate) it
210: .next();
211:
212: _certs
213: .add(new DERTaggedObject(false, 2,
214: AttributeCertificate
215: .getInstance(ASN1Object
216: .fromByteArray(attrCert
217: .getEncoded()))));
218: }
219: } catch (IllegalArgumentException e) {
220: throw new CMSException("error processing attribute certs",
221: e);
222: } catch (IOException e) {
223: throw new CMSException("error processing attribute certs",
224: e);
225: }
226: }
227:
228: /**
229: * Add a store of precalculated signers to the generator.
230: *
231: * @param signerStore store of signers
232: */
233: public void addSigners(SignerInformationStore signerStore) {
234: Iterator it = signerStore.getSigners().iterator();
235:
236: while (it.hasNext()) {
237: _signers.add(it.next());
238: }
239: }
240:
241: /**
242: * Return a map of oids and byte arrays representing the digests calculated on the content during
243: * the last generate.
244: *
245: * @return a map of oids (as String objects) and byte[] representing digests.
246: */
247: public Map getGeneratedDigests() {
248: return new HashMap(_digests);
249: }
250: }
|