1 package org.bouncycastle.asn1;
2 
3 import java.io.IOException;
4 import java.util.Enumeration;
5 
6 /**
7  * A DER encoded set object
8  */
9 public class DERSet
10     extends ASN1Set
11 {
12     private int bodyLength = -1;
13 
14     /**
15      * create an empty set
16      */
DERSet()17     public DERSet()
18     {
19     }
20 
21     /**
22      * @param obj - a single object that makes up the set.
23      */
DERSet( ASN1Encodable obj)24     public DERSet(
25         ASN1Encodable obj)
26     {
27         super(obj);
28     }
29 
30     /**
31      * @param v - a vector of objects making up the set.
32      */
DERSet( ASN1EncodableVector v)33     public DERSet(
34         ASN1EncodableVector v)
35     {
36         super(v, true);
37     }
38 
39     /**
40      * create a set from an array of objects.
41      */
DERSet( ASN1Encodable[] a)42     public DERSet(
43         ASN1Encodable[]   a)
44     {
45         super(a, true);
46     }
47 
DERSet( ASN1EncodableVector v, boolean doSort)48     DERSet(
49         ASN1EncodableVector v,
50         boolean                  doSort)
51     {
52         super(v, doSort);
53     }
54 
getBodyLength()55     private int getBodyLength()
56         throws IOException
57     {
58         if (bodyLength < 0)
59         {
60             int length = 0;
61 
62             for (Enumeration e = this.getObjects(); e.hasMoreElements();)
63             {
64                 Object    obj = e.nextElement();
65 
66                 length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
67             }
68 
69             bodyLength = length;
70         }
71 
72         return bodyLength;
73     }
74 
encodedLength()75     int encodedLength()
76         throws IOException
77     {
78         int length = getBodyLength();
79 
80         return 1 + StreamUtil.calculateBodyLength(length) + length;
81     }
82 
83     /*
84      * A note on the implementation:
85      * <p>
86      * As DER requires the constructed, definite-length model to
87      * be used for structured types, this varies slightly from the
88      * ASN.1 descriptions given. Rather than just outputting SET,
89      * we also have to specify CONSTRUCTED, and the objects length.
90      */
encode( ASN1OutputStream out)91     void encode(
92         ASN1OutputStream out)
93         throws IOException
94     {
95         ASN1OutputStream        dOut = out.getDERSubStream();
96         int                     length = getBodyLength();
97 
98         out.write(BERTags.SET | BERTags.CONSTRUCTED);
99         out.writeLength(length);
100 
101         for (Enumeration e = this.getObjects(); e.hasMoreElements();)
102         {
103             Object    obj = e.nextElement();
104 
105             dOut.writeObject((ASN1Encodable)obj);
106         }
107     }
108 }
109