1/*
2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
3 * Please refer to the LICENSE.txt for licensing details.
4 */
5package ch.ethz.ssh2.crypto;
6
7import java.io.IOException;
8
9import java.math.BigInteger;
10
11/**
12 * SimpleDERReader.
13 *
14 * @author Christian Plattner
15 * @version 2.50, 03/15/10
16 */
17public class SimpleDERReader
18{
19	byte[] buffer;
20	int pos;
21	int count;
22
23	public SimpleDERReader(byte[] b)
24	{
25		resetInput(b);
26	}
27
28	public SimpleDERReader(byte[] b, int off, int len)
29	{
30		resetInput(b, off, len);
31	}
32
33	public void resetInput(byte[] b)
34	{
35		resetInput(b, 0, b.length);
36	}
37
38	public void resetInput(byte[] b, int off, int len)
39	{
40		buffer = b;
41		pos = off;
42		count = len;
43	}
44
45	private byte readByte() throws IOException
46	{
47		if (count <= 0)
48			throw new IOException("DER byte array: out of data");
49		count--;
50		return buffer[pos++];
51	}
52
53	private byte[] readBytes(int len) throws IOException
54	{
55		if (len > count)
56			throw new IOException("DER byte array: out of data");
57
58		byte[] b = new byte[len];
59
60		System.arraycopy(buffer, pos, b, 0, len);
61
62		pos += len;
63		count -= len;
64
65		return b;
66	}
67
68	public int available()
69	{
70		return count;
71	}
72
73	private int readLength() throws IOException
74	{
75		int len = readByte() & 0xff;
76
77		if ((len & 0x80) == 0)
78			return len;
79
80		int remain = len & 0x7F;
81
82		if (remain == 0)
83			return -1;
84
85		len = 0;
86
87		while (remain > 0)
88		{
89			len = len << 8;
90			len = len | (readByte() & 0xff);
91			remain--;
92		}
93
94		return len;
95	}
96
97	public int ignoreNextObject() throws IOException
98	{
99		int type = readByte() & 0xff;
100
101		int len = readLength();
102
103		if ((len < 0) || len > available())
104			throw new IOException("Illegal len in DER object (" + len  + ")");
105
106		readBytes(len);
107
108		return type;
109	}
110
111	public BigInteger readInt() throws IOException
112	{
113		int type = readByte() & 0xff;
114
115		if (type != 0x02)
116			throw new IOException("Expected DER Integer, but found type " + type);
117
118		int len = readLength();
119
120		if ((len < 0) || len > available())
121			throw new IOException("Illegal len in DER object (" + len  + ")");
122
123		byte[] b = readBytes(len);
124
125		return new BigInteger(b);
126	}
127
128	public byte[] readSequenceAsByteArray() throws IOException
129	{
130		int type = readByte() & 0xff;
131
132		if (type != 0x30)
133			throw new IOException("Expected DER Sequence, but found type " + type);
134
135		int len = readLength();
136
137		if ((len < 0) || len > available())
138			throw new IOException("Illegal len in DER object (" + len  + ")");
139
140		return readBytes(len);
141	}
142
143	public byte[] readOctetString() throws IOException
144	{
145		int type = readByte() & 0xff;
146
147		if (type != 0x04)
148			throw new IOException("Expected DER Octetstring, but found type " + type);
149
150		int len = readLength();
151
152		if ((len < 0) || len > available())
153			throw new IOException("Illegal len in DER object (" + len  + ")");
154
155		return readBytes(len);
156	}
157
158}
159