1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.ByteArrayInputStream; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.EOFException; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.FilterInputStream; 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.InputStream; 8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.util.io.Streams; 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * a general purpose ASN.1 decoder - note: this class differs from the 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * others in that it returns null after it has read the last object in 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * the stream. If an ASN.1 NULL is encountered a DER/BER Null object is 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * returned. 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class ASN1InputStream 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam extends FilterInputStream 194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom implements BERTags 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 21c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private final int limit; 22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private final boolean lazyEvaluate; 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private final byte[][] tmpBuffers; 256e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public ASN1InputStream( 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InputStream is) 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom this(is, StreamUtil.findLimit(is)); 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Create an ASN1InputStream based on the input byte array. The length of DER objects in 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * the stream is automatically limited to the length of the input array. 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param input array containing ASN.1 encoded data. 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public ASN1InputStream( 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] input) 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this(new ByteArrayInputStream(input), input.length); 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 44c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom /** 45c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * Create an ASN1InputStream based on the input byte array. The length of DER objects in 46c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * the stream is automatically limited to the length of the input array. 47c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * 48c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param input array containing ASN.1 encoded data. 49c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param lazyEvaluate true if parsing inside constructed objects can be delayed. 50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public ASN1InputStream( 52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] input, 53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean lazyEvaluate) 54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this(new ByteArrayInputStream(input), input.length, lazyEvaluate); 56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Create an ASN1InputStream where no DER object will be longer than limit. 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param input stream containing ASN.1 encoded data. 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param limit maximum size of a DER encoded object. 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public ASN1InputStream( 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InputStream input, 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int limit) 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this(input, limit, false); 69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom /** 72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * Create an ASN1InputStream where no DER object will be longer than limit, and constructed 73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * objects such as sequences will be parsed lazily. 74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * 75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param input stream containing ASN.1 encoded data. 764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * @param lazyEvaluate true if parsing inside constructed objects can be delayed. 774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom */ 784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public ASN1InputStream( 794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom InputStream input, 804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean lazyEvaluate) 814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom this(input, StreamUtil.findLimit(input), lazyEvaluate); 834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom /** 864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * Create an ASN1InputStream where no DER object will be longer than limit, and constructed 874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * objects such as sequences will be parsed lazily. 884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * 894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * @param input stream containing ASN.1 encoded data. 90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param limit maximum size of a DER encoded object. 91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param lazyEvaluate true if parsing inside constructed objects can be delayed. 92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public ASN1InputStream( 94c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom InputStream input, 95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int limit, 96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean lazyEvaluate) 97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam super(input); 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.limit = limit; 100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this.lazyEvaluate = lazyEvaluate; 1014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom this.tmpBuffers = new byte[11][]; 1024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int getLimit() 1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return limit; 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 108c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int readLength() 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 112c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return readLength(this, limit); 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void readFully( 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] bytes) 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 119c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (Streams.readFully(this, bytes) != bytes.length) 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new EOFException("EOF encountered in middle of object"); 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 126c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * build an object given its tag and the number of bytes to construct it from. 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 1284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom protected ASN1Primitive buildObject( 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int tag, 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int tagNo, 131c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int length) 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 134c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean isConstructed = (tag & CONSTRUCTED) != 0; 135c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 136c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length); 137c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if ((tag & APPLICATION) != 0) 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 140c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray()); 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 143c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if ((tag & TAGGED) != 0) 144c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1456e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo); 146c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 148c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (isConstructed) 149c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 150c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // TODO There are other tags that may be constructed (e.g. BIT_STRING) 151c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom switch (tagNo) 152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 153c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case OCTET_STRING: 154c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // 155c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // yes, people actually do this... 156c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // 1574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1EncodableVector v = buildDEREncodableVector(defIn); 1584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1OctetString[] strings = new ASN1OctetString[v.size()]; 1594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom for (int i = 0; i != strings.length; i++) 1614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom strings[i] = (ASN1OctetString)v.get(i); 1634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new BEROctetString(strings); 166c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case SEQUENCE: 167c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (lazyEvaluate) 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new LazyEncodedSequence(defIn.toByteArray()); 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 173c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return DERFactory.createSequence(buildDEREncodableVector(defIn)); 174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 175c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case SET: 1764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return DERFactory.createSet(buildDEREncodableVector(defIn)); 177c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case EXTERNAL: 178c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return new DERExternal(buildDEREncodableVector(defIn)); 179c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom default: 1804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throw new IOException("unknown tag " + tagNo + " encountered"); 181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return createPrimitiveDERObject(tagNo, defIn, tmpBuffers); 185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ASN1EncodableVector buildEncodableVector() 188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 190c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ASN1EncodableVector v = new ASN1EncodableVector(); 1914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive o; 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 193c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom while ((o = readObject()) != null) 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 195c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom v.add(o); 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 198c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return v; 199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 200c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 201c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ASN1EncodableVector buildDEREncodableVector( 202c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom DefiniteLengthInputStream dIn) throws IOException 203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 204c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return new ASN1InputStream(dIn).buildEncodableVector(); 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 2074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public ASN1Primitive readObject() 208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int tag = read(); 211c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (tag <= 0) 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 213c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (tag == 0) 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 215c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException("unexpected end-of-contents marker"); 216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 221c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // 222c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // calculate tag number 223c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // 224c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int tagNo = readTagNumber(this, tag); 225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 226c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean isConstructed = (tag & CONSTRUCTED) != 0; 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 228c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // 229c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // calculate length 230c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // 231c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int length = readLength(); 232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 233c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (length < 0) // indefinite length method 234c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 235c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (!isConstructed) 236c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 237c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException("indefinite length primitive encoding encountered"); 238c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 2406e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit); 2416e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom ASN1StreamParser sp = new ASN1StreamParser(indIn, limit); 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 243c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if ((tag & APPLICATION) != 0) 244c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 2456e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject(); 246c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 2476e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 248c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if ((tag & TAGGED) != 0) 249c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 2506e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject(); 251c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 253c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // TODO There are other tags that may be constructed (e.g. BIT_STRING) 254c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom switch (tagNo) 255c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 256c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case OCTET_STRING: 2576e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new BEROctetStringParser(sp).getLoadedObject(); 258c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case SEQUENCE: 2596e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new BERSequenceParser(sp).getLoadedObject(); 260c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case SET: 2616e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new BERSetParser(sp).getLoadedObject(); 262c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case EXTERNAL: 2636e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new DERExternalParser(sp).getLoadedObject(); 264c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom default: 265c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException("unknown BER object encountered"); 266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 2706e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom try 2716e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2726e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return buildObject(tag, tagNo, length); 2736e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 2746e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom catch (IllegalArgumentException e) 2756e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2766e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom throw new ASN1Exception("corrupted stream detected", e); 2776e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 281c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom static int readTagNumber(InputStream s, int tag) 282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int tagNo = tag & 0x1f; 285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 286c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // 287c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // with tagged object tag number is bottom 5 bits, or stored at the start of the content 288c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // 289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (tagNo == 0x1f) 290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam tagNo = 0; 292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 293c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int b = s.read(); 294c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 295c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // X.690-0207 8.1.2.4.2 296c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." 297c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if ((b & 0x7f) == 0) // Note: -1 will pass 298c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 299c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException("corrupted stream - invalid high tag number found"); 300c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 301c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while ((b >= 0) && ((b & 0x80) != 0)) 303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam tagNo |= (b & 0x7f); 305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam tagNo <<= 7; 306c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom b = s.read(); 307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (b < 0) 310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new EOFException("EOF found inside tag value."); 312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 314b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam tagNo |= (b & 0x7f); 315b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 317b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return tagNo; 318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 319b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 320c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom static int readLength(InputStream s, int limit) 321c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws IOException 322c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 323c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int length = s.read(); 324c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (length < 0) 325c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 326c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new EOFException("EOF found when length expected"); 327c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 328c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 329c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (length == 0x80) 330c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 331c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return -1; // indefinite-length encoding 332c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 333c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 334c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (length > 127) 335c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 336c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int size = length & 0x7f; 337c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 3386e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here 339c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (size > 4) 340c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 341c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException("DER length more than 4 bytes: " + size); 342c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 343c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 344c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom length = 0; 345c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom for (int i = 0; i < size; i++) 346c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 347c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int next = s.read(); 348c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 349c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (next < 0) 350c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 351c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new EOFException("EOF found reading length"); 352c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 353c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 354c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom length = (length << 8) + next; 355c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 356c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 357c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (length < 0) 358c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 359c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException("corrupted stream - negative length found"); 360c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 361c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 362c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (length >= limit) // after all we must have read at least 1 byte 363c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 364c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException("corrupted stream - out of bounds length found"); 365c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 366c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 367c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 368c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return length; 369c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 370c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 3714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private static byte[] getBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers) 3724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throws IOException 3734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int len = defIn.getRemaining(); 3754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (defIn.getRemaining() < tmpBuffers.length) 3764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom byte[] buf = tmpBuffers[len]; 3784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (buf == null) 3804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom buf = tmpBuffers[len] = new byte[len]; 3824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom Streams.readFully(defIn, buf); 3854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return buf; 3874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 3894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return defIn.toByteArray(); 3914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn) 3954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throws IOException 3964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int len = defIn.getRemaining() / 2; 3984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom char[] buf = new char[len]; 3994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int totalRead = 0; 4004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom while (totalRead < len) 4014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 4024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int ch1 = defIn.read(); 4034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (ch1 < 0) 4044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 4054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom break; 4064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 4074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int ch2 = defIn.read(); 4084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (ch2 < 0) 4094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 4104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom break; 4114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 4124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom buf[totalRead++] = (char)((ch1 << 8) | (ch2 & 0xff)); 4134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 4144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 4154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return buf; 4164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 4174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 4184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom static ASN1Primitive createPrimitiveDERObject( 419c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int tagNo, 4204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom DefiniteLengthInputStream defIn, 4214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom byte[][] tmpBuffers) 4224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throws IOException 423c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 424c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom switch (tagNo) 425c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 426c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case BIT_STRING: 4274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return DERBitString.fromInputStream(defIn.getRemaining(), defIn); 428c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case BMP_STRING: 4294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DERBMPString(getBMPCharBuffer(defIn)); 430c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case BOOLEAN: 4314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers)); 432c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case ENUMERATED: 4334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers)); 434c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case GENERALIZED_TIME: 4354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new ASN1GeneralizedTime(defIn.toByteArray()); 436c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case GENERAL_STRING: 4374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DERGeneralString(defIn.toByteArray()); 438c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case IA5_STRING: 4394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DERIA5String(defIn.toByteArray()); 440c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case INTEGER: 4414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new ASN1Integer(defIn.toByteArray()); 442c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case NULL: 443c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?) 444c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case NUMERIC_STRING: 4454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DERNumericString(defIn.toByteArray()); 446c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case OBJECT_IDENTIFIER: 4474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers)); 448c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case OCTET_STRING: 4494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DEROctetString(defIn.toByteArray()); 450c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case PRINTABLE_STRING: 4514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DERPrintableString(defIn.toByteArray()); 452c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case T61_STRING: 4534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DERT61String(defIn.toByteArray()); 454c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case UNIVERSAL_STRING: 4554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DERUniversalString(defIn.toByteArray()); 456c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case UTC_TIME: 4574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new ASN1UTCTime(defIn.toByteArray()); 458c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case UTF8_STRING: 4594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DERUTF8String(defIn.toByteArray()); 460c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case VISIBLE_STRING: 4614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DERVisibleString(defIn.toByteArray()); 462c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom default: 4634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throw new IOException("unknown tag " + tagNo + " encountered"); 464c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 465c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 466c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom} 467