1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.ByteArrayOutputStream; 4c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.IOException; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Enumeration; 6db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstromimport java.util.Vector; 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamabstract public class ASN1Set 94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom extends ASN1Primitive 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private Vector set = new Vector(); 124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private boolean isSorted = false; 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return an ASN1Set from the given object. 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param obj the object we want converted. 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the object cannot be converted. 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static ASN1Set getInstance( 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Object obj) 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj == null || obj instanceof ASN1Set) 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (ASN1Set)obj; 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else if (obj instanceof ASN1SetParser) 284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive()); 304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else if (obj instanceof byte[]) 324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom try 344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj)); 364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom catch (IOException e) 384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage()); 404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else if (obj instanceof ASN1Encodable) 434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive(); 454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (primitive instanceof ASN1Set) 474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return (ASN1Set)primitive; 494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Return an ASN1 set from a tagged object. There is a special 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * case here, if an object appears to have been explicitly tagged on 58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * reading but we were expecting it to be implicitly tagged in the 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * normal course of events it indicates that we lost the surrounding 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * set - so we need to add it back (this will happen if the tagged 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * object is a sequence that contains other sequences). If you are 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * dealing with implicitly tagged sets you really <b>should</b> 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * be using this method. 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param obj the tagged object. 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param explicit true if the object is meant to be explicitly tagged 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * false otherwise. 68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the tagged object cannot 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * be converted. 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static ASN1Set getInstance( 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1TaggedObject obj, 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean explicit) 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (explicit) 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!obj.isExplicit()) 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("object implicit - explicit expected."); 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (ASN1Set)obj.getObject(); 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // constructed object which appears to be explicitly tagged 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // and it's really implicit means we have to add the 894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // surrounding set. 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj.isExplicit()) 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (obj instanceof BERTaggedObject) 944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new BERSet(obj.getObject()); 964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DLSet(obj.getObject()); 1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj.getObject() instanceof ASN1Set) 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (ASN1Set)obj.getObject(); 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // in this case the parser returns a sequence, convert it 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // into a set. 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1EncodableVector v = new ASN1EncodableVector(); 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj.getObject() instanceof ASN1Sequence) 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Sequence s = (ASN1Sequence)obj.getObject(); 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (obj instanceof BERTaggedObject) 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new BERSet(s.toArray()); 1244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 1264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DLSet(s.toArray()); 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 133c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected ASN1Set() 1374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom /** 1414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * create a sequence containing one object 1424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom */ 1434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected ASN1Set( 1444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable obj) 1454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom set.addElement(obj); 1474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom /** 1504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * create a sequence containing a vector of objects. 1514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom */ 1524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected ASN1Set( 1534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1EncodableVector v, 1544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean doSort) 1554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom for (int i = 0; i != v.size(); i++) 1574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom set.addElement(v.get(i)); 1594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (doSort) 1624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom this.sort(); 1644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom /** 1684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * create a sequence containing a vector of objects. 1694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom */ 1704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected ASN1Set( 1714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable[] array, 1724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean doSort) 173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom for (int i = 0; i != array.length; i++) 1754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom set.addElement(array[i]); 1774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (doSort) 1804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom this.sort(); 1824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 185db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom public Enumeration getObjects() 186db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 187db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom return set.elements(); 188db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 189db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 190db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom /** 191db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom * return the object at the set position indicated by index. 192db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom * 193db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom * @param index the set number (starting at zero) of the object 194db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom * @return the object at the set position indicated by index. 195db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom */ 1964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public ASN1Encodable getObjectAt( 197db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom int index) 198db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 1994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return (ASN1Encodable)set.elementAt(index); 200db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 201db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 202db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom /** 203db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom * return the number of objects in this set. 204db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom * 205db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom * @return the number of objects in this set. 206db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom */ 207db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom public int size() 208db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 209db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom return set.size(); 210db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 2126e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom public ASN1Encodable[] toArray() 2136e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2146e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom ASN1Encodable[] values = new ASN1Encodable[this.size()]; 2156e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2166e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom for (int i = 0; i != this.size(); i++) 2176e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom values[i] = this.getObjectAt(i); 2196e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 2206e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return values; 2226e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 2236e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 224c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public ASN1SetParser parser() 225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 226c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom final ASN1Set outer = this; 227c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 228c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return new ASN1SetParser() 229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 230c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private final int max = size(); 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 232c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private int index; 233c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 2344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public ASN1Encodable readObject() throws IOException 235c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 236c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (index == max) 237c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 238c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return null; 239c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 240c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 2414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable obj = getObjectAt(index++); 242c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (obj instanceof ASN1Sequence) 243c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 244c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return ((ASN1Sequence)obj).parser(); 245c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 246c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (obj instanceof ASN1Set) 247c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 248c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return ((ASN1Set)obj).parser(); 249c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 250c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 251c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return obj; 252c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 253c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 2544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public ASN1Primitive getLoadedObject() 2556e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2566e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return outer; 2576e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 2586e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public ASN1Primitive toASN1Primitive() 260c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 261c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return outer; 262c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 263c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom }; 264c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 265c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 266db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom public int hashCode() 267db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 268db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom Enumeration e = this.getObjects(); 269db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom int hashCode = size(); 270db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 271db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom while (e.hasMoreElements()) 272db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 273db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom Object o = getNext(e); 274db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom hashCode *= 17; 275db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 276db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom hashCode ^= o.hashCode(); 277db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 278db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 279db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom return hashCode; 280db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 281c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 2824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive toDERObject() 2834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 2844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (isSorted) 2854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 2864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Set derSet = new DERSet(); 2874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 2884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom derSet.set = this.set; 2894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 2904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return derSet; 2914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 2924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 2934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 2944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom Vector v = new Vector(); 2954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 2964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom for (int i = 0; i != set.size(); i++) 2974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 2984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom v.addElement(set.elementAt(i)); 2994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Set derSet = new DERSet(); 3024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom derSet.set = v; 3044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom derSet.sort(); 3064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return derSet; 3084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive toDLObject() 3124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Set derSet = new DLSet(); 3144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom derSet.set = this.set; 3164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return derSet; 3184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 320c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean asn1Equals( 3214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive o) 322c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 323c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (!(o instanceof ASN1Set)) 324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return false; 326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 328c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ASN1Set other = (ASN1Set)o; 329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (this.size() != other.size()) 331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return false; 333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration s1 = this.getObjects(); 336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration s2 = other.getObjects(); 337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (s1.hasMoreElements()) 339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 3404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable obj1 = getNext(s1); 3414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable obj2 = getNext(s2); 3426e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 3434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive o1 = obj1.toASN1Primitive(); 3444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive o2 = obj2.toASN1Primitive(); 345c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 3466e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (o1 == o2 || o1.equals(o2)) 347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 348c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom continue; 349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 350c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 351c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return false; 352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 354b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return true; 355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private ASN1Encodable getNext(Enumeration e) 3586e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 3594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable encObj = (ASN1Encodable)e.nextElement(); 3606e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 3616e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom // unfortunately null was allowed as a substitute for DER null 3626e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (encObj == null) 3636e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 3646e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return DERNull.INSTANCE; 3656e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 3666e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 3676e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return encObj; 3686e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 3696e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 370db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom /** 371db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom * return true if a <= b (arrays are assumed padded with zeros). 372db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom */ 373db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom private boolean lessThanOrEqual( 374db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom byte[] a, 375db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom byte[] b) 376db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 377db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom int len = Math.min(a.length, b.length); 378db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom for (int i = 0; i != len; ++i) 379db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 380db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom if (a[i] != b[i]) 381db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 382db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom return (a[i] & 0xff) < (b[i] & 0xff); 383db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 384db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 385db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom return len == a.length; 386db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 387b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 388c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private byte[] getEncoded( 3894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable obj) 390c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 391c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 392c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ASN1OutputStream aOut = new ASN1OutputStream(bOut); 393c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 394c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom try 395c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 396c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom aOut.writeObject(obj); 397c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 398c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom catch (IOException e) 399c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 400c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IllegalArgumentException("cannot encode object added to SET"); 401c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 402c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 403c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return bOut.toByteArray(); 404c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 405c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 406db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom protected void sort() 407db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 4084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!isSorted) 409db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 4104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom isSorted = true; 4114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (set.size() > 1) 412db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 4134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean swapped = true; 4144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int lastSwap = set.size() - 1; 415db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 4164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom while (swapped) 417db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 4184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int index = 0; 4194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int swapIndex = 0; 4204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom byte[] a = getEncoded((ASN1Encodable)set.elementAt(0)); 421db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 4224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom swapped = false; 4234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 4244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom while (index != lastSwap) 425db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 4264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom byte[] b = getEncoded((ASN1Encodable)set.elementAt(index + 1)); 427db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 4284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (lessThanOrEqual(a, b)) 4294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 4304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom a = b; 4314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 4324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 4334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 4344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom Object o = set.elementAt(index); 435db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 4364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom set.setElementAt(set.elementAt(index + 1), index); 4374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom set.setElementAt(o, index + 1); 4384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 4394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom swapped = true; 4404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom swapIndex = index; 4414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 4424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 4434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom index++; 444db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 445db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 4464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom lastSwap = swapIndex; 447db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 448db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 449db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 450db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 451db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 4524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean isConstructed() 453db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 4544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return true; 455db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 456db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 4574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom abstract void encode(ASN1OutputStream out) 458db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom throws IOException; 459db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom 460db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom public String toString() 461db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom { 4624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return set.toString(); 463db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom } 464b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 465