Mercurial > dropbear
comparison libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c @ 389:5ff8218bcee9
propagate from branch 'au.asn.ucc.matt.ltm.dropbear' (head 2af95f00ebd5bb7a28b3817db1218442c935388e)
to branch 'au.asn.ucc.matt.dropbear' (head ecd779509ef23a8cdf64888904fc9b31d78aa933)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 11 Jan 2007 03:14:55 +0000 |
parents | 0cbe8f6dbf9e |
children | f849a5ca2efc |
comparison
equal
deleted
inserted
replaced
388:fb54020f78e1 | 389:5ff8218bcee9 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.com | |
10 */ | |
11 #include "tomcrypt.h" | |
12 #include <stdarg.h> | |
13 | |
14 | |
15 /** | |
16 @file der_decode_sequence_ex.c | |
17 ASN.1 DER, decode a SEQUENCE, Tom St Denis | |
18 */ | |
19 | |
20 #ifdef LTC_DER | |
21 | |
22 /** | |
23 Decode a SEQUENCE | |
24 @param in The DER encoded input | |
25 @param inlen The size of the input | |
26 @param list The list of items to decode | |
27 @param outlen The number of items in the list | |
28 @param ordered Search an unordeded or ordered list | |
29 @return CRYPT_OK on success | |
30 */ | |
31 int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, | |
32 ltc_asn1_list *list, unsigned long outlen, int ordered) | |
33 { | |
34 int err, type; | |
35 unsigned long size, x, y, z, i, blksize; | |
36 void *data; | |
37 | |
38 LTC_ARGCHK(in != NULL); | |
39 LTC_ARGCHK(list != NULL); | |
40 | |
41 /* get blk size */ | |
42 if (inlen < 2) { | |
43 return CRYPT_INVALID_PACKET; | |
44 } | |
45 | |
46 /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */ | |
47 x = 0; | |
48 if (in[x] != 0x30 && in[x] != 0x31) { | |
49 return CRYPT_INVALID_PACKET; | |
50 } | |
51 ++x; | |
52 | |
53 if (in[x] < 128) { | |
54 blksize = in[x++]; | |
55 } else if (in[x] & 0x80) { | |
56 if (in[x] < 0x81 || in[x] > 0x83) { | |
57 return CRYPT_INVALID_PACKET; | |
58 } | |
59 y = in[x++] & 0x7F; | |
60 | |
61 /* would reading the len bytes overrun? */ | |
62 if (x + y > inlen) { | |
63 return CRYPT_INVALID_PACKET; | |
64 } | |
65 | |
66 /* read len */ | |
67 blksize = 0; | |
68 while (y--) { | |
69 blksize = (blksize << 8) | (unsigned long)in[x++]; | |
70 } | |
71 } | |
72 | |
73 /* would this blksize overflow? */ | |
74 if (x + blksize > inlen) { | |
75 return CRYPT_INVALID_PACKET; | |
76 } | |
77 | |
78 /* mark all as unused */ | |
79 for (i = 0; i < outlen; i++) { | |
80 list[i].used = 0; | |
81 } | |
82 | |
83 /* ok read data */ | |
84 inlen = blksize; | |
85 for (i = 0; i < outlen; i++) { | |
86 z = 0; | |
87 type = list[i].type; | |
88 size = list[i].size; | |
89 data = list[i].data; | |
90 if (!ordered && list[i].used == 1) { continue; } | |
91 | |
92 if (type == LTC_ASN1_EOL) { | |
93 break; | |
94 } | |
95 | |
96 switch (type) { | |
97 case LTC_ASN1_BOOLEAN: | |
98 z = inlen; | |
99 if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { | |
100 goto LBL_ERR; | |
101 } | |
102 if ((err = der_length_boolean(&z)) != CRYPT_OK) { | |
103 goto LBL_ERR; | |
104 } | |
105 break; | |
106 | |
107 case LTC_ASN1_INTEGER: | |
108 z = inlen; | |
109 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { | |
110 if (!ordered) { continue; } | |
111 goto LBL_ERR; | |
112 } | |
113 if ((err = der_length_integer(data, &z)) != CRYPT_OK) { | |
114 goto LBL_ERR; | |
115 } | |
116 break; | |
117 | |
118 case LTC_ASN1_SHORT_INTEGER: | |
119 z = inlen; | |
120 if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { | |
121 if (!ordered) { continue; } | |
122 goto LBL_ERR; | |
123 } | |
124 if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { | |
125 goto LBL_ERR; | |
126 } | |
127 | |
128 break; | |
129 | |
130 case LTC_ASN1_BIT_STRING: | |
131 z = inlen; | |
132 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { | |
133 if (!ordered) { continue; } | |
134 goto LBL_ERR; | |
135 } | |
136 list[i].size = size; | |
137 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { | |
138 goto LBL_ERR; | |
139 } | |
140 break; | |
141 | |
142 case LTC_ASN1_OCTET_STRING: | |
143 z = inlen; | |
144 if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { | |
145 if (!ordered) { continue; } | |
146 goto LBL_ERR; | |
147 } | |
148 list[i].size = size; | |
149 if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { | |
150 goto LBL_ERR; | |
151 } | |
152 break; | |
153 | |
154 case LTC_ASN1_NULL: | |
155 if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { | |
156 if (!ordered) { continue; } | |
157 err = CRYPT_INVALID_PACKET; | |
158 goto LBL_ERR; | |
159 } | |
160 z = 2; | |
161 break; | |
162 | |
163 case LTC_ASN1_OBJECT_IDENTIFIER: | |
164 z = inlen; | |
165 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { | |
166 if (!ordered) { continue; } | |
167 goto LBL_ERR; | |
168 } | |
169 list[i].size = size; | |
170 if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { | |
171 goto LBL_ERR; | |
172 } | |
173 break; | |
174 | |
175 case LTC_ASN1_IA5_STRING: | |
176 z = inlen; | |
177 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { | |
178 if (!ordered) { continue; } | |
179 goto LBL_ERR; | |
180 } | |
181 list[i].size = size; | |
182 if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { | |
183 goto LBL_ERR; | |
184 } | |
185 break; | |
186 | |
187 | |
188 case LTC_ASN1_PRINTABLE_STRING: | |
189 z = inlen; | |
190 if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { | |
191 if (!ordered) { continue; } | |
192 goto LBL_ERR; | |
193 } | |
194 list[i].size = size; | |
195 if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { | |
196 goto LBL_ERR; | |
197 } | |
198 break; | |
199 | |
200 case LTC_ASN1_UTF8_STRING: | |
201 z = inlen; | |
202 if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) { | |
203 if (!ordered) { continue; } | |
204 goto LBL_ERR; | |
205 } | |
206 list[i].size = size; | |
207 if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) { | |
208 goto LBL_ERR; | |
209 } | |
210 break; | |
211 | |
212 case LTC_ASN1_UTCTIME: | |
213 z = inlen; | |
214 if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { | |
215 if (!ordered) { continue; } | |
216 goto LBL_ERR; | |
217 } | |
218 break; | |
219 | |
220 case LTC_ASN1_SET: | |
221 z = inlen; | |
222 if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { | |
223 if (!ordered) { continue; } | |
224 goto LBL_ERR; | |
225 } | |
226 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { | |
227 goto LBL_ERR; | |
228 } | |
229 break; | |
230 | |
231 case LTC_ASN1_SETOF: | |
232 case LTC_ASN1_SEQUENCE: | |
233 /* detect if we have the right type */ | |
234 if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { | |
235 err = CRYPT_INVALID_PACKET; | |
236 goto LBL_ERR; | |
237 } | |
238 | |
239 z = inlen; | |
240 if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { | |
241 if (!ordered) { continue; } | |
242 goto LBL_ERR; | |
243 } | |
244 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { | |
245 goto LBL_ERR; | |
246 } | |
247 break; | |
248 | |
249 | |
250 case LTC_ASN1_CHOICE: | |
251 z = inlen; | |
252 if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { | |
253 if (!ordered) { continue; } | |
254 goto LBL_ERR; | |
255 } | |
256 break; | |
257 | |
258 default: | |
259 err = CRYPT_INVALID_ARG; | |
260 goto LBL_ERR; | |
261 } | |
262 x += z; | |
263 inlen -= z; | |
264 list[i].used = 1; | |
265 if (!ordered) { | |
266 /* restart the decoder */ | |
267 i = -1; | |
268 } | |
269 } | |
270 | |
271 for (i = 0; i < outlen; i++) { | |
272 if (list[i].used == 0) { | |
273 err = CRYPT_INVALID_PACKET; | |
274 goto LBL_ERR; | |
275 } | |
276 } | |
277 err = CRYPT_OK; | |
278 | |
279 LBL_ERR: | |
280 return err; | |
281 } | |
282 | |
283 #endif | |
284 | |
285 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c,v $ */ | |
286 /* $Revision: 1.15 $ */ | |
287 /* $Date: 2006/11/26 02:25:18 $ */ |