001: package org.bouncycastle.cms;
002:
003: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
004:
005: import javax.crypto.Cipher;
006: import javax.crypto.KeyGenerator;
007: import javax.crypto.NoSuchPaddingException;
008: import java.io.IOException;
009: import java.security.AlgorithmParameters;
010: import java.security.NoSuchAlgorithmException;
011: import java.security.NoSuchProviderException;
012: import java.util.HashMap;
013: import java.util.Map;
014:
015: class CMSEnvelopedHelper {
016: static final CMSEnvelopedHelper INSTANCE = new CMSEnvelopedHelper();
017:
018: private static final Map KEYSIZES = new HashMap();
019: private static final Map BASE_CIPHER_NAMES = new HashMap();
020: private static final Map CIPHER_ALG_NAMES = new HashMap();
021:
022: static {
023: KEYSIZES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, new Integer(
024: 192));
025: KEYSIZES
026: .put(CMSEnvelopedGenerator.AES128_CBC, new Integer(128));
027: KEYSIZES
028: .put(CMSEnvelopedGenerator.AES192_CBC, new Integer(192));
029: KEYSIZES
030: .put(CMSEnvelopedGenerator.AES256_CBC, new Integer(256));
031:
032: BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC,
033: "DESEDE");
034: BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES");
035: BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES");
036: BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES");
037:
038: CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC,
039: "DESEDE/CBC/PKCS5Padding");
040: CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES128_CBC,
041: "AES/CBC/PKCS5Padding");
042: CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES192_CBC,
043: "AES/CBC/PKCS5Padding");
044: CIPHER_ALG_NAMES.put(CMSEnvelopedGenerator.AES256_CBC,
045: "AES/CBC/PKCS5Padding");
046: }
047:
048: private String getAsymmetricEncryptionAlgName(
049: String encryptionAlgOID) {
050: if (PKCSObjectIdentifiers.rsaEncryption.getId().equals(
051: encryptionAlgOID)) {
052: return "RSA/ECB/PKCS1Padding";
053: }
054:
055: return encryptionAlgOID;
056: }
057:
058: Cipher createAsymmetricCipher(String encryptionOid, String provider)
059: throws NoSuchAlgorithmException, NoSuchProviderException,
060: NoSuchPaddingException {
061: try {
062: return createCipher(encryptionOid, provider);
063: } catch (NoSuchAlgorithmException e) {
064: return createCipher(
065: getAsymmetricEncryptionAlgName(encryptionOid),
066: provider);
067: }
068: }
069:
070: KeyGenerator createSymmetricKeyGenerator(String encryptionOID,
071: String provider) throws NoSuchProviderException,
072: NoSuchAlgorithmException {
073: try {
074: return createKeyGenerator(encryptionOID, provider);
075: } catch (NoSuchAlgorithmException e) {
076: try {
077: String algName = (String) BASE_CIPHER_NAMES
078: .get(encryptionOID);
079: if (algName != null) {
080: return createKeyGenerator(algName, provider);
081: }
082: } catch (NoSuchAlgorithmException ex) {
083: // ignore
084: }
085: if (provider != null) {
086: return createSymmetricKeyGenerator(encryptionOID, null);
087: }
088: throw e;
089: }
090: }
091:
092: AlgorithmParameters createAlgorithmParameters(String encryptionOID,
093: String provider) throws NoSuchProviderException,
094: NoSuchAlgorithmException {
095: try {
096: return createAlgorithmParams(encryptionOID, provider);
097: } catch (NoSuchAlgorithmException e) {
098: try {
099: String algName = (String) BASE_CIPHER_NAMES
100: .get(encryptionOID);
101: if (algName != null) {
102: return createAlgorithmParams(algName, provider);
103: }
104: } catch (NoSuchAlgorithmException ex) {
105: // ignore
106: }
107: //
108: // can't try with default provider here as parameters must be from the specified provider.
109: //
110: throw e;
111: }
112: }
113:
114: String getRFC3211WrapperName(String oid) {
115: String alg = (String) BASE_CIPHER_NAMES.get(oid);
116:
117: if (alg == null) {
118: throw new IllegalArgumentException("no name for " + oid);
119: }
120:
121: return alg + "RFC3211Wrap";
122: }
123:
124: int getKeySize(String oid) {
125: Integer keySize = (Integer) KEYSIZES.get(oid);
126:
127: if (keySize == null) {
128: throw new IllegalArgumentException("no keysize for " + oid);
129: }
130:
131: return keySize.intValue();
132: }
133:
134: private Cipher createCipher(String algName, String provider)
135: throws NoSuchProviderException, NoSuchAlgorithmException,
136: NoSuchPaddingException {
137: if (provider != null) {
138: return Cipher.getInstance(algName, provider);
139: } else {
140: return Cipher.getInstance(algName);
141: }
142: }
143:
144: private AlgorithmParameters createAlgorithmParams(String algName,
145: String provider) throws NoSuchProviderException,
146: NoSuchAlgorithmException {
147: if (provider != null) {
148: return AlgorithmParameters.getInstance(algName, provider);
149: } else {
150: return AlgorithmParameters.getInstance(algName);
151: }
152: }
153:
154: private KeyGenerator createKeyGenerator(String algName,
155: String provider) throws NoSuchProviderException,
156: NoSuchAlgorithmException {
157: if (provider != null) {
158: return KeyGenerator.getInstance(algName, provider);
159: } else {
160: return KeyGenerator.getInstance(algName);
161: }
162: }
163:
164: Cipher getSymmetricCipher(String encryptionOID, String provider)
165: throws NoSuchProviderException, NoSuchAlgorithmException,
166: NoSuchPaddingException {
167: try {
168: return createCipher(encryptionOID, provider);
169: } catch (NoSuchAlgorithmException e) {
170: String alternate = (String) CIPHER_ALG_NAMES
171: .get(encryptionOID);
172:
173: try {
174: return createCipher(alternate, provider);
175: } catch (NoSuchAlgorithmException ex) {
176: if (provider != null) {
177: return getSymmetricCipher(encryptionOID, null); // roll back to default
178: }
179: throw e;
180: }
181: }
182: }
183:
184: AlgorithmParameters getEncryptionAlgorithmParameters(String encOID,
185: byte[] encParams, String provider) throws CMSException,
186: NoSuchProviderException {
187: if (encParams == null) {
188: return null;
189: }
190:
191: try {
192: AlgorithmParameters params = createAlgorithmParameters(
193: encOID, provider);
194:
195: params.init(encParams, "ASN.1");
196:
197: return params;
198: } catch (NoSuchAlgorithmException e) {
199: throw new CMSException(
200: "can't find parameters for algorithm", e);
201: } catch (IOException e) {
202: throw new CMSException("can't find parse parameters", e);
203: }
204: }
205:
206: String getSymmetricCipherName(String oid) {
207: String algName = (String) BASE_CIPHER_NAMES.get(oid);
208: if (algName != null) {
209: return algName;
210: }
211: return oid;
212: }
213: }
|