1 package org.bouncycastle.asn1.cms;
2 
3 import java.util.Enumeration;
4 
5 import org.bouncycastle.asn1.ASN1EncodableVector;
6 import org.bouncycastle.asn1.ASN1Integer;
7 import org.bouncycastle.asn1.ASN1Object;
8 import org.bouncycastle.asn1.ASN1Primitive;
9 import org.bouncycastle.asn1.ASN1Sequence;
10 import org.bouncycastle.asn1.ASN1Set;
11 import org.bouncycastle.asn1.ASN1TaggedObject;
12 import org.bouncycastle.asn1.BERSequence;
13 import org.bouncycastle.asn1.DERTaggedObject;
14 
15 /**
16  * <a href="https://tools.ietf.org/html/rfc5652#section-6.1">RFC 5652</a> EnvelopedData object.
17  * <pre>
18  * EnvelopedData ::= SEQUENCE {
19  *     version CMSVersion,
20  *     originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
21  *     recipientInfos RecipientInfos,
22  *     encryptedContentInfo EncryptedContentInfo,
23  *     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
24  * }
25  * </pre>
26  */
27 public class EnvelopedData
28     extends ASN1Object
29 {
30     private ASN1Integer              version;
31     private OriginatorInfo          originatorInfo;
32     private ASN1Set                 recipientInfos;
33     private EncryptedContentInfo    encryptedContentInfo;
34     private ASN1Set                 unprotectedAttrs;
35 
EnvelopedData( OriginatorInfo originatorInfo, ASN1Set recipientInfos, EncryptedContentInfo encryptedContentInfo, ASN1Set unprotectedAttrs)36     public EnvelopedData(
37         OriginatorInfo          originatorInfo,
38         ASN1Set                 recipientInfos,
39         EncryptedContentInfo    encryptedContentInfo,
40         ASN1Set                 unprotectedAttrs)
41     {
42         version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, unprotectedAttrs));
43 
44         this.originatorInfo = originatorInfo;
45         this.recipientInfos = recipientInfos;
46         this.encryptedContentInfo = encryptedContentInfo;
47         this.unprotectedAttrs = unprotectedAttrs;
48     }
49 
EnvelopedData( OriginatorInfo originatorInfo, ASN1Set recipientInfos, EncryptedContentInfo encryptedContentInfo, Attributes unprotectedAttrs)50     public EnvelopedData(
51         OriginatorInfo          originatorInfo,
52         ASN1Set                 recipientInfos,
53         EncryptedContentInfo    encryptedContentInfo,
54         Attributes              unprotectedAttrs)
55     {
56         version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, ASN1Set.getInstance(unprotectedAttrs)));
57 
58         this.originatorInfo = originatorInfo;
59         this.recipientInfos = recipientInfos;
60         this.encryptedContentInfo = encryptedContentInfo;
61         this.unprotectedAttrs = ASN1Set.getInstance(unprotectedAttrs);
62     }
63 
64     /**
65      * @deprecated use getInstance()
66      */
EnvelopedData( ASN1Sequence seq)67     public EnvelopedData(
68         ASN1Sequence seq)
69     {
70         int     index = 0;
71 
72         version = (ASN1Integer)seq.getObjectAt(index++);
73 
74         Object  tmp = seq.getObjectAt(index++);
75 
76         if (tmp instanceof ASN1TaggedObject)
77         {
78             originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false);
79             tmp = seq.getObjectAt(index++);
80         }
81 
82         recipientInfos = ASN1Set.getInstance(tmp);
83 
84         encryptedContentInfo = EncryptedContentInfo.getInstance(seq.getObjectAt(index++));
85 
86         if(seq.size() > index)
87         {
88             unprotectedAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false);
89         }
90     }
91 
92     /**
93      * Return an EnvelopedData object from a tagged object.
94      *
95      * @param obj the tagged object holding the object we want.
96      * @param explicit true if the object is meant to be explicitly
97      *              tagged false otherwise.
98      * @exception IllegalArgumentException if the object held by the
99      *          tagged object cannot be converted.
100      */
getInstance( ASN1TaggedObject obj, boolean explicit)101     public static EnvelopedData getInstance(
102         ASN1TaggedObject obj,
103         boolean explicit)
104     {
105         return getInstance(ASN1Sequence.getInstance(obj, explicit));
106     }
107 
108     /**
109      * Return an EnvelopedData object from the given object.
110      * <p>
111      * Accepted inputs:
112      * <ul>
113      * <li> null &rarr; null
114      * <li> {@link EnvelopedData} object
115      * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with EnvelopedData structure inside
116      * </ul>
117      *
118      * @param obj the object we want converted.
119      * @exception IllegalArgumentException if the object cannot be converted.
120      */
getInstance( Object obj)121     public static EnvelopedData getInstance(
122         Object obj)
123     {
124         if (obj instanceof EnvelopedData)
125         {
126             return (EnvelopedData)obj;
127         }
128 
129         if (obj != null)
130         {
131             return new EnvelopedData(ASN1Sequence.getInstance(obj));
132         }
133 
134         return null;
135     }
136 
getVersion()137     public ASN1Integer getVersion()
138     {
139         return version;
140     }
141 
getOriginatorInfo()142     public OriginatorInfo getOriginatorInfo()
143     {
144         return originatorInfo;
145     }
146 
getRecipientInfos()147     public ASN1Set getRecipientInfos()
148     {
149         return recipientInfos;
150     }
151 
getEncryptedContentInfo()152     public EncryptedContentInfo getEncryptedContentInfo()
153     {
154         return encryptedContentInfo;
155     }
156 
getUnprotectedAttrs()157     public ASN1Set getUnprotectedAttrs()
158     {
159         return unprotectedAttrs;
160     }
161 
162     /**
163      * Produce an object suitable for an ASN1OutputStream.
164      */
toASN1Primitive()165     public ASN1Primitive toASN1Primitive()
166     {
167         ASN1EncodableVector  v = new ASN1EncodableVector(5);
168 
169         v.add(version);
170 
171         if (originatorInfo != null)
172         {
173             v.add(new DERTaggedObject(false, 0, originatorInfo));
174         }
175 
176         v.add(recipientInfos);
177         v.add(encryptedContentInfo);
178 
179         if (unprotectedAttrs != null)
180         {
181             v.add(new DERTaggedObject(false, 1, unprotectedAttrs));
182         }
183 
184         return new BERSequence(v);
185     }
186 
calculateVersion(OriginatorInfo originatorInfo, ASN1Set recipientInfos, ASN1Set unprotectedAttrs)187     public static int calculateVersion(OriginatorInfo originatorInfo, ASN1Set recipientInfos, ASN1Set unprotectedAttrs)
188     {
189         int version;
190 
191         if (originatorInfo != null || unprotectedAttrs != null)
192         {
193             version = 2;
194         }
195         else
196         {
197             version = 0;
198 
199             Enumeration e = recipientInfos.getObjects();
200 
201             while (e.hasMoreElements())
202             {
203                 RecipientInfo   ri = RecipientInfo.getInstance(e.nextElement());
204 
205                 if (!ri.getVersion().hasValue(version))
206                 {
207                     version = 2;
208                     break;
209                 }
210             }
211         }
212 
213         return version;
214     }
215 }
216