1 package org.bouncycastle.asn1.cms;
2 
3 import org.bouncycastle.asn1.ASN1EncodableVector;
4 import org.bouncycastle.asn1.ASN1Integer;
5 import org.bouncycastle.asn1.ASN1Object;
6 import org.bouncycastle.asn1.ASN1OctetString;
7 import org.bouncycastle.asn1.ASN1Primitive;
8 import org.bouncycastle.asn1.ASN1Sequence;
9 import org.bouncycastle.asn1.ASN1TaggedObject;
10 import org.bouncycastle.asn1.DERSequence;
11 import org.bouncycastle.asn1.DERTaggedObject;
12 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
13 
14 /**
15  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.7">RFC 5652</a>:
16  * Content encryption key delivery mechanisms.
17  * <pre>
18  * PasswordRecipientInfo ::= SEQUENCE {
19  *     version       CMSVersion,   -- Always set to 0
20  *     keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier
21  *                             OPTIONAL,
22  *     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
23  *     encryptedKey  EncryptedKey }
24  * </pre>
25  */
26 public class PasswordRecipientInfo
27     extends ASN1Object
28 {
29     private ASN1Integer          version;
30     private AlgorithmIdentifier keyDerivationAlgorithm;
31     private AlgorithmIdentifier keyEncryptionAlgorithm;
32     private ASN1OctetString     encryptedKey;
33 
PasswordRecipientInfo( AlgorithmIdentifier keyEncryptionAlgorithm, ASN1OctetString encryptedKey)34     public PasswordRecipientInfo(
35         AlgorithmIdentifier     keyEncryptionAlgorithm,
36         ASN1OctetString         encryptedKey)
37     {
38         this.version = new ASN1Integer(0);
39         this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
40         this.encryptedKey = encryptedKey;
41     }
42 
PasswordRecipientInfo( AlgorithmIdentifier keyDerivationAlgorithm, AlgorithmIdentifier keyEncryptionAlgorithm, ASN1OctetString encryptedKey)43     public PasswordRecipientInfo(
44         AlgorithmIdentifier     keyDerivationAlgorithm,
45         AlgorithmIdentifier     keyEncryptionAlgorithm,
46         ASN1OctetString         encryptedKey)
47     {
48         this.version = new ASN1Integer(0);
49         this.keyDerivationAlgorithm = keyDerivationAlgorithm;
50         this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
51         this.encryptedKey = encryptedKey;
52     }
53 
54     /**
55      * @deprecated use getInstance() method.
56      */
PasswordRecipientInfo( ASN1Sequence seq)57     public PasswordRecipientInfo(
58         ASN1Sequence seq)
59     {
60         version = (ASN1Integer)seq.getObjectAt(0);
61         if (seq.getObjectAt(1) instanceof ASN1TaggedObject)
62         {
63             keyDerivationAlgorithm = AlgorithmIdentifier.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false);
64             keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(2));
65             encryptedKey = (ASN1OctetString)seq.getObjectAt(3);
66         }
67         else
68         {
69             keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
70             encryptedKey = (ASN1OctetString)seq.getObjectAt(2);
71         }
72     }
73 
74     /**
75      * Return a PasswordRecipientInfo object from a tagged object.
76      *
77      * @param obj the tagged object holding the object we want.
78      * @param explicit true if the object is meant to be explicitly
79      *              tagged false otherwise.
80      * @exception IllegalArgumentException if the object held by the
81      *          tagged object cannot be converted.
82      */
getInstance( ASN1TaggedObject obj, boolean explicit)83     public static PasswordRecipientInfo getInstance(
84         ASN1TaggedObject    obj,
85         boolean             explicit)
86     {
87         return getInstance(ASN1Sequence.getInstance(obj, explicit));
88     }
89 
90     /**
91      * Return a PasswordRecipientInfo object from the given object.
92      * <p>
93      * Accepted inputs:
94      * <ul>
95      * <li> null &rarr; null
96      * <li> {@link PasswordRecipientInfo} object
97      * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with PasswordRecipientInfo structure inside
98      * </ul>
99      *
100      * @param obj the object we want converted.
101      * @exception IllegalArgumentException if the object cannot be converted.
102      */
getInstance( Object obj)103     public static PasswordRecipientInfo getInstance(
104         Object obj)
105     {
106         if (obj instanceof PasswordRecipientInfo)
107         {
108             return (PasswordRecipientInfo)obj;
109         }
110 
111         if (obj != null)
112         {
113             return new PasswordRecipientInfo(ASN1Sequence.getInstance(obj));
114         }
115 
116         return null;
117     }
118 
getVersion()119     public ASN1Integer getVersion()
120     {
121         return version;
122     }
123 
getKeyDerivationAlgorithm()124     public AlgorithmIdentifier getKeyDerivationAlgorithm()
125     {
126         return keyDerivationAlgorithm;
127     }
128 
getKeyEncryptionAlgorithm()129     public AlgorithmIdentifier getKeyEncryptionAlgorithm()
130     {
131         return keyEncryptionAlgorithm;
132     }
133 
getEncryptedKey()134     public ASN1OctetString getEncryptedKey()
135     {
136         return encryptedKey;
137     }
138 
139     /**
140      * Produce an object suitable for an ASN1OutputStream.
141      */
toASN1Primitive()142     public ASN1Primitive toASN1Primitive()
143     {
144         ASN1EncodableVector v = new ASN1EncodableVector(4);
145 
146         v.add(version);
147 
148         if (keyDerivationAlgorithm != null)
149         {
150             v.add(new DERTaggedObject(false, 0, keyDerivationAlgorithm));
151         }
152         v.add(keyEncryptionAlgorithm);
153         v.add(encryptedKey);
154 
155         return new DERSequence(v);
156     }
157 }
158