Mercurial > dropbear
comparison src/pk/asn1/der/sequence/der_encode_sequence_ex.c @ 380:d5faf4814ddb libtomcrypt-orig libtomcrypt-1.16
Update to LibTomCrypt 1.16
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 11 Jan 2007 02:22:00 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
280:59400faa4b44 | 380:d5faf4814ddb |
---|---|
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_encode_sequence_ex.c | |
17 ASN.1 DER, encode a SEQUENCE, Tom St Denis | |
18 */ | |
19 | |
20 #ifdef LTC_DER | |
21 | |
22 /** | |
23 Encode a SEQUENCE | |
24 @param list The list of items to encode | |
25 @param inlen The number of items in the list | |
26 @param out [out] The destination | |
27 @param outlen [in/out] The size of the output | |
28 @param type_of LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF | |
29 @return CRYPT_OK on success | |
30 */ | |
31 int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, | |
32 unsigned char *out, unsigned long *outlen, int type_of) | |
33 { | |
34 int err, type; | |
35 unsigned long size, x, y, z, i; | |
36 void *data; | |
37 | |
38 LTC_ARGCHK(list != NULL); | |
39 LTC_ARGCHK(out != NULL); | |
40 LTC_ARGCHK(outlen != NULL); | |
41 | |
42 /* get size of output that will be required */ | |
43 y = 0; | |
44 for (i = 0; i < inlen; i++) { | |
45 type = list[i].type; | |
46 size = list[i].size; | |
47 data = list[i].data; | |
48 | |
49 if (type == LTC_ASN1_EOL) { | |
50 break; | |
51 } | |
52 | |
53 switch (type) { | |
54 case LTC_ASN1_BOOLEAN: | |
55 if ((err = der_length_boolean(&x)) != CRYPT_OK) { | |
56 goto LBL_ERR; | |
57 } | |
58 y += x; | |
59 break; | |
60 | |
61 case LTC_ASN1_INTEGER: | |
62 if ((err = der_length_integer(data, &x)) != CRYPT_OK) { | |
63 goto LBL_ERR; | |
64 } | |
65 y += x; | |
66 break; | |
67 | |
68 case LTC_ASN1_SHORT_INTEGER: | |
69 if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) { | |
70 goto LBL_ERR; | |
71 } | |
72 y += x; | |
73 break; | |
74 | |
75 case LTC_ASN1_BIT_STRING: | |
76 if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { | |
77 goto LBL_ERR; | |
78 } | |
79 y += x; | |
80 break; | |
81 | |
82 case LTC_ASN1_OCTET_STRING: | |
83 if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { | |
84 goto LBL_ERR; | |
85 } | |
86 y += x; | |
87 break; | |
88 | |
89 case LTC_ASN1_NULL: | |
90 y += 2; | |
91 break; | |
92 | |
93 case LTC_ASN1_OBJECT_IDENTIFIER: | |
94 if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { | |
95 goto LBL_ERR; | |
96 } | |
97 y += x; | |
98 break; | |
99 | |
100 case LTC_ASN1_IA5_STRING: | |
101 if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { | |
102 goto LBL_ERR; | |
103 } | |
104 y += x; | |
105 break; | |
106 | |
107 case LTC_ASN1_PRINTABLE_STRING: | |
108 if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { | |
109 goto LBL_ERR; | |
110 } | |
111 y += x; | |
112 break; | |
113 | |
114 case LTC_ASN1_UTF8_STRING: | |
115 if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { | |
116 goto LBL_ERR; | |
117 } | |
118 y += x; | |
119 break; | |
120 | |
121 case LTC_ASN1_UTCTIME: | |
122 if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { | |
123 goto LBL_ERR; | |
124 } | |
125 y += x; | |
126 break; | |
127 | |
128 case LTC_ASN1_SET: | |
129 case LTC_ASN1_SETOF: | |
130 case LTC_ASN1_SEQUENCE: | |
131 if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { | |
132 goto LBL_ERR; | |
133 } | |
134 y += x; | |
135 break; | |
136 | |
137 default: | |
138 err = CRYPT_INVALID_ARG; | |
139 goto LBL_ERR; | |
140 } | |
141 } | |
142 | |
143 /* calc header size */ | |
144 z = y; | |
145 if (y < 128) { | |
146 y += 2; | |
147 } else if (y < 256) { | |
148 /* 0x30 0x81 LL */ | |
149 y += 3; | |
150 } else if (y < 65536UL) { | |
151 /* 0x30 0x82 LL LL */ | |
152 y += 4; | |
153 } else if (y < 16777216UL) { | |
154 /* 0x30 0x83 LL LL LL */ | |
155 y += 5; | |
156 } else { | |
157 err = CRYPT_INVALID_ARG; | |
158 goto LBL_ERR; | |
159 } | |
160 | |
161 /* too big ? */ | |
162 if (*outlen < y) { | |
163 *outlen = y; | |
164 err = CRYPT_BUFFER_OVERFLOW; | |
165 goto LBL_ERR; | |
166 } | |
167 | |
168 /* store header */ | |
169 x = 0; | |
170 out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31; | |
171 | |
172 if (z < 128) { | |
173 out[x++] = (unsigned char)z; | |
174 } else if (z < 256) { | |
175 out[x++] = 0x81; | |
176 out[x++] = (unsigned char)z; | |
177 } else if (z < 65536UL) { | |
178 out[x++] = 0x82; | |
179 out[x++] = (unsigned char)((z>>8UL)&255); | |
180 out[x++] = (unsigned char)(z&255); | |
181 } else if (z < 16777216UL) { | |
182 out[x++] = 0x83; | |
183 out[x++] = (unsigned char)((z>>16UL)&255); | |
184 out[x++] = (unsigned char)((z>>8UL)&255); | |
185 out[x++] = (unsigned char)(z&255); | |
186 } | |
187 | |
188 /* store data */ | |
189 *outlen -= x; | |
190 for (i = 0; i < inlen; i++) { | |
191 type = list[i].type; | |
192 size = list[i].size; | |
193 data = list[i].data; | |
194 | |
195 if (type == LTC_ASN1_EOL) { | |
196 break; | |
197 } | |
198 | |
199 switch (type) { | |
200 case LTC_ASN1_BOOLEAN: | |
201 z = *outlen; | |
202 if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) { | |
203 goto LBL_ERR; | |
204 } | |
205 x += z; | |
206 *outlen -= z; | |
207 break; | |
208 | |
209 case LTC_ASN1_INTEGER: | |
210 z = *outlen; | |
211 if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) { | |
212 goto LBL_ERR; | |
213 } | |
214 x += z; | |
215 *outlen -= z; | |
216 break; | |
217 | |
218 case LTC_ASN1_SHORT_INTEGER: | |
219 z = *outlen; | |
220 if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) { | |
221 goto LBL_ERR; | |
222 } | |
223 x += z; | |
224 *outlen -= z; | |
225 break; | |
226 | |
227 case LTC_ASN1_BIT_STRING: | |
228 z = *outlen; | |
229 if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) { | |
230 goto LBL_ERR; | |
231 } | |
232 x += z; | |
233 *outlen -= z; | |
234 break; | |
235 | |
236 case LTC_ASN1_OCTET_STRING: | |
237 z = *outlen; | |
238 if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) { | |
239 goto LBL_ERR; | |
240 } | |
241 x += z; | |
242 *outlen -= z; | |
243 break; | |
244 | |
245 case LTC_ASN1_NULL: | |
246 out[x++] = 0x05; | |
247 out[x++] = 0x00; | |
248 *outlen -= 2; | |
249 break; | |
250 | |
251 case LTC_ASN1_OBJECT_IDENTIFIER: | |
252 z = *outlen; | |
253 if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) { | |
254 goto LBL_ERR; | |
255 } | |
256 x += z; | |
257 *outlen -= z; | |
258 break; | |
259 | |
260 case LTC_ASN1_IA5_STRING: | |
261 z = *outlen; | |
262 if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) { | |
263 goto LBL_ERR; | |
264 } | |
265 x += z; | |
266 *outlen -= z; | |
267 break; | |
268 | |
269 case LTC_ASN1_PRINTABLE_STRING: | |
270 z = *outlen; | |
271 if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) { | |
272 goto LBL_ERR; | |
273 } | |
274 x += z; | |
275 *outlen -= z; | |
276 break; | |
277 | |
278 case LTC_ASN1_UTF8_STRING: | |
279 z = *outlen; | |
280 if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) { | |
281 goto LBL_ERR; | |
282 } | |
283 x += z; | |
284 *outlen -= z; | |
285 break; | |
286 | |
287 case LTC_ASN1_UTCTIME: | |
288 z = *outlen; | |
289 if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) { | |
290 goto LBL_ERR; | |
291 } | |
292 x += z; | |
293 *outlen -= z; | |
294 break; | |
295 | |
296 case LTC_ASN1_SET: | |
297 z = *outlen; | |
298 if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { | |
299 goto LBL_ERR; | |
300 } | |
301 x += z; | |
302 *outlen -= z; | |
303 break; | |
304 | |
305 case LTC_ASN1_SETOF: | |
306 z = *outlen; | |
307 if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) { | |
308 goto LBL_ERR; | |
309 } | |
310 x += z; | |
311 *outlen -= z; | |
312 break; | |
313 | |
314 case LTC_ASN1_SEQUENCE: | |
315 z = *outlen; | |
316 if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) { | |
317 goto LBL_ERR; | |
318 } | |
319 x += z; | |
320 *outlen -= z; | |
321 break; | |
322 | |
323 default: | |
324 err = CRYPT_INVALID_ARG; | |
325 goto LBL_ERR; | |
326 } | |
327 } | |
328 *outlen = x; | |
329 err = CRYPT_OK; | |
330 | |
331 LBL_ERR: | |
332 return err; | |
333 } | |
334 | |
335 #endif |