0
|
1 package com.trilead.ssh2.crypto;
|
|
2
|
|
3 import java.io.IOException;
|
|
4
|
|
5 import java.math.BigInteger;
|
|
6
|
|
7 /**
|
|
8 * SimpleDERReader.
|
|
9 *
|
|
10 * @author Christian Plattner, plattner@trilead.com
|
|
11 * @version $Id: SimpleDERReader.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
|
|
12 */
|
|
13 public class SimpleDERReader {
|
|
14 private static final int CONSTRUCTED = 0x20;
|
|
15
|
|
16 byte[] buffer;
|
|
17 int pos;
|
|
18 int count;
|
|
19
|
|
20 public SimpleDERReader(byte[] b) {
|
|
21 resetInput(b);
|
|
22 }
|
|
23
|
|
24 public SimpleDERReader(byte[] b, int off, int len) {
|
|
25 resetInput(b, off, len);
|
|
26 }
|
|
27
|
|
28 public void resetInput(byte[] b) {
|
|
29 resetInput(b, 0, b.length);
|
|
30 }
|
|
31
|
|
32 public void resetInput(byte[] b, int off, int len) {
|
|
33 buffer = b;
|
|
34 pos = off;
|
|
35 count = len;
|
|
36 }
|
|
37
|
|
38 private byte readByte() throws IOException {
|
|
39 if (count <= 0)
|
|
40 throw new IOException("DER byte array: out of data");
|
|
41
|
|
42 count--;
|
|
43 return buffer[pos++];
|
|
44 }
|
|
45
|
|
46 private byte[] readBytes(int len) throws IOException {
|
|
47 if (len > count)
|
|
48 throw new IOException("DER byte array: out of data");
|
|
49
|
|
50 byte[] b = new byte[len];
|
|
51 System.arraycopy(buffer, pos, b, 0, len);
|
|
52 pos += len;
|
|
53 count -= len;
|
|
54 return b;
|
|
55 }
|
|
56
|
|
57 public int available() {
|
|
58 return count;
|
|
59 }
|
|
60
|
|
61 private int readLength() throws IOException {
|
|
62 int len = readByte() & 0xff;
|
|
63
|
|
64 if ((len & 0x80) == 0)
|
|
65 return len;
|
|
66
|
|
67 int remain = len & 0x7F;
|
|
68
|
|
69 if (remain == 0)
|
|
70 return -1;
|
|
71
|
|
72 len = 0;
|
|
73
|
|
74 while (remain > 0) {
|
|
75 len = len << 8;
|
|
76 len = len | (readByte() & 0xff);
|
|
77 remain--;
|
|
78 }
|
|
79
|
|
80 return len;
|
|
81 }
|
|
82
|
|
83 public int ignoreNextObject() throws IOException {
|
|
84 int type = readByte() & 0xff;
|
|
85 int len = readLength();
|
|
86
|
|
87 if ((len < 0) || len > available())
|
|
88 throw new IOException("Illegal len in DER object (" + len + ")");
|
|
89
|
|
90 readBytes(len);
|
|
91 return type;
|
|
92 }
|
|
93
|
|
94 public BigInteger readInt() throws IOException {
|
|
95 int type = readByte() & 0xff;
|
|
96
|
|
97 if (type != 0x02)
|
|
98 throw new IOException("Expected DER Integer, but found type " + type);
|
|
99
|
|
100 int len = readLength();
|
|
101
|
|
102 if ((len < 0) || len > available())
|
|
103 throw new IOException("Illegal len in DER object (" + len + ")");
|
|
104
|
|
105 byte[] b = readBytes(len);
|
|
106 BigInteger bi = new BigInteger(b);
|
|
107 return bi;
|
|
108 }
|
|
109
|
|
110 public int readConstructedType() throws IOException {
|
|
111 int type = readByte() & 0xff;
|
|
112
|
|
113 if ((type & CONSTRUCTED) != CONSTRUCTED)
|
|
114 throw new IOException("Expected constructed type, but was " + type);
|
|
115
|
|
116 return type & 0x1f;
|
|
117 }
|
|
118
|
|
119 public SimpleDERReader readConstructed() throws IOException {
|
|
120 int len = readLength();
|
|
121
|
|
122 if ((len < 0) || len > available())
|
|
123 throw new IOException("Illegal len in DER object (" + len + ")");
|
|
124
|
|
125 SimpleDERReader cr = new SimpleDERReader(buffer, pos, len);
|
|
126 pos += len;
|
|
127 count -= len;
|
|
128 return cr;
|
|
129 }
|
|
130
|
|
131 public byte[] readSequenceAsByteArray() throws IOException {
|
|
132 int type = readByte() & 0xff;
|
|
133
|
|
134 if (type != 0x30)
|
|
135 throw new IOException("Expected DER Sequence, but found type " + type);
|
|
136
|
|
137 int len = readLength();
|
|
138
|
|
139 if ((len < 0) || len > available())
|
|
140 throw new IOException("Illegal len in DER object (" + len + ")");
|
|
141
|
|
142 byte[] b = readBytes(len);
|
|
143 return b;
|
|
144 }
|
|
145
|
|
146 public String readOid() throws IOException {
|
|
147 int type = readByte() & 0xff;
|
|
148
|
|
149 if (type != 0x06)
|
|
150 throw new IOException("Expected DER OID, but found type " + type);
|
|
151
|
|
152 int len = readLength();
|
|
153
|
|
154 if ((len < 1) || len > available())
|
|
155 throw new IOException("Illegal len in DER object (" + len + ")");
|
|
156
|
|
157 byte[] b = readBytes(len);
|
|
158 long value = 0;
|
|
159 StringBuilder sb = new StringBuilder(64);
|
|
160
|
|
161 switch (b[0] / 40) {
|
|
162 case 0:
|
|
163 sb.append('0');
|
|
164 break;
|
|
165
|
|
166 case 1:
|
|
167 sb.append('1');
|
|
168 b[0] -= 40;
|
|
169 break;
|
|
170
|
|
171 default:
|
|
172 sb.append('2');
|
|
173 b[0] -= 80;
|
|
174 break;
|
|
175 }
|
|
176
|
|
177 for (int i = 0; i < len; i++) {
|
|
178 value = (value << 7) + (b[i] & 0x7F);
|
|
179
|
|
180 if ((b[i] & 0x80) == 0) {
|
|
181 sb.append('.');
|
|
182 sb.append(value);
|
|
183 value = 0;
|
|
184 }
|
|
185 }
|
|
186
|
|
187 return sb.toString();
|
|
188 }
|
|
189
|
|
190 public byte[] readOctetString() throws IOException {
|
|
191 int type = readByte() & 0xff;
|
|
192
|
|
193 if (type != 0x04 && type != 0x03)
|
|
194 throw new IOException("Expected DER Octetstring, but found type " + type);
|
|
195
|
|
196 int len = readLength();
|
|
197
|
|
198 if ((len < 0) || len > available())
|
|
199 throw new IOException("Illegal len in DER object (" + len + ")");
|
|
200
|
|
201 byte[] b = readBytes(len);
|
|
202 return b;
|
|
203 }
|
|
204
|
|
205 }
|