01: package org.bouncycastle.cms;
02:
03: import org.bouncycastle.asn1.ASN1OctetString;
04: import org.bouncycastle.asn1.ASN1Sequence;
05: import org.bouncycastle.asn1.DERObjectIdentifier;
06: import org.bouncycastle.asn1.cms.PasswordRecipientInfo;
07: import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
08:
09: import javax.crypto.Cipher;
10: import javax.crypto.NoSuchPaddingException;
11: import javax.crypto.spec.IvParameterSpec;
12: import javax.crypto.spec.SecretKeySpec;
13: import java.io.InputStream;
14: import java.security.InvalidAlgorithmParameterException;
15: import java.security.InvalidKeyException;
16: import java.security.Key;
17: import java.security.NoSuchAlgorithmException;
18: import java.security.NoSuchProviderException;
19:
20: /**
21: * the RecipientInfo class for a recipient who has been sent a message
22: * encrypted using a password.
23: */
24: public class PasswordRecipientInformation extends RecipientInformation {
25: private PasswordRecipientInfo _info;
26: private AlgorithmIdentifier _encAlg;
27:
28: public PasswordRecipientInformation(PasswordRecipientInfo info,
29: AlgorithmIdentifier encAlg, InputStream data) {
30: super (encAlg, AlgorithmIdentifier.getInstance(info
31: .getKeyEncryptionAlgorithm()), data);
32:
33: this ._info = info;
34: this ._encAlg = encAlg;
35: this ._rid = new RecipientId();
36: }
37:
38: /**
39: * decrypt the content and return an input stream.
40: */
41: public CMSTypedStream getContentStream(Key key, String prov)
42: throws CMSException, NoSuchProviderException {
43: try {
44: AlgorithmIdentifier kekAlg = AlgorithmIdentifier
45: .getInstance(_info.getKeyEncryptionAlgorithm());
46: ASN1Sequence kekAlgParams = (ASN1Sequence) kekAlg
47: .getParameters();
48: byte[] encryptedKey = _info.getEncryptedKey().getOctets();
49: String kekAlgName = DERObjectIdentifier.getInstance(
50: kekAlgParams.getObjectAt(0)).getId();
51: Cipher keyCipher = Cipher.getInstance(
52: CMSEnvelopedHelper.INSTANCE
53: .getRFC3211WrapperName(kekAlgName), prov);
54:
55: IvParameterSpec ivSpec = new IvParameterSpec(
56: ASN1OctetString.getInstance(
57: kekAlgParams.getObjectAt(1)).getOctets());
58: keyCipher.init(Cipher.UNWRAP_MODE, new SecretKeySpec(
59: ((CMSPBEKey) key).getEncoded(kekAlgName),
60: kekAlgName), ivSpec);
61:
62: AlgorithmIdentifier aid = _encAlg;
63: String alg = aid.getObjectId().getId();
64: Key sKey = keyCipher.unwrap(encryptedKey, alg,
65: Cipher.SECRET_KEY);
66:
67: return getContentFromSessionKey(sKey, prov);
68: } catch (NoSuchAlgorithmException e) {
69: throw new CMSException("can't find algorithm.", e);
70: } catch (InvalidKeyException e) {
71: throw new CMSException("key invalid in message.", e);
72: } catch (NoSuchPaddingException e) {
73: throw new CMSException("required padding not supported.", e);
74: } catch (InvalidAlgorithmParameterException e) {
75: throw new CMSException("invalid iv.", e);
76: }
77: }
78: }
|