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