1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.FilterOutputStream; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.OutputStream; 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class DEROutputStream 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam extends FilterOutputStream implements DERTags 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DEROutputStream( 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam OutputStream os) 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam super(os); 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private void writeLength( 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int length) 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (length > 127) 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int size = 1; 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int val = length; 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while ((val >>>= 8) != 0) 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam size++; 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam write((byte)(size | 0x80)); 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = (size - 1) * 8; i >= 0; i -= 8) 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam write((byte)(length >> i)); 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam write((byte)length); 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam void writeEncoded( 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int tag, 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] bytes) 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam write(tag); 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam writeLength(bytes.length); 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam write(bytes); 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom void writeTag(int flags, int tagNo) 54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws IOException 55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (tagNo < 31) 57c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom write(flags | tagNo); 59c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 60c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 61c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom write(flags | 0x1f); 63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (tagNo < 128) 64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom write(tagNo); 66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] stack = new byte[5]; 70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int pos = stack.length; 71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom stack[--pos] = (byte)(tagNo & 0x7F); 73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom do 75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom tagNo >>= 7; 77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom stack[--pos] = (byte)(tagNo & 0x7F | 0x80); 78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom while (tagNo > 127); 80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom write(stack, pos, stack.length - pos); 82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 85c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 86c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom void writeEncoded(int flags, int tagNo, byte[] bytes) 87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws IOException 88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom writeTag(flags, tagNo); 90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom writeLength(bytes.length); 91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom write(bytes); 92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void writeNull() 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam write(NULL); 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam write(0x00); 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public void write(byte[] buf) 102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws IOException 103c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom out.write(buf, 0, buf.length); 105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 106c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 107c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public void write(byte[] buf, int offSet, int len) 108c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws IOException 109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 110c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom out.write(buf, offSet, len); 111c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 112c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void writeObject( 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Object obj) 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj == null) 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam writeNull(); 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (obj instanceof DERObject) 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ((DERObject)obj).encode(this); 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (obj instanceof DEREncodable) 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ((DEREncodable)obj).getDERObject().encode(this); 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IOException("object not DEREncodable"); 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 135