001: package org.bouncycastle.cms;
002:
003: import org.bouncycastle.asn1.ASN1Sequence;
004: import org.bouncycastle.asn1.ASN1Set;
005: import org.bouncycastle.asn1.ASN1TaggedObject;
006: import org.bouncycastle.asn1.DEREncodable;
007: import org.bouncycastle.asn1.DERObject;
008: import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
009: import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
010: import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
011: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
012: import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
013: import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
014: import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
015: import org.bouncycastle.x509.NoSuchStoreException;
016: import org.bouncycastle.x509.X509CollectionStoreParameters;
017: import org.bouncycastle.x509.X509Store;
018: import org.bouncycastle.x509.X509V2AttributeCertificate;
019:
020: import java.io.ByteArrayInputStream;
021: import java.io.IOException;
022: import java.security.InvalidAlgorithmParameterException;
023: import java.security.MessageDigest;
024: import java.security.NoSuchAlgorithmException;
025: import java.security.NoSuchProviderException;
026: import java.security.Signature;
027: import java.security.cert.CRLException;
028: import java.security.cert.CertStore;
029: import java.security.cert.CertificateException;
030: import java.security.cert.CertificateFactory;
031: import java.security.cert.CollectionCertStoreParameters;
032: import java.util.ArrayList;
033: import java.util.Enumeration;
034: import java.util.HashMap;
035: import java.util.List;
036: import java.util.Map;
037:
038: class CMSSignedHelper {
039: static final CMSSignedHelper INSTANCE = new CMSSignedHelper();
040:
041: private static final Map encryptionAlgs = new HashMap();
042: private static final Map digestAlgs = new HashMap();
043: private static final Map digestAliases = new HashMap();
044:
045: static {
046: encryptionAlgs.put(
047: X9ObjectIdentifiers.id_dsa_with_sha1.getId(), "DSA");
048: encryptionAlgs.put(X9ObjectIdentifiers.id_dsa.getId(), "DSA");
049: encryptionAlgs.put(OIWObjectIdentifiers.dsaWithSHA1.getId(),
050: "DSA");
051: encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption.getId(),
052: "RSA");
053: encryptionAlgs.put(PKCSObjectIdentifiers.sha1WithRSAEncryption
054: .getId(), "RSA");
055: encryptionAlgs
056: .put(
057: TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm,
058: "RSA");
059: encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa.getId(),
060: "RSA");
061: encryptionAlgs.put(CMSSignedDataGenerator.ENCRYPTION_ECDSA,
062: "ECDSA");
063: encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA2.getId(),
064: "ECDSA");
065: encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA224
066: .getId(), "ECDSA");
067: encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA256
068: .getId(), "ECDSA");
069: encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA384
070: .getId(), "ECDSA");
071: encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA512
072: .getId(), "ECDSA");
073: encryptionAlgs.put(CMSSignedDataGenerator.ENCRYPTION_RSA_PSS,
074: "RSAandMGF1");
075: encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94
076: .getId(), "GOST3410");
077: encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001
078: .getId(), "ECGOST3410");
079: encryptionAlgs.put("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410");
080: encryptionAlgs.put("1.3.6.1.4.1.5849.1.1.5", "GOST3410");
081:
082: digestAlgs.put(PKCSObjectIdentifiers.md5.getId(), "MD5");
083: digestAlgs.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1");
084: digestAlgs.put(NISTObjectIdentifiers.id_sha224.getId(),
085: "SHA224");
086: digestAlgs.put(NISTObjectIdentifiers.id_sha256.getId(),
087: "SHA256");
088: digestAlgs.put(NISTObjectIdentifiers.id_sha384.getId(),
089: "SHA384");
090: digestAlgs.put(NISTObjectIdentifiers.id_sha512.getId(),
091: "SHA512");
092: digestAlgs.put(PKCSObjectIdentifiers.sha1WithRSAEncryption
093: .getId(), "SHA1");
094: digestAlgs.put(PKCSObjectIdentifiers.sha224WithRSAEncryption
095: .getId(), "SHA224");
096: digestAlgs.put(PKCSObjectIdentifiers.sha256WithRSAEncryption
097: .getId(), "SHA256");
098: digestAlgs.put(PKCSObjectIdentifiers.sha384WithRSAEncryption
099: .getId(), "SHA384");
100: digestAlgs.put(PKCSObjectIdentifiers.sha512WithRSAEncryption
101: .getId(), "SHA512");
102: digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128.getId(),
103: "RIPEMD128");
104: digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160.getId(),
105: "RIPEMD160");
106: digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256.getId(),
107: "RIPEMD256");
108: digestAlgs.put(CryptoProObjectIdentifiers.gostR3411.getId(),
109: "GOST3411");
110: digestAlgs.put("1.3.6.1.4.1.5849.1.2.1", "GOST3411");
111:
112: digestAliases.put("SHA1", new String[] { "SHA-1" });
113: digestAliases.put("SHA224", new String[] { "SHA-224" });
114: digestAliases.put("SHA256", new String[] { "SHA-256" });
115: digestAliases.put("SHA384", new String[] { "SHA-384" });
116: digestAliases.put("SHA512", new String[] { "SHA-512" });
117: }
118:
119: /**
120: * Return the digest algorithm using one of the standard JCA string
121: * representations rather than the algorithm identifier (if possible).
122: */
123: String getDigestAlgName(String digestAlgOID) {
124: String algName = (String) digestAlgs.get(digestAlgOID);
125:
126: if (algName != null) {
127: return algName;
128: }
129:
130: return digestAlgOID;
131: }
132:
133: String[] getDigestAliases(String algName) {
134: String[] aliases = (String[]) digestAliases.get(algName);
135:
136: if (aliases != null) {
137: return aliases;
138: }
139:
140: return new String[0];
141: }
142:
143: /**
144: * Return the digest encryption algorithm using one of the standard
145: * JCA string representations rather the the algorithm identifier (if
146: * possible).
147: */
148: String getEncryptionAlgName(String encryptionAlgOID) {
149: String algName = (String) encryptionAlgs.get(encryptionAlgOID);
150:
151: if (algName != null) {
152: return algName;
153: }
154:
155: return encryptionAlgOID;
156: }
157:
158: MessageDigest getDigestInstance(String algorithm, String provider)
159: throws NoSuchProviderException, NoSuchAlgorithmException {
160: try {
161: return createDigestInstance(algorithm, provider);
162: } catch (NoSuchAlgorithmException e) {
163: String[] aliases = getDigestAliases(algorithm);
164: for (int i = 0; i != aliases.length; i++) {
165: try {
166: return createDigestInstance(aliases[i], provider);
167: } catch (NoSuchAlgorithmException ex) {
168: // continue
169: }
170: }
171: if (provider != null) {
172: return getDigestInstance(algorithm, null); // try rolling back
173: }
174: throw e;
175: }
176: }
177:
178: private MessageDigest createDigestInstance(String algorithm,
179: String provider) throws NoSuchAlgorithmException,
180: NoSuchProviderException {
181: if (provider != null) {
182: return MessageDigest.getInstance(algorithm, provider);
183: } else {
184: return MessageDigest.getInstance(algorithm);
185: }
186: }
187:
188: Signature getSignatureInstance(String algorithm, String provider)
189: throws NoSuchProviderException, NoSuchAlgorithmException {
190: if (provider != null) {
191: return Signature.getInstance(algorithm, provider);
192: } else {
193: return Signature.getInstance(algorithm);
194: }
195: }
196:
197: X509Store createAttributeStore(String type, String provider,
198: ASN1Set certSet) throws NoSuchStoreException,
199: NoSuchProviderException, CMSException {
200: List certs = new ArrayList();
201:
202: if (certSet != null) {
203: Enumeration e = certSet.getObjects();
204:
205: while (e.hasMoreElements()) {
206: try {
207: DERObject obj = ((DEREncodable) e.nextElement())
208: .getDERObject();
209:
210: if (obj instanceof ASN1TaggedObject) {
211: ASN1TaggedObject tagged = (ASN1TaggedObject) obj;
212:
213: if (tagged.getTagNo() == 2) {
214: certs.add(new X509V2AttributeCertificate(
215: ASN1Sequence.getInstance(tagged,
216: false).getEncoded()));
217: }
218: }
219: } catch (IOException ex) {
220: throw new CMSException(
221: "can't re-encode attribute certificate!",
222: ex);
223: }
224: }
225: }
226:
227: try {
228: return X509Store.getInstance(
229: "AttributeCertificate/" + type,
230: new X509CollectionStoreParameters(certs), provider);
231: } catch (IllegalArgumentException e) {
232: throw new CMSException("can't setup the X509Store", e);
233: }
234: }
235:
236: X509Store createCertificateStore(String type, String provider,
237: ASN1Set certSet) throws NoSuchStoreException,
238: NoSuchProviderException, CMSException {
239: List certs = new ArrayList();
240:
241: if (certSet != null) {
242: addCertsFromSet(certs, certSet, provider);
243: }
244:
245: try {
246: return X509Store.getInstance("Certificate/" + type,
247: new X509CollectionStoreParameters(certs), provider);
248: } catch (IllegalArgumentException e) {
249: throw new CMSException("can't setup the X509Store", e);
250: }
251: }
252:
253: X509Store createCRLsStore(String type, String provider,
254: ASN1Set crlSet) throws NoSuchStoreException,
255: NoSuchProviderException, CMSException {
256: List crls = new ArrayList();
257:
258: if (crlSet != null) {
259: addCRLsFromSet(crls, crlSet, provider);
260: }
261:
262: try {
263: return X509Store.getInstance("CRL/" + type,
264: new X509CollectionStoreParameters(crls), provider);
265: } catch (IllegalArgumentException e) {
266: throw new CMSException("can't setup the X509Store", e);
267: }
268: }
269:
270: CertStore createCertStore(String type, String provider,
271: ASN1Set certSet, ASN1Set crlSet)
272: throws NoSuchProviderException, CMSException,
273: NoSuchAlgorithmException {
274: List certsAndcrls = new ArrayList();
275:
276: //
277: // load the certificates and revocation lists if we have any
278: //
279:
280: if (certSet != null) {
281: addCertsFromSet(certsAndcrls, certSet, provider);
282: }
283:
284: if (crlSet != null) {
285: addCRLsFromSet(certsAndcrls, crlSet, provider);
286: }
287:
288: try {
289: if (provider != null) {
290: return CertStore
291: .getInstance(type,
292: new CollectionCertStoreParameters(
293: certsAndcrls), provider);
294: } else {
295: return CertStore
296: .getInstance(type,
297: new CollectionCertStoreParameters(
298: certsAndcrls));
299: }
300: } catch (InvalidAlgorithmParameterException e) {
301: throw new CMSException("can't setup the CertStore", e);
302: }
303: }
304:
305: private void addCertsFromSet(List certs, ASN1Set certSet,
306: String provider) throws NoSuchProviderException,
307: CMSException {
308: CertificateFactory cf;
309:
310: try {
311: if (provider != null) {
312: cf = CertificateFactory.getInstance("X.509", provider);
313: } else {
314: cf = CertificateFactory.getInstance("X.509");
315: }
316: } catch (CertificateException ex) {
317: throw new CMSException("can't get certificate factory.", ex);
318: }
319: Enumeration e = certSet.getObjects();
320:
321: while (e.hasMoreElements()) {
322: try {
323: DERObject obj = ((DEREncodable) e.nextElement())
324: .getDERObject();
325:
326: if (obj instanceof ASN1Sequence) {
327: certs
328: .add(cf
329: .generateCertificate(new ByteArrayInputStream(
330: obj.getEncoded())));
331: }
332: } catch (IOException ex) {
333: throw new CMSException("can't re-encode certificate!",
334: ex);
335: } catch (CertificateException ex) {
336: throw new CMSException("can't re-encode certificate!",
337: ex);
338: }
339: }
340: }
341:
342: private void addCRLsFromSet(List crls, ASN1Set certSet,
343: String provider) throws NoSuchProviderException,
344: CMSException {
345: CertificateFactory cf;
346:
347: try {
348: if (provider != null) {
349: cf = CertificateFactory.getInstance("X.509", provider);
350: } else {
351: cf = CertificateFactory.getInstance("X.509");
352: }
353: } catch (CertificateException ex) {
354: throw new CMSException("can't get certificate factory.", ex);
355: }
356: Enumeration e = certSet.getObjects();
357:
358: while (e.hasMoreElements()) {
359: try {
360: DERObject obj = ((DEREncodable) e.nextElement())
361: .getDERObject();
362:
363: crls.add(cf.generateCRL(new ByteArrayInputStream(obj
364: .getEncoded())));
365: } catch (IOException ex) {
366: throw new CMSException("can't re-encode CRL!", ex);
367: } catch (CRLException ex) {
368: throw new CMSException("can't re-encode CRL!", ex);
369: }
370: }
371: }
372:
373: private boolean anyCertHasTypeOther() {
374: // not supported
375: return false;
376: }
377:
378: private boolean anyCertHasV1Attribute() {
379: // obsolete
380: return false;
381: }
382:
383: private boolean anyCertHasV2Attribute() {
384: // TODO
385: return false;
386: }
387:
388: private boolean anyCrlHasTypeOther() {
389: // not supported
390: return false;
391: }
392:
393: }
|