• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.asn1;
2 
3 import java.io.ByteArrayOutputStream;
4 import java.io.IOException;
5 
6 /**
7  * Class representing the DER-type External
8  */
9 public class DERExternal
10     extends ASN1Primitive
11 {
12     private ASN1ObjectIdentifier directReference;
13     private ASN1Integer indirectReference;
14     private ASN1Primitive dataValueDescriptor;
15     private int encoding;
16     private ASN1Primitive externalContent;
17 
DERExternal(ASN1EncodableVector vector)18     public DERExternal(ASN1EncodableVector vector)
19     {
20         int offset = 0;
21 
22         ASN1Primitive enc = getObjFromVector(vector, offset);
23         if (enc instanceof ASN1ObjectIdentifier)
24         {
25             directReference = (ASN1ObjectIdentifier)enc;
26             offset++;
27             enc = getObjFromVector(vector, offset);
28         }
29         if (enc instanceof ASN1Integer)
30         {
31             indirectReference = (ASN1Integer) enc;
32             offset++;
33             enc = getObjFromVector(vector, offset);
34         }
35         if (!(enc instanceof DERTaggedObject))
36         {
37             dataValueDescriptor = (ASN1Primitive) enc;
38             offset++;
39             enc = getObjFromVector(vector, offset);
40         }
41 
42         if (vector.size() != offset + 1)
43         {
44             throw new IllegalArgumentException("input vector too large");
45         }
46 
47         if (!(enc instanceof DERTaggedObject))
48         {
49             throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
50         }
51         DERTaggedObject obj = (DERTaggedObject)enc;
52         setEncoding(obj.getTagNo());
53         externalContent = obj.getObject();
54     }
55 
getObjFromVector(ASN1EncodableVector v, int index)56     private ASN1Primitive getObjFromVector(ASN1EncodableVector v, int index)
57     {
58         if (v.size() <= index)
59         {
60             throw new IllegalArgumentException("too few objects in input vector");
61         }
62 
63         return v.get(index).toASN1Primitive();
64     }
65     /**
66      * Creates a new instance of DERExternal
67      * See X.690 for more informations about the meaning of these parameters
68      * @param directReference The direct reference or <code>null</code> if not set.
69      * @param indirectReference The indirect reference or <code>null</code> if not set.
70      * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
71      * @param externalData The external data in its encoded form.
72      */
DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)73     public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
74     {
75         this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
76     }
77 
78     /**
79      * Creates a new instance of DERExternal.
80      * See X.690 for more informations about the meaning of these parameters
81      * @param directReference The direct reference or <code>null</code> if not set.
82      * @param indirectReference The indirect reference or <code>null</code> if not set.
83      * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
84      * @param encoding The encoding to be used for the external data
85      * @param externalData The external data
86      */
DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)87     public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
88     {
89         setDirectReference(directReference);
90         setIndirectReference(indirectReference);
91         setDataValueDescriptor(dataValueDescriptor);
92         setEncoding(encoding);
93         setExternalContent(externalData.toASN1Primitive());
94     }
95 
96     /* (non-Javadoc)
97      * @see java.lang.Object#hashCode()
98      */
hashCode()99     public int hashCode()
100     {
101         int ret = 0;
102         if (directReference != null)
103         {
104             ret = directReference.hashCode();
105         }
106         if (indirectReference != null)
107         {
108             ret ^= indirectReference.hashCode();
109         }
110         if (dataValueDescriptor != null)
111         {
112             ret ^= dataValueDescriptor.hashCode();
113         }
114         ret ^= externalContent.hashCode();
115         return ret;
116     }
117 
isConstructed()118     boolean isConstructed()
119     {
120         return true;
121     }
122 
encodedLength()123     int encodedLength()
124         throws IOException
125     {
126         return this.getEncoded().length;
127     }
128 
129     /* (non-Javadoc)
130      * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
131      */
encode(ASN1OutputStream out)132     void encode(ASN1OutputStream out)
133         throws IOException
134     {
135         ByteArrayOutputStream baos = new ByteArrayOutputStream();
136         if (directReference != null)
137         {
138             baos.write(directReference.getEncoded(ASN1Encoding.DER));
139         }
140         if (indirectReference != null)
141         {
142             baos.write(indirectReference.getEncoded(ASN1Encoding.DER));
143         }
144         if (dataValueDescriptor != null)
145         {
146             baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DER));
147         }
148         DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
149         baos.write(obj.getEncoded(ASN1Encoding.DER));
150         out.writeEncoded(BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
151     }
152 
153     /* (non-Javadoc)
154      * @see org.bouncycastle.asn1.ASN1Primitive#asn1Equals(org.bouncycastle.asn1.ASN1Primitive)
155      */
asn1Equals(ASN1Primitive o)156     boolean asn1Equals(ASN1Primitive o)
157     {
158         if (!(o instanceof DERExternal))
159         {
160             return false;
161         }
162         if (this == o)
163         {
164             return true;
165         }
166         DERExternal other = (DERExternal)o;
167         if (directReference != null)
168         {
169             if (other.directReference == null || !other.directReference.equals(directReference))
170             {
171                 return false;
172             }
173         }
174         if (indirectReference != null)
175         {
176             if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
177             {
178                 return false;
179             }
180         }
181         if (dataValueDescriptor != null)
182         {
183             if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
184             {
185                 return false;
186             }
187         }
188         return externalContent.equals(other.externalContent);
189     }
190 
191     /**
192      * Returns the data value descriptor
193      * @return The descriptor
194      */
getDataValueDescriptor()195     public ASN1Primitive getDataValueDescriptor()
196     {
197         return dataValueDescriptor;
198     }
199 
200     /**
201      * Returns the direct reference of the external element
202      * @return The reference
203      */
getDirectReference()204     public ASN1ObjectIdentifier getDirectReference()
205     {
206         return directReference;
207     }
208 
209     /**
210      * Returns the encoding of the content. Valid values are
211      * <ul>
212      * <li><code>0</code> single-ASN1-type</li>
213      * <li><code>1</code> OCTET STRING</li>
214      * <li><code>2</code> BIT STRING</li>
215      * </ul>
216      * @return The encoding
217      */
getEncoding()218     public int getEncoding()
219     {
220         return encoding;
221     }
222 
223     /**
224      * Returns the content of this element
225      * @return The content
226      */
getExternalContent()227     public ASN1Primitive getExternalContent()
228     {
229         return externalContent;
230     }
231 
232     /**
233      * Returns the indirect reference of this element
234      * @return The reference
235      */
getIndirectReference()236     public ASN1Integer getIndirectReference()
237     {
238         return indirectReference;
239     }
240 
241     /**
242      * Sets the data value descriptor
243      * @param dataValueDescriptor The descriptor
244      */
setDataValueDescriptor(ASN1Primitive dataValueDescriptor)245     private void setDataValueDescriptor(ASN1Primitive dataValueDescriptor)
246     {
247         this.dataValueDescriptor = dataValueDescriptor;
248     }
249 
250     /**
251      * Sets the direct reference of the external element
252      * @param directReferemce The reference
253      */
setDirectReference(ASN1ObjectIdentifier directReferemce)254     private void setDirectReference(ASN1ObjectIdentifier directReferemce)
255     {
256         this.directReference = directReferemce;
257     }
258 
259     /**
260      * Sets the encoding of the content. Valid values are
261      * <ul>
262      * <li><code>0</code> single-ASN1-type</li>
263      * <li><code>1</code> OCTET STRING</li>
264      * <li><code>2</code> BIT STRING</li>
265      * </ul>
266      * @param encoding The encoding
267      */
setEncoding(int encoding)268     private void setEncoding(int encoding)
269     {
270         if (encoding < 0 || encoding > 2)
271         {
272             throw new IllegalArgumentException("invalid encoding value: " + encoding);
273         }
274         this.encoding = encoding;
275     }
276 
277     /**
278      * Sets the content of this element
279      * @param externalContent The content
280      */
setExternalContent(ASN1Primitive externalContent)281     private void setExternalContent(ASN1Primitive externalContent)
282     {
283         this.externalContent = externalContent;
284     }
285 
286     /**
287      * Sets the indirect reference of this element
288      * @param indirectReference The reference
289      */
setIndirectReference(ASN1Integer indirectReference)290     private void setIndirectReference(ASN1Integer indirectReference)
291     {
292         this.indirectReference = indirectReference;
293     }
294 }
295