Mercurial > dropbear
comparison libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c @ 302:973fccb59ea4 ucc-axis-hack
propagate from branch 'au.asn.ucc.matt.dropbear' (head 11034278bd1917bebcbdc69cf53b1891ce9db121)
to branch 'au.asn.ucc.matt.dropbear.ucc-axis-hack' (head 10a1f614fec73d0820c3f61160d9db409b9beb46)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 25 Mar 2006 12:59:58 +0000 |
parents | 1b9e69c058d2 |
children |
comparison
equal
deleted
inserted
replaced
299:740e782679be | 302:973fccb59ea4 |
---|---|
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.org | |
10 */ | |
11 #include "tomcrypt.h" | |
12 #include <stdarg.h> | |
13 | |
14 | |
15 /** | |
16 @file der_decode_sequence.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 @return CRYPT_OK on success | |
29 */ | |
30 int der_decode_sequence(const unsigned char *in, unsigned long inlen, | |
31 ltc_asn1_list *list, unsigned long outlen) | |
32 { | |
33 int err, type; | |
34 unsigned long size, x, y, z, i, blksize; | |
35 void *data; | |
36 | |
37 LTC_ARGCHK(in != NULL); | |
38 LTC_ARGCHK(list != NULL); | |
39 | |
40 /* get blk size */ | |
41 if (inlen < 2) { | |
42 return CRYPT_INVALID_PACKET; | |
43 } | |
44 | |
45 /* sequence type? */ | |
46 x = 0; | |
47 if (in[x++] != 0x30) { | |
48 return CRYPT_INVALID_PACKET; | |
49 } | |
50 | |
51 if (in[x] < 128) { | |
52 blksize = in[x++]; | |
53 } else if (in[x] & 0x80) { | |
54 if (in[x] < 0x81 || in[x] > 0x83) { | |
55 return CRYPT_INVALID_PACKET; | |
56 } | |
57 y = in[x++] & 0x7F; | |
58 | |
59 /* would reading the len bytes overrun? */ | |
60 if (x + y > inlen) { | |
61 return CRYPT_INVALID_PACKET; | |
62 } | |
63 | |
64 /* read len */ | |
65 blksize = 0; | |
66 while (y--) { | |
67 blksize = (blksize << 8) | (unsigned long)in[x++]; | |
68 } | |
69 } | |
70 | |
71 /* would this blksize overflow? */ | |
72 if (x + blksize > inlen) { | |
73 return CRYPT_INVALID_PACKET; | |
74 } | |
75 | |
76 /* ok read data */ | |
77 inlen = blksize; | |
78 for (i = 0; i < outlen; i++) { | |
79 type = list[i].type; | |
80 size = list[i].size; | |
81 data = list[i].data; | |
82 | |
83 if (type == LTC_ASN1_EOL) { | |
84 break; | |
85 } | |
86 | |
87 switch (type) { | |
88 case LTC_ASN1_INTEGER: | |
89 z = inlen; | |
90 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { | |
91 goto LBL_ERR; | |
92 } | |
93 if ((err = der_length_integer(data, &z)) != CRYPT_OK) { | |
94 goto LBL_ERR; | |
95 } | |
96 x += z; | |
97 inlen -= z; | |
98 break; | |
99 | |
100 | |
101 case LTC_ASN1_SHORT_INTEGER: | |
102 z = inlen; | |
103 if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { | |
104 goto LBL_ERR; | |
105 } | |
106 if ((err = der_length_short_integer(size, &z)) != CRYPT_OK) { | |
107 goto LBL_ERR; | |
108 } | |
109 x += z; | |
110 inlen -= z; | |
111 break; | |
112 | |
113 case LTC_ASN1_BIT_STRING: | |
114 z = inlen; | |
115 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { | |
116 goto LBL_ERR; | |
117 } | |
118 list[i].size = size; | |
119 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { | |
120 goto LBL_ERR; | |
121 } | |
122 x += z; | |
123 inlen -= z; | |
124 break; | |
125 | |
126 case LTC_ASN1_OCTET_STRING: | |
127 z = inlen; | |
128 if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { | |
129 goto LBL_ERR; | |
130 } | |
131 list[i].size = size; | |
132 if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { | |
133 goto LBL_ERR; | |
134 } | |
135 x += z; | |
136 inlen -= z; | |
137 break; | |
138 | |
139 case LTC_ASN1_NULL: | |
140 if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { | |
141 err = CRYPT_INVALID_PACKET; | |
142 goto LBL_ERR; | |
143 } | |
144 x += 2; | |
145 inlen -= 2; | |
146 break; | |
147 | |
148 case LTC_ASN1_OBJECT_IDENTIFIER: | |
149 z = inlen; | |
150 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { | |
151 goto LBL_ERR; | |
152 } | |
153 list[i].size = size; | |
154 if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { | |
155 goto LBL_ERR; | |
156 } | |
157 x += z; | |
158 inlen -= z; | |
159 break; | |
160 | |
161 case LTC_ASN1_IA5_STRING: | |
162 z = inlen; | |
163 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { | |
164 goto LBL_ERR; | |
165 } | |
166 list[i].size = size; | |
167 if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { | |
168 goto LBL_ERR; | |
169 } | |
170 x += z; | |
171 inlen -= z; | |
172 break; | |
173 | |
174 | |
175 case LTC_ASN1_PRINTABLE_STRING: | |
176 z = inlen; | |
177 if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { | |
178 goto LBL_ERR; | |
179 } | |
180 list[i].size = size; | |
181 if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { | |
182 goto LBL_ERR; | |
183 } | |
184 x += z; | |
185 inlen -= z; | |
186 break; | |
187 | |
188 case LTC_ASN1_UTCTIME: | |
189 z = inlen; | |
190 if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { | |
191 goto LBL_ERR; | |
192 } | |
193 x += z; | |
194 inlen -= z; | |
195 break; | |
196 | |
197 case LTC_ASN1_SEQUENCE: | |
198 z = inlen; | |
199 if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { | |
200 goto LBL_ERR; | |
201 } | |
202 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { | |
203 goto LBL_ERR; | |
204 } | |
205 x += z; | |
206 inlen -= z; | |
207 break; | |
208 | |
209 | |
210 case LTC_ASN1_CHOICE: | |
211 z = inlen; | |
212 if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { | |
213 goto LBL_ERR; | |
214 } | |
215 x += z; | |
216 inlen -= z; | |
217 break; | |
218 | |
219 default: | |
220 err = CRYPT_INVALID_ARG; | |
221 goto LBL_ERR; | |
222 } | |
223 } | |
224 err = CRYPT_OK; | |
225 | |
226 LBL_ERR: | |
227 return err; | |
228 } | |
229 | |
230 #endif | |
231 | |
232 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c,v $ */ | |
233 /* $Revision: 1.8 $ */ | |
234 /* $Date: 2005/06/18 19:20:23 $ */ |