diff options
author | lv-426 <oxcafebaby@yahoo.com> | 2008-06-22 18:20:35 +0000 |
---|---|---|
committer | lv-426 <oxcafebaby@yahoo.com> | 2008-06-22 18:20:35 +0000 |
commit | a0339d2458867dbe9485499265641ff205063445 (patch) | |
tree | 055b38828b3696520408a32edf81df5bb37400f0 /src/daemon/https/minitasn1 | |
parent | 97c026da05495b83f1511906c2ca027e12ef6cf7 (diff) | |
download | libmicrohttpd-a0339d2458867dbe9485499265641ff205063445.tar.gz libmicrohttpd-a0339d2458867dbe9485499265641ff205063445.zip |
initial GNU TLS import - this should reduce in size considerable
Diffstat (limited to 'src/daemon/https/minitasn1')
-rw-r--r-- | src/daemon/https/minitasn1/Makefile.am | 16 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/README | 3 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/coding.c | 1229 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/decoding.c | 2821 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/element.c | 1013 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/element.h | 13 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/errors.c | 135 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/errors.h | 30 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/gstr.c | 68 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/gstr.h | 5 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/int.h | 112 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/libtasn1.h | 246 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/mem.h | 27 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/parser_aux.c | 1072 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/parser_aux.h | 63 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/structure.c | 1221 | ||||
-rw-r--r-- | src/daemon/https/minitasn1/structure.h | 23 |
17 files changed, 8097 insertions, 0 deletions
diff --git a/src/daemon/https/minitasn1/Makefile.am b/src/daemon/https/minitasn1/Makefile.am new file mode 100644 index 00000000..fc924cc4 --- /dev/null +++ b/src/daemon/https/minitasn1/Makefile.am | |||
@@ -0,0 +1,16 @@ | |||
1 | |||
2 | AM_CPPFLAGS = -I./includes \ | ||
3 | -I$(top_srcdir)/src/daemon/https/lgl \ | ||
4 | -I$(top_srcdir)/src/daemon/https/tls \ | ||
5 | -I$(top_srcdir)/src/daemon/https/includes | ||
6 | |||
7 | noinst_LTLIBRARIES = libasn1.la | ||
8 | |||
9 | libasn1_la_SOURCES = \ | ||
10 | libtasn1.h \ | ||
11 | mem.h \ | ||
12 | gstr.h \ | ||
13 | errors.h \ | ||
14 | int.h \ | ||
15 | parser_aux.h structure.h element.h decoding.c gstr.c errors.c \ | ||
16 | parser_aux.c structure.c element.c coding.c | ||
diff --git a/src/daemon/https/minitasn1/README b/src/daemon/https/minitasn1/README new file mode 100644 index 00000000..9d484dfc --- /dev/null +++ b/src/daemon/https/minitasn1/README | |||
@@ -0,0 +1,3 @@ | |||
1 | This is just a mirror of the files in the libtasn1's | ||
2 | lib/ directory. | ||
3 | |||
diff --git a/src/daemon/https/minitasn1/coding.c b/src/daemon/https/minitasn1/coding.c new file mode 100644 index 00000000..10870e01 --- /dev/null +++ b/src/daemon/https/minitasn1/coding.c | |||
@@ -0,0 +1,1229 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2006 Free Software Foundation | ||
3 | * Copyright (C) 2002 Fabio Fiorina | ||
4 | * | ||
5 | * This file is part of LIBTASN1. | ||
6 | * | ||
7 | * The LIBTASN1 library is free software; you can redistribute it | ||
8 | * and/or modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | */ | ||
22 | |||
23 | |||
24 | /*****************************************************/ | ||
25 | /* File: coding.c */ | ||
26 | /* Description: Functions to create a DER coding of */ | ||
27 | /* an ASN1 type. */ | ||
28 | /*****************************************************/ | ||
29 | |||
30 | #include <int.h> | ||
31 | #include <errors.h> | ||
32 | #include "parser_aux.h" | ||
33 | #include <gstr.h> | ||
34 | #include "element.h" | ||
35 | #include <structure.h> | ||
36 | |||
37 | #define MAX_TAG_LEN 16 | ||
38 | |||
39 | /******************************************************/ | ||
40 | /* Function : _asn1_error_description_value_not_found */ | ||
41 | /* Description: creates the ErrorDescription string */ | ||
42 | /* for the ASN1_VALUE_NOT_FOUND error. */ | ||
43 | /* Parameters: */ | ||
44 | /* node: node of the tree where the value is NULL. */ | ||
45 | /* ErrorDescription: string returned. */ | ||
46 | /* Return: */ | ||
47 | /******************************************************/ | ||
48 | void | ||
49 | _asn1_error_description_value_not_found (node_asn * node, | ||
50 | char *ErrorDescription) | ||
51 | { | ||
52 | |||
53 | if (ErrorDescription == NULL) | ||
54 | return; | ||
55 | |||
56 | Estrcpy (ErrorDescription, ":: value of element '"); | ||
57 | _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), | ||
58 | MAX_ERROR_DESCRIPTION_SIZE - 40); | ||
59 | Estrcat (ErrorDescription, "' not found"); | ||
60 | |||
61 | } | ||
62 | |||
63 | /** | ||
64 | * asn1_length_der: | ||
65 | * @len: value to convert. | ||
66 | * @ans: string returned. | ||
67 | * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]). | ||
68 | * | ||
69 | * Creates the DER coding for the LEN parameter (only the length). | ||
70 | * The @ans buffer is pre-allocated and must have room for the output. | ||
71 | **/ | ||
72 | void | ||
73 | asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len) | ||
74 | { | ||
75 | int k; | ||
76 | unsigned char temp[SIZEOF_UNSIGNED_LONG_INT]; | ||
77 | |||
78 | if (len < 128) | ||
79 | { | ||
80 | /* short form */ | ||
81 | if (ans != NULL) | ||
82 | ans[0] = (unsigned char) len; | ||
83 | *ans_len = 1; | ||
84 | } | ||
85 | else | ||
86 | { | ||
87 | /* Long form */ | ||
88 | k = 0; | ||
89 | while (len) | ||
90 | { | ||
91 | temp[k++] = len & 0xFF; | ||
92 | len = len >> 8; | ||
93 | } | ||
94 | *ans_len = k + 1; | ||
95 | if (ans != NULL) | ||
96 | { | ||
97 | ans[0] = ((unsigned char) k & 0x7F) + 128; | ||
98 | while (k--) | ||
99 | ans[*ans_len - 1 - k] = temp[k]; | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | |||
104 | /******************************************************/ | ||
105 | /* Function : _asn1_tag_der */ | ||
106 | /* Description: creates the DER coding for the CLASS */ | ||
107 | /* and TAG parameters. */ | ||
108 | /* Parameters: */ | ||
109 | /* class: value to convert. */ | ||
110 | /* tag_value: value to convert. */ | ||
111 | /* ans: string returned. */ | ||
112 | /* ans_len: number of meaningful bytes of ANS */ | ||
113 | /* (ans[0]..ans[ans_len-1]). */ | ||
114 | /* Return: */ | ||
115 | /******************************************************/ | ||
116 | void | ||
117 | _asn1_tag_der (unsigned char class, unsigned int tag_value, | ||
118 | unsigned char *ans, int *ans_len) | ||
119 | { | ||
120 | int k; | ||
121 | unsigned char temp[SIZEOF_UNSIGNED_INT]; | ||
122 | |||
123 | if (tag_value < 31) | ||
124 | { | ||
125 | /* short form */ | ||
126 | ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F)); | ||
127 | *ans_len = 1; | ||
128 | } | ||
129 | else | ||
130 | { | ||
131 | /* Long form */ | ||
132 | ans[0] = (class & 0xE0) + 31; | ||
133 | k = 0; | ||
134 | while (tag_value) | ||
135 | { | ||
136 | temp[k++] = tag_value & 0x7F; | ||
137 | tag_value = tag_value >> 7; | ||
138 | } | ||
139 | *ans_len = k + 1; | ||
140 | while (k--) | ||
141 | ans[*ans_len - 1 - k] = temp[k] + 128; | ||
142 | ans[*ans_len - 1] -= 128; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * asn1_octet_der: | ||
148 | * @str: OCTET string. | ||
149 | * @str_len: STR length (str[0]..str[str_len-1]). | ||
150 | * @der: string returned. | ||
151 | * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]). | ||
152 | * | ||
153 | * Creates the DER coding for an OCTET type (length included). | ||
154 | **/ | ||
155 | void | ||
156 | asn1_octet_der (const unsigned char *str, int str_len, | ||
157 | unsigned char *der, int *der_len) | ||
158 | { | ||
159 | int len_len; | ||
160 | |||
161 | if (der == NULL || str_len < 0) | ||
162 | return; | ||
163 | asn1_length_der (str_len, der, &len_len); | ||
164 | memcpy (der + len_len, str, str_len); | ||
165 | *der_len = str_len + len_len; | ||
166 | } | ||
167 | |||
168 | /******************************************************/ | ||
169 | /* Function : _asn1_time_der */ | ||
170 | /* Description: creates the DER coding for a TIME */ | ||
171 | /* type (length included). */ | ||
172 | /* Parameters: */ | ||
173 | /* str: TIME null-terminated string. */ | ||
174 | /* der: string returned. */ | ||
175 | /* der_len: number of meaningful bytes of DER */ | ||
176 | /* (der[0]..der[ans_len-1]). Initially it */ | ||
177 | /* if must store the lenght of DER. */ | ||
178 | /* Return: */ | ||
179 | /* ASN1_MEM_ERROR when DER isn't big enough */ | ||
180 | /* ASN1_SUCCESS otherwise */ | ||
181 | /******************************************************/ | ||
182 | asn1_retCode | ||
183 | _asn1_time_der (unsigned char *str, unsigned char *der, int *der_len) | ||
184 | { | ||
185 | int len_len; | ||
186 | int max_len; | ||
187 | |||
188 | max_len = *der_len; | ||
189 | |||
190 | asn1_length_der (strlen (str), (max_len > 0) ? der : NULL, &len_len); | ||
191 | |||
192 | if ((len_len + (int) strlen (str)) <= max_len) | ||
193 | memcpy (der + len_len, str, strlen (str)); | ||
194 | *der_len = len_len + strlen (str); | ||
195 | |||
196 | if ((*der_len) > max_len) | ||
197 | return ASN1_MEM_ERROR; | ||
198 | |||
199 | return ASN1_SUCCESS; | ||
200 | } | ||
201 | |||
202 | |||
203 | /* | ||
204 | void | ||
205 | _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str) | ||
206 | { | ||
207 | int len_len,str_len; | ||
208 | char temp[20]; | ||
209 | |||
210 | if(str==NULL) return; | ||
211 | str_len=asn1_get_length_der(der,*der_len,&len_len); | ||
212 | if (str_len<0) return; | ||
213 | memcpy(temp,der+len_len,str_len); | ||
214 | *der_len=str_len+len_len; | ||
215 | switch(str_len){ | ||
216 | case 11: | ||
217 | temp[10]=0; | ||
218 | strcat(temp,"00+0000"); | ||
219 | break; | ||
220 | case 13: | ||
221 | temp[12]=0; | ||
222 | strcat(temp,"+0000"); | ||
223 | break; | ||
224 | case 15: | ||
225 | temp[15]=0; | ||
226 | memmove(temp+12,temp+10,6); | ||
227 | temp[10]=temp[11]='0'; | ||
228 | break; | ||
229 | case 17: | ||
230 | temp[17]=0; | ||
231 | break; | ||
232 | default: | ||
233 | return; | ||
234 | } | ||
235 | strcpy(str,temp); | ||
236 | } | ||
237 | */ | ||
238 | |||
239 | /******************************************************/ | ||
240 | /* Function : _asn1_objectid_der */ | ||
241 | /* Description: creates the DER coding for an */ | ||
242 | /* OBJECT IDENTIFIER type (length included). */ | ||
243 | /* Parameters: */ | ||
244 | /* str: OBJECT IDENTIFIER null-terminated string. */ | ||
245 | /* der: string returned. */ | ||
246 | /* der_len: number of meaningful bytes of DER */ | ||
247 | /* (der[0]..der[ans_len-1]). Initially it */ | ||
248 | /* must store the length of DER. */ | ||
249 | /* Return: */ | ||
250 | /* ASN1_MEM_ERROR when DER isn't big enough */ | ||
251 | /* ASN1_SUCCESS otherwise */ | ||
252 | /******************************************************/ | ||
253 | asn1_retCode | ||
254 | _asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len) | ||
255 | { | ||
256 | int len_len, counter, k, first, max_len; | ||
257 | char *temp, *n_end, *n_start; | ||
258 | unsigned char bit7; | ||
259 | unsigned long val, val1 = 0; | ||
260 | |||
261 | max_len = *der_len; | ||
262 | |||
263 | temp = (char *) _asn1_alloca (strlen (str) + 2); | ||
264 | if (temp == NULL) | ||
265 | return ASN1_MEM_ALLOC_ERROR; | ||
266 | |||
267 | strcpy (temp, str); | ||
268 | strcat (temp, "."); | ||
269 | |||
270 | counter = 0; | ||
271 | n_start = temp; | ||
272 | while ((n_end = strchr (n_start, '.'))) | ||
273 | { | ||
274 | *n_end = 0; | ||
275 | val = strtoul (n_start, NULL, 10); | ||
276 | counter++; | ||
277 | |||
278 | if (counter == 1) | ||
279 | val1 = val; | ||
280 | else if (counter == 2) | ||
281 | { | ||
282 | if (max_len > 0) | ||
283 | der[0] = 40 * val1 + val; | ||
284 | *der_len = 1; | ||
285 | } | ||
286 | else | ||
287 | { | ||
288 | first = 0; | ||
289 | for (k = 4; k >= 0; k--) | ||
290 | { | ||
291 | bit7 = (val >> (k * 7)) & 0x7F; | ||
292 | if (bit7 || first || !k) | ||
293 | { | ||
294 | if (k) | ||
295 | bit7 |= 0x80; | ||
296 | if (max_len > (*der_len)) | ||
297 | der[*der_len] = bit7; | ||
298 | (*der_len)++; | ||
299 | first = 1; | ||
300 | } | ||
301 | } | ||
302 | |||
303 | } | ||
304 | n_start = n_end + 1; | ||
305 | } | ||
306 | |||
307 | asn1_length_der (*der_len, NULL, &len_len); | ||
308 | if (max_len >= (*der_len + len_len)) | ||
309 | { | ||
310 | memmove (der + len_len, der, *der_len); | ||
311 | asn1_length_der (*der_len, der, &len_len); | ||
312 | } | ||
313 | *der_len += len_len; | ||
314 | |||
315 | _asn1_afree (temp); | ||
316 | |||
317 | if (max_len < (*der_len)) | ||
318 | return ASN1_MEM_ERROR; | ||
319 | |||
320 | return ASN1_SUCCESS; | ||
321 | } | ||
322 | |||
323 | |||
324 | const char bit_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 }; | ||
325 | |||
326 | /** | ||
327 | * asn1_bit_der: | ||
328 | * @str: BIT string. | ||
329 | * @bit_len: number of meaningful bits in STR. | ||
330 | * @der: string returned. | ||
331 | * @der_len: number of meaningful bytes of DER | ||
332 | * (der[0]..der[ans_len-1]). | ||
333 | * | ||
334 | * Creates the DER coding for a BIT STRING type (length and pad | ||
335 | * included). | ||
336 | **/ | ||
337 | void | ||
338 | asn1_bit_der (const unsigned char *str, int bit_len, | ||
339 | unsigned char *der, int *der_len) | ||
340 | { | ||
341 | int len_len, len_byte, len_pad; | ||
342 | |||
343 | if (der == NULL) | ||
344 | return; | ||
345 | len_byte = bit_len >> 3; | ||
346 | len_pad = 8 - (bit_len & 7); | ||
347 | if (len_pad == 8) | ||
348 | len_pad = 0; | ||
349 | else | ||
350 | len_byte++; | ||
351 | asn1_length_der (len_byte + 1, der, &len_len); | ||
352 | der[len_len] = len_pad; | ||
353 | memcpy (der + len_len + 1, str, len_byte); | ||
354 | der[len_len + len_byte] &= bit_mask[len_pad]; | ||
355 | *der_len = len_byte + len_len + 1; | ||
356 | } | ||
357 | |||
358 | |||
359 | /******************************************************/ | ||
360 | /* Function : _asn1_complete_explicit_tag */ | ||
361 | /* Description: add the length coding to the EXPLICIT */ | ||
362 | /* tags. */ | ||
363 | /* Parameters: */ | ||
364 | /* node: pointer to the tree element. */ | ||
365 | /* der: string with the DER coding of the whole tree*/ | ||
366 | /* counter: number of meaningful bytes of DER */ | ||
367 | /* (der[0]..der[*counter-1]). */ | ||
368 | /* max_len: size of der vector */ | ||
369 | /* Return: */ | ||
370 | /* ASN1_MEM_ERROR if der vector isn't big enough, */ | ||
371 | /* otherwise ASN1_SUCCESS. */ | ||
372 | /******************************************************/ | ||
373 | asn1_retCode | ||
374 | _asn1_complete_explicit_tag (node_asn * node, unsigned char *der, | ||
375 | int *counter, int *max_len) | ||
376 | { | ||
377 | node_asn *p; | ||
378 | int is_tag_implicit, len2, len3; | ||
379 | unsigned char temp[SIZEOF_UNSIGNED_INT]; | ||
380 | |||
381 | is_tag_implicit = 0; | ||
382 | |||
383 | if (node->type & CONST_TAG) | ||
384 | { | ||
385 | p = node->down; | ||
386 | /* When there are nested tags we must complete them reverse to | ||
387 | the order they were created. This is because completing a tag | ||
388 | modifies all data within it, including the incomplete tags | ||
389 | which store buffer positions -- simon@josefsson.org 2002-09-06 | ||
390 | */ | ||
391 | while (p->right) | ||
392 | p = p->right; | ||
393 | while (p && p != node->down->left) | ||
394 | { | ||
395 | if (type_field (p->type) == TYPE_TAG) | ||
396 | { | ||
397 | if (p->type & CONST_EXPLICIT) | ||
398 | { | ||
399 | len2 = strtol (p->name, NULL, 10); | ||
400 | _asn1_set_name (p, NULL); | ||
401 | asn1_length_der (*counter - len2, temp, &len3); | ||
402 | if (len3 <= (*max_len)) | ||
403 | { | ||
404 | memmove (der + len2 + len3, der + len2, | ||
405 | *counter - len2); | ||
406 | memcpy (der + len2, temp, len3); | ||
407 | } | ||
408 | *max_len -= len3; | ||
409 | *counter += len3; | ||
410 | is_tag_implicit = 0; | ||
411 | } | ||
412 | else | ||
413 | { /* CONST_IMPLICIT */ | ||
414 | if (!is_tag_implicit) | ||
415 | { | ||
416 | is_tag_implicit = 1; | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | p = p->left; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | if (*max_len < 0) | ||
425 | return ASN1_MEM_ERROR; | ||
426 | |||
427 | return ASN1_SUCCESS; | ||
428 | } | ||
429 | |||
430 | |||
431 | /******************************************************/ | ||
432 | /* Function : _asn1_insert_tag_der */ | ||
433 | /* Description: creates the DER coding of tags of one */ | ||
434 | /* NODE. */ | ||
435 | /* Parameters: */ | ||
436 | /* node: pointer to the tree element. */ | ||
437 | /* der: string returned */ | ||
438 | /* counter: number of meaningful bytes of DER */ | ||
439 | /* (counter[0]..der[*counter-1]). */ | ||
440 | /* max_len: size of der vector */ | ||
441 | /* Return: */ | ||
442 | /* ASN1_GENERIC_ERROR if the type is unknown, */ | ||
443 | /* ASN1_MEM_ERROR if der vector isn't big enough, */ | ||
444 | /* otherwise ASN1_SUCCESS. */ | ||
445 | /******************************************************/ | ||
446 | asn1_retCode | ||
447 | _asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter, | ||
448 | int *max_len) | ||
449 | { | ||
450 | node_asn *p; | ||
451 | int tag_len, is_tag_implicit; | ||
452 | unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1]; | ||
453 | unsigned long tag_implicit = 0; | ||
454 | char tag_der[MAX_TAG_LEN]; | ||
455 | |||
456 | is_tag_implicit = 0; | ||
457 | |||
458 | if (node->type & CONST_TAG) | ||
459 | { | ||
460 | p = node->down; | ||
461 | while (p) | ||
462 | { | ||
463 | if (type_field (p->type) == TYPE_TAG) | ||
464 | { | ||
465 | if (p->type & CONST_APPLICATION) | ||
466 | class = ASN1_CLASS_APPLICATION; | ||
467 | else if (p->type & CONST_UNIVERSAL) | ||
468 | class = ASN1_CLASS_UNIVERSAL; | ||
469 | else if (p->type & CONST_PRIVATE) | ||
470 | class = ASN1_CLASS_PRIVATE; | ||
471 | else | ||
472 | class = ASN1_CLASS_CONTEXT_SPECIFIC; | ||
473 | |||
474 | if (p->type & CONST_EXPLICIT) | ||
475 | { | ||
476 | if (is_tag_implicit) | ||
477 | _asn1_tag_der (class_implicit, tag_implicit, tag_der, | ||
478 | &tag_len); | ||
479 | else | ||
480 | _asn1_tag_der (class | ASN1_CLASS_STRUCTURED, | ||
481 | strtoul (p->value, NULL, 10), tag_der, | ||
482 | &tag_len); | ||
483 | |||
484 | *max_len -= tag_len; | ||
485 | if (*max_len >= 0) | ||
486 | memcpy (der + *counter, tag_der, tag_len); | ||
487 | *counter += tag_len; | ||
488 | |||
489 | _asn1_ltostr (*counter, temp); | ||
490 | _asn1_set_name (p, temp); | ||
491 | |||
492 | is_tag_implicit = 0; | ||
493 | } | ||
494 | else | ||
495 | { /* CONST_IMPLICIT */ | ||
496 | if (!is_tag_implicit) | ||
497 | { | ||
498 | if ((type_field (node->type) == TYPE_SEQUENCE) || | ||
499 | (type_field (node->type) == TYPE_SEQUENCE_OF) || | ||
500 | (type_field (node->type) == TYPE_SET) || | ||
501 | (type_field (node->type) == TYPE_SET_OF)) | ||
502 | class |= ASN1_CLASS_STRUCTURED; | ||
503 | class_implicit = class; | ||
504 | tag_implicit = strtoul (p->value, NULL, 10); | ||
505 | is_tag_implicit = 1; | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | p = p->right; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | if (is_tag_implicit) | ||
514 | { | ||
515 | _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len); | ||
516 | } | ||
517 | else | ||
518 | { | ||
519 | switch (type_field (node->type)) | ||
520 | { | ||
521 | case TYPE_NULL: | ||
522 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der, | ||
523 | &tag_len); | ||
524 | break; | ||
525 | case TYPE_BOOLEAN: | ||
526 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der, | ||
527 | &tag_len); | ||
528 | break; | ||
529 | case TYPE_INTEGER: | ||
530 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der, | ||
531 | &tag_len); | ||
532 | break; | ||
533 | case TYPE_ENUMERATED: | ||
534 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der, | ||
535 | &tag_len); | ||
536 | break; | ||
537 | case TYPE_OBJECT_ID: | ||
538 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der, | ||
539 | &tag_len); | ||
540 | break; | ||
541 | case TYPE_TIME: | ||
542 | if (node->type & CONST_UTC) | ||
543 | { | ||
544 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der, | ||
545 | &tag_len); | ||
546 | } | ||
547 | else | ||
548 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime, | ||
549 | tag_der, &tag_len); | ||
550 | break; | ||
551 | case TYPE_OCTET_STRING: | ||
552 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der, | ||
553 | &tag_len); | ||
554 | break; | ||
555 | case TYPE_GENERALSTRING: | ||
556 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING, | ||
557 | tag_der, &tag_len); | ||
558 | break; | ||
559 | case TYPE_BIT_STRING: | ||
560 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der, | ||
561 | &tag_len); | ||
562 | break; | ||
563 | case TYPE_SEQUENCE: | ||
564 | case TYPE_SEQUENCE_OF: | ||
565 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, | ||
566 | ASN1_TAG_SEQUENCE, tag_der, &tag_len); | ||
567 | break; | ||
568 | case TYPE_SET: | ||
569 | case TYPE_SET_OF: | ||
570 | _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, | ||
571 | ASN1_TAG_SET, tag_der, &tag_len); | ||
572 | break; | ||
573 | case TYPE_TAG: | ||
574 | tag_len = 0; | ||
575 | break; | ||
576 | case TYPE_CHOICE: | ||
577 | tag_len = 0; | ||
578 | break; | ||
579 | case TYPE_ANY: | ||
580 | tag_len = 0; | ||
581 | break; | ||
582 | default: | ||
583 | return ASN1_GENERIC_ERROR; | ||
584 | } | ||
585 | } | ||
586 | |||
587 | *max_len -= tag_len; | ||
588 | if (*max_len >= 0) | ||
589 | memcpy (der + *counter, tag_der, tag_len); | ||
590 | *counter += tag_len; | ||
591 | |||
592 | if (*max_len < 0) | ||
593 | return ASN1_MEM_ERROR; | ||
594 | |||
595 | return ASN1_SUCCESS; | ||
596 | } | ||
597 | |||
598 | /******************************************************/ | ||
599 | /* Function : _asn1_ordering_set */ | ||
600 | /* Description: puts the elements of a SET type in */ | ||
601 | /* the correct order according to DER rules. */ | ||
602 | /* Parameters: */ | ||
603 | /* der: string with the DER coding. */ | ||
604 | /* node: pointer to the SET element. */ | ||
605 | /* Return: */ | ||
606 | /******************************************************/ | ||
607 | void | ||
608 | _asn1_ordering_set (unsigned char *der, int der_len, node_asn * node) | ||
609 | { | ||
610 | struct vet | ||
611 | { | ||
612 | int end; | ||
613 | unsigned long value; | ||
614 | struct vet *next, *prev; | ||
615 | }; | ||
616 | |||
617 | int counter, len, len2; | ||
618 | struct vet *first, *last, *p_vet, *p2_vet; | ||
619 | node_asn *p; | ||
620 | unsigned char class, *temp; | ||
621 | unsigned long tag; | ||
622 | |||
623 | counter = 0; | ||
624 | |||
625 | if (type_field (node->type) != TYPE_SET) | ||
626 | return; | ||
627 | |||
628 | p = node->down; | ||
629 | while ((type_field (p->type) == TYPE_TAG) | ||
630 | || (type_field (p->type) == TYPE_SIZE)) | ||
631 | p = p->right; | ||
632 | |||
633 | if ((p == NULL) || (p->right == NULL)) | ||
634 | return; | ||
635 | |||
636 | first = last = NULL; | ||
637 | while (p) | ||
638 | { | ||
639 | p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet)); | ||
640 | if (p_vet == NULL) | ||
641 | return; | ||
642 | |||
643 | p_vet->next = NULL; | ||
644 | p_vet->prev = last; | ||
645 | if (first == NULL) | ||
646 | first = p_vet; | ||
647 | else | ||
648 | last->next = p_vet; | ||
649 | last = p_vet; | ||
650 | |||
651 | /* tag value calculation */ | ||
652 | if (asn1_get_tag_der | ||
653 | (der + counter, der_len - counter, &class, &len2, | ||
654 | &tag) != ASN1_SUCCESS) | ||
655 | return; | ||
656 | p_vet->value = (class << 24) | tag; | ||
657 | counter += len2; | ||
658 | |||
659 | /* extraction and length */ | ||
660 | len2 = asn1_get_length_der (der + counter, der_len - counter, &len); | ||
661 | if (len2 < 0) | ||
662 | return; | ||
663 | counter += len + len2; | ||
664 | |||
665 | p_vet->end = counter; | ||
666 | p = p->right; | ||
667 | } | ||
668 | |||
669 | p_vet = first; | ||
670 | |||
671 | while (p_vet) | ||
672 | { | ||
673 | p2_vet = p_vet->next; | ||
674 | counter = 0; | ||
675 | while (p2_vet) | ||
676 | { | ||
677 | if (p_vet->value > p2_vet->value) | ||
678 | { | ||
679 | /* change position */ | ||
680 | temp = (unsigned char *) _asn1_alloca (p_vet->end - counter); | ||
681 | if (temp == NULL) | ||
682 | return; | ||
683 | |||
684 | memcpy (temp, der + counter, p_vet->end - counter); | ||
685 | memcpy (der + counter, der + p_vet->end, | ||
686 | p2_vet->end - p_vet->end); | ||
687 | memcpy (der + counter + p2_vet->end - p_vet->end, temp, | ||
688 | p_vet->end - counter); | ||
689 | _asn1_afree (temp); | ||
690 | |||
691 | tag = p_vet->value; | ||
692 | p_vet->value = p2_vet->value; | ||
693 | p2_vet->value = tag; | ||
694 | |||
695 | p_vet->end = counter + (p2_vet->end - p_vet->end); | ||
696 | } | ||
697 | counter = p_vet->end; | ||
698 | |||
699 | p2_vet = p2_vet->next; | ||
700 | p_vet = p_vet->next; | ||
701 | } | ||
702 | |||
703 | if (p_vet != first) | ||
704 | p_vet->prev->next = NULL; | ||
705 | else | ||
706 | first = NULL; | ||
707 | _asn1_afree (p_vet); | ||
708 | p_vet = first; | ||
709 | } | ||
710 | } | ||
711 | |||
712 | /******************************************************/ | ||
713 | /* Function : _asn1_ordering_set_of */ | ||
714 | /* Description: puts the elements of a SET OF type in */ | ||
715 | /* the correct order according to DER rules. */ | ||
716 | /* Parameters: */ | ||
717 | /* der: string with the DER coding. */ | ||
718 | /* node: pointer to the SET OF element. */ | ||
719 | /* Return: */ | ||
720 | /******************************************************/ | ||
721 | void | ||
722 | _asn1_ordering_set_of (unsigned char *der, int der_len, node_asn * node) | ||
723 | { | ||
724 | struct vet | ||
725 | { | ||
726 | int end; | ||
727 | struct vet *next, *prev; | ||
728 | }; | ||
729 | |||
730 | int counter, len, len2, change; | ||
731 | struct vet *first, *last, *p_vet, *p2_vet; | ||
732 | node_asn *p; | ||
733 | unsigned char *temp, class; | ||
734 | unsigned long k, max; | ||
735 | |||
736 | counter = 0; | ||
737 | |||
738 | if (type_field (node->type) != TYPE_SET_OF) | ||
739 | return; | ||
740 | |||
741 | p = node->down; | ||
742 | while ((type_field (p->type) == TYPE_TAG) | ||
743 | || (type_field (p->type) == TYPE_SIZE)) | ||
744 | p = p->right; | ||
745 | p = p->right; | ||
746 | |||
747 | if ((p == NULL) || (p->right == NULL)) | ||
748 | return; | ||
749 | |||
750 | first = last = NULL; | ||
751 | while (p) | ||
752 | { | ||
753 | p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet)); | ||
754 | if (p_vet == NULL) | ||
755 | return; | ||
756 | |||
757 | p_vet->next = NULL; | ||
758 | p_vet->prev = last; | ||
759 | if (first == NULL) | ||
760 | first = p_vet; | ||
761 | else | ||
762 | last->next = p_vet; | ||
763 | last = p_vet; | ||
764 | |||
765 | /* extraction of tag and length */ | ||
766 | if (der_len - counter > 0) | ||
767 | { | ||
768 | |||
769 | if (asn1_get_tag_der | ||
770 | (der + counter, der_len - counter, &class, &len, | ||
771 | NULL) != ASN1_SUCCESS) | ||
772 | return; | ||
773 | counter += len; | ||
774 | |||
775 | len2 = asn1_get_length_der (der + counter, der_len - counter, &len); | ||
776 | if (len2 < 0) | ||
777 | return; | ||
778 | counter += len + len2; | ||
779 | } | ||
780 | |||
781 | p_vet->end = counter; | ||
782 | p = p->right; | ||
783 | } | ||
784 | |||
785 | p_vet = first; | ||
786 | |||
787 | while (p_vet) | ||
788 | { | ||
789 | p2_vet = p_vet->next; | ||
790 | counter = 0; | ||
791 | while (p2_vet) | ||
792 | { | ||
793 | if ((p_vet->end - counter) > (p2_vet->end - p_vet->end)) | ||
794 | max = p_vet->end - counter; | ||
795 | else | ||
796 | max = p2_vet->end - p_vet->end; | ||
797 | |||
798 | change = -1; | ||
799 | for (k = 0; k < max; k++) | ||
800 | if (der[counter + k] > der[p_vet->end + k]) | ||
801 | { | ||
802 | change = 1; | ||
803 | break; | ||
804 | } | ||
805 | else if (der[counter + k] < der[p_vet->end + k]) | ||
806 | { | ||
807 | change = 0; | ||
808 | break; | ||
809 | } | ||
810 | |||
811 | if ((change == -1) | ||
812 | && ((p_vet->end - counter) > (p2_vet->end - p_vet->end))) | ||
813 | change = 1; | ||
814 | |||
815 | if (change == 1) | ||
816 | { | ||
817 | /* change position */ | ||
818 | temp = (unsigned char *) _asn1_alloca (p_vet->end - counter); | ||
819 | if (temp == NULL) | ||
820 | return; | ||
821 | |||
822 | memcpy (temp, der + counter, (p_vet->end) - counter); | ||
823 | memcpy (der + counter, der + (p_vet->end), | ||
824 | (p2_vet->end) - (p_vet->end)); | ||
825 | memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp, | ||
826 | (p_vet->end) - counter); | ||
827 | _asn1_afree (temp); | ||
828 | |||
829 | p_vet->end = counter + (p2_vet->end - p_vet->end); | ||
830 | } | ||
831 | counter = p_vet->end; | ||
832 | |||
833 | p2_vet = p2_vet->next; | ||
834 | p_vet = p_vet->next; | ||
835 | } | ||
836 | |||
837 | if (p_vet != first) | ||
838 | p_vet->prev->next = NULL; | ||
839 | else | ||
840 | first = NULL; | ||
841 | _asn1_afree (p_vet); | ||
842 | p_vet = first; | ||
843 | } | ||
844 | } | ||
845 | |||
846 | /** | ||
847 | * asn1_der_coding - Creates the DER encoding for the NAME structure | ||
848 | * @element: pointer to an ASN1 element | ||
849 | * @name: the name of the structure you want to encode (it must be | ||
850 | * inside *POINTER). | ||
851 | * @ider: vector that will contain the DER encoding. DER must be a | ||
852 | * pointer to memory cells already allocated. | ||
853 | * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy | ||
854 | * holds the sizeof of der vector. | ||
855 | * @errorDescription : return the error description or an empty | ||
856 | * string if success. | ||
857 | * | ||
858 | * Creates the DER encoding for the NAME structure (inside *POINTER | ||
859 | * structure). | ||
860 | * | ||
861 | * Returns: | ||
862 | * | ||
863 | * ASN1_SUCCESS: DER encoding OK. | ||
864 | * | ||
865 | * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element. | ||
866 | * | ||
867 | * ASN1_VALUE_NOT_FOUND: There is an element without a value. | ||
868 | * | ||
869 | * ASN1_MEM_ERROR: @ider vector isn't big enough. Also in this case | ||
870 | * LEN will contain the length needed. | ||
871 | * | ||
872 | **/ | ||
873 | asn1_retCode | ||
874 | asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len, | ||
875 | char *ErrorDescription) | ||
876 | { | ||
877 | node_asn *node, *p, *p2; | ||
878 | char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1]; | ||
879 | int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old; | ||
880 | asn1_retCode err; | ||
881 | unsigned char *der = ider; | ||
882 | |||
883 | node = asn1_find_node (element, name); | ||
884 | if (node == NULL) | ||
885 | return ASN1_ELEMENT_NOT_FOUND; | ||
886 | |||
887 | /* Node is now a locally allocated variable. | ||
888 | * That is because in some point we modify the | ||
889 | * structure, and I don't know why! --nmav | ||
890 | */ | ||
891 | node = _asn1_copy_structure3 (node); | ||
892 | if (node == NULL) | ||
893 | return ASN1_ELEMENT_NOT_FOUND; | ||
894 | |||
895 | max_len = *len; | ||
896 | |||
897 | counter = 0; | ||
898 | move = DOWN; | ||
899 | p = node; | ||
900 | while (1) | ||
901 | { | ||
902 | |||
903 | counter_old = counter; | ||
904 | max_len_old = max_len; | ||
905 | if (move != UP) | ||
906 | { | ||
907 | err = _asn1_insert_tag_der (p, der, &counter, &max_len); | ||
908 | if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) | ||
909 | goto error; | ||
910 | } | ||
911 | switch (type_field (p->type)) | ||
912 | { | ||
913 | case TYPE_NULL: | ||
914 | max_len--; | ||
915 | if (max_len >= 0) | ||
916 | der[counter] = 0; | ||
917 | counter++; | ||
918 | move = RIGHT; | ||
919 | break; | ||
920 | case TYPE_BOOLEAN: | ||
921 | if ((p->type & CONST_DEFAULT) && (p->value == NULL)) | ||
922 | { | ||
923 | counter = counter_old; | ||
924 | max_len = max_len_old; | ||
925 | } | ||
926 | else | ||
927 | { | ||
928 | if (p->value == NULL) | ||
929 | { | ||
930 | _asn1_error_description_value_not_found (p, | ||
931 | ErrorDescription); | ||
932 | err = ASN1_VALUE_NOT_FOUND; | ||
933 | goto error; | ||
934 | } | ||
935 | max_len -= 2; | ||
936 | if (max_len >= 0) | ||
937 | { | ||
938 | der[counter++] = 1; | ||
939 | if (p->value[0] == 'F') | ||
940 | der[counter++] = 0; | ||
941 | else | ||
942 | der[counter++] = 0xFF; | ||
943 | } | ||
944 | else | ||
945 | counter += 2; | ||
946 | } | ||
947 | move = RIGHT; | ||
948 | break; | ||
949 | case TYPE_INTEGER: | ||
950 | case TYPE_ENUMERATED: | ||
951 | if ((p->type & CONST_DEFAULT) && (p->value == NULL)) | ||
952 | { | ||
953 | counter = counter_old; | ||
954 | max_len = max_len_old; | ||
955 | } | ||
956 | else | ||
957 | { | ||
958 | if (p->value == NULL) | ||
959 | { | ||
960 | _asn1_error_description_value_not_found (p, | ||
961 | ErrorDescription); | ||
962 | err = ASN1_VALUE_NOT_FOUND; | ||
963 | goto error; | ||
964 | } | ||
965 | len2 = asn1_get_length_der (p->value, p->value_len, &len3); | ||
966 | if (len2 < 0) | ||
967 | { | ||
968 | err = ASN1_DER_ERROR; | ||
969 | goto error; | ||
970 | } | ||
971 | max_len -= len2 + len3; | ||
972 | if (max_len >= 0) | ||
973 | memcpy (der + counter, p->value, len3 + len2); | ||
974 | counter += len3 + len2; | ||
975 | } | ||
976 | move = RIGHT; | ||
977 | break; | ||
978 | case TYPE_OBJECT_ID: | ||
979 | if ((p->type & CONST_DEFAULT) && (p->value == NULL)) | ||
980 | { | ||
981 | counter = counter_old; | ||
982 | max_len = max_len_old; | ||
983 | } | ||
984 | else | ||
985 | { | ||
986 | if (p->value == NULL) | ||
987 | { | ||
988 | _asn1_error_description_value_not_found (p, | ||
989 | ErrorDescription); | ||
990 | err = ASN1_VALUE_NOT_FOUND; | ||
991 | goto error; | ||
992 | } | ||
993 | len2 = max_len; | ||
994 | err = _asn1_objectid_der (p->value, der + counter, &len2); | ||
995 | if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) | ||
996 | goto error; | ||
997 | |||
998 | max_len -= len2; | ||
999 | counter += len2; | ||
1000 | } | ||
1001 | move = RIGHT; | ||
1002 | break; | ||
1003 | case TYPE_TIME: | ||
1004 | if (p->value == NULL) | ||
1005 | { | ||
1006 | _asn1_error_description_value_not_found (p, ErrorDescription); | ||
1007 | err = ASN1_VALUE_NOT_FOUND; | ||
1008 | goto error; | ||
1009 | } | ||
1010 | len2 = max_len; | ||
1011 | err = _asn1_time_der (p->value, der + counter, &len2); | ||
1012 | if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) | ||
1013 | goto error; | ||
1014 | |||
1015 | max_len -= len2; | ||
1016 | counter += len2; | ||
1017 | move = RIGHT; | ||
1018 | break; | ||
1019 | case TYPE_OCTET_STRING: | ||
1020 | if (p->value == NULL) | ||
1021 | { | ||
1022 | _asn1_error_description_value_not_found (p, ErrorDescription); | ||
1023 | err = ASN1_VALUE_NOT_FOUND; | ||
1024 | goto error; | ||
1025 | } | ||
1026 | len2 = asn1_get_length_der (p->value, p->value_len, &len3); | ||
1027 | if (len2 < 0) | ||
1028 | { | ||
1029 | err = ASN1_DER_ERROR; | ||
1030 | goto error; | ||
1031 | } | ||
1032 | max_len -= len2 + len3; | ||
1033 | if (max_len >= 0) | ||
1034 | memcpy (der + counter, p->value, len3 + len2); | ||
1035 | counter += len3 + len2; | ||
1036 | move = RIGHT; | ||
1037 | break; | ||
1038 | case TYPE_GENERALSTRING: | ||
1039 | if (p->value == NULL) | ||
1040 | { | ||
1041 | _asn1_error_description_value_not_found (p, ErrorDescription); | ||
1042 | err = ASN1_VALUE_NOT_FOUND; | ||
1043 | goto error; | ||
1044 | } | ||
1045 | len2 = asn1_get_length_der (p->value, p->value_len, &len3); | ||
1046 | if (len2 < 0) | ||
1047 | { | ||
1048 | err = ASN1_DER_ERROR; | ||
1049 | goto error; | ||
1050 | } | ||
1051 | max_len -= len2 + len3; | ||
1052 | if (max_len >= 0) | ||
1053 | memcpy (der + counter, p->value, len3 + len2); | ||
1054 | counter += len3 + len2; | ||
1055 | move = RIGHT; | ||
1056 | break; | ||
1057 | case TYPE_BIT_STRING: | ||
1058 | if (p->value == NULL) | ||
1059 | { | ||
1060 | _asn1_error_description_value_not_found (p, ErrorDescription); | ||
1061 | err = ASN1_VALUE_NOT_FOUND; | ||
1062 | goto error; | ||
1063 | } | ||
1064 | len2 = asn1_get_length_der (p->value, p->value_len, &len3); | ||
1065 | if (len2 < 0) | ||
1066 | { | ||
1067 | err = ASN1_DER_ERROR; | ||
1068 | goto error; | ||
1069 | } | ||
1070 | max_len -= len2 + len3; | ||
1071 | if (max_len >= 0) | ||
1072 | memcpy (der + counter, p->value, len3 + len2); | ||
1073 | counter += len3 + len2; | ||
1074 | move = RIGHT; | ||
1075 | break; | ||
1076 | case TYPE_SEQUENCE: | ||
1077 | case TYPE_SET: | ||
1078 | if (move != UP) | ||
1079 | { | ||
1080 | _asn1_ltostr (counter, temp); | ||
1081 | tlen = strlen (temp); | ||
1082 | if (tlen > 0) | ||
1083 | _asn1_set_value (p, temp, tlen + 1); | ||
1084 | if (p->down == NULL) | ||
1085 | { | ||
1086 | move = UP; | ||
1087 | continue; | ||
1088 | } | ||
1089 | else | ||
1090 | { | ||
1091 | p2 = p->down; | ||
1092 | while (p2 && (type_field (p2->type) == TYPE_TAG)) | ||
1093 | p2 = p2->right; | ||
1094 | if (p2) | ||
1095 | { | ||
1096 | p = p2; | ||
1097 | move = RIGHT; | ||
1098 | continue; | ||
1099 | } | ||
1100 | move = UP; | ||
1101 | continue; | ||
1102 | } | ||
1103 | } | ||
1104 | else | ||
1105 | { /* move==UP */ | ||
1106 | len2 = strtol (p->value, NULL, 10); | ||
1107 | _asn1_set_value (p, NULL, 0); | ||
1108 | if ((type_field (p->type) == TYPE_SET) && (max_len >= 0)) | ||
1109 | _asn1_ordering_set (der + len2, max_len - len2, p); | ||
1110 | asn1_length_der (counter - len2, temp, &len3); | ||
1111 | max_len -= len3; | ||
1112 | if (max_len >= 0) | ||
1113 | { | ||
1114 | memmove (der + len2 + len3, der + len2, counter - len2); | ||
1115 | memcpy (der + len2, temp, len3); | ||
1116 | } | ||
1117 | counter += len3; | ||
1118 | move = RIGHT; | ||
1119 | } | ||
1120 | break; | ||
1121 | case TYPE_SEQUENCE_OF: | ||
1122 | case TYPE_SET_OF: | ||
1123 | if (move != UP) | ||
1124 | { | ||
1125 | _asn1_ltostr (counter, temp); | ||
1126 | tlen = strlen (temp); | ||
1127 | |||
1128 | if (tlen > 0) | ||
1129 | _asn1_set_value (p, temp, tlen + 1); | ||
1130 | p = p->down; | ||
1131 | while ((type_field (p->type) == TYPE_TAG) | ||
1132 | || (type_field (p->type) == TYPE_SIZE)) | ||
1133 | p = p->right; | ||
1134 | if (p->right) | ||
1135 | { | ||
1136 | p = p->right; | ||
1137 | move = RIGHT; | ||
1138 | continue; | ||
1139 | } | ||
1140 | else | ||
1141 | p = _asn1_find_up (p); | ||
1142 | move = UP; | ||
1143 | } | ||
1144 | if (move == UP) | ||
1145 | { | ||
1146 | len2 = strtol (p->value, NULL, 10); | ||
1147 | _asn1_set_value (p, NULL, 0); | ||
1148 | if ((type_field (p->type) == TYPE_SET_OF) | ||
1149 | && (max_len - len2 > 0)) | ||
1150 | { | ||
1151 | _asn1_ordering_set_of (der + len2, max_len - len2, p); | ||
1152 | } | ||
1153 | asn1_length_der (counter - len2, temp, &len3); | ||
1154 | max_len -= len3; | ||
1155 | if (max_len >= 0) | ||
1156 | { | ||
1157 | memmove (der + len2 + len3, der + len2, counter - len2); | ||
1158 | memcpy (der + len2, temp, len3); | ||
1159 | } | ||
1160 | counter += len3; | ||
1161 | move = RIGHT; | ||
1162 | } | ||
1163 | break; | ||
1164 | case TYPE_ANY: | ||
1165 | if (p->value == NULL) | ||
1166 | { | ||
1167 | _asn1_error_description_value_not_found (p, ErrorDescription); | ||
1168 | err = ASN1_VALUE_NOT_FOUND; | ||
1169 | goto error; | ||
1170 | } | ||
1171 | len2 = asn1_get_length_der (p->value, p->value_len, &len3); | ||
1172 | if (len2 < 0) | ||
1173 | { | ||
1174 | err = ASN1_DER_ERROR; | ||
1175 | goto error; | ||
1176 | } | ||
1177 | max_len -= len2; | ||
1178 | if (max_len >= 0) | ||
1179 | memcpy (der + counter, p->value + len3, len2); | ||
1180 | counter += len2; | ||
1181 | move = RIGHT; | ||
1182 | break; | ||
1183 | default: | ||
1184 | move = (move == UP) ? RIGHT : DOWN; | ||
1185 | break; | ||
1186 | } | ||
1187 | |||
1188 | if ((move != DOWN) && (counter != counter_old)) | ||
1189 | { | ||
1190 | err = _asn1_complete_explicit_tag (p, der, &counter, &max_len); | ||
1191 | if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) | ||
1192 | goto error; | ||
1193 | } | ||
1194 | |||
1195 | if (p == node && move != DOWN) | ||
1196 | break; | ||
1197 | |||
1198 | if (move == DOWN) | ||
1199 | { | ||
1200 | if (p->down) | ||
1201 | p = p->down; | ||
1202 | else | ||
1203 | move = RIGHT; | ||
1204 | } | ||
1205 | if (move == RIGHT) | ||
1206 | { | ||
1207 | if (p->right) | ||
1208 | p = p->right; | ||
1209 | else | ||
1210 | move = UP; | ||
1211 | } | ||
1212 | if (move == UP) | ||
1213 | p = _asn1_find_up (p); | ||
1214 | } | ||
1215 | |||
1216 | *len = counter; | ||
1217 | |||
1218 | if (max_len < 0) | ||
1219 | { | ||
1220 | err = ASN1_MEM_ERROR; | ||
1221 | goto error; | ||
1222 | } | ||
1223 | |||
1224 | err = ASN1_SUCCESS; | ||
1225 | |||
1226 | error: | ||
1227 | asn1_delete_structure (&node); | ||
1228 | return err; | ||
1229 | } | ||
diff --git a/src/daemon/https/minitasn1/decoding.c b/src/daemon/https/minitasn1/decoding.c new file mode 100644 index 00000000..0e00cd92 --- /dev/null +++ b/src/daemon/https/minitasn1/decoding.c | |||
@@ -0,0 +1,2821 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2006 Free Software Foundation | ||
3 | * Copyright (C) 2002 Fabio Fiorina | ||
4 | * | ||
5 | * This file is part of LIBTASN1. | ||
6 | * | ||
7 | * The LIBTASN1 library is free software; you can redistribute it | ||
8 | * and/or modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | */ | ||
22 | |||
23 | |||
24 | /*****************************************************/ | ||
25 | /* File: decoding.c */ | ||
26 | /* Description: Functions to manage DER decoding */ | ||
27 | /*****************************************************/ | ||
28 | |||
29 | #include <int.h> | ||
30 | #include <errors.h> | ||
31 | #include "parser_aux.h" | ||
32 | #include <gstr.h> | ||
33 | #include "structure.h" | ||
34 | #include "element.h" | ||
35 | |||
36 | |||
37 | void | ||
38 | _asn1_error_description_tag_error (node_asn * node, char *ErrorDescription) | ||
39 | { | ||
40 | |||
41 | Estrcpy (ErrorDescription, ":: tag error near element '"); | ||
42 | _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), | ||
43 | MAX_ERROR_DESCRIPTION_SIZE - 40); | ||
44 | Estrcat (ErrorDescription, "'"); | ||
45 | |||
46 | } | ||
47 | |||
48 | /** | ||
49 | * asn1_get_length_der: | ||
50 | * @der: DER data to decode. | ||
51 | * @der_len: Length of DER data to decode. | ||
52 | * @len: Output variable containing the length of the DER length field. | ||
53 | * | ||
54 | * Extract a length field from DER data. | ||
55 | * | ||
56 | * Return value: Return the decoded length value, or -1 on indefinite | ||
57 | * length, or -2 when the value was too big. | ||
58 | **/ | ||
59 | signed long | ||
60 | asn1_get_length_der (const unsigned char *der, int der_len, int *len) | ||
61 | { | ||
62 | unsigned long ans; | ||
63 | int k, punt; | ||
64 | |||
65 | *len = 0; | ||
66 | if (der_len <= 0) | ||
67 | return 0; | ||
68 | |||
69 | if (!(der[0] & 128)) | ||
70 | { | ||
71 | /* short form */ | ||
72 | *len = 1; | ||
73 | return der[0]; | ||
74 | } | ||
75 | else | ||
76 | { | ||
77 | /* Long form */ | ||
78 | k = der[0] & 0x7F; | ||
79 | punt = 1; | ||
80 | if (k) | ||
81 | { /* definite length method */ | ||
82 | ans = 0; | ||
83 | while (punt <= k && punt < der_len) | ||
84 | { | ||
85 | unsigned long last = ans; | ||
86 | |||
87 | ans = ans * 256 + der[punt++]; | ||
88 | if (ans < last) | ||
89 | /* we wrapped around, no bignum support... */ | ||
90 | return -2; | ||
91 | } | ||
92 | } | ||
93 | else | ||
94 | { /* indefinite length method */ | ||
95 | ans = -1; | ||
96 | } | ||
97 | |||
98 | *len = punt; | ||
99 | return ans; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | |||
104 | |||
105 | |||
106 | /** | ||
107 | * asn1_get_tag_der: | ||
108 | * @der: DER data to decode. | ||
109 | * @der_len: Length of DER data to decode. | ||
110 | * @cls: Output variable containing decoded class. | ||
111 | * @len: Output variable containing the length of the DER TAG data. | ||
112 | * @tag: Output variable containing the decoded tag. | ||
113 | * | ||
114 | * Decode the class and TAG from DER code. | ||
115 | * | ||
116 | * Return value: Returns ASN1_SUCCESS on success, or an error. | ||
117 | **/ | ||
118 | int | ||
119 | asn1_get_tag_der (const unsigned char *der, int der_len, | ||
120 | unsigned char *cls, int *len, unsigned long *tag) | ||
121 | { | ||
122 | int punt, ris; | ||
123 | |||
124 | if (der == NULL || der_len <= 0 || len == NULL) | ||
125 | return ASN1_DER_ERROR; | ||
126 | |||
127 | *cls = der[0] & 0xE0; | ||
128 | if ((der[0] & 0x1F) != 0x1F) | ||
129 | { | ||
130 | /* short form */ | ||
131 | *len = 1; | ||
132 | ris = der[0] & 0x1F; | ||
133 | } | ||
134 | else | ||
135 | { | ||
136 | /* Long form */ | ||
137 | punt = 1; | ||
138 | ris = 0; | ||
139 | while (punt <= der_len && der[punt] & 128) | ||
140 | { | ||
141 | int last = ris; | ||
142 | ris = ris * 128 + (der[punt++] & 0x7F); | ||
143 | if (ris < last) | ||
144 | /* wrapper around, and no bignums... */ | ||
145 | return ASN1_DER_ERROR; | ||
146 | } | ||
147 | if (punt >= der_len) | ||
148 | return ASN1_DER_ERROR; | ||
149 | { | ||
150 | int last = ris; | ||
151 | ris = ris * 128 + (der[punt++] & 0x7F); | ||
152 | if (ris < last) | ||
153 | /* wrapper around, and no bignums... */ | ||
154 | return ASN1_DER_ERROR; | ||
155 | } | ||
156 | *len = punt; | ||
157 | } | ||
158 | if (tag) | ||
159 | *tag = ris; | ||
160 | return ASN1_SUCCESS; | ||
161 | } | ||
162 | |||
163 | |||
164 | |||
165 | |||
166 | /** | ||
167 | * asn1_get_octet_der: | ||
168 | * @der: DER data to decode containing the OCTET SEQUENCE. | ||
169 | * @der_len: Length of DER data to decode. | ||
170 | * @ret_len: Output variable containing the length of the DER data. | ||
171 | * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in. | ||
172 | * @str_size: Length of pre-allocated output buffer. | ||
173 | * @str_len: Output variable containing the length of the OCTET SEQUENCE. | ||
174 | * | ||
175 | * Extract an OCTET SEQUENCE from DER data. | ||
176 | * | ||
177 | * Return value: Returns ASN1_SUCCESS on success, or an error. | ||
178 | **/ | ||
179 | int | ||
180 | asn1_get_octet_der (const unsigned char *der, int der_len, | ||
181 | int *ret_len, unsigned char *str, int str_size, | ||
182 | int *str_len) | ||
183 | { | ||
184 | int len_len; | ||
185 | |||
186 | if (der_len <= 0) | ||
187 | return ASN1_GENERIC_ERROR; | ||
188 | |||
189 | /* if(str==NULL) return ASN1_SUCCESS; */ | ||
190 | *str_len = asn1_get_length_der (der, der_len, &len_len); | ||
191 | |||
192 | if (*str_len < 0) | ||
193 | return ASN1_DER_ERROR; | ||
194 | |||
195 | *ret_len = *str_len + len_len; | ||
196 | if (str_size >= *str_len) | ||
197 | memcpy (str, der + len_len, *str_len); | ||
198 | else | ||
199 | { | ||
200 | return ASN1_MEM_ERROR; | ||
201 | } | ||
202 | |||
203 | return ASN1_SUCCESS; | ||
204 | } | ||
205 | |||
206 | |||
207 | |||
208 | /* Returns ASN1_SUCCESS on success or an error code on error. | ||
209 | */ | ||
210 | int | ||
211 | _asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len, | ||
212 | char *str, int str_size) | ||
213 | { | ||
214 | int len_len, str_len; | ||
215 | |||
216 | if (der_len <= 0 || str == NULL) | ||
217 | return ASN1_DER_ERROR; | ||
218 | str_len = asn1_get_length_der (der, der_len, &len_len); | ||
219 | if (str_len < 0 || str_size < str_len) | ||
220 | return ASN1_DER_ERROR; | ||
221 | memcpy (str, der + len_len, str_len); | ||
222 | str[str_len] = 0; | ||
223 | *ret_len = str_len + len_len; | ||
224 | |||
225 | return ASN1_SUCCESS; | ||
226 | } | ||
227 | |||
228 | |||
229 | |||
230 | void | ||
231 | _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len, | ||
232 | char *str, int str_size) | ||
233 | { | ||
234 | int len_len, len, k; | ||
235 | char temp[20]; | ||
236 | unsigned long val, val1; | ||
237 | |||
238 | *ret_len = 0; | ||
239 | if (str && str_size > 0) | ||
240 | str[0] = 0; /* no oid */ | ||
241 | |||
242 | if (str == NULL || der_len <= 0) | ||
243 | return; | ||
244 | len = asn1_get_length_der (der, der_len, &len_len); | ||
245 | |||
246 | if (len < 0 || len > der_len || len_len > der_len) | ||
247 | return; | ||
248 | |||
249 | val1 = der[len_len] / 40; | ||
250 | val = der[len_len] - val1 * 40; | ||
251 | |||
252 | _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp)); | ||
253 | _asn1_str_cat (str, str_size, "."); | ||
254 | _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp)); | ||
255 | |||
256 | val = 0; | ||
257 | for (k = 1; k < len; k++) | ||
258 | { | ||
259 | val = val << 7; | ||
260 | val |= der[len_len + k] & 0x7F; | ||
261 | if (!(der[len_len + k] & 0x80)) | ||
262 | { | ||
263 | _asn1_str_cat (str, str_size, "."); | ||
264 | _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp)); | ||
265 | val = 0; | ||
266 | } | ||
267 | } | ||
268 | *ret_len = len + len_len; | ||
269 | } | ||
270 | |||
271 | |||
272 | |||
273 | |||
274 | /** | ||
275 | * asn1_get_bit_der: | ||
276 | * @der: DER data to decode containing the BIT SEQUENCE. | ||
277 | * @der_len: Length of DER data to decode. | ||
278 | * @ret_len: Output variable containing the length of the DER data. | ||
279 | * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in. | ||
280 | * @str_size: Length of pre-allocated output buffer. | ||
281 | * @bit_len: Output variable containing the size of the BIT SEQUENCE. | ||
282 | * | ||
283 | * Extract a BIT SEQUENCE from DER data. | ||
284 | * | ||
285 | * Return value: Return ASN1_SUCCESS on success, or an error. | ||
286 | **/ | ||
287 | int | ||
288 | asn1_get_bit_der (const unsigned char *der, int der_len, | ||
289 | int *ret_len, unsigned char *str, int str_size, | ||
290 | int *bit_len) | ||
291 | { | ||
292 | int len_len, len_byte; | ||
293 | |||
294 | if (der_len <= 0) | ||
295 | return ASN1_GENERIC_ERROR; | ||
296 | len_byte = asn1_get_length_der (der, der_len, &len_len) - 1; | ||
297 | if (len_byte < 0) | ||
298 | return ASN1_DER_ERROR; | ||
299 | |||
300 | *ret_len = len_byte + len_len + 1; | ||
301 | *bit_len = len_byte * 8 - der[len_len]; | ||
302 | |||
303 | if (str_size >= len_byte) | ||
304 | memcpy (str, der + len_len + 1, len_byte); | ||
305 | else | ||
306 | { | ||
307 | return ASN1_MEM_ERROR; | ||
308 | } | ||
309 | |||
310 | return ASN1_SUCCESS; | ||
311 | } | ||
312 | |||
313 | |||
314 | |||
315 | |||
316 | int | ||
317 | _asn1_extract_tag_der (node_asn * node, const unsigned char *der, int der_len, | ||
318 | int *ret_len) | ||
319 | { | ||
320 | node_asn *p; | ||
321 | int counter, len2, len3, is_tag_implicit; | ||
322 | unsigned long tag, tag_implicit = 0; | ||
323 | unsigned char class, class2, class_implicit = 0; | ||
324 | |||
325 | if (der_len <= 0) | ||
326 | return ASN1_GENERIC_ERROR; | ||
327 | |||
328 | counter = is_tag_implicit = 0; | ||
329 | |||
330 | if (node->type & CONST_TAG) | ||
331 | { | ||
332 | p = node->down; | ||
333 | while (p) | ||
334 | { | ||
335 | if (type_field (p->type) == TYPE_TAG) | ||
336 | { | ||
337 | if (p->type & CONST_APPLICATION) | ||
338 | class2 = ASN1_CLASS_APPLICATION; | ||
339 | else if (p->type & CONST_UNIVERSAL) | ||
340 | class2 = ASN1_CLASS_UNIVERSAL; | ||
341 | else if (p->type & CONST_PRIVATE) | ||
342 | class2 = ASN1_CLASS_PRIVATE; | ||
343 | else | ||
344 | class2 = ASN1_CLASS_CONTEXT_SPECIFIC; | ||
345 | |||
346 | if (p->type & CONST_EXPLICIT) | ||
347 | { | ||
348 | if (asn1_get_tag_der | ||
349 | (der + counter, der_len - counter, &class, &len2, | ||
350 | &tag) != ASN1_SUCCESS) | ||
351 | return ASN1_DER_ERROR; | ||
352 | if (counter + len2 > der_len) | ||
353 | return ASN1_DER_ERROR; | ||
354 | counter += len2; | ||
355 | len3 = | ||
356 | asn1_get_length_der (der + counter, der_len - counter, | ||
357 | &len2); | ||
358 | if (len3 < 0) | ||
359 | return ASN1_DER_ERROR; | ||
360 | counter += len2; | ||
361 | if (!is_tag_implicit) | ||
362 | { | ||
363 | if ((class != (class2 | ASN1_CLASS_STRUCTURED)) || | ||
364 | (tag != strtoul ((char *) p->value, NULL, 10))) | ||
365 | return ASN1_TAG_ERROR; | ||
366 | } | ||
367 | else | ||
368 | { /* ASN1_TAG_IMPLICIT */ | ||
369 | if ((class != class_implicit) || (tag != tag_implicit)) | ||
370 | return ASN1_TAG_ERROR; | ||
371 | } | ||
372 | |||
373 | is_tag_implicit = 0; | ||
374 | } | ||
375 | else | ||
376 | { /* ASN1_TAG_IMPLICIT */ | ||
377 | if (!is_tag_implicit) | ||
378 | { | ||
379 | if ((type_field (node->type) == TYPE_SEQUENCE) || | ||
380 | (type_field (node->type) == TYPE_SEQUENCE_OF) || | ||
381 | (type_field (node->type) == TYPE_SET) || | ||
382 | (type_field (node->type) == TYPE_SET_OF)) | ||
383 | class2 |= ASN1_CLASS_STRUCTURED; | ||
384 | class_implicit = class2; | ||
385 | tag_implicit = strtoul ((char *) p->value, NULL, 10); | ||
386 | is_tag_implicit = 1; | ||
387 | } | ||
388 | } | ||
389 | } | ||
390 | p = p->right; | ||
391 | } | ||
392 | } | ||
393 | |||
394 | if (is_tag_implicit) | ||
395 | { | ||
396 | if (asn1_get_tag_der | ||
397 | (der + counter, der_len - counter, &class, &len2, | ||
398 | &tag) != ASN1_SUCCESS) | ||
399 | return ASN1_DER_ERROR; | ||
400 | if (counter + len2 > der_len) | ||
401 | return ASN1_DER_ERROR; | ||
402 | |||
403 | if ((class != class_implicit) || (tag != tag_implicit)) | ||
404 | { | ||
405 | if (type_field (node->type) == TYPE_OCTET_STRING) | ||
406 | { | ||
407 | class_implicit |= ASN1_CLASS_STRUCTURED; | ||
408 | if ((class != class_implicit) || (tag != tag_implicit)) | ||
409 | return ASN1_TAG_ERROR; | ||
410 | } | ||
411 | else | ||
412 | return ASN1_TAG_ERROR; | ||
413 | } | ||
414 | } | ||
415 | else | ||
416 | { | ||
417 | if (type_field (node->type) == TYPE_TAG) | ||
418 | { | ||
419 | counter = 0; | ||
420 | *ret_len = counter; | ||
421 | return ASN1_SUCCESS; | ||
422 | } | ||
423 | |||
424 | if (asn1_get_tag_der | ||
425 | (der + counter, der_len - counter, &class, &len2, | ||
426 | &tag) != ASN1_SUCCESS) | ||
427 | return ASN1_DER_ERROR; | ||
428 | if (counter + len2 > der_len) | ||
429 | return ASN1_DER_ERROR; | ||
430 | |||
431 | switch (type_field (node->type)) | ||
432 | { | ||
433 | case TYPE_NULL: | ||
434 | if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL)) | ||
435 | return ASN1_DER_ERROR; | ||
436 | break; | ||
437 | case TYPE_BOOLEAN: | ||
438 | if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN)) | ||
439 | return ASN1_DER_ERROR; | ||
440 | break; | ||
441 | case TYPE_INTEGER: | ||
442 | if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER)) | ||
443 | return ASN1_DER_ERROR; | ||
444 | break; | ||
445 | case TYPE_ENUMERATED: | ||
446 | if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED)) | ||
447 | return ASN1_DER_ERROR; | ||
448 | break; | ||
449 | case TYPE_OBJECT_ID: | ||
450 | if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID)) | ||
451 | return ASN1_DER_ERROR; | ||
452 | break; | ||
453 | case TYPE_TIME: | ||
454 | if (node->type & CONST_UTC) | ||
455 | { | ||
456 | if ((class != ASN1_CLASS_UNIVERSAL) | ||
457 | || (tag != ASN1_TAG_UTCTime)) | ||
458 | return ASN1_DER_ERROR; | ||
459 | } | ||
460 | else | ||
461 | { | ||
462 | if ((class != ASN1_CLASS_UNIVERSAL) | ||
463 | || (tag != ASN1_TAG_GENERALIZEDTime)) | ||
464 | return ASN1_DER_ERROR; | ||
465 | } | ||
466 | break; | ||
467 | case TYPE_OCTET_STRING: | ||
468 | if (((class != ASN1_CLASS_UNIVERSAL) | ||
469 | && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))) | ||
470 | || (tag != ASN1_TAG_OCTET_STRING)) | ||
471 | return ASN1_DER_ERROR; | ||
472 | break; | ||
473 | case TYPE_GENERALSTRING: | ||
474 | if ((class != ASN1_CLASS_UNIVERSAL) | ||
475 | || (tag != ASN1_TAG_GENERALSTRING)) | ||
476 | return ASN1_DER_ERROR; | ||
477 | break; | ||
478 | case TYPE_BIT_STRING: | ||
479 | if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING)) | ||
480 | return ASN1_DER_ERROR; | ||
481 | break; | ||
482 | case TYPE_SEQUENCE: | ||
483 | case TYPE_SEQUENCE_OF: | ||
484 | if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)) | ||
485 | || (tag != ASN1_TAG_SEQUENCE)) | ||
486 | return ASN1_DER_ERROR; | ||
487 | break; | ||
488 | case TYPE_SET: | ||
489 | case TYPE_SET_OF: | ||
490 | if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)) | ||
491 | || (tag != ASN1_TAG_SET)) | ||
492 | return ASN1_DER_ERROR; | ||
493 | break; | ||
494 | case TYPE_ANY: | ||
495 | counter -= len2; | ||
496 | break; | ||
497 | default: | ||
498 | return ASN1_DER_ERROR; | ||
499 | break; | ||
500 | } | ||
501 | } | ||
502 | |||
503 | counter += len2; | ||
504 | *ret_len = counter; | ||
505 | return ASN1_SUCCESS; | ||
506 | } | ||
507 | |||
508 | |||
509 | int | ||
510 | _asn1_delete_not_used (node_asn * node) | ||
511 | { | ||
512 | node_asn *p, *p2; | ||
513 | |||
514 | if (node == NULL) | ||
515 | return ASN1_ELEMENT_NOT_FOUND; | ||
516 | |||
517 | p = node; | ||
518 | while (p) | ||
519 | { | ||
520 | if (p->type & CONST_NOT_USED) | ||
521 | { | ||
522 | p2 = NULL; | ||
523 | if (p != node) | ||
524 | { | ||
525 | p2 = _asn1_find_left (p); | ||
526 | if (!p2) | ||
527 | p2 = _asn1_find_up (p); | ||
528 | } | ||
529 | asn1_delete_structure (&p); | ||
530 | p = p2; | ||
531 | } | ||
532 | |||
533 | if (!p) | ||
534 | break; /* reach node */ | ||
535 | |||
536 | if (p->down) | ||
537 | { | ||
538 | p = p->down; | ||
539 | } | ||
540 | else | ||
541 | { | ||
542 | if (p == node) | ||
543 | p = NULL; | ||
544 | else if (p->right) | ||
545 | p = p->right; | ||
546 | else | ||
547 | { | ||
548 | while (1) | ||
549 | { | ||
550 | p = _asn1_find_up (p); | ||
551 | if (p == node) | ||
552 | { | ||
553 | p = NULL; | ||
554 | break; | ||
555 | } | ||
556 | if (p->right) | ||
557 | { | ||
558 | p = p->right; | ||
559 | break; | ||
560 | } | ||
561 | } | ||
562 | } | ||
563 | } | ||
564 | } | ||
565 | return ASN1_SUCCESS; | ||
566 | } | ||
567 | |||
568 | |||
569 | asn1_retCode | ||
570 | _asn1_get_octet_string (const unsigned char *der, node_asn * node, int *len) | ||
571 | { | ||
572 | int len2, len3, counter, counter2, counter_end, tot_len, indefinite; | ||
573 | unsigned char *temp, *temp2; | ||
574 | |||
575 | counter = 0; | ||
576 | |||
577 | if (*(der - 1) & ASN1_CLASS_STRUCTURED) | ||
578 | { | ||
579 | tot_len = 0; | ||
580 | indefinite = asn1_get_length_der (der, *len, &len3); | ||
581 | if (indefinite < -1) | ||
582 | return ASN1_DER_ERROR; | ||
583 | |||
584 | counter += len3; | ||
585 | if (indefinite >= 0) | ||
586 | indefinite += len3; | ||
587 | |||
588 | while (1) | ||
589 | { | ||
590 | if (counter > (*len)) | ||
591 | return ASN1_DER_ERROR; | ||
592 | |||
593 | if (indefinite == -1) | ||
594 | { | ||
595 | if ((der[counter] == 0) && (der[counter + 1] == 0)) | ||
596 | { | ||
597 | counter += 2; | ||
598 | break; | ||
599 | } | ||
600 | } | ||
601 | else if (counter >= indefinite) | ||
602 | break; | ||
603 | |||
604 | if (der[counter] != ASN1_TAG_OCTET_STRING) | ||
605 | return ASN1_DER_ERROR; | ||
606 | |||
607 | counter++; | ||
608 | |||
609 | len2 = asn1_get_length_der (der + counter, *len - counter, &len3); | ||
610 | if (len2 <= 0) | ||
611 | return ASN1_DER_ERROR; | ||
612 | |||
613 | counter += len3 + len2; | ||
614 | tot_len += len2; | ||
615 | } | ||
616 | |||
617 | /* copy */ | ||
618 | if (node) | ||
619 | { | ||
620 | asn1_length_der (tot_len, NULL, &len2); | ||
621 | temp = _asn1_alloca (len2 + tot_len); | ||
622 | if (temp == NULL) | ||
623 | { | ||
624 | return ASN1_MEM_ALLOC_ERROR; | ||
625 | } | ||
626 | |||
627 | asn1_length_der (tot_len, temp, &len2); | ||
628 | tot_len += len2; | ||
629 | temp2 = temp + len2; | ||
630 | len2 = asn1_get_length_der (der, *len, &len3); | ||
631 | if (len2 < -1) | ||
632 | return ASN1_DER_ERROR; | ||
633 | counter2 = len3 + 1; | ||
634 | |||
635 | if (indefinite == -1) | ||
636 | counter_end = counter - 2; | ||
637 | else | ||
638 | counter_end = counter; | ||
639 | |||
640 | while (counter2 < counter_end) | ||
641 | { | ||
642 | len2 = | ||
643 | asn1_get_length_der (der + counter2, *len - counter, &len3); | ||
644 | if (len2 < -1) | ||
645 | return ASN1_DER_ERROR; | ||
646 | |||
647 | /* FIXME: to be checked. Is this ok? Has the | ||
648 | * size been checked before? | ||
649 | */ | ||
650 | memcpy (temp2, der + counter2 + len3, len2); | ||
651 | temp2 += len2; | ||
652 | counter2 += len2 + len3 + 1; | ||
653 | } | ||
654 | |||
655 | _asn1_set_value (node, temp, tot_len); | ||
656 | _asn1_afree (temp); | ||
657 | } | ||
658 | } | ||
659 | else | ||
660 | { /* NOT STRUCTURED */ | ||
661 | len2 = asn1_get_length_der (der, *len, &len3); | ||
662 | if (len2 < 0) | ||
663 | return ASN1_DER_ERROR; | ||
664 | if (len3 + len2 > *len) | ||
665 | return ASN1_DER_ERROR; | ||
666 | if (node) | ||
667 | _asn1_set_value (node, der, len3 + len2); | ||
668 | counter = len3 + len2; | ||
669 | } | ||
670 | |||
671 | *len = counter; | ||
672 | return ASN1_SUCCESS; | ||
673 | |||
674 | } | ||
675 | |||
676 | |||
677 | asn1_retCode | ||
678 | _asn1_get_indefinite_length_string (const unsigned char *der, int *len) | ||
679 | { | ||
680 | int len2, len3, counter, indefinite; | ||
681 | unsigned long tag; | ||
682 | unsigned char class; | ||
683 | |||
684 | counter = indefinite = 0; | ||
685 | |||
686 | while (1) | ||
687 | { | ||
688 | if ((*len) < counter) | ||
689 | return ASN1_DER_ERROR; | ||
690 | |||
691 | if ((der[counter] == 0) && (der[counter + 1] == 0)) | ||
692 | { | ||
693 | counter += 2; | ||
694 | indefinite--; | ||
695 | if (indefinite <= 0) | ||
696 | break; | ||
697 | else | ||
698 | continue; | ||
699 | } | ||
700 | |||
701 | if (asn1_get_tag_der | ||
702 | (der + counter, *len - counter, &class, &len2, | ||
703 | &tag) != ASN1_SUCCESS) | ||
704 | return ASN1_DER_ERROR; | ||
705 | if (counter + len2 > *len) | ||
706 | return ASN1_DER_ERROR; | ||
707 | counter += len2; | ||
708 | len2 = asn1_get_length_der (der + counter, *len - counter, &len3); | ||
709 | if (len2 < -1) | ||
710 | return ASN1_DER_ERROR; | ||
711 | if (len2 == -1) | ||
712 | { | ||
713 | indefinite++; | ||
714 | counter += 1; | ||
715 | } | ||
716 | else | ||
717 | { | ||
718 | counter += len2 + len3; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | *len = counter; | ||
723 | return ASN1_SUCCESS; | ||
724 | |||
725 | } | ||
726 | |||
727 | |||
728 | /** | ||
729 | * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string. | ||
730 | * @element: pointer to an ASN1 structure. | ||
731 | * @ider: vector that contains the DER encoding. | ||
732 | * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]. | ||
733 | * @errorDescription: null-terminated string contains details when an | ||
734 | * error occurred. | ||
735 | * | ||
736 | * Fill the structure *ELEMENT with values of a DER encoding | ||
737 | * string. The sructure must just be created with function | ||
738 | * 'create_stucture'. If an error occurs during the decoding | ||
739 | * procedure, the *ELEMENT is deleted and set equal to | ||
740 | * %ASN1_TYPE_EMPTY. | ||
741 | * | ||
742 | * Returns: | ||
743 | * | ||
744 | * ASN1_SUCCESS: DER encoding OK. | ||
745 | * | ||
746 | * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY. | ||
747 | * | ||
748 | * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match | ||
749 | * the structure NAME. *ELEMENT deleted. | ||
750 | **/ | ||
751 | |||
752 | asn1_retCode | ||
753 | asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len, | ||
754 | char *errorDescription) | ||
755 | { | ||
756 | node_asn *node, *p, *p2, *p3; | ||
757 | char temp[128]; | ||
758 | int counter, len2, len3, len4, move, ris, tlen; | ||
759 | unsigned char class, *temp2; | ||
760 | unsigned long tag; | ||
761 | int indefinite, result; | ||
762 | const unsigned char *der = ider; | ||
763 | |||
764 | node = *element; | ||
765 | |||
766 | if (node == ASN1_TYPE_EMPTY) | ||
767 | return ASN1_ELEMENT_NOT_FOUND; | ||
768 | |||
769 | if (node->type & CONST_OPTION) | ||
770 | { | ||
771 | asn1_delete_structure (element); | ||
772 | return ASN1_GENERIC_ERROR; | ||
773 | } | ||
774 | |||
775 | counter = 0; | ||
776 | move = DOWN; | ||
777 | p = node; | ||
778 | while (1) | ||
779 | { | ||
780 | ris = ASN1_SUCCESS; | ||
781 | if (move != UP) | ||
782 | { | ||
783 | if (p->type & CONST_SET) | ||
784 | { | ||
785 | p2 = _asn1_find_up (p); | ||
786 | len2 = strtol (p2->value, NULL, 10); | ||
787 | if (len2 == -1) | ||
788 | { | ||
789 | if (!der[counter] && !der[counter + 1]) | ||
790 | { | ||
791 | p = p2; | ||
792 | move = UP; | ||
793 | counter += 2; | ||
794 | continue; | ||
795 | } | ||
796 | } | ||
797 | else if (counter == len2) | ||
798 | { | ||
799 | p = p2; | ||
800 | move = UP; | ||
801 | continue; | ||
802 | } | ||
803 | else if (counter > len2) | ||
804 | { | ||
805 | asn1_delete_structure (element); | ||
806 | return ASN1_DER_ERROR; | ||
807 | } | ||
808 | p2 = p2->down; | ||
809 | while (p2) | ||
810 | { | ||
811 | if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) | ||
812 | { | ||
813 | if (type_field (p2->type) != TYPE_CHOICE) | ||
814 | ris = | ||
815 | _asn1_extract_tag_der (p2, der + counter, | ||
816 | len - counter, &len2); | ||
817 | else | ||
818 | { | ||
819 | p3 = p2->down; | ||
820 | while (p3) | ||
821 | { | ||
822 | ris = | ||
823 | _asn1_extract_tag_der (p3, der + counter, | ||
824 | len - counter, &len2); | ||
825 | if (ris == ASN1_SUCCESS) | ||
826 | break; | ||
827 | p3 = p3->right; | ||
828 | } | ||
829 | } | ||
830 | if (ris == ASN1_SUCCESS) | ||
831 | { | ||
832 | p2->type &= ~CONST_NOT_USED; | ||
833 | p = p2; | ||
834 | break; | ||
835 | } | ||
836 | } | ||
837 | p2 = p2->right; | ||
838 | } | ||
839 | if (p2 == NULL) | ||
840 | { | ||
841 | asn1_delete_structure (element); | ||
842 | return ASN1_DER_ERROR; | ||
843 | } | ||
844 | } | ||
845 | |||
846 | if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) | ||
847 | { | ||
848 | p2 = _asn1_find_up (p); | ||
849 | len2 = strtol (p2->value, NULL, 10); | ||
850 | if (counter == len2) | ||
851 | { | ||
852 | if (p->right) | ||
853 | { | ||
854 | p2 = p->right; | ||
855 | move = RIGHT; | ||
856 | } | ||
857 | else | ||
858 | move = UP; | ||
859 | |||
860 | if (p->type & CONST_OPTION) | ||
861 | asn1_delete_structure (&p); | ||
862 | |||
863 | p = p2; | ||
864 | continue; | ||
865 | } | ||
866 | } | ||
867 | |||
868 | if (type_field (p->type) == TYPE_CHOICE) | ||
869 | { | ||
870 | while (p->down) | ||
871 | { | ||
872 | if (counter < len) | ||
873 | ris = | ||
874 | _asn1_extract_tag_der (p->down, der + counter, | ||
875 | len - counter, &len2); | ||
876 | else | ||
877 | ris = ASN1_DER_ERROR; | ||
878 | if (ris == ASN1_SUCCESS) | ||
879 | { | ||
880 | while (p->down->right) | ||
881 | { | ||
882 | p2 = p->down->right; | ||
883 | asn1_delete_structure (&p2); | ||
884 | } | ||
885 | break; | ||
886 | } | ||
887 | else if (ris == ASN1_ERROR_TYPE_ANY) | ||
888 | { | ||
889 | asn1_delete_structure (element); | ||
890 | return ASN1_ERROR_TYPE_ANY; | ||
891 | } | ||
892 | else | ||
893 | { | ||
894 | p2 = p->down; | ||
895 | asn1_delete_structure (&p2); | ||
896 | } | ||
897 | } | ||
898 | |||
899 | if (p->down == NULL) | ||
900 | { | ||
901 | if (!(p->type & CONST_OPTION)) | ||
902 | { | ||
903 | asn1_delete_structure (element); | ||
904 | return ASN1_DER_ERROR; | ||
905 | } | ||
906 | } | ||
907 | else | ||
908 | p = p->down; | ||
909 | } | ||
910 | |||
911 | if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) | ||
912 | { | ||
913 | p2 = _asn1_find_up (p); | ||
914 | len2 = strtol (p2->value, NULL, 10); | ||
915 | if ((len2 != -1) && (counter > len2)) | ||
916 | ris = ASN1_TAG_ERROR; | ||
917 | } | ||
918 | |||
919 | if (ris == ASN1_SUCCESS) | ||
920 | ris = | ||
921 | _asn1_extract_tag_der (p, der + counter, len - counter, &len2); | ||
922 | if (ris != ASN1_SUCCESS) | ||
923 | { | ||
924 | if (p->type & CONST_OPTION) | ||
925 | { | ||
926 | p->type |= CONST_NOT_USED; | ||
927 | move = RIGHT; | ||
928 | } | ||
929 | else if (p->type & CONST_DEFAULT) | ||
930 | { | ||
931 | _asn1_set_value (p, NULL, 0); | ||
932 | move = RIGHT; | ||
933 | } | ||
934 | else | ||
935 | { | ||
936 | if (errorDescription != NULL) | ||
937 | _asn1_error_description_tag_error (p, errorDescription); | ||
938 | |||
939 | asn1_delete_structure (element); | ||
940 | return ASN1_TAG_ERROR; | ||
941 | } | ||
942 | } | ||
943 | else | ||
944 | counter += len2; | ||
945 | } | ||
946 | |||
947 | if (ris == ASN1_SUCCESS) | ||
948 | { | ||
949 | switch (type_field (p->type)) | ||
950 | { | ||
951 | case TYPE_NULL: | ||
952 | if (der[counter]) | ||
953 | { | ||
954 | asn1_delete_structure (element); | ||
955 | return ASN1_DER_ERROR; | ||
956 | } | ||
957 | counter++; | ||
958 | move = RIGHT; | ||
959 | break; | ||
960 | case TYPE_BOOLEAN: | ||
961 | if (der[counter++] != 1) | ||
962 | { | ||
963 | asn1_delete_structure (element); | ||
964 | return ASN1_DER_ERROR; | ||
965 | } | ||
966 | if (der[counter++] == 0) | ||
967 | _asn1_set_value (p, "F", 1); | ||
968 | else | ||
969 | _asn1_set_value (p, "T", 1); | ||
970 | move = RIGHT; | ||
971 | break; | ||
972 | case TYPE_INTEGER: | ||
973 | case TYPE_ENUMERATED: | ||
974 | len2 = | ||
975 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
976 | if (len2 < 0) | ||
977 | return ASN1_DER_ERROR; | ||
978 | if (len2 + len3 > len - counter) | ||
979 | return ASN1_DER_ERROR; | ||
980 | _asn1_set_value (p, der + counter, len3 + len2); | ||
981 | counter += len3 + len2; | ||
982 | move = RIGHT; | ||
983 | break; | ||
984 | case TYPE_OBJECT_ID: | ||
985 | _asn1_get_objectid_der (der + counter, len - counter, &len2, | ||
986 | temp, sizeof (temp)); | ||
987 | tlen = strlen (temp); | ||
988 | if (tlen > 0) | ||
989 | _asn1_set_value (p, temp, tlen + 1); | ||
990 | counter += len2; | ||
991 | move = RIGHT; | ||
992 | break; | ||
993 | case TYPE_TIME: | ||
994 | result = | ||
995 | _asn1_get_time_der (der + counter, len - counter, &len2, temp, | ||
996 | sizeof (temp) - 1); | ||
997 | if (result != ASN1_SUCCESS) | ||
998 | { | ||
999 | asn1_delete_structure (element); | ||
1000 | return result; | ||
1001 | } | ||
1002 | tlen = strlen (temp); | ||
1003 | if (tlen > 0) | ||
1004 | _asn1_set_value (p, temp, tlen + 1); | ||
1005 | counter += len2; | ||
1006 | move = RIGHT; | ||
1007 | break; | ||
1008 | case TYPE_OCTET_STRING: | ||
1009 | len3 = len - counter; | ||
1010 | ris = _asn1_get_octet_string (der + counter, p, &len3); | ||
1011 | if (ris != ASN1_SUCCESS) | ||
1012 | return ris; | ||
1013 | counter += len3; | ||
1014 | move = RIGHT; | ||
1015 | break; | ||
1016 | case TYPE_GENERALSTRING: | ||
1017 | len2 = | ||
1018 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
1019 | if (len2 < 0) | ||
1020 | return ASN1_DER_ERROR; | ||
1021 | if (len3 + len2 > len - counter) | ||
1022 | return ASN1_DER_ERROR; | ||
1023 | _asn1_set_value (p, der + counter, len3 + len2); | ||
1024 | counter += len3 + len2; | ||
1025 | move = RIGHT; | ||
1026 | break; | ||
1027 | case TYPE_BIT_STRING: | ||
1028 | len2 = | ||
1029 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
1030 | if (len2 < 0) | ||
1031 | return ASN1_DER_ERROR; | ||
1032 | if (len3 + len2 > len - counter) | ||
1033 | return ASN1_DER_ERROR; | ||
1034 | _asn1_set_value (p, der + counter, len3 + len2); | ||
1035 | counter += len3 + len2; | ||
1036 | move = RIGHT; | ||
1037 | break; | ||
1038 | case TYPE_SEQUENCE: | ||
1039 | case TYPE_SET: | ||
1040 | if (move == UP) | ||
1041 | { | ||
1042 | len2 = strtol (p->value, NULL, 10); | ||
1043 | _asn1_set_value (p, NULL, 0); | ||
1044 | if (len2 == -1) | ||
1045 | { /* indefinite length method */ | ||
1046 | if (len - counter + 1 > 0) | ||
1047 | { | ||
1048 | if ((der[counter]) || der[counter + 1]) | ||
1049 | { | ||
1050 | asn1_delete_structure (element); | ||
1051 | return ASN1_DER_ERROR; | ||
1052 | } | ||
1053 | } | ||
1054 | else | ||
1055 | return ASN1_DER_ERROR; | ||
1056 | counter += 2; | ||
1057 | } | ||
1058 | else | ||
1059 | { /* definite length method */ | ||
1060 | if (len2 != counter) | ||
1061 | { | ||
1062 | asn1_delete_structure (element); | ||
1063 | return ASN1_DER_ERROR; | ||
1064 | } | ||
1065 | } | ||
1066 | move = RIGHT; | ||
1067 | } | ||
1068 | else | ||
1069 | { /* move==DOWN || move==RIGHT */ | ||
1070 | len3 = | ||
1071 | asn1_get_length_der (der + counter, len - counter, &len2); | ||
1072 | if (len3 < -1) | ||
1073 | return ASN1_DER_ERROR; | ||
1074 | counter += len2; | ||
1075 | if (len3 > 0) | ||
1076 | { | ||
1077 | _asn1_ltostr (counter + len3, temp); | ||
1078 | tlen = strlen (temp); | ||
1079 | if (tlen > 0) | ||
1080 | _asn1_set_value (p, temp, tlen + 1); | ||
1081 | move = DOWN; | ||
1082 | } | ||
1083 | else if (len3 == 0) | ||
1084 | { | ||
1085 | p2 = p->down; | ||
1086 | while (p2) | ||
1087 | { | ||
1088 | if (type_field (p2->type) != TYPE_TAG) | ||
1089 | { | ||
1090 | p3 = p2->right; | ||
1091 | asn1_delete_structure (&p2); | ||
1092 | p2 = p3; | ||
1093 | } | ||
1094 | else | ||
1095 | p2 = p2->right; | ||
1096 | } | ||
1097 | move = RIGHT; | ||
1098 | } | ||
1099 | else | ||
1100 | { /* indefinite length method */ | ||
1101 | _asn1_set_value (p, "-1", 3); | ||
1102 | move = DOWN; | ||
1103 | } | ||
1104 | } | ||
1105 | break; | ||
1106 | case TYPE_SEQUENCE_OF: | ||
1107 | case TYPE_SET_OF: | ||
1108 | if (move == UP) | ||
1109 | { | ||
1110 | len2 = strtol (p->value, NULL, 10); | ||
1111 | if (len2 == -1) | ||
1112 | { /* indefinite length method */ | ||
1113 | if ((counter + 2) > len) | ||
1114 | return ASN1_DER_ERROR; | ||
1115 | if ((der[counter]) || der[counter + 1]) | ||
1116 | { | ||
1117 | _asn1_append_sequence_set (p); | ||
1118 | p = p->down; | ||
1119 | while (p->right) | ||
1120 | p = p->right; | ||
1121 | move = RIGHT; | ||
1122 | continue; | ||
1123 | } | ||
1124 | _asn1_set_value (p, NULL, 0); | ||
1125 | counter += 2; | ||
1126 | } | ||
1127 | else | ||
1128 | { /* definite length method */ | ||
1129 | if (len2 > counter) | ||
1130 | { | ||
1131 | _asn1_append_sequence_set (p); | ||
1132 | p = p->down; | ||
1133 | while (p->right) | ||
1134 | p = p->right; | ||
1135 | move = RIGHT; | ||
1136 | continue; | ||
1137 | } | ||
1138 | _asn1_set_value (p, NULL, 0); | ||
1139 | if (len2 != counter) | ||
1140 | { | ||
1141 | asn1_delete_structure (element); | ||
1142 | return ASN1_DER_ERROR; | ||
1143 | } | ||
1144 | } | ||
1145 | } | ||
1146 | else | ||
1147 | { /* move==DOWN || move==RIGHT */ | ||
1148 | len3 = | ||
1149 | asn1_get_length_der (der + counter, len - counter, &len2); | ||
1150 | if (len3 < -1) | ||
1151 | return ASN1_DER_ERROR; | ||
1152 | counter += len2; | ||
1153 | if (len3) | ||
1154 | { | ||
1155 | if (len3 > 0) | ||
1156 | { /* definite length method */ | ||
1157 | _asn1_ltostr (counter + len3, temp); | ||
1158 | tlen = strlen (temp); | ||
1159 | |||
1160 | if (tlen > 0) | ||
1161 | _asn1_set_value (p, temp, tlen + 1); | ||
1162 | } | ||
1163 | else | ||
1164 | { /* indefinite length method */ | ||
1165 | _asn1_set_value (p, "-1", 3); | ||
1166 | } | ||
1167 | p2 = p->down; | ||
1168 | while ((type_field (p2->type) == TYPE_TAG) | ||
1169 | || (type_field (p2->type) == TYPE_SIZE)) | ||
1170 | p2 = p2->right; | ||
1171 | if (p2->right == NULL) | ||
1172 | _asn1_append_sequence_set (p); | ||
1173 | p = p2; | ||
1174 | } | ||
1175 | } | ||
1176 | move = RIGHT; | ||
1177 | break; | ||
1178 | case TYPE_ANY: | ||
1179 | if (asn1_get_tag_der | ||
1180 | (der + counter, len - counter, &class, &len2, | ||
1181 | &tag) != ASN1_SUCCESS) | ||
1182 | return ASN1_DER_ERROR; | ||
1183 | if (counter + len2 > len) | ||
1184 | return ASN1_DER_ERROR; | ||
1185 | len4 = | ||
1186 | asn1_get_length_der (der + counter + len2, | ||
1187 | len - counter - len2, &len3); | ||
1188 | if (len4 < -1) | ||
1189 | return ASN1_DER_ERROR; | ||
1190 | if (len4 > len - counter + len2 + len3) | ||
1191 | return ASN1_DER_ERROR; | ||
1192 | if (len4 != -1) | ||
1193 | { | ||
1194 | len2 += len4; | ||
1195 | asn1_length_der (len2 + len3, NULL, &len4); | ||
1196 | temp2 = (unsigned char *) _asn1_alloca (len2 + len3 + len4); | ||
1197 | if (temp2 == NULL) | ||
1198 | { | ||
1199 | asn1_delete_structure (element); | ||
1200 | return ASN1_MEM_ALLOC_ERROR; | ||
1201 | } | ||
1202 | |||
1203 | asn1_octet_der (der + counter, len2 + len3, temp2, &len4); | ||
1204 | _asn1_set_value (p, temp2, len4); | ||
1205 | _asn1_afree (temp2); | ||
1206 | counter += len2 + len3; | ||
1207 | } | ||
1208 | else | ||
1209 | { /* indefinite length */ | ||
1210 | /* Check indefinite lenth method in an EXPLICIT TAG */ | ||
1211 | if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80)) | ||
1212 | indefinite = 1; | ||
1213 | else | ||
1214 | indefinite = 0; | ||
1215 | |||
1216 | len2 = len - counter; | ||
1217 | ris = | ||
1218 | _asn1_get_indefinite_length_string (der + counter, &len2); | ||
1219 | if (ris != ASN1_SUCCESS) | ||
1220 | { | ||
1221 | asn1_delete_structure (element); | ||
1222 | return ris; | ||
1223 | } | ||
1224 | asn1_length_der (len2, NULL, &len4); | ||
1225 | temp2 = (unsigned char *) _asn1_alloca (len2 + len4); | ||
1226 | if (temp2 == NULL) | ||
1227 | { | ||
1228 | asn1_delete_structure (element); | ||
1229 | return ASN1_MEM_ALLOC_ERROR; | ||
1230 | } | ||
1231 | |||
1232 | asn1_octet_der (der + counter, len2, temp2, &len4); | ||
1233 | _asn1_set_value (p, temp2, len4); | ||
1234 | _asn1_afree (temp2); | ||
1235 | counter += len2; | ||
1236 | |||
1237 | /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with | ||
1238 | an indefinite length method. */ | ||
1239 | if (indefinite) | ||
1240 | { | ||
1241 | if (!der[counter] && !der[counter + 1]) | ||
1242 | { | ||
1243 | counter += 2; | ||
1244 | } | ||
1245 | else | ||
1246 | { | ||
1247 | asn1_delete_structure (element); | ||
1248 | return ASN1_DER_ERROR; | ||
1249 | } | ||
1250 | } | ||
1251 | } | ||
1252 | move = RIGHT; | ||
1253 | break; | ||
1254 | default: | ||
1255 | move = (move == UP) ? RIGHT : DOWN; | ||
1256 | break; | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1260 | if (p == node && move != DOWN) | ||
1261 | break; | ||
1262 | |||
1263 | if (move == DOWN) | ||
1264 | { | ||
1265 | if (p->down) | ||
1266 | p = p->down; | ||
1267 | else | ||
1268 | move = RIGHT; | ||
1269 | } | ||
1270 | if ((move == RIGHT) && !(p->type & CONST_SET)) | ||
1271 | { | ||
1272 | if (p->right) | ||
1273 | p = p->right; | ||
1274 | else | ||
1275 | move = UP; | ||
1276 | } | ||
1277 | if (move == UP) | ||
1278 | p = _asn1_find_up (p); | ||
1279 | } | ||
1280 | |||
1281 | _asn1_delete_not_used (*element); | ||
1282 | |||
1283 | if (counter != len) | ||
1284 | { | ||
1285 | asn1_delete_structure (element); | ||
1286 | return ASN1_DER_ERROR; | ||
1287 | } | ||
1288 | |||
1289 | return ASN1_SUCCESS; | ||
1290 | } | ||
1291 | |||
1292 | |||
1293 | #define FOUND 1 | ||
1294 | #define SAME_BRANCH 2 | ||
1295 | #define OTHER_BRANCH 3 | ||
1296 | #define EXIT 4 | ||
1297 | |||
1298 | /** | ||
1299 | * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string. | ||
1300 | * @structure: pointer to an ASN1 structure | ||
1301 | * @elementName: name of the element to fill | ||
1302 | * @ider: vector that contains the DER encoding of the whole structure. | ||
1303 | * @len: number of bytes of *der: der[0]..der[len-1] | ||
1304 | * @errorDescription: null-terminated string contains details when an | ||
1305 | * error occurred. | ||
1306 | * | ||
1307 | * Fill the element named ELEMENTNAME with values of a DER encoding | ||
1308 | * string. The sructure must just be created with function | ||
1309 | * 'create_stucture'. The DER vector must contain the encoding | ||
1310 | * string of the whole STRUCTURE. If an error occurs during the | ||
1311 | * decoding procedure, the *STRUCTURE is deleted and set equal to | ||
1312 | * %ASN1_TYPE_EMPTY. | ||
1313 | * | ||
1314 | * Returns: | ||
1315 | * | ||
1316 | * ASN1_SUCCESS: DER encoding OK. | ||
1317 | * | ||
1318 | * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY or | ||
1319 | * elementName == NULL. | ||
1320 | * | ||
1321 | * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match | ||
1322 | * the structure STRUCTURE. *ELEMENT deleted. | ||
1323 | * | ||
1324 | **/ | ||
1325 | asn1_retCode | ||
1326 | asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName, | ||
1327 | const void *ider, int len, char *errorDescription) | ||
1328 | { | ||
1329 | node_asn *node, *p, *p2, *p3, *nodeFound = ASN1_TYPE_EMPTY; | ||
1330 | char temp[128], currentName[MAX_NAME_SIZE * 10], *dot_p, *char_p; | ||
1331 | int nameLen = MAX_NAME_SIZE * 10 - 1, state; | ||
1332 | int counter, len2, len3, len4, move, ris, tlen; | ||
1333 | unsigned char class, *temp2; | ||
1334 | unsigned long tag; | ||
1335 | int indefinite, result; | ||
1336 | const unsigned char *der = ider; | ||
1337 | |||
1338 | node = *structure; | ||
1339 | |||
1340 | if (node == ASN1_TYPE_EMPTY) | ||
1341 | return ASN1_ELEMENT_NOT_FOUND; | ||
1342 | |||
1343 | if (elementName == NULL) | ||
1344 | { | ||
1345 | asn1_delete_structure (structure); | ||
1346 | return ASN1_ELEMENT_NOT_FOUND; | ||
1347 | } | ||
1348 | |||
1349 | if (node->type & CONST_OPTION) | ||
1350 | { | ||
1351 | asn1_delete_structure (structure); | ||
1352 | return ASN1_GENERIC_ERROR; | ||
1353 | } | ||
1354 | |||
1355 | if ((*structure)->name) | ||
1356 | { /* Has *structure got a name? */ | ||
1357 | nameLen -= strlen ((*structure)->name); | ||
1358 | if (nameLen > 0) | ||
1359 | strcpy (currentName, (*structure)->name); | ||
1360 | else | ||
1361 | { | ||
1362 | asn1_delete_structure (structure); | ||
1363 | return ASN1_MEM_ERROR; | ||
1364 | } | ||
1365 | if (!(strcmp (currentName, elementName))) | ||
1366 | { | ||
1367 | state = FOUND; | ||
1368 | nodeFound = *structure; | ||
1369 | } | ||
1370 | else if (!memcmp (currentName, elementName, strlen (currentName))) | ||
1371 | state = SAME_BRANCH; | ||
1372 | else | ||
1373 | state = OTHER_BRANCH; | ||
1374 | } | ||
1375 | else | ||
1376 | { /* *structure doesn't have a name? */ | ||
1377 | currentName[0] = 0; | ||
1378 | if (elementName[0] == 0) | ||
1379 | { | ||
1380 | state = FOUND; | ||
1381 | nodeFound = *structure; | ||
1382 | } | ||
1383 | else | ||
1384 | { | ||
1385 | state = SAME_BRANCH; | ||
1386 | } | ||
1387 | } | ||
1388 | |||
1389 | counter = 0; | ||
1390 | move = DOWN; | ||
1391 | p = node; | ||
1392 | while (1) | ||
1393 | { | ||
1394 | |||
1395 | ris = ASN1_SUCCESS; | ||
1396 | |||
1397 | if (move != UP) | ||
1398 | { | ||
1399 | if (p->type & CONST_SET) | ||
1400 | { | ||
1401 | p2 = _asn1_find_up (p); | ||
1402 | len2 = strtol (p2->value, NULL, 10); | ||
1403 | if (counter == len2) | ||
1404 | { | ||
1405 | p = p2; | ||
1406 | move = UP; | ||
1407 | continue; | ||
1408 | } | ||
1409 | else if (counter > len2) | ||
1410 | { | ||
1411 | asn1_delete_structure (structure); | ||
1412 | return ASN1_DER_ERROR; | ||
1413 | } | ||
1414 | p2 = p2->down; | ||
1415 | while (p2) | ||
1416 | { | ||
1417 | if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) | ||
1418 | { | ||
1419 | if (type_field (p2->type) != TYPE_CHOICE) | ||
1420 | ris = | ||
1421 | _asn1_extract_tag_der (p2, der + counter, | ||
1422 | len - counter, &len2); | ||
1423 | else | ||
1424 | { | ||
1425 | p3 = p2->down; | ||
1426 | while (p3) | ||
1427 | { | ||
1428 | ris = | ||
1429 | _asn1_extract_tag_der (p3, der + counter, | ||
1430 | len - counter, &len2); | ||
1431 | if (ris == ASN1_SUCCESS) | ||
1432 | break; | ||
1433 | p3 = p3->right; | ||
1434 | } | ||
1435 | } | ||
1436 | if (ris == ASN1_SUCCESS) | ||
1437 | { | ||
1438 | p2->type &= ~CONST_NOT_USED; | ||
1439 | p = p2; | ||
1440 | break; | ||
1441 | } | ||
1442 | } | ||
1443 | p2 = p2->right; | ||
1444 | } | ||
1445 | if (p2 == NULL) | ||
1446 | { | ||
1447 | asn1_delete_structure (structure); | ||
1448 | return ASN1_DER_ERROR; | ||
1449 | } | ||
1450 | } | ||
1451 | |||
1452 | if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) | ||
1453 | { | ||
1454 | p2 = _asn1_find_up (p); | ||
1455 | len2 = strtol (p2->value, NULL, 10); | ||
1456 | if (counter == len2) | ||
1457 | { | ||
1458 | if (p->right) | ||
1459 | { | ||
1460 | p2 = p->right; | ||
1461 | move = RIGHT; | ||
1462 | } | ||
1463 | else | ||
1464 | move = UP; | ||
1465 | |||
1466 | if (p->type & CONST_OPTION) | ||
1467 | asn1_delete_structure (&p); | ||
1468 | |||
1469 | p = p2; | ||
1470 | continue; | ||
1471 | } | ||
1472 | } | ||
1473 | |||
1474 | if (type_field (p->type) == TYPE_CHOICE) | ||
1475 | { | ||
1476 | while (p->down) | ||
1477 | { | ||
1478 | if (counter < len) | ||
1479 | ris = | ||
1480 | _asn1_extract_tag_der (p->down, der + counter, | ||
1481 | len - counter, &len2); | ||
1482 | else | ||
1483 | ris = ASN1_DER_ERROR; | ||
1484 | if (ris == ASN1_SUCCESS) | ||
1485 | { | ||
1486 | while (p->down->right) | ||
1487 | { | ||
1488 | p2 = p->down->right; | ||
1489 | asn1_delete_structure (&p2); | ||
1490 | } | ||
1491 | break; | ||
1492 | } | ||
1493 | else if (ris == ASN1_ERROR_TYPE_ANY) | ||
1494 | { | ||
1495 | asn1_delete_structure (structure); | ||
1496 | return ASN1_ERROR_TYPE_ANY; | ||
1497 | } | ||
1498 | else | ||
1499 | { | ||
1500 | p2 = p->down; | ||
1501 | asn1_delete_structure (&p2); | ||
1502 | } | ||
1503 | } | ||
1504 | |||
1505 | if (p->down == NULL) | ||
1506 | { | ||
1507 | if (!(p->type & CONST_OPTION)) | ||
1508 | { | ||
1509 | asn1_delete_structure (structure); | ||
1510 | return ASN1_DER_ERROR; | ||
1511 | } | ||
1512 | } | ||
1513 | else | ||
1514 | p = p->down; | ||
1515 | } | ||
1516 | |||
1517 | if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) | ||
1518 | { | ||
1519 | p2 = _asn1_find_up (p); | ||
1520 | len2 = strtol (p2->value, NULL, 10); | ||
1521 | if (counter > len2) | ||
1522 | ris = ASN1_TAG_ERROR; | ||
1523 | } | ||
1524 | |||
1525 | if (ris == ASN1_SUCCESS) | ||
1526 | ris = | ||
1527 | _asn1_extract_tag_der (p, der + counter, len - counter, &len2); | ||
1528 | if (ris != ASN1_SUCCESS) | ||
1529 | { | ||
1530 | if (p->type & CONST_OPTION) | ||
1531 | { | ||
1532 | p->type |= CONST_NOT_USED; | ||
1533 | move = RIGHT; | ||
1534 | } | ||
1535 | else if (p->type & CONST_DEFAULT) | ||
1536 | { | ||
1537 | _asn1_set_value (p, NULL, 0); | ||
1538 | move = RIGHT; | ||
1539 | } | ||
1540 | else | ||
1541 | { | ||
1542 | if (errorDescription != NULL) | ||
1543 | _asn1_error_description_tag_error (p, errorDescription); | ||
1544 | |||
1545 | asn1_delete_structure (structure); | ||
1546 | return ASN1_TAG_ERROR; | ||
1547 | } | ||
1548 | } | ||
1549 | else | ||
1550 | counter += len2; | ||
1551 | } | ||
1552 | |||
1553 | if (ris == ASN1_SUCCESS) | ||
1554 | { | ||
1555 | switch (type_field (p->type)) | ||
1556 | { | ||
1557 | case TYPE_NULL: | ||
1558 | if (der[counter]) | ||
1559 | { | ||
1560 | asn1_delete_structure (structure); | ||
1561 | return ASN1_DER_ERROR; | ||
1562 | } | ||
1563 | |||
1564 | if (p == nodeFound) | ||
1565 | state = EXIT; | ||
1566 | |||
1567 | counter++; | ||
1568 | move = RIGHT; | ||
1569 | break; | ||
1570 | case TYPE_BOOLEAN: | ||
1571 | if (der[counter++] != 1) | ||
1572 | { | ||
1573 | asn1_delete_structure (structure); | ||
1574 | return ASN1_DER_ERROR; | ||
1575 | } | ||
1576 | |||
1577 | if (state == FOUND) | ||
1578 | { | ||
1579 | if (der[counter++] == 0) | ||
1580 | _asn1_set_value (p, "F", 1); | ||
1581 | else | ||
1582 | _asn1_set_value (p, "T", 1); | ||
1583 | |||
1584 | if (p == nodeFound) | ||
1585 | state = EXIT; | ||
1586 | |||
1587 | } | ||
1588 | else | ||
1589 | counter++; | ||
1590 | |||
1591 | move = RIGHT; | ||
1592 | break; | ||
1593 | case TYPE_INTEGER: | ||
1594 | case TYPE_ENUMERATED: | ||
1595 | len2 = | ||
1596 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
1597 | if (len2 < 0) | ||
1598 | return ASN1_DER_ERROR; | ||
1599 | if (state == FOUND) | ||
1600 | { | ||
1601 | if (len3 + len2 > len - counter) | ||
1602 | return ASN1_DER_ERROR; | ||
1603 | _asn1_set_value (p, der + counter, len3 + len2); | ||
1604 | |||
1605 | if (p == nodeFound) | ||
1606 | state = EXIT; | ||
1607 | } | ||
1608 | counter += len3 + len2; | ||
1609 | move = RIGHT; | ||
1610 | break; | ||
1611 | case TYPE_OBJECT_ID: | ||
1612 | if (state == FOUND) | ||
1613 | { | ||
1614 | _asn1_get_objectid_der (der + counter, len - counter, &len2, | ||
1615 | temp, sizeof (temp)); | ||
1616 | tlen = strlen (temp); | ||
1617 | |||
1618 | if (tlen > 0) | ||
1619 | _asn1_set_value (p, temp, tlen + 1); | ||
1620 | |||
1621 | if (p == nodeFound) | ||
1622 | state = EXIT; | ||
1623 | } | ||
1624 | else | ||
1625 | { | ||
1626 | len2 = | ||
1627 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
1628 | if (len2 < 0) | ||
1629 | return ASN1_DER_ERROR; | ||
1630 | len2 += len3; | ||
1631 | } | ||
1632 | |||
1633 | counter += len2; | ||
1634 | move = RIGHT; | ||
1635 | break; | ||
1636 | case TYPE_TIME: | ||
1637 | if (state == FOUND) | ||
1638 | { | ||
1639 | result = | ||
1640 | _asn1_get_time_der (der + counter, len - counter, &len2, | ||
1641 | temp, sizeof (temp) - 1); | ||
1642 | if (result != ASN1_SUCCESS) | ||
1643 | { | ||
1644 | asn1_delete_structure (structure); | ||
1645 | return result; | ||
1646 | } | ||
1647 | |||
1648 | tlen = strlen (temp); | ||
1649 | if (tlen > 0) | ||
1650 | _asn1_set_value (p, temp, tlen + 1); | ||
1651 | |||
1652 | if (p == nodeFound) | ||
1653 | state = EXIT; | ||
1654 | } | ||
1655 | else | ||
1656 | { | ||
1657 | len2 = | ||
1658 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
1659 | if (len2 < 0) | ||
1660 | return ASN1_DER_ERROR; | ||
1661 | len2 += len3; | ||
1662 | } | ||
1663 | |||
1664 | counter += len2; | ||
1665 | move = RIGHT; | ||
1666 | break; | ||
1667 | case TYPE_OCTET_STRING: | ||
1668 | len3 = len - counter; | ||
1669 | if (state == FOUND) | ||
1670 | { | ||
1671 | ris = _asn1_get_octet_string (der + counter, p, &len3); | ||
1672 | if (p == nodeFound) | ||
1673 | state = EXIT; | ||
1674 | } | ||
1675 | else | ||
1676 | ris = _asn1_get_octet_string (der + counter, NULL, &len3); | ||
1677 | |||
1678 | if (ris != ASN1_SUCCESS) | ||
1679 | return ris; | ||
1680 | counter += len3; | ||
1681 | move = RIGHT; | ||
1682 | break; | ||
1683 | case TYPE_GENERALSTRING: | ||
1684 | len2 = | ||
1685 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
1686 | if (len2 < 0) | ||
1687 | return ASN1_DER_ERROR; | ||
1688 | if (state == FOUND) | ||
1689 | { | ||
1690 | if (len3 + len2 > len - counter) | ||
1691 | return ASN1_DER_ERROR; | ||
1692 | _asn1_set_value (p, der + counter, len3 + len2); | ||
1693 | |||
1694 | if (p == nodeFound) | ||
1695 | state = EXIT; | ||
1696 | } | ||
1697 | counter += len3 + len2; | ||
1698 | move = RIGHT; | ||
1699 | break; | ||
1700 | case TYPE_BIT_STRING: | ||
1701 | len2 = | ||
1702 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
1703 | if (len2 < 0) | ||
1704 | return ASN1_DER_ERROR; | ||
1705 | if (state == FOUND) | ||
1706 | { | ||
1707 | if (len3 + len2 > len - counter) | ||
1708 | return ASN1_DER_ERROR; | ||
1709 | _asn1_set_value (p, der + counter, len3 + len2); | ||
1710 | |||
1711 | if (p == nodeFound) | ||
1712 | state = EXIT; | ||
1713 | } | ||
1714 | counter += len3 + len2; | ||
1715 | move = RIGHT; | ||
1716 | break; | ||
1717 | case TYPE_SEQUENCE: | ||
1718 | case TYPE_SET: | ||
1719 | if (move == UP) | ||
1720 | { | ||
1721 | len2 = strtol (p->value, NULL, 10); | ||
1722 | _asn1_set_value (p, NULL, 0); | ||
1723 | if (len2 == -1) | ||
1724 | { /* indefinite length method */ | ||
1725 | if ((der[counter]) || der[counter + 1]) | ||
1726 | { | ||
1727 | asn1_delete_structure (structure); | ||
1728 | return ASN1_DER_ERROR; | ||
1729 | } | ||
1730 | counter += 2; | ||
1731 | } | ||
1732 | else | ||
1733 | { /* definite length method */ | ||
1734 | if (len2 != counter) | ||
1735 | { | ||
1736 | asn1_delete_structure (structure); | ||
1737 | return ASN1_DER_ERROR; | ||
1738 | } | ||
1739 | } | ||
1740 | if (p == nodeFound) | ||
1741 | state = EXIT; | ||
1742 | move = RIGHT; | ||
1743 | } | ||
1744 | else | ||
1745 | { /* move==DOWN || move==RIGHT */ | ||
1746 | if (state == OTHER_BRANCH) | ||
1747 | { | ||
1748 | len3 = | ||
1749 | asn1_get_length_der (der + counter, len - counter, | ||
1750 | &len2); | ||
1751 | if (len3 < 0) | ||
1752 | return ASN1_DER_ERROR; | ||
1753 | counter += len2 + len3; | ||
1754 | move = RIGHT; | ||
1755 | } | ||
1756 | else | ||
1757 | { /* state==SAME_BRANCH or state==FOUND */ | ||
1758 | len3 = | ||
1759 | asn1_get_length_der (der + counter, len - counter, | ||
1760 | &len2); | ||
1761 | if (len3 < 0) | ||
1762 | return ASN1_DER_ERROR; | ||
1763 | counter += len2; | ||
1764 | if (len3 > 0) | ||
1765 | { | ||
1766 | _asn1_ltostr (counter + len3, temp); | ||
1767 | tlen = strlen (temp); | ||
1768 | |||
1769 | if (tlen > 0) | ||
1770 | _asn1_set_value (p, temp, tlen + 1); | ||
1771 | move = DOWN; | ||
1772 | } | ||
1773 | else if (len3 == 0) | ||
1774 | { | ||
1775 | p2 = p->down; | ||
1776 | while (p2) | ||
1777 | { | ||
1778 | if (type_field (p2->type) != TYPE_TAG) | ||
1779 | { | ||
1780 | p3 = p2->right; | ||
1781 | asn1_delete_structure (&p2); | ||
1782 | p2 = p3; | ||
1783 | } | ||
1784 | else | ||
1785 | p2 = p2->right; | ||
1786 | } | ||
1787 | move = RIGHT; | ||
1788 | } | ||
1789 | else | ||
1790 | { /* indefinite length method */ | ||
1791 | _asn1_set_value (p, "-1", 3); | ||
1792 | move = DOWN; | ||
1793 | } | ||
1794 | } | ||
1795 | } | ||
1796 | break; | ||
1797 | case TYPE_SEQUENCE_OF: | ||
1798 | case TYPE_SET_OF: | ||
1799 | if (move == UP) | ||
1800 | { | ||
1801 | len2 = strtol (p->value, NULL, 10); | ||
1802 | if (len2 > counter) | ||
1803 | { | ||
1804 | _asn1_append_sequence_set (p); | ||
1805 | p = p->down; | ||
1806 | while (p->right) | ||
1807 | p = p->right; | ||
1808 | move = RIGHT; | ||
1809 | continue; | ||
1810 | } | ||
1811 | _asn1_set_value (p, NULL, 0); | ||
1812 | if (len2 != counter) | ||
1813 | { | ||
1814 | asn1_delete_structure (structure); | ||
1815 | return ASN1_DER_ERROR; | ||
1816 | } | ||
1817 | |||
1818 | if (p == nodeFound) | ||
1819 | state = EXIT; | ||
1820 | } | ||
1821 | else | ||
1822 | { /* move==DOWN || move==RIGHT */ | ||
1823 | if (state == OTHER_BRANCH) | ||
1824 | { | ||
1825 | len3 = | ||
1826 | asn1_get_length_der (der + counter, len - counter, | ||
1827 | &len2); | ||
1828 | if (len3 < 0) | ||
1829 | return ASN1_DER_ERROR; | ||
1830 | counter += len2 + len3; | ||
1831 | move = RIGHT; | ||
1832 | } | ||
1833 | else | ||
1834 | { /* state==FOUND or state==SAME_BRANCH */ | ||
1835 | len3 = | ||
1836 | asn1_get_length_der (der + counter, len - counter, | ||
1837 | &len2); | ||
1838 | if (len3 < 0) | ||
1839 | return ASN1_DER_ERROR; | ||
1840 | counter += len2; | ||
1841 | if (len3) | ||
1842 | { | ||
1843 | _asn1_ltostr (counter + len3, temp); | ||
1844 | tlen = strlen (temp); | ||
1845 | |||
1846 | if (tlen > 0) | ||
1847 | _asn1_set_value (p, temp, tlen + 1); | ||
1848 | p2 = p->down; | ||
1849 | while ((type_field (p2->type) == TYPE_TAG) | ||
1850 | || (type_field (p2->type) == TYPE_SIZE)) | ||
1851 | p2 = p2->right; | ||
1852 | if (p2->right == NULL) | ||
1853 | _asn1_append_sequence_set (p); | ||
1854 | p = p2; | ||
1855 | state = FOUND; | ||
1856 | } | ||
1857 | } | ||
1858 | } | ||
1859 | |||
1860 | break; | ||
1861 | case TYPE_ANY: | ||
1862 | if (asn1_get_tag_der | ||
1863 | (der + counter, len - counter, &class, &len2, | ||
1864 | &tag) != ASN1_SUCCESS) | ||
1865 | return ASN1_DER_ERROR; | ||
1866 | if (counter + len2 > len) | ||
1867 | return ASN1_DER_ERROR; | ||
1868 | |||
1869 | len4 = | ||
1870 | asn1_get_length_der (der + counter + len2, | ||
1871 | len - counter - len2, &len3); | ||
1872 | if (len4 < -1) | ||
1873 | return ASN1_DER_ERROR; | ||
1874 | |||
1875 | if (len4 != -1) | ||
1876 | { | ||
1877 | len2 += len4; | ||
1878 | if (state == FOUND) | ||
1879 | { | ||
1880 | asn1_length_der (len2 + len3, NULL, &len4); | ||
1881 | temp2 = | ||
1882 | (unsigned char *) _asn1_alloca (len2 + len3 + len4); | ||
1883 | if (temp2 == NULL) | ||
1884 | { | ||
1885 | asn1_delete_structure (structure); | ||
1886 | return ASN1_MEM_ALLOC_ERROR; | ||
1887 | } | ||
1888 | |||
1889 | asn1_octet_der (der + counter, len2 + len3, temp2, | ||
1890 | &len4); | ||
1891 | _asn1_set_value (p, temp2, len4); | ||
1892 | _asn1_afree (temp2); | ||
1893 | |||
1894 | if (p == nodeFound) | ||
1895 | state = EXIT; | ||
1896 | } | ||
1897 | counter += len2 + len3; | ||
1898 | } | ||
1899 | else | ||
1900 | { /* indefinite length */ | ||
1901 | /* Check indefinite lenth method in an EXPLICIT TAG */ | ||
1902 | if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80)) | ||
1903 | indefinite = 1; | ||
1904 | else | ||
1905 | indefinite = 0; | ||
1906 | |||
1907 | len2 = len - counter; | ||
1908 | ris = | ||
1909 | _asn1_get_indefinite_length_string (der + counter, &len2); | ||
1910 | if (ris != ASN1_SUCCESS) | ||
1911 | { | ||
1912 | asn1_delete_structure (structure); | ||
1913 | return ris; | ||
1914 | } | ||
1915 | |||
1916 | if (state == FOUND) | ||
1917 | { | ||
1918 | asn1_length_der (len2, NULL, &len4); | ||
1919 | temp2 = (unsigned char *) _asn1_alloca (len2 + len4); | ||
1920 | if (temp2 == NULL) | ||
1921 | { | ||
1922 | asn1_delete_structure (structure); | ||
1923 | return ASN1_MEM_ALLOC_ERROR; | ||
1924 | } | ||
1925 | |||
1926 | asn1_octet_der (der + counter, len2, temp2, &len4); | ||
1927 | _asn1_set_value (p, temp2, len4); | ||
1928 | _asn1_afree (temp2); | ||
1929 | |||
1930 | if (p == nodeFound) | ||
1931 | state = EXIT; | ||
1932 | } | ||
1933 | |||
1934 | counter += len2; | ||
1935 | |||
1936 | /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with | ||
1937 | an indefinite length method. */ | ||
1938 | if (indefinite) | ||
1939 | { | ||
1940 | if (!der[counter] && !der[counter + 1]) | ||
1941 | { | ||
1942 | counter += 2; | ||
1943 | } | ||
1944 | else | ||
1945 | { | ||
1946 | asn1_delete_structure (structure); | ||
1947 | return ASN1_DER_ERROR; | ||
1948 | } | ||
1949 | } | ||
1950 | } | ||
1951 | move = RIGHT; | ||
1952 | break; | ||
1953 | |||
1954 | default: | ||
1955 | move = (move == UP) ? RIGHT : DOWN; | ||
1956 | break; | ||
1957 | } | ||
1958 | } | ||
1959 | |||
1960 | if ((p == node && move != DOWN) || (state == EXIT)) | ||
1961 | break; | ||
1962 | |||
1963 | if (move == DOWN) | ||
1964 | { | ||
1965 | if (p->down) | ||
1966 | { | ||
1967 | p = p->down; | ||
1968 | |||
1969 | if (state != FOUND) | ||
1970 | { | ||
1971 | nameLen -= strlen (p->name) + 1; | ||
1972 | if (nameLen > 0) | ||
1973 | { | ||
1974 | if (currentName[0]) | ||
1975 | strcat (currentName, "."); | ||
1976 | strcat (currentName, p->name); | ||
1977 | } | ||
1978 | else | ||
1979 | { | ||
1980 | asn1_delete_structure (structure); | ||
1981 | return ASN1_MEM_ERROR; | ||
1982 | } | ||
1983 | if (!(strcmp (currentName, elementName))) | ||
1984 | { | ||
1985 | state = FOUND; | ||
1986 | nodeFound = p; | ||
1987 | } | ||
1988 | else | ||
1989 | if (!memcmp | ||
1990 | (currentName, elementName, strlen (currentName))) | ||
1991 | state = SAME_BRANCH; | ||
1992 | else | ||
1993 | state = OTHER_BRANCH; | ||
1994 | } | ||
1995 | } | ||
1996 | else | ||
1997 | move = RIGHT; | ||
1998 | } | ||
1999 | |||
2000 | if ((move == RIGHT) && !(p->type & CONST_SET)) | ||
2001 | { | ||
2002 | if (p->right) | ||
2003 | { | ||
2004 | p = p->right; | ||
2005 | |||
2006 | if (state != FOUND) | ||
2007 | { | ||
2008 | dot_p = char_p = currentName; | ||
2009 | while ((char_p = strchr (char_p, '.'))) | ||
2010 | { | ||
2011 | dot_p = char_p++; | ||
2012 | dot_p++; | ||
2013 | } | ||
2014 | |||
2015 | nameLen += strlen (currentName) - (dot_p - currentName); | ||
2016 | *dot_p = 0; | ||
2017 | |||
2018 | nameLen -= strlen (p->name); | ||
2019 | if (nameLen > 0) | ||
2020 | strcat (currentName, p->name); | ||
2021 | else | ||
2022 | { | ||
2023 | asn1_delete_structure (structure); | ||
2024 | return ASN1_MEM_ERROR; | ||
2025 | } | ||
2026 | |||
2027 | if (!(strcmp (currentName, elementName))) | ||
2028 | { | ||
2029 | state = FOUND; | ||
2030 | nodeFound = p; | ||
2031 | } | ||
2032 | else | ||
2033 | if (!memcmp | ||
2034 | (currentName, elementName, strlen (currentName))) | ||
2035 | state = SAME_BRANCH; | ||
2036 | else | ||
2037 | state = OTHER_BRANCH; | ||
2038 | } | ||
2039 | } | ||
2040 | else | ||
2041 | move = UP; | ||
2042 | } | ||
2043 | |||
2044 | if (move == UP) | ||
2045 | { | ||
2046 | p = _asn1_find_up (p); | ||
2047 | |||
2048 | if (state != FOUND) | ||
2049 | { | ||
2050 | dot_p = char_p = currentName; | ||
2051 | while ((char_p = strchr (char_p, '.'))) | ||
2052 | { | ||
2053 | dot_p = char_p++; | ||
2054 | dot_p++; | ||
2055 | } | ||
2056 | |||
2057 | nameLen += strlen (currentName) - (dot_p - currentName); | ||
2058 | *dot_p = 0; | ||
2059 | |||
2060 | if (!(strcmp (currentName, elementName))) | ||
2061 | { | ||
2062 | state = FOUND; | ||
2063 | nodeFound = p; | ||
2064 | } | ||
2065 | else | ||
2066 | if (!memcmp (currentName, elementName, strlen (currentName))) | ||
2067 | state = SAME_BRANCH; | ||
2068 | else | ||
2069 | state = OTHER_BRANCH; | ||
2070 | } | ||
2071 | } | ||
2072 | } | ||
2073 | |||
2074 | _asn1_delete_not_used (*structure); | ||
2075 | |||
2076 | if (counter > len) | ||
2077 | { | ||
2078 | asn1_delete_structure (structure); | ||
2079 | return ASN1_DER_ERROR; | ||
2080 | } | ||
2081 | |||
2082 | return ASN1_SUCCESS; | ||
2083 | } | ||
2084 | |||
2085 | |||
2086 | |||
2087 | /** | ||
2088 | * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string. | ||
2089 | * @element: pointer to an ASN1 element | ||
2090 | * @ider: vector that contains the DER encoding. | ||
2091 | * @len: number of bytes of *@ider: @ider[0]..@ider[len-1] | ||
2092 | * @name_element: an element of NAME structure. | ||
2093 | * @start: the position of the first byte of NAME_ELEMENT decoding | ||
2094 | * (@ider[*start]) | ||
2095 | * @end: the position of the last byte of NAME_ELEMENT decoding | ||
2096 | * (@ider[*end]) | ||
2097 | * | ||
2098 | * Find the start and end point of an element in a DER encoding | ||
2099 | * string. I mean that if you have a der encoding and you have | ||
2100 | * already used the function "asn1_der_decoding" to fill a structure, | ||
2101 | * it may happen that you want to find the piece of string concerning | ||
2102 | * an element of the structure. | ||
2103 | * | ||
2104 | * Example: the sequence "tbsCertificate" inside an X509 certificate. | ||
2105 | * | ||
2106 | * Returns: | ||
2107 | * | ||
2108 | * ASN1_SUCCESS: DER encoding OK. | ||
2109 | * | ||
2110 | * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE EMPTY or | ||
2111 | * NAME_ELEMENT is not a valid element. | ||
2112 | * | ||
2113 | * ASN1_TAG_ERROR,ASN1_DER_ERROR: the der encoding doesn't match | ||
2114 | * the structure ELEMENT. | ||
2115 | * | ||
2116 | **/ | ||
2117 | asn1_retCode | ||
2118 | asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len, | ||
2119 | const char *name_element, int *start, int *end) | ||
2120 | { | ||
2121 | node_asn *node, *node_to_find, *p, *p2, *p3; | ||
2122 | int counter, len2, len3, len4, move, ris; | ||
2123 | unsigned char class; | ||
2124 | unsigned long tag; | ||
2125 | int indefinite; | ||
2126 | const unsigned char *der = ider; | ||
2127 | |||
2128 | node = element; | ||
2129 | |||
2130 | if (node == ASN1_TYPE_EMPTY) | ||
2131 | return ASN1_ELEMENT_NOT_FOUND; | ||
2132 | |||
2133 | node_to_find = asn1_find_node (node, name_element); | ||
2134 | |||
2135 | if (node_to_find == NULL) | ||
2136 | return ASN1_ELEMENT_NOT_FOUND; | ||
2137 | |||
2138 | if (node_to_find == node) | ||
2139 | { | ||
2140 | *start = 0; | ||
2141 | *end = len - 1; | ||
2142 | return ASN1_SUCCESS; | ||
2143 | } | ||
2144 | |||
2145 | if (node->type & CONST_OPTION) | ||
2146 | return ASN1_GENERIC_ERROR; | ||
2147 | |||
2148 | counter = 0; | ||
2149 | move = DOWN; | ||
2150 | p = node; | ||
2151 | while (1) | ||
2152 | { | ||
2153 | ris = ASN1_SUCCESS; | ||
2154 | |||
2155 | if (move != UP) | ||
2156 | { | ||
2157 | if (p->type & CONST_SET) | ||
2158 | { | ||
2159 | p2 = _asn1_find_up (p); | ||
2160 | len2 = strtol (p2->value, NULL, 10); | ||
2161 | if (len2 == -1) | ||
2162 | { | ||
2163 | if (!der[counter] && !der[counter + 1]) | ||
2164 | { | ||
2165 | p = p2; | ||
2166 | move = UP; | ||
2167 | counter += 2; | ||
2168 | continue; | ||
2169 | } | ||
2170 | } | ||
2171 | else if (counter == len2) | ||
2172 | { | ||
2173 | p = p2; | ||
2174 | move = UP; | ||
2175 | continue; | ||
2176 | } | ||
2177 | else if (counter > len2) | ||
2178 | return ASN1_DER_ERROR; | ||
2179 | p2 = p2->down; | ||
2180 | while (p2) | ||
2181 | { | ||
2182 | if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) | ||
2183 | { /* CONTROLLARE */ | ||
2184 | if (type_field (p2->type) != TYPE_CHOICE) | ||
2185 | ris = | ||
2186 | _asn1_extract_tag_der (p2, der + counter, | ||
2187 | len - counter, &len2); | ||
2188 | else | ||
2189 | { | ||
2190 | p3 = p2->down; | ||
2191 | ris = | ||
2192 | _asn1_extract_tag_der (p3, der + counter, | ||
2193 | len - counter, &len2); | ||
2194 | } | ||
2195 | if (ris == ASN1_SUCCESS) | ||
2196 | { | ||
2197 | p2->type &= ~CONST_NOT_USED; | ||
2198 | p = p2; | ||
2199 | break; | ||
2200 | } | ||
2201 | } | ||
2202 | p2 = p2->right; | ||
2203 | } | ||
2204 | if (p2 == NULL) | ||
2205 | return ASN1_DER_ERROR; | ||
2206 | } | ||
2207 | |||
2208 | if (p == node_to_find) | ||
2209 | *start = counter; | ||
2210 | |||
2211 | if (type_field (p->type) == TYPE_CHOICE) | ||
2212 | { | ||
2213 | p = p->down; | ||
2214 | ris = | ||
2215 | _asn1_extract_tag_der (p, der + counter, len - counter, | ||
2216 | &len2); | ||
2217 | if (p == node_to_find) | ||
2218 | *start = counter; | ||
2219 | } | ||
2220 | |||
2221 | if (ris == ASN1_SUCCESS) | ||
2222 | ris = | ||
2223 | _asn1_extract_tag_der (p, der + counter, len - counter, &len2); | ||
2224 | if (ris != ASN1_SUCCESS) | ||
2225 | { | ||
2226 | if (p->type & CONST_OPTION) | ||
2227 | { | ||
2228 | p->type |= CONST_NOT_USED; | ||
2229 | move = RIGHT; | ||
2230 | } | ||
2231 | else if (p->type & CONST_DEFAULT) | ||
2232 | { | ||
2233 | move = RIGHT; | ||
2234 | } | ||
2235 | else | ||
2236 | { | ||
2237 | return ASN1_TAG_ERROR; | ||
2238 | } | ||
2239 | } | ||
2240 | else | ||
2241 | counter += len2; | ||
2242 | } | ||
2243 | |||
2244 | if (ris == ASN1_SUCCESS) | ||
2245 | { | ||
2246 | switch (type_field (p->type)) | ||
2247 | { | ||
2248 | case TYPE_NULL: | ||
2249 | if (der[counter]) | ||
2250 | return ASN1_DER_ERROR; | ||
2251 | counter++; | ||
2252 | move = RIGHT; | ||
2253 | break; | ||
2254 | case TYPE_BOOLEAN: | ||
2255 | if (der[counter++] != 1) | ||
2256 | return ASN1_DER_ERROR; | ||
2257 | counter++; | ||
2258 | move = RIGHT; | ||
2259 | break; | ||
2260 | case TYPE_INTEGER: | ||
2261 | case TYPE_ENUMERATED: | ||
2262 | len2 = | ||
2263 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
2264 | if (len2 < 0) | ||
2265 | return ASN1_DER_ERROR; | ||
2266 | counter += len3 + len2; | ||
2267 | move = RIGHT; | ||
2268 | break; | ||
2269 | case TYPE_OBJECT_ID: | ||
2270 | len2 = | ||
2271 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
2272 | if (len2 < 0) | ||
2273 | return ASN1_DER_ERROR; | ||
2274 | counter += len2 + len3; | ||
2275 | move = RIGHT; | ||
2276 | break; | ||
2277 | case TYPE_TIME: | ||
2278 | len2 = | ||
2279 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
2280 | if (len2 < 0) | ||
2281 | return ASN1_DER_ERROR; | ||
2282 | counter += len2 + len3; | ||
2283 | move = RIGHT; | ||
2284 | break; | ||
2285 | case TYPE_OCTET_STRING: | ||
2286 | len3 = len - counter; | ||
2287 | ris = _asn1_get_octet_string (der + counter, NULL, &len3); | ||
2288 | if (ris != ASN1_SUCCESS) | ||
2289 | return ris; | ||
2290 | counter += len3; | ||
2291 | move = RIGHT; | ||
2292 | break; | ||
2293 | case TYPE_GENERALSTRING: | ||
2294 | len2 = | ||
2295 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
2296 | if (len2 < 0) | ||
2297 | return ASN1_DER_ERROR; | ||
2298 | counter += len3 + len2; | ||
2299 | move = RIGHT; | ||
2300 | break; | ||
2301 | case TYPE_BIT_STRING: | ||
2302 | len2 = | ||
2303 | asn1_get_length_der (der + counter, len - counter, &len3); | ||
2304 | if (len2 < 0) | ||
2305 | return ASN1_DER_ERROR; | ||
2306 | counter += len3 + len2; | ||
2307 | move = RIGHT; | ||
2308 | break; | ||
2309 | case TYPE_SEQUENCE: | ||
2310 | case TYPE_SET: | ||
2311 | if (move != UP) | ||
2312 | { | ||
2313 | len3 = | ||
2314 | asn1_get_length_der (der + counter, len - counter, &len2); | ||
2315 | if (len3 < -1) | ||
2316 | return ASN1_DER_ERROR; | ||
2317 | counter += len2; | ||
2318 | if (len3 == 0) | ||
2319 | move = RIGHT; | ||
2320 | else | ||
2321 | move = DOWN; | ||
2322 | } | ||
2323 | else | ||
2324 | { | ||
2325 | if (!der[counter] && !der[counter + 1]) /* indefinite length method */ | ||
2326 | counter += 2; | ||
2327 | move = RIGHT; | ||
2328 | } | ||
2329 | break; | ||
2330 | case TYPE_SEQUENCE_OF: | ||
2331 | case TYPE_SET_OF: | ||
2332 | if (move != UP) | ||
2333 | { | ||
2334 | len3 = | ||
2335 | asn1_get_length_der (der + counter, len - counter, &len2); | ||
2336 | if (len3 < -1) | ||
2337 | return ASN1_DER_ERROR; | ||
2338 | counter += len2; | ||
2339 | if ((len3 == -1) && !der[counter] && !der[counter + 1]) | ||
2340 | counter += 2; | ||
2341 | else if (len3) | ||
2342 | { | ||
2343 | p2 = p->down; | ||
2344 | while ((type_field (p2->type) == TYPE_TAG) || | ||
2345 | (type_field (p2->type) == TYPE_SIZE)) | ||
2346 | p2 = p2->right; | ||
2347 | p = p2; | ||
2348 | } | ||
2349 | } | ||
2350 | else | ||
2351 | { | ||
2352 | if (!der[counter] && !der[counter + 1]) /* indefinite length method */ | ||
2353 | counter += 2; | ||
2354 | } | ||
2355 | move = RIGHT; | ||
2356 | break; | ||
2357 | case TYPE_ANY: | ||
2358 | if (asn1_get_tag_der | ||
2359 | (der + counter, len - counter, &class, &len2, | ||
2360 | &tag) != ASN1_SUCCESS) | ||
2361 | return ASN1_DER_ERROR; | ||
2362 | if (counter + len2 > len) | ||
2363 | return ASN1_DER_ERROR; | ||
2364 | |||
2365 | len4 = | ||
2366 | asn1_get_length_der (der + counter + len2, | ||
2367 | len - counter - len2, &len3); | ||
2368 | if (len4 < -1) | ||
2369 | return ASN1_DER_ERROR; | ||
2370 | |||
2371 | if (len4 != -1) | ||
2372 | { | ||
2373 | counter += len2 + len4 + len3; | ||
2374 | } | ||
2375 | else | ||
2376 | { /* indefinite length */ | ||
2377 | /* Check indefinite lenth method in an EXPLICIT TAG */ | ||
2378 | if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80)) | ||
2379 | indefinite = 1; | ||
2380 | else | ||
2381 | indefinite = 0; | ||
2382 | |||
2383 | len2 = len - counter; | ||
2384 | ris = | ||
2385 | _asn1_get_indefinite_length_string (der + counter, &len2); | ||
2386 | if (ris != ASN1_SUCCESS) | ||
2387 | return ris; | ||
2388 | counter += len2; | ||
2389 | |||
2390 | /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with | ||
2391 | an indefinite length method. */ | ||
2392 | if (indefinite) | ||
2393 | { | ||
2394 | if (!der[counter] && !der[counter + 1]) | ||
2395 | counter += 2; | ||
2396 | else | ||
2397 | return ASN1_DER_ERROR; | ||
2398 | } | ||
2399 | } | ||
2400 | move = RIGHT; | ||
2401 | break; | ||
2402 | default: | ||
2403 | move = (move == UP) ? RIGHT : DOWN; | ||
2404 | break; | ||
2405 | } | ||
2406 | } | ||
2407 | |||
2408 | if ((p == node_to_find) && (move == RIGHT)) | ||
2409 | { | ||
2410 | *end = counter - 1; | ||
2411 | return ASN1_SUCCESS; | ||
2412 | } | ||
2413 | |||
2414 | if (p == node && move != DOWN) | ||
2415 | break; | ||
2416 | |||
2417 | if (move == DOWN) | ||
2418 | { | ||
2419 | if (p->down) | ||
2420 | p = p->down; | ||
2421 | else | ||
2422 | move = RIGHT; | ||
2423 | } | ||
2424 | if ((move == RIGHT) && !(p->type & CONST_SET)) | ||
2425 | { | ||
2426 | if (p->right) | ||
2427 | p = p->right; | ||
2428 | else | ||
2429 | move = UP; | ||
2430 | } | ||
2431 | if (move == UP) | ||
2432 | p = _asn1_find_up (p); | ||
2433 | } | ||
2434 | |||
2435 | return ASN1_ELEMENT_NOT_FOUND; | ||
2436 | } | ||
2437 | |||
2438 | |||
2439 | /** | ||
2440 | * asn1_expand_any_defined_by - Expand "ANY DEFINED BY" fields in structure. | ||
2441 | * @definitions: ASN1 definitions | ||
2442 | * @element: pointer to an ASN1 structure | ||
2443 | * | ||
2444 | * Expands every "ANY DEFINED BY" element of a structure created from | ||
2445 | * a DER decoding process (asn1_der_decoding function). The element ANY | ||
2446 | * must be defined by an OBJECT IDENTIFIER. The type used to expand | ||
2447 | * the element ANY is the first one following the definition of | ||
2448 | * the actual value of the OBJECT IDENTIFIER. | ||
2449 | * | ||
2450 | * | ||
2451 | * Returns: | ||
2452 | * | ||
2453 | * ASN1_SUCCESS: Substitution OK. | ||
2454 | * | ||
2455 | * ASN1_ERROR_TYPE_ANY: Some "ANY DEFINED BY" element couldn't be | ||
2456 | * expanded due to a problem in OBJECT_ID -> TYPE association. | ||
2457 | * | ||
2458 | * other errors: Result of der decoding process. | ||
2459 | **/ | ||
2460 | |||
2461 | asn1_retCode | ||
2462 | asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element) | ||
2463 | { | ||
2464 | char definitionsName[MAX_NAME_SIZE], name[2 * MAX_NAME_SIZE + 1], | ||
2465 | value[MAX_NAME_SIZE]; | ||
2466 | asn1_retCode retCode = ASN1_SUCCESS, result; | ||
2467 | int len, len2, len3; | ||
2468 | ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY; | ||
2469 | char errorDescription[MAX_ERROR_DESCRIPTION_SIZE]; | ||
2470 | |||
2471 | if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY)) | ||
2472 | return ASN1_ELEMENT_NOT_FOUND; | ||
2473 | |||
2474 | strcpy (definitionsName, definitions->name); | ||
2475 | strcat (definitionsName, "."); | ||
2476 | |||
2477 | p = *element; | ||
2478 | while (p) | ||
2479 | { | ||
2480 | |||
2481 | switch (type_field (p->type)) | ||
2482 | { | ||
2483 | case TYPE_ANY: | ||
2484 | if ((p->type & CONST_DEFINED_BY) && (p->value)) | ||
2485 | { | ||
2486 | /* search the "DEF_BY" element */ | ||
2487 | p2 = p->down; | ||
2488 | while ((p2) && (type_field (p2->type) != TYPE_CONSTANT)) | ||
2489 | p2 = p2->right; | ||
2490 | |||
2491 | if (!p2) | ||
2492 | { | ||
2493 | retCode = ASN1_ERROR_TYPE_ANY; | ||
2494 | break; | ||
2495 | } | ||
2496 | |||
2497 | p3 = _asn1_find_up (p); | ||
2498 | |||
2499 | if (!p3) | ||
2500 | { | ||
2501 | retCode = ASN1_ERROR_TYPE_ANY; | ||
2502 | break; | ||
2503 | } | ||
2504 | |||
2505 | p3 = p3->down; | ||
2506 | while (p3) | ||
2507 | { | ||
2508 | if ((p3->name) && !(strcmp (p3->name, p2->name))) | ||
2509 | break; | ||
2510 | p3 = p3->right; | ||
2511 | } | ||
2512 | |||
2513 | if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) || | ||
2514 | (p3->value == NULL)) | ||
2515 | { | ||
2516 | |||
2517 | p3 = _asn1_find_up (p); | ||
2518 | p3 = _asn1_find_up (p3); | ||
2519 | |||
2520 | if (!p3) | ||
2521 | { | ||
2522 | retCode = ASN1_ERROR_TYPE_ANY; | ||
2523 | break; | ||
2524 | } | ||
2525 | |||
2526 | p3 = p3->down; | ||
2527 | |||
2528 | while (p3) | ||
2529 | { | ||
2530 | if ((p3->name) && !(strcmp (p3->name, p2->name))) | ||
2531 | break; | ||
2532 | p3 = p3->right; | ||
2533 | } | ||
2534 | |||
2535 | if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) || | ||
2536 | (p3->value == NULL)) | ||
2537 | { | ||
2538 | retCode = ASN1_ERROR_TYPE_ANY; | ||
2539 | break; | ||
2540 | } | ||
2541 | } | ||
2542 | |||
2543 | /* search the OBJECT_ID into definitions */ | ||
2544 | p2 = definitions->down; | ||
2545 | while (p2) | ||
2546 | { | ||
2547 | if ((type_field (p2->type) == TYPE_OBJECT_ID) && | ||
2548 | (p2->type & CONST_ASSIGN)) | ||
2549 | { | ||
2550 | strcpy (name, definitionsName); | ||
2551 | strcat (name, p2->name); | ||
2552 | |||
2553 | len = MAX_NAME_SIZE; | ||
2554 | result = | ||
2555 | asn1_read_value (definitions, name, value, &len); | ||
2556 | |||
2557 | if ((result == ASN1_SUCCESS) | ||
2558 | && (!strcmp (p3->value, value))) | ||
2559 | { | ||
2560 | p2 = p2->right; /* pointer to the structure to | ||
2561 | use for expansion */ | ||
2562 | while ((p2) && (p2->type & CONST_ASSIGN)) | ||
2563 | p2 = p2->right; | ||
2564 | |||
2565 | if (p2) | ||
2566 | { | ||
2567 | strcpy (name, definitionsName); | ||
2568 | strcat (name, p2->name); | ||
2569 | |||
2570 | result = | ||
2571 | asn1_create_element (definitions, name, &aux); | ||
2572 | if (result == ASN1_SUCCESS) | ||
2573 | { | ||
2574 | _asn1_set_name (aux, p->name); | ||
2575 | len2 = | ||
2576 | asn1_get_length_der (p->value, | ||
2577 | p->value_len, &len3); | ||
2578 | if (len2 < 0) | ||
2579 | return ASN1_DER_ERROR; | ||
2580 | |||
2581 | result = | ||
2582 | asn1_der_decoding (&aux, p->value + len3, | ||
2583 | len2, | ||
2584 | errorDescription); | ||
2585 | if (result == ASN1_SUCCESS) | ||
2586 | { | ||
2587 | |||
2588 | _asn1_set_right (aux, p->right); | ||
2589 | _asn1_set_right (p, aux); | ||
2590 | |||
2591 | result = asn1_delete_structure (&p); | ||
2592 | if (result == ASN1_SUCCESS) | ||
2593 | { | ||
2594 | p = aux; | ||
2595 | aux = ASN1_TYPE_EMPTY; | ||
2596 | break; | ||
2597 | } | ||
2598 | else | ||
2599 | { /* error with asn1_delete_structure */ | ||
2600 | asn1_delete_structure (&aux); | ||
2601 | retCode = result; | ||
2602 | break; | ||
2603 | } | ||
2604 | } | ||
2605 | else | ||
2606 | { /* error with asn1_der_decoding */ | ||
2607 | retCode = result; | ||
2608 | break; | ||
2609 | } | ||
2610 | } | ||
2611 | else | ||
2612 | { /* error with asn1_create_element */ | ||
2613 | retCode = result; | ||
2614 | break; | ||
2615 | } | ||
2616 | } | ||
2617 | else | ||
2618 | { /* error with the pointer to the structure to exapand */ | ||
2619 | retCode = ASN1_ERROR_TYPE_ANY; | ||
2620 | break; | ||
2621 | } | ||
2622 | } | ||
2623 | } | ||
2624 | p2 = p2->right; | ||
2625 | } /* end while */ | ||
2626 | |||
2627 | if (!p2) | ||
2628 | { | ||
2629 | retCode = ASN1_ERROR_TYPE_ANY; | ||
2630 | break; | ||
2631 | } | ||
2632 | |||
2633 | } | ||
2634 | break; | ||
2635 | default: | ||
2636 | break; | ||
2637 | } | ||
2638 | |||
2639 | |||
2640 | if (p->down) | ||
2641 | { | ||
2642 | p = p->down; | ||
2643 | } | ||
2644 | else if (p == *element) | ||
2645 | { | ||
2646 | p = NULL; | ||
2647 | break; | ||
2648 | } | ||
2649 | else if (p->right) | ||
2650 | p = p->right; | ||
2651 | else | ||
2652 | { | ||
2653 | while (1) | ||
2654 | { | ||
2655 | p = _asn1_find_up (p); | ||
2656 | if (p == *element) | ||
2657 | { | ||
2658 | p = NULL; | ||
2659 | break; | ||
2660 | } | ||
2661 | if (p->right) | ||
2662 | { | ||
2663 | p = p->right; | ||
2664 | break; | ||
2665 | } | ||
2666 | } | ||
2667 | } | ||
2668 | } | ||
2669 | |||
2670 | return retCode; | ||
2671 | } | ||
2672 | |||
2673 | |||
2674 | |||
2675 | /** | ||
2676 | * asn1_expand_octet_string - Expand "OCTET STRING" fields in structure. | ||
2677 | * @definitions: ASN1 definitions | ||
2678 | * @element: pointer to an ASN1 structure | ||
2679 | * @octetName: name of the OCTECT STRING field to expand. | ||
2680 | * @objectName: name of the OBJECT IDENTIFIER field to use to define | ||
2681 | * the type for expansion. | ||
2682 | * | ||
2683 | * Expands an "OCTET STRING" element of a structure created from a | ||
2684 | * DER decoding process (asn1_der_decoding function). The type used | ||
2685 | * for expansion is the first one following the definition of the | ||
2686 | * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME. | ||
2687 | * | ||
2688 | * Returns: | ||
2689 | * | ||
2690 | * ASN1_SUCCESS: Substitution OK. | ||
2691 | * | ||
2692 | * ASN1_ELEMENT_NOT_FOUND: OBJECTNAME or OCTETNAME are not correct. | ||
2693 | * | ||
2694 | * ASN1_VALUE_NOT_VALID: Wasn't possible to find the type to use | ||
2695 | * for expansion. | ||
2696 | * | ||
2697 | * other errors: result of der decoding process. | ||
2698 | **/ | ||
2699 | asn1_retCode | ||
2700 | asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element, | ||
2701 | const char *octetName, const char *objectName) | ||
2702 | { | ||
2703 | char name[2 * MAX_NAME_SIZE + 1], value[MAX_NAME_SIZE]; | ||
2704 | asn1_retCode retCode = ASN1_SUCCESS, result; | ||
2705 | int len, len2, len3; | ||
2706 | ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY; | ||
2707 | ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY; | ||
2708 | char errorDescription[MAX_ERROR_DESCRIPTION_SIZE]; | ||
2709 | |||
2710 | if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY)) | ||
2711 | return ASN1_ELEMENT_NOT_FOUND; | ||
2712 | |||
2713 | octetNode = asn1_find_node (*element, octetName); | ||
2714 | if (octetNode == ASN1_TYPE_EMPTY) | ||
2715 | return ASN1_ELEMENT_NOT_FOUND; | ||
2716 | if (type_field (octetNode->type) != TYPE_OCTET_STRING) | ||
2717 | return ASN1_ELEMENT_NOT_FOUND; | ||
2718 | if (octetNode->value == NULL) | ||
2719 | return ASN1_VALUE_NOT_FOUND; | ||
2720 | |||
2721 | objectNode = asn1_find_node (*element, objectName); | ||
2722 | if (objectNode == ASN1_TYPE_EMPTY) | ||
2723 | return ASN1_ELEMENT_NOT_FOUND; | ||
2724 | |||
2725 | if (type_field (objectNode->type) != TYPE_OBJECT_ID) | ||
2726 | return ASN1_ELEMENT_NOT_FOUND; | ||
2727 | |||
2728 | if (objectNode->value == NULL) | ||
2729 | return ASN1_VALUE_NOT_FOUND; | ||
2730 | |||
2731 | |||
2732 | /* search the OBJECT_ID into definitions */ | ||
2733 | p2 = definitions->down; | ||
2734 | while (p2) | ||
2735 | { | ||
2736 | if ((type_field (p2->type) == TYPE_OBJECT_ID) && | ||
2737 | (p2->type & CONST_ASSIGN)) | ||
2738 | { | ||
2739 | strcpy (name, definitions->name); | ||
2740 | strcat (name, "."); | ||
2741 | strcat (name, p2->name); | ||
2742 | |||
2743 | len = sizeof (value); | ||
2744 | result = asn1_read_value (definitions, name, value, &len); | ||
2745 | |||
2746 | if ((result == ASN1_SUCCESS) | ||
2747 | && (!strcmp (objectNode->value, value))) | ||
2748 | { | ||
2749 | |||
2750 | p2 = p2->right; /* pointer to the structure to | ||
2751 | use for expansion */ | ||
2752 | while ((p2) && (p2->type & CONST_ASSIGN)) | ||
2753 | p2 = p2->right; | ||
2754 | |||
2755 | if (p2) | ||
2756 | { | ||
2757 | strcpy (name, definitions->name); | ||
2758 | strcat (name, "."); | ||
2759 | strcat (name, p2->name); | ||
2760 | |||
2761 | result = asn1_create_element (definitions, name, &aux); | ||
2762 | if (result == ASN1_SUCCESS) | ||
2763 | { | ||
2764 | _asn1_set_name (aux, octetNode->name); | ||
2765 | len2 = | ||
2766 | asn1_get_length_der (octetNode->value, | ||
2767 | octetNode->value_len, &len3); | ||
2768 | if (len2 < 0) | ||
2769 | return ASN1_DER_ERROR; | ||
2770 | |||
2771 | result = | ||
2772 | asn1_der_decoding (&aux, octetNode->value + len3, | ||
2773 | len2, errorDescription); | ||
2774 | if (result == ASN1_SUCCESS) | ||
2775 | { | ||
2776 | |||
2777 | _asn1_set_right (aux, octetNode->right); | ||
2778 | _asn1_set_right (octetNode, aux); | ||
2779 | |||
2780 | result = asn1_delete_structure (&octetNode); | ||
2781 | if (result == ASN1_SUCCESS) | ||
2782 | { | ||
2783 | aux = ASN1_TYPE_EMPTY; | ||
2784 | break; | ||
2785 | } | ||
2786 | else | ||
2787 | { /* error with asn1_delete_structure */ | ||
2788 | asn1_delete_structure (&aux); | ||
2789 | retCode = result; | ||
2790 | break; | ||
2791 | } | ||
2792 | } | ||
2793 | else | ||
2794 | { /* error with asn1_der_decoding */ | ||
2795 | retCode = result; | ||
2796 | break; | ||
2797 | } | ||
2798 | } | ||
2799 | else | ||
2800 | { /* error with asn1_create_element */ | ||
2801 | retCode = result; | ||
2802 | break; | ||
2803 | } | ||
2804 | } | ||
2805 | else | ||
2806 | { /* error with the pointer to the structure to exapand */ | ||
2807 | retCode = ASN1_VALUE_NOT_VALID; | ||
2808 | break; | ||
2809 | } | ||
2810 | } | ||
2811 | } | ||
2812 | |||
2813 | p2 = p2->right; | ||
2814 | |||
2815 | } | ||
2816 | |||
2817 | if (!p2) | ||
2818 | retCode = ASN1_VALUE_NOT_VALID; | ||
2819 | |||
2820 | return retCode; | ||
2821 | } | ||
diff --git a/src/daemon/https/minitasn1/element.c b/src/daemon/https/minitasn1/element.c new file mode 100644 index 00000000..25b4975a --- /dev/null +++ b/src/daemon/https/minitasn1/element.c | |||
@@ -0,0 +1,1013 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2006 Free Software Foundation | ||
3 | * Copyright (C) 2000, 2001, 2002, 2003 Fabio Fiorina | ||
4 | * | ||
5 | * This file is part of LIBTASN1. | ||
6 | * | ||
7 | * The LIBTASN1 library is free software; you can redistribute it | ||
8 | * and/or modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | */ | ||
22 | |||
23 | /*****************************************************/ | ||
24 | /* File: element.c */ | ||
25 | /* Description: Functions with the read and write */ | ||
26 | /* functions. */ | ||
27 | /*****************************************************/ | ||
28 | |||
29 | |||
30 | #include <int.h> | ||
31 | #include <errors.h> | ||
32 | #include "parser_aux.h" | ||
33 | #include <gstr.h> | ||
34 | #include "structure.h" | ||
35 | |||
36 | void | ||
37 | _asn1_hierarchical_name (node_asn * node, char *name, int name_size) | ||
38 | { | ||
39 | node_asn *p; | ||
40 | char tmp_name[64]; | ||
41 | |||
42 | p = node; | ||
43 | |||
44 | name[0] = 0; | ||
45 | |||
46 | while (p != NULL) | ||
47 | { | ||
48 | if (p->name != NULL) | ||
49 | { | ||
50 | _asn1_str_cpy (tmp_name, sizeof (tmp_name), name), | ||
51 | _asn1_str_cpy (name, name_size, p->name); | ||
52 | _asn1_str_cat (name, name_size, "."); | ||
53 | _asn1_str_cat (name, name_size, tmp_name); | ||
54 | } | ||
55 | p = _asn1_find_up (p); | ||
56 | } | ||
57 | |||
58 | if (name[0] == 0) | ||
59 | _asn1_str_cpy (name, name_size, "ROOT"); | ||
60 | } | ||
61 | |||
62 | |||
63 | /******************************************************************/ | ||
64 | /* Function : _asn1_convert_integer */ | ||
65 | /* Description: converts an integer from a null terminated string */ | ||
66 | /* to der decoding. The convertion from a null */ | ||
67 | /* terminated string to an integer is made with */ | ||
68 | /* the 'strtol' function. */ | ||
69 | /* Parameters: */ | ||
70 | /* value: null terminated string to convert. */ | ||
71 | /* value_out: convertion result (memory must be already */ | ||
72 | /* allocated). */ | ||
73 | /* value_out_size: number of bytes of value_out. */ | ||
74 | /* len: number of significant byte of value_out. */ | ||
75 | /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */ | ||
76 | /******************************************************************/ | ||
77 | asn1_retCode | ||
78 | _asn1_convert_integer (const char *value, unsigned char *value_out, | ||
79 | int value_out_size, int *len) | ||
80 | { | ||
81 | char negative; | ||
82 | unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; | ||
83 | long valtmp; | ||
84 | int k, k2; | ||
85 | |||
86 | valtmp = strtol (value, NULL, 10); | ||
87 | |||
88 | for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) | ||
89 | { | ||
90 | val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF; | ||
91 | } | ||
92 | |||
93 | if (val[0] & 0x80) | ||
94 | negative = 1; | ||
95 | else | ||
96 | negative = 0; | ||
97 | |||
98 | for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++) | ||
99 | { | ||
100 | if (negative && (val[k] != 0xFF)) | ||
101 | break; | ||
102 | else if (!negative && val[k]) | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80))) | ||
107 | k--; | ||
108 | |||
109 | *len = SIZEOF_UNSIGNED_LONG_INT - k; | ||
110 | |||
111 | if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size) | ||
112 | /* VALUE_OUT is too short to contain the value conversion */ | ||
113 | return ASN1_MEM_ERROR; | ||
114 | |||
115 | for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++) | ||
116 | value_out[k2 - k] = val[k2]; | ||
117 | |||
118 | |||
119 | #ifdef LIBTASN1_DEBUG_INTEGER | ||
120 | _libtasn1_log ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len); | ||
121 | for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) | ||
122 | _libtasn1_log (", vOut[%d]=%d", k, value_out[k]); | ||
123 | _libtasn1_log ("\n"); | ||
124 | #endif | ||
125 | |||
126 | |||
127 | return ASN1_SUCCESS; | ||
128 | } | ||
129 | |||
130 | |||
131 | int | ||
132 | _asn1_append_sequence_set (node_asn * node) | ||
133 | { | ||
134 | node_asn *p, *p2; | ||
135 | char temp[10]; | ||
136 | long n; | ||
137 | |||
138 | if (!node || !(node->down)) | ||
139 | return ASN1_GENERIC_ERROR; | ||
140 | |||
141 | p = node->down; | ||
142 | while ((type_field (p->type) == TYPE_TAG) | ||
143 | || (type_field (p->type) == TYPE_SIZE)) | ||
144 | p = p->right; | ||
145 | p2 = _asn1_copy_structure3 (p); | ||
146 | while (p->right) | ||
147 | p = p->right; | ||
148 | _asn1_set_right (p, p2); | ||
149 | |||
150 | if (p->name == NULL) | ||
151 | _asn1_str_cpy (temp, sizeof (temp), "?1"); | ||
152 | else | ||
153 | { | ||
154 | n = strtol (p->name + 1, NULL, 0); | ||
155 | n++; | ||
156 | temp[0] = '?'; | ||
157 | _asn1_ltostr (n, temp + 1); | ||
158 | } | ||
159 | _asn1_set_name (p2, temp); | ||
160 | /* p2->type |= CONST_OPTION; */ | ||
161 | |||
162 | return ASN1_SUCCESS; | ||
163 | } | ||
164 | |||
165 | |||
166 | /** | ||
167 | * asn1_write_value - Set the value of one element inside a structure. | ||
168 | * @node_root: pointer to a structure | ||
169 | * @name: the name of the element inside the structure that you want to set. | ||
170 | * @ivalue: vector used to specify the value to set. If len is >0, | ||
171 | * VALUE must be a two's complement form integer. if len=0 *VALUE | ||
172 | * must be a null terminated string with an integer value. | ||
173 | * @len: number of bytes of *value to use to set the value: | ||
174 | * value[0]..value[len-1] or 0 if value is a null terminated string | ||
175 | * | ||
176 | * Set the value of one element inside a structure. | ||
177 | * | ||
178 | * If an element is OPTIONAL and you want to delete it, you must use | ||
179 | * the value=NULL and len=0. Using "pkix.asn": | ||
180 | * | ||
181 | * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID", | ||
182 | * NULL, 0); | ||
183 | * | ||
184 | * Description for each type: | ||
185 | * | ||
186 | * INTEGER: VALUE must contain a two's complement form integer. | ||
187 | * | ||
188 | * value[0]=0xFF , len=1 -> integer=-1. | ||
189 | * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1. | ||
190 | * value[0]=0x01 , len=1 -> integer= 1. | ||
191 | * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1. | ||
192 | * value="123" , len=0 -> integer= 123. | ||
193 | * | ||
194 | * ENUMERATED: As INTEGER (but only with not negative numbers). | ||
195 | * | ||
196 | * BOOLEAN: VALUE must be the null terminated string "TRUE" or | ||
197 | * "FALSE" and LEN != 0. | ||
198 | * | ||
199 | * value="TRUE" , len=1 -> boolean=TRUE. | ||
200 | * value="FALSE" , len=1 -> boolean=FALSE. | ||
201 | * | ||
202 | * OBJECT IDENTIFIER: VALUE must be a null terminated string with | ||
203 | * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0. | ||
204 | * | ||
205 | * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha. | ||
206 | * | ||
207 | * UTCTime: VALUE must be a null terminated string in one of these | ||
208 | * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ", | ||
209 | * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'", | ||
210 | * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0. | ||
211 | * | ||
212 | * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998 | ||
213 | * at 12h 00m Greenwich Mean Time | ||
214 | * | ||
215 | * GeneralizedTime: VALUE must be in one of this format: | ||
216 | * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ", | ||
217 | * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'", | ||
218 | * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s | ||
219 | * indicates the seconds with any precision like "10.1" or "01.02". | ||
220 | * LEN != 0 | ||
221 | * | ||
222 | * value="2001010112001.12-0700" , len=1 -> time=Jannuary | ||
223 | * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time | ||
224 | * | ||
225 | * OCTET STRING: VALUE contains the octet string and LEN is the | ||
226 | * number of octets. | ||
227 | * | ||
228 | * value="$\backslash$x01$\backslash$x02$\backslash$x03" , | ||
229 | * len=3 -> three bytes octet string | ||
230 | * | ||
231 | * GeneralString: VALUE contains the generalstring and LEN is the | ||
232 | * number of octets. | ||
233 | * | ||
234 | * value="$\backslash$x01$\backslash$x02$\backslash$x03" , | ||
235 | * len=3 -> three bytes generalstring | ||
236 | * | ||
237 | * BIT STRING: VALUE contains the bit string organized by bytes and | ||
238 | * LEN is the number of bits. | ||
239 | * | ||
240 | * value="$\backslash$xCF" , len=6 -> bit string="110011" (six | ||
241 | * bits) | ||
242 | * | ||
243 | * CHOICE: if NAME indicates a choice type, VALUE must specify one of | ||
244 | * the alternatives with a null terminated string. LEN != 0. Using | ||
245 | * "pkix.asn"\: | ||
246 | * | ||
247 | * result=asn1_write_value(cert, | ||
248 | * "certificate1.tbsCertificate.subject", "rdnSequence", | ||
249 | * 1); | ||
250 | * | ||
251 | * ANY: VALUE indicates the der encoding of a structure. LEN != 0. | ||
252 | * | ||
253 | * SEQUENCE OF: VALUE must be the null terminated string "NEW" and | ||
254 | * LEN != 0. With this instruction another element is appended in | ||
255 | * the sequence. The name of this element will be "?1" if it's the | ||
256 | * first one, "?2" for the second and so on. | ||
257 | * | ||
258 | * Using "pkix.asn"\: | ||
259 | * | ||
260 | * result=asn1_write_value(cert, | ||
261 | * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1); | ||
262 | * | ||
263 | * SET OF: the same as SEQUENCE OF. Using "pkix.asn": | ||
264 | * | ||
265 | * result=asn1_write_value(cert, | ||
266 | * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1); | ||
267 | * | ||
268 | * Returns: | ||
269 | * | ||
270 | * ASN1_SUCCESS: Set value OK. | ||
271 | * | ||
272 | * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element. | ||
273 | * | ||
274 | * ASN1_VALUE_NOT_VALID: VALUE has a wrong format. | ||
275 | * | ||
276 | **/ | ||
277 | asn1_retCode | ||
278 | asn1_write_value (ASN1_TYPE node_root, const char *name, | ||
279 | const void *ivalue, int len) | ||
280 | { | ||
281 | node_asn *node, *p, *p2; | ||
282 | unsigned char *temp, *value_temp = NULL, *default_temp = NULL; | ||
283 | int len2, k, k2, negative; | ||
284 | const unsigned char *value = ivalue; | ||
285 | |||
286 | node = asn1_find_node (node_root, name); | ||
287 | if (node == NULL) | ||
288 | return ASN1_ELEMENT_NOT_FOUND; | ||
289 | |||
290 | if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0)) | ||
291 | { | ||
292 | asn1_delete_structure (&node); | ||
293 | return ASN1_SUCCESS; | ||
294 | } | ||
295 | |||
296 | if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL) | ||
297 | && (len == 0)) | ||
298 | { | ||
299 | p = node->down; | ||
300 | while ((type_field (p->type) == TYPE_TAG) | ||
301 | || (type_field (p->type) == TYPE_SIZE)) | ||
302 | p = p->right; | ||
303 | |||
304 | while (p->right) | ||
305 | asn1_delete_structure (&p->right); | ||
306 | |||
307 | return ASN1_SUCCESS; | ||
308 | } | ||
309 | |||
310 | switch (type_field (node->type)) | ||
311 | { | ||
312 | case TYPE_BOOLEAN: | ||
313 | if (!strcmp (value, "TRUE")) | ||
314 | { | ||
315 | if (node->type & CONST_DEFAULT) | ||
316 | { | ||
317 | p = node->down; | ||
318 | while (type_field (p->type) != TYPE_DEFAULT) | ||
319 | p = p->right; | ||
320 | if (p->type & CONST_TRUE) | ||
321 | _asn1_set_value (node, NULL, 0); | ||
322 | else | ||
323 | _asn1_set_value (node, "T", 1); | ||
324 | } | ||
325 | else | ||
326 | _asn1_set_value (node, "T", 1); | ||
327 | } | ||
328 | else if (!strcmp (value, "FALSE")) | ||
329 | { | ||
330 | if (node->type & CONST_DEFAULT) | ||
331 | { | ||
332 | p = node->down; | ||
333 | while (type_field (p->type) != TYPE_DEFAULT) | ||
334 | p = p->right; | ||
335 | if (p->type & CONST_FALSE) | ||
336 | _asn1_set_value (node, NULL, 0); | ||
337 | else | ||
338 | _asn1_set_value (node, "F", 1); | ||
339 | } | ||
340 | else | ||
341 | _asn1_set_value (node, "F", 1); | ||
342 | } | ||
343 | else | ||
344 | return ASN1_VALUE_NOT_VALID; | ||
345 | break; | ||
346 | case TYPE_INTEGER: | ||
347 | case TYPE_ENUMERATED: | ||
348 | if (len == 0) | ||
349 | { | ||
350 | if ((isdigit (value[0])) || (value[0] == '-')) | ||
351 | { | ||
352 | value_temp = | ||
353 | (unsigned char *) _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT); | ||
354 | if (value_temp == NULL) | ||
355 | return ASN1_MEM_ALLOC_ERROR; | ||
356 | |||
357 | _asn1_convert_integer (value, value_temp, | ||
358 | SIZEOF_UNSIGNED_LONG_INT, &len); | ||
359 | } | ||
360 | else | ||
361 | { /* is an identifier like v1 */ | ||
362 | if (!(node->type & CONST_LIST)) | ||
363 | return ASN1_VALUE_NOT_VALID; | ||
364 | p = node->down; | ||
365 | while (p) | ||
366 | { | ||
367 | if (type_field (p->type) == TYPE_CONSTANT) | ||
368 | { | ||
369 | if ((p->name) && (!strcmp (p->name, value))) | ||
370 | { | ||
371 | value_temp = | ||
372 | (unsigned char *) | ||
373 | _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT); | ||
374 | if (value_temp == NULL) | ||
375 | return ASN1_MEM_ALLOC_ERROR; | ||
376 | |||
377 | _asn1_convert_integer (p->value, | ||
378 | value_temp, | ||
379 | SIZEOF_UNSIGNED_LONG_INT, | ||
380 | &len); | ||
381 | break; | ||
382 | } | ||
383 | } | ||
384 | p = p->right; | ||
385 | } | ||
386 | if (p == NULL) | ||
387 | return ASN1_VALUE_NOT_VALID; | ||
388 | } | ||
389 | } | ||
390 | else | ||
391 | { /* len != 0 */ | ||
392 | value_temp = (unsigned char *) _asn1_alloca (len); | ||
393 | if (value_temp == NULL) | ||
394 | return ASN1_MEM_ALLOC_ERROR; | ||
395 | memcpy (value_temp, value, len); | ||
396 | } | ||
397 | |||
398 | |||
399 | if (value_temp[0] & 0x80) | ||
400 | negative = 1; | ||
401 | else | ||
402 | negative = 0; | ||
403 | |||
404 | if (negative && (type_field (node->type) == TYPE_ENUMERATED)) | ||
405 | { | ||
406 | _asn1_afree (value_temp); | ||
407 | return ASN1_VALUE_NOT_VALID; | ||
408 | } | ||
409 | |||
410 | for (k = 0; k < len - 1; k++) | ||
411 | if (negative && (value_temp[k] != 0xFF)) | ||
412 | break; | ||
413 | else if (!negative && value_temp[k]) | ||
414 | break; | ||
415 | |||
416 | if ((negative && !(value_temp[k] & 0x80)) || | ||
417 | (!negative && (value_temp[k] & 0x80))) | ||
418 | k--; | ||
419 | |||
420 | asn1_length_der (len - k, NULL, &len2); | ||
421 | temp = (unsigned char *) _asn1_alloca (len - k + len2); | ||
422 | if (temp == NULL) | ||
423 | return ASN1_MEM_ALLOC_ERROR; | ||
424 | |||
425 | asn1_octet_der (value_temp + k, len - k, temp, &len2); | ||
426 | _asn1_set_value (node, temp, len2); | ||
427 | |||
428 | _asn1_afree (temp); | ||
429 | |||
430 | |||
431 | if (node->type & CONST_DEFAULT) | ||
432 | { | ||
433 | p = node->down; | ||
434 | while (type_field (p->type) != TYPE_DEFAULT) | ||
435 | p = p->right; | ||
436 | if ((isdigit (p->value[0])) || (p->value[0] == '-')) | ||
437 | { | ||
438 | default_temp = | ||
439 | (unsigned char *) _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT); | ||
440 | if (default_temp == NULL) | ||
441 | return ASN1_MEM_ALLOC_ERROR; | ||
442 | |||
443 | _asn1_convert_integer (p->value, default_temp, | ||
444 | SIZEOF_UNSIGNED_LONG_INT, &len2); | ||
445 | } | ||
446 | else | ||
447 | { /* is an identifier like v1 */ | ||
448 | if (!(node->type & CONST_LIST)) | ||
449 | return ASN1_VALUE_NOT_VALID; | ||
450 | p2 = node->down; | ||
451 | while (p2) | ||
452 | { | ||
453 | if (type_field (p2->type) == TYPE_CONSTANT) | ||
454 | { | ||
455 | if ((p2->name) && (!strcmp (p2->name, p->value))) | ||
456 | { | ||
457 | default_temp = | ||
458 | (unsigned char *) | ||
459 | _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT); | ||
460 | if (default_temp == NULL) | ||
461 | return ASN1_MEM_ALLOC_ERROR; | ||
462 | |||
463 | _asn1_convert_integer (p2->value, | ||
464 | default_temp, | ||
465 | SIZEOF_UNSIGNED_LONG_INT, | ||
466 | &len2); | ||
467 | break; | ||
468 | } | ||
469 | } | ||
470 | p2 = p2->right; | ||
471 | } | ||
472 | if (p2 == NULL) | ||
473 | return ASN1_VALUE_NOT_VALID; | ||
474 | } | ||
475 | |||
476 | |||
477 | if ((len - k) == len2) | ||
478 | { | ||
479 | for (k2 = 0; k2 < len2; k2++) | ||
480 | if (value_temp[k + k2] != default_temp[k2]) | ||
481 | { | ||
482 | break; | ||
483 | } | ||
484 | if (k2 == len2) | ||
485 | _asn1_set_value (node, NULL, 0); | ||
486 | } | ||
487 | _asn1_afree (default_temp); | ||
488 | } | ||
489 | _asn1_afree (value_temp); | ||
490 | break; | ||
491 | case TYPE_OBJECT_ID: | ||
492 | for (k = 0; k < strlen (value); k++) | ||
493 | if ((!isdigit (value[k])) && (value[k] != '.') && (value[k] != '+')) | ||
494 | return ASN1_VALUE_NOT_VALID; | ||
495 | if (node->type & CONST_DEFAULT) | ||
496 | { | ||
497 | p = node->down; | ||
498 | while (type_field (p->type) != TYPE_DEFAULT) | ||
499 | p = p->right; | ||
500 | if (!strcmp (value, p->value)) | ||
501 | { | ||
502 | _asn1_set_value (node, NULL, 0); | ||
503 | break; | ||
504 | } | ||
505 | } | ||
506 | _asn1_set_value (node, value, strlen (value) + 1); | ||
507 | break; | ||
508 | case TYPE_TIME: | ||
509 | if (node->type & CONST_UTC) | ||
510 | { | ||
511 | if (strlen (value) < 11) | ||
512 | return ASN1_VALUE_NOT_VALID; | ||
513 | for (k = 0; k < 10; k++) | ||
514 | if (!isdigit (value[k])) | ||
515 | return ASN1_VALUE_NOT_VALID; | ||
516 | switch (strlen (value)) | ||
517 | { | ||
518 | case 11: | ||
519 | if (value[10] != 'Z') | ||
520 | return ASN1_VALUE_NOT_VALID; | ||
521 | break; | ||
522 | case 13: | ||
523 | if ((!isdigit (value[10])) || (!isdigit (value[11])) || | ||
524 | (value[12] != 'Z')) | ||
525 | return ASN1_VALUE_NOT_VALID; | ||
526 | break; | ||
527 | case 15: | ||
528 | if ((value[10] != '+') && (value[10] != '-')) | ||
529 | return ASN1_VALUE_NOT_VALID; | ||
530 | for (k = 11; k < 15; k++) | ||
531 | if (!isdigit (value[k])) | ||
532 | return ASN1_VALUE_NOT_VALID; | ||
533 | break; | ||
534 | case 17: | ||
535 | if ((!isdigit (value[10])) || (!isdigit (value[11]))) | ||
536 | return ASN1_VALUE_NOT_VALID; | ||
537 | if ((value[12] != '+') && (value[12] != '-')) | ||
538 | return ASN1_VALUE_NOT_VALID; | ||
539 | for (k = 13; k < 17; k++) | ||
540 | if (!isdigit (value[k])) | ||
541 | return ASN1_VALUE_NOT_VALID; | ||
542 | break; | ||
543 | default: | ||
544 | return ASN1_VALUE_NOT_FOUND; | ||
545 | } | ||
546 | _asn1_set_value (node, value, strlen (value) + 1); | ||
547 | } | ||
548 | else | ||
549 | { /* GENERALIZED TIME */ | ||
550 | if (value) | ||
551 | _asn1_set_value (node, value, strlen (value) + 1); | ||
552 | } | ||
553 | break; | ||
554 | case TYPE_OCTET_STRING: | ||
555 | if (len == 0) | ||
556 | len = strlen (value); | ||
557 | asn1_length_der (len, NULL, &len2); | ||
558 | temp = (unsigned char *) _asn1_alloca (len + len2); | ||
559 | if (temp == NULL) | ||
560 | return ASN1_MEM_ALLOC_ERROR; | ||
561 | |||
562 | asn1_octet_der (value, len, temp, &len2); | ||
563 | _asn1_set_value (node, temp, len2); | ||
564 | _asn1_afree (temp); | ||
565 | break; | ||
566 | case TYPE_GENERALSTRING: | ||
567 | if (len == 0) | ||
568 | len = strlen (value); | ||
569 | asn1_length_der (len, NULL, &len2); | ||
570 | temp = (unsigned char *) _asn1_alloca (len + len2); | ||
571 | if (temp == NULL) | ||
572 | return ASN1_MEM_ALLOC_ERROR; | ||
573 | |||
574 | asn1_octet_der (value, len, temp, &len2); | ||
575 | _asn1_set_value (node, temp, len2); | ||
576 | _asn1_afree (temp); | ||
577 | break; | ||
578 | case TYPE_BIT_STRING: | ||
579 | if (len == 0) | ||
580 | len = strlen (value); | ||
581 | asn1_length_der ((len >> 3) + 2, NULL, &len2); | ||
582 | temp = (unsigned char *) _asn1_alloca ((len >> 3) + 2 + len2); | ||
583 | if (temp == NULL) | ||
584 | return ASN1_MEM_ALLOC_ERROR; | ||
585 | |||
586 | asn1_bit_der (value, len, temp, &len2); | ||
587 | _asn1_set_value (node, temp, len2); | ||
588 | _asn1_afree (temp); | ||
589 | break; | ||
590 | case TYPE_CHOICE: | ||
591 | p = node->down; | ||
592 | while (p) | ||
593 | { | ||
594 | if (!strcmp (p->name, value)) | ||
595 | { | ||
596 | p2 = node->down; | ||
597 | while (p2) | ||
598 | { | ||
599 | if (p2 != p) | ||
600 | { | ||
601 | asn1_delete_structure (&p2); | ||
602 | p2 = node->down; | ||
603 | } | ||
604 | else | ||
605 | p2 = p2->right; | ||
606 | } | ||
607 | break; | ||
608 | } | ||
609 | p = p->right; | ||
610 | } | ||
611 | if (!p) | ||
612 | return ASN1_ELEMENT_NOT_FOUND; | ||
613 | break; | ||
614 | case TYPE_ANY: | ||
615 | asn1_length_der (len, NULL, &len2); | ||
616 | temp = (unsigned char *) _asn1_alloca (len + len2); | ||
617 | if (temp == NULL) | ||
618 | return ASN1_MEM_ALLOC_ERROR; | ||
619 | |||
620 | asn1_octet_der (value, len, temp, &len2); | ||
621 | _asn1_set_value (node, temp, len2); | ||
622 | _asn1_afree (temp); | ||
623 | break; | ||
624 | case TYPE_SEQUENCE_OF: | ||
625 | case TYPE_SET_OF: | ||
626 | if (strcmp (value, "NEW")) | ||
627 | return ASN1_VALUE_NOT_VALID; | ||
628 | _asn1_append_sequence_set (node); | ||
629 | break; | ||
630 | default: | ||
631 | return ASN1_ELEMENT_NOT_FOUND; | ||
632 | break; | ||
633 | } | ||
634 | |||
635 | return ASN1_SUCCESS; | ||
636 | } | ||
637 | |||
638 | |||
639 | #define PUT_VALUE( ptr, ptr_size, data, data_size) \ | ||
640 | *len = data_size; \ | ||
641 | if (ptr_size < data_size) { \ | ||
642 | return ASN1_MEM_ERROR; \ | ||
643 | } else { \ | ||
644 | memcpy( ptr, data, data_size); \ | ||
645 | } | ||
646 | |||
647 | #define PUT_STR_VALUE( ptr, ptr_size, data) \ | ||
648 | *len = strlen(data) + 1; \ | ||
649 | if (ptr_size < *len) { \ | ||
650 | return ASN1_MEM_ERROR; \ | ||
651 | } else { \ | ||
652 | /* this strcpy is checked */ \ | ||
653 | strcpy(ptr, data); \ | ||
654 | } | ||
655 | |||
656 | #define ADD_STR_VALUE( ptr, ptr_size, data) \ | ||
657 | *len = strlen(data) + 1; \ | ||
658 | if (ptr_size < strlen(ptr)+(*len)) { \ | ||
659 | return ASN1_MEM_ERROR; \ | ||
660 | } else { \ | ||
661 | /* this strcat is checked */ \ | ||
662 | strcat(ptr, data); \ | ||
663 | } | ||
664 | |||
665 | /** | ||
666 | * asn1_read_value - Returns the value of one element inside a structure | ||
667 | * @root: pointer to a structure. | ||
668 | * @name: the name of the element inside a structure that you want to read. | ||
669 | * @ivalue: vector that will contain the element's content, must be a | ||
670 | * pointer to memory cells already allocated. | ||
671 | * @len: number of bytes of *value: value[0]..value[len-1]. Initialy | ||
672 | * holds the sizeof value. | ||
673 | * | ||
674 | * Returns the value of one element inside a structure. | ||
675 | * | ||
676 | * If an element is OPTIONAL and the function "read_value" returns | ||
677 | * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present | ||
678 | * in the der encoding that created the structure. The first element | ||
679 | * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and | ||
680 | * so on. | ||
681 | * | ||
682 | * INTEGER: VALUE will contain a two's complement form integer. | ||
683 | * | ||
684 | * integer=-1 -> value[0]=0xFF , len=1. | ||
685 | * integer=1 -> value[0]=0x01 , len=1. | ||
686 | * | ||
687 | * ENUMERATED: As INTEGER (but only with not negative numbers). | ||
688 | * | ||
689 | * BOOLEAN: VALUE will be the null terminated string "TRUE" or | ||
690 | * "FALSE" and LEN=5 or LEN=6. | ||
691 | * | ||
692 | * OBJECT IDENTIFIER: VALUE will be a null terminated string with | ||
693 | * each number separated by a dot (i.e. "1.2.3.543.1"). | ||
694 | * | ||
695 | * LEN = strlen(VALUE)+1 | ||
696 | * | ||
697 | * UTCTime: VALUE will be a null terminated string in one of these | ||
698 | * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'". | ||
699 | * LEN=strlen(VALUE)+1. | ||
700 | * | ||
701 | * GeneralizedTime: VALUE will be a null terminated string in the | ||
702 | * same format used to set the value. | ||
703 | * | ||
704 | * OCTET STRING: VALUE will contain the octet string and LEN will be | ||
705 | * the number of octets. | ||
706 | * | ||
707 | * GeneralString: VALUE will contain the generalstring and LEN will | ||
708 | * be the number of octets. | ||
709 | * | ||
710 | * BIT STRING: VALUE will contain the bit string organized by bytes | ||
711 | * and LEN will be the number of bits. | ||
712 | * | ||
713 | * CHOICE: If NAME indicates a choice type, VALUE will specify the | ||
714 | * alternative selected. | ||
715 | * | ||
716 | * ANY: If NAME indicates an any type, VALUE will indicate the DER | ||
717 | * encoding of the structure actually used. | ||
718 | * | ||
719 | * Returns: | ||
720 | * | ||
721 | * ASN1_SUCCESS: Set value OK. | ||
722 | * | ||
723 | * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element. | ||
724 | * | ||
725 | * ASN1_VALUE_NOT_FOUND: There isn't any value for the element selected. | ||
726 | * | ||
727 | * ASN1_MEM_ERROR: The value vector isn't big enough to store the result. | ||
728 | * In this case LEN will contain the number of bytes needed. | ||
729 | * | ||
730 | **/ | ||
731 | asn1_retCode | ||
732 | asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len) | ||
733 | { | ||
734 | node_asn *node, *p, *p2; | ||
735 | int len2, len3; | ||
736 | int value_size = *len; | ||
737 | unsigned char *value = ivalue; | ||
738 | |||
739 | node = asn1_find_node (root, name); | ||
740 | if (node == NULL) | ||
741 | return ASN1_ELEMENT_NOT_FOUND; | ||
742 | |||
743 | if ((type_field (node->type) != TYPE_NULL) && | ||
744 | (type_field (node->type) != TYPE_CHOICE) && | ||
745 | !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) && | ||
746 | (node->value == NULL)) | ||
747 | return ASN1_VALUE_NOT_FOUND; | ||
748 | |||
749 | switch (type_field (node->type)) | ||
750 | { | ||
751 | case TYPE_NULL: | ||
752 | PUT_STR_VALUE (value, value_size, "NULL"); | ||
753 | break; | ||
754 | case TYPE_BOOLEAN: | ||
755 | if ((node->type & CONST_DEFAULT) && (node->value == NULL)) | ||
756 | { | ||
757 | p = node->down; | ||
758 | while (type_field (p->type) != TYPE_DEFAULT) | ||
759 | p = p->right; | ||
760 | if (p->type & CONST_TRUE) | ||
761 | { | ||
762 | PUT_STR_VALUE (value, value_size, "TRUE"); | ||
763 | } | ||
764 | else | ||
765 | { | ||
766 | PUT_STR_VALUE (value, value_size, "FALSE"); | ||
767 | } | ||
768 | } | ||
769 | else if (node->value[0] == 'T') | ||
770 | { | ||
771 | PUT_STR_VALUE (value, value_size, "TRUE"); | ||
772 | } | ||
773 | else | ||
774 | { | ||
775 | PUT_STR_VALUE (value, value_size, "FALSE"); | ||
776 | } | ||
777 | break; | ||
778 | case TYPE_INTEGER: | ||
779 | case TYPE_ENUMERATED: | ||
780 | if ((node->type & CONST_DEFAULT) && (node->value == NULL)) | ||
781 | { | ||
782 | p = node->down; | ||
783 | while (type_field (p->type) != TYPE_DEFAULT) | ||
784 | p = p->right; | ||
785 | if ((isdigit (p->value[0])) || (p->value[0] == '-') | ||
786 | || (p->value[0] == '+')) | ||
787 | { | ||
788 | if (_asn1_convert_integer | ||
789 | (p->value, value, value_size, len) != ASN1_SUCCESS) | ||
790 | return ASN1_MEM_ERROR; | ||
791 | } | ||
792 | else | ||
793 | { /* is an identifier like v1 */ | ||
794 | p2 = node->down; | ||
795 | while (p2) | ||
796 | { | ||
797 | if (type_field (p2->type) == TYPE_CONSTANT) | ||
798 | { | ||
799 | if ((p2->name) && (!strcmp (p2->name, p->value))) | ||
800 | { | ||
801 | if (_asn1_convert_integer | ||
802 | (p2->value, value, value_size, | ||
803 | len) != ASN1_SUCCESS) | ||
804 | return ASN1_MEM_ERROR; | ||
805 | break; | ||
806 | } | ||
807 | } | ||
808 | p2 = p2->right; | ||
809 | } | ||
810 | } | ||
811 | } | ||
812 | else | ||
813 | { | ||
814 | len2 = -1; | ||
815 | if (asn1_get_octet_der | ||
816 | (node->value, node->value_len, &len2, value, value_size, | ||
817 | len) != ASN1_SUCCESS) | ||
818 | return ASN1_MEM_ERROR; | ||
819 | } | ||
820 | break; | ||
821 | case TYPE_OBJECT_ID: | ||
822 | if (node->type & CONST_ASSIGN) | ||
823 | { | ||
824 | value[0] = 0; | ||
825 | p = node->down; | ||
826 | while (p) | ||
827 | { | ||
828 | if (type_field (p->type) == TYPE_CONSTANT) | ||
829 | { | ||
830 | ADD_STR_VALUE (value, value_size, p->value); | ||
831 | if (p->right) | ||
832 | { | ||
833 | ADD_STR_VALUE (value, value_size, "."); | ||
834 | } | ||
835 | } | ||
836 | p = p->right; | ||
837 | } | ||
838 | *len = strlen (value) + 1; | ||
839 | } | ||
840 | else if ((node->type & CONST_DEFAULT) && (node->value == NULL)) | ||
841 | { | ||
842 | p = node->down; | ||
843 | while (type_field (p->type) != TYPE_DEFAULT) | ||
844 | p = p->right; | ||
845 | PUT_STR_VALUE (value, value_size, p->value); | ||
846 | } | ||
847 | else | ||
848 | { | ||
849 | PUT_STR_VALUE (value, value_size, node->value); | ||
850 | } | ||
851 | break; | ||
852 | case TYPE_TIME: | ||
853 | PUT_STR_VALUE (value, value_size, node->value); | ||
854 | break; | ||
855 | case TYPE_OCTET_STRING: | ||
856 | len2 = -1; | ||
857 | if (asn1_get_octet_der | ||
858 | (node->value, node->value_len, &len2, value, value_size, | ||
859 | len) != ASN1_SUCCESS) | ||
860 | return ASN1_MEM_ERROR; | ||
861 | break; | ||
862 | case TYPE_GENERALSTRING: | ||
863 | len2 = -1; | ||
864 | if (asn1_get_octet_der | ||
865 | (node->value, node->value_len, &len2, value, value_size, | ||
866 | len) != ASN1_SUCCESS) | ||
867 | return ASN1_MEM_ERROR; | ||
868 | break; | ||
869 | case TYPE_BIT_STRING: | ||
870 | len2 = -1; | ||
871 | if (asn1_get_bit_der | ||
872 | (node->value, node->value_len, &len2, value, value_size, | ||
873 | len) != ASN1_SUCCESS) | ||
874 | return ASN1_MEM_ERROR; | ||
875 | break; | ||
876 | case TYPE_CHOICE: | ||
877 | PUT_STR_VALUE (value, value_size, node->down->name); | ||
878 | break; | ||
879 | case TYPE_ANY: | ||
880 | len3 = -1; | ||
881 | len2 = asn1_get_length_der (node->value, node->value_len, &len3); | ||
882 | if (len2 < 0) | ||
883 | return ASN1_DER_ERROR; | ||
884 | PUT_VALUE (value, value_size, node->value + len3, len2); | ||
885 | break; | ||
886 | default: | ||
887 | return ASN1_ELEMENT_NOT_FOUND; | ||
888 | break; | ||
889 | } | ||
890 | return ASN1_SUCCESS; | ||
891 | } | ||
892 | |||
893 | |||
894 | /** | ||
895 | * asn1_read_tag - Returns the TAG of one element inside a structure | ||
896 | * @root: pointer to a structure | ||
897 | * @name: the name of the element inside a structure. | ||
898 | * @tagValue: variable that will contain the TAG value. | ||
899 | * @classValue: variable that will specify the TAG type. | ||
900 | * | ||
901 | * Returns the TAG and the CLASS of one element inside a structure. | ||
902 | * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION, | ||
903 | * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or | ||
904 | * %ASN1_CLASS_CONTEXT_SPECIFIC. | ||
905 | * | ||
906 | * Returns: | ||
907 | * | ||
908 | * ASN1_SUCCESS: Set value OK. | ||
909 | * | ||
910 | * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element. | ||
911 | * | ||
912 | **/ | ||
913 | asn1_retCode | ||
914 | asn1_read_tag (node_asn * root, const char *name, int *tagValue, | ||
915 | int *classValue) | ||
916 | { | ||
917 | node_asn *node, *p, *pTag; | ||
918 | |||
919 | node = asn1_find_node (root, name); | ||
920 | if (node == NULL) | ||
921 | return ASN1_ELEMENT_NOT_FOUND; | ||
922 | |||
923 | p = node->down; | ||
924 | |||
925 | /* pTag will points to the IMPLICIT TAG */ | ||
926 | pTag = NULL; | ||
927 | if (node->type & CONST_TAG) | ||
928 | { | ||
929 | while (p) | ||
930 | { | ||
931 | if (type_field (p->type) == TYPE_TAG) | ||
932 | { | ||
933 | if ((p->type & CONST_IMPLICIT) && (pTag == NULL)) | ||
934 | pTag = p; | ||
935 | else if (p->type & CONST_EXPLICIT) | ||
936 | pTag = NULL; | ||
937 | } | ||
938 | p = p->right; | ||
939 | } | ||
940 | } | ||
941 | |||
942 | if (pTag) | ||
943 | { | ||
944 | *tagValue = strtoul (pTag->value, NULL, 10); | ||
945 | |||
946 | if (pTag->type & CONST_APPLICATION) | ||
947 | *classValue = ASN1_CLASS_APPLICATION; | ||
948 | else if (pTag->type & CONST_UNIVERSAL) | ||
949 | *classValue = ASN1_CLASS_UNIVERSAL; | ||
950 | else if (pTag->type & CONST_PRIVATE) | ||
951 | *classValue = ASN1_CLASS_PRIVATE; | ||
952 | else | ||
953 | *classValue = ASN1_CLASS_CONTEXT_SPECIFIC; | ||
954 | } | ||
955 | else | ||
956 | { | ||
957 | *classValue = ASN1_CLASS_UNIVERSAL; | ||
958 | |||
959 | switch (type_field (node->type)) | ||
960 | { | ||
961 | case TYPE_NULL: | ||
962 | *tagValue = ASN1_TAG_NULL; | ||
963 | break; | ||
964 | case TYPE_BOOLEAN: | ||
965 | *tagValue = ASN1_TAG_BOOLEAN; | ||
966 | break; | ||
967 | case TYPE_INTEGER: | ||
968 | *tagValue = ASN1_TAG_INTEGER; | ||
969 | break; | ||
970 | case TYPE_ENUMERATED: | ||
971 | *tagValue = ASN1_TAG_ENUMERATED; | ||
972 | break; | ||
973 | case TYPE_OBJECT_ID: | ||
974 | *tagValue = ASN1_TAG_OBJECT_ID; | ||
975 | break; | ||
976 | case TYPE_TIME: | ||
977 | if (node->type & CONST_UTC) | ||
978 | { | ||
979 | *tagValue = ASN1_TAG_UTCTime; | ||
980 | } | ||
981 | else | ||
982 | *tagValue = ASN1_TAG_GENERALIZEDTime; | ||
983 | break; | ||
984 | case TYPE_OCTET_STRING: | ||
985 | *tagValue = ASN1_TAG_OCTET_STRING; | ||
986 | break; | ||
987 | case TYPE_GENERALSTRING: | ||
988 | *tagValue = ASN1_TAG_GENERALSTRING; | ||
989 | break; | ||
990 | case TYPE_BIT_STRING: | ||
991 | *tagValue = ASN1_TAG_BIT_STRING; | ||
992 | break; | ||
993 | case TYPE_SEQUENCE: | ||
994 | case TYPE_SEQUENCE_OF: | ||
995 | *tagValue = ASN1_TAG_SEQUENCE; | ||
996 | break; | ||
997 | case TYPE_SET: | ||
998 | case TYPE_SET_OF: | ||
999 | *tagValue = ASN1_TAG_SET; | ||
1000 | break; | ||
1001 | case TYPE_TAG: | ||
1002 | case TYPE_CHOICE: | ||
1003 | case TYPE_ANY: | ||
1004 | break; | ||
1005 | default: | ||
1006 | break; | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | |||
1011 | return ASN1_SUCCESS; | ||
1012 | |||
1013 | } | ||
diff --git a/src/daemon/https/minitasn1/element.h b/src/daemon/https/minitasn1/element.h new file mode 100644 index 00000000..3db95295 --- /dev/null +++ b/src/daemon/https/minitasn1/element.h | |||
@@ -0,0 +1,13 @@ | |||
1 | |||
2 | #ifndef _ELEMENT_H | ||
3 | #define _ELEMENT_H | ||
4 | |||
5 | |||
6 | asn1_retCode _asn1_append_sequence_set(node_asn *node); | ||
7 | |||
8 | asn1_retCode _asn1_convert_integer(const char *value,unsigned char *value_out, | ||
9 | int value_out_size, int *len); | ||
10 | |||
11 | void _asn1_hierarchical_name(node_asn *node,char *name,int name_size); | ||
12 | |||
13 | #endif | ||
diff --git a/src/daemon/https/minitasn1/errors.c b/src/daemon/https/minitasn1/errors.c new file mode 100644 index 00000000..544b3f01 --- /dev/null +++ b/src/daemon/https/minitasn1/errors.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Free Software Foundation, Inc. | ||
3 | * Copyright (C) 2002, 2005 Fabio Fiorina | ||
4 | * | ||
5 | * This file is part of LIBTASN1. | ||
6 | * | ||
7 | * The LIBTASN1 library is free software; you can redistribute it | ||
8 | * and/or modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | */ | ||
22 | |||
23 | #include <int.h> | ||
24 | #include "errors.h" | ||
25 | #ifdef STDC_HEADERS | ||
26 | # include <stdarg.h> | ||
27 | #endif | ||
28 | |||
29 | |||
30 | #define LIBTASN1_ERROR_ENTRY(name) \ | ||
31 | { #name, name } | ||
32 | |||
33 | struct libtasn1_error_entry | ||
34 | { | ||
35 | const char *name; | ||
36 | int number; | ||
37 | }; | ||
38 | typedef struct libtasn1_error_entry libtasn1_error_entry; | ||
39 | |||
40 | static const libtasn1_error_entry error_algorithms[] = { | ||
41 | LIBTASN1_ERROR_ENTRY (ASN1_SUCCESS), | ||
42 | LIBTASN1_ERROR_ENTRY (ASN1_FILE_NOT_FOUND), | ||
43 | LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_FOUND), | ||
44 | LIBTASN1_ERROR_ENTRY (ASN1_IDENTIFIER_NOT_FOUND), | ||
45 | LIBTASN1_ERROR_ENTRY (ASN1_DER_ERROR), | ||
46 | LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_FOUND), | ||
47 | LIBTASN1_ERROR_ENTRY (ASN1_GENERIC_ERROR), | ||
48 | LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_VALID), | ||
49 | LIBTASN1_ERROR_ENTRY (ASN1_TAG_ERROR), | ||
50 | LIBTASN1_ERROR_ENTRY (ASN1_TAG_IMPLICIT), | ||
51 | LIBTASN1_ERROR_ENTRY (ASN1_ERROR_TYPE_ANY), | ||
52 | LIBTASN1_ERROR_ENTRY (ASN1_SYNTAX_ERROR), | ||
53 | LIBTASN1_ERROR_ENTRY (ASN1_MEM_ERROR), | ||
54 | LIBTASN1_ERROR_ENTRY (ASN1_MEM_ALLOC_ERROR), | ||
55 | LIBTASN1_ERROR_ENTRY (ASN1_DER_OVERFLOW), | ||
56 | LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG), | ||
57 | LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR), | ||
58 | LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY), | ||
59 | {0} | ||
60 | }; | ||
61 | |||
62 | #define LIBTASN1_ERROR_LOOP(b) \ | ||
63 | const libtasn1_error_entry *p; \ | ||
64 | for(p = error_algorithms; p->name != NULL; p++) { b ; } | ||
65 | |||
66 | #define LIBTASN1_ERROR_ALG_LOOP(a) \ | ||
67 | LIBTASN1_ERROR_LOOP( if(p->number == error) { a; break; } ) | ||
68 | |||
69 | |||
70 | |||
71 | /** | ||
72 | * libtasn1_perror - prints a string to stderr with a description of an error | ||
73 | * @error: is an error returned by a libtasn1 function. | ||
74 | * | ||
75 | * This function is like perror(). The only difference is that it | ||
76 | * accepts an error returned by a libtasn1 function. | ||
77 | **/ | ||
78 | void | ||
79 | libtasn1_perror (asn1_retCode error) | ||
80 | { | ||
81 | const char *ret = NULL; | ||
82 | |||
83 | /* avoid prefix */ | ||
84 | LIBTASN1_ERROR_ALG_LOOP (ret = p->name + sizeof ("ASN1_") - 1); | ||
85 | |||
86 | fprintf (stderr, "LIBTASN1 ERROR: %s\n", ret); | ||
87 | |||
88 | } | ||
89 | |||
90 | |||
91 | /** | ||
92 | * libtasn1_strerror - Returns a string with a description of an error | ||
93 | * @error: is an error returned by a libtasn1 function. | ||
94 | * | ||
95 | * This function is similar to strerror(). The only difference is | ||
96 | * that it accepts an error (number) returned by a libtasn1 function. | ||
97 | * | ||
98 | * Returns: Pointer to static zero-terminated string describing error | ||
99 | * code. | ||
100 | **/ | ||
101 | const char * | ||
102 | libtasn1_strerror (asn1_retCode error) | ||
103 | { | ||
104 | const char *ret = NULL; | ||
105 | |||
106 | /* avoid prefix */ | ||
107 | LIBTASN1_ERROR_ALG_LOOP (ret = p->name + sizeof ("ASN1_") - 1); | ||
108 | |||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | /* this function will output a message. | ||
113 | */ | ||
114 | #ifdef LIBTASN1_DEBUG | ||
115 | void | ||
116 | _libtasn1_log (const char *fmt, ...) | ||
117 | { | ||
118 | va_list args; | ||
119 | char str[MAX_LOG_SIZE]; | ||
120 | |||
121 | va_start (args, fmt); | ||
122 | vsprintf (str, fmt, args); /* Flawfinder: ignore */ | ||
123 | va_end (args); | ||
124 | |||
125 | fprintf (stderr, str); | ||
126 | |||
127 | return; | ||
128 | } | ||
129 | #else /* not DEBUG */ | ||
130 | void | ||
131 | _libtasn1_log (const char *fmt, ...) | ||
132 | { | ||
133 | return; | ||
134 | } | ||
135 | #endif /* DEBUG */ | ||
diff --git a/src/daemon/https/minitasn1/errors.h b/src/daemon/https/minitasn1/errors.h new file mode 100644 index 00000000..f8bf2242 --- /dev/null +++ b/src/daemon/https/minitasn1/errors.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2006 Free Software Foundation, Inc. | ||
3 | * Copyright (C) 2002 Fabio Fiorina | ||
4 | * | ||
5 | * This file is part of LIBTASN1. | ||
6 | * | ||
7 | * The LIBTASN1 library is free software; you can redistribute it | ||
8 | * and/or modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | */ | ||
22 | |||
23 | #ifndef ERRORS_H | ||
24 | #define ERRORS_H | ||
25 | |||
26 | #include "int.h" | ||
27 | |||
28 | void _libtasn1_log( const char *fmt, ...); | ||
29 | |||
30 | #endif /* ERRORS_H */ | ||
diff --git a/src/daemon/https/minitasn1/gstr.c b/src/daemon/https/minitasn1/gstr.c new file mode 100644 index 00000000..0430ee1a --- /dev/null +++ b/src/daemon/https/minitasn1/gstr.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Free Software Foundation | ||
3 | * Copyright (C) 2002 Nikos Mavroyanopoulos | ||
4 | * | ||
5 | * This file is part of LIBTASN1. | ||
6 | * | ||
7 | * The LIBTASN1 library is free software; you can redistribute it | ||
8 | * and/or modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | */ | ||
22 | |||
23 | #include <int.h> | ||
24 | |||
25 | /* These function are like strcat, strcpy. They only | ||
26 | * do bounds checking (they shouldn't cause buffer overruns), | ||
27 | * and they always produce null terminated strings. | ||
28 | * | ||
29 | * They should be used only with null terminated strings. | ||
30 | */ | ||
31 | void | ||
32 | _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src) | ||
33 | { | ||
34 | size_t str_size = strlen (src); | ||
35 | size_t dest_size = strlen (dest); | ||
36 | |||
37 | if (dest_tot_size - dest_size > str_size) | ||
38 | { | ||
39 | strcat (dest, src); | ||
40 | } | ||
41 | else | ||
42 | { | ||
43 | if (dest_tot_size - dest_size > 0) | ||
44 | { | ||
45 | strncat (dest, src, (dest_tot_size - dest_size) - 1); | ||
46 | dest[dest_tot_size - 1] = 0; | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | |||
51 | void | ||
52 | _asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src) | ||
53 | { | ||
54 | size_t str_size = strlen (src); | ||
55 | |||
56 | if (dest_tot_size > str_size) | ||
57 | { | ||
58 | strcpy (dest, src); | ||
59 | } | ||
60 | else | ||
61 | { | ||
62 | if (dest_tot_size > 0) | ||
63 | { | ||
64 | strncpy (dest, src, (dest_tot_size) - 1); | ||
65 | dest[dest_tot_size - 1] = 0; | ||
66 | } | ||
67 | } | ||
68 | } | ||
diff --git a/src/daemon/https/minitasn1/gstr.h b/src/daemon/https/minitasn1/gstr.h new file mode 100644 index 00000000..5508d26e --- /dev/null +++ b/src/daemon/https/minitasn1/gstr.h | |||
@@ -0,0 +1,5 @@ | |||
1 | void _asn1_str_cpy( char* dest, size_t dest_tot_size, const char* src); | ||
2 | void _asn1_str_cat( char* dest, size_t dest_tot_size, const char* src); | ||
3 | |||
4 | #define Estrcpy(x,y) _asn1_str_cpy(x,MAX_ERROR_DESCRIPTION_SIZE,y) | ||
5 | #define Estrcat(x,y) _asn1_str_cat(x,MAX_ERROR_DESCRIPTION_SIZE,y) | ||
diff --git a/src/daemon/https/minitasn1/int.h b/src/daemon/https/minitasn1/int.h new file mode 100644 index 00000000..d9d18c77 --- /dev/null +++ b/src/daemon/https/minitasn1/int.h | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2006 Free Software Foundation, Inc. | ||
3 | * Copyright (C) 2002 Fabio Fiorina | ||
4 | * | ||
5 | * This file is part of LIBTASN1. | ||
6 | * | ||
7 | * The LIBTASN1 library is free software; you can redistribute it | ||
8 | * and/or modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | */ | ||
22 | |||
23 | #ifndef INT_H | ||
24 | #define INT_H | ||
25 | |||
26 | #include <libtasn1.h> | ||
27 | #include <defines.h> | ||
28 | |||
29 | /* | ||
30 | #define LIBTASN1_DEBUG | ||
31 | #define LIBTASN1_DEBUG_PARSER | ||
32 | #define LIBTASN1_DEBUG_INTEGER | ||
33 | */ | ||
34 | |||
35 | #include <mem.h> | ||
36 | |||
37 | #define MAX_LOG_SIZE 1024 /* maximum number of characters of a log message */ | ||
38 | |||
39 | /* Define used for visiting trees. */ | ||
40 | #define UP 1 | ||
41 | #define RIGHT 2 | ||
42 | #define DOWN 3 | ||
43 | |||
44 | /****************************************/ | ||
45 | /* Returns the first 8 bits. */ | ||
46 | /* Used with the field type of node_asn */ | ||
47 | /****************************************/ | ||
48 | #define type_field(x) (x&0xFF) | ||
49 | |||
50 | /* List of constants for field type of typedef node_asn */ | ||
51 | #define TYPE_CONSTANT 1 | ||
52 | #define TYPE_IDENTIFIER 2 | ||
53 | #define TYPE_INTEGER 3 | ||
54 | #define TYPE_BOOLEAN 4 | ||
55 | #define TYPE_SEQUENCE 5 | ||
56 | #define TYPE_BIT_STRING 6 | ||
57 | #define TYPE_OCTET_STRING 7 | ||
58 | #define TYPE_TAG 8 | ||
59 | #define TYPE_DEFAULT 9 | ||
60 | #define TYPE_SIZE 10 | ||
61 | #define TYPE_SEQUENCE_OF 11 | ||
62 | #define TYPE_OBJECT_ID 12 | ||
63 | #define TYPE_ANY 13 | ||
64 | #define TYPE_SET 14 | ||
65 | #define TYPE_SET_OF 15 | ||
66 | #define TYPE_DEFINITIONS 16 | ||
67 | #define TYPE_TIME 17 | ||
68 | #define TYPE_CHOICE 18 | ||
69 | #define TYPE_IMPORTS 19 | ||
70 | #define TYPE_NULL 20 | ||
71 | #define TYPE_ENUMERATED 21 | ||
72 | #define TYPE_GENERALSTRING 27 | ||
73 | |||
74 | |||
75 | /***********************************************************************/ | ||
76 | /* List of constants to better specify the type of typedef node_asn. */ | ||
77 | /***********************************************************************/ | ||
78 | /* Used with TYPE_TAG */ | ||
79 | #define CONST_UNIVERSAL (1<<8) | ||
80 | #define CONST_PRIVATE (1<<9) | ||
81 | #define CONST_APPLICATION (1<<10) | ||
82 | #define CONST_EXPLICIT (1<<11) | ||
83 | #define CONST_IMPLICIT (1<<12) | ||
84 | |||
85 | #define CONST_TAG (1<<13) /* Used in ASN.1 assignement */ | ||
86 | #define CONST_OPTION (1<<14) | ||
87 | #define CONST_DEFAULT (1<<15) | ||
88 | #define CONST_TRUE (1<<16) | ||
89 | #define CONST_FALSE (1<<17) | ||
90 | |||
91 | #define CONST_LIST (1<<18) /* Used with TYPE_INTEGER and TYPE_BIT_STRING */ | ||
92 | #define CONST_MIN_MAX (1<<19) | ||
93 | |||
94 | #define CONST_1_PARAM (1<<20) | ||
95 | |||
96 | #define CONST_SIZE (1<<21) | ||
97 | |||
98 | #define CONST_DEFINED_BY (1<<22) | ||
99 | |||
100 | #define CONST_GENERALIZED (1<<23) | ||
101 | #define CONST_UTC (1<<24) | ||
102 | |||
103 | /* #define CONST_IMPORTS (1<<25) */ | ||
104 | |||
105 | #define CONST_NOT_USED (1<<26) | ||
106 | #define CONST_SET (1<<27) | ||
107 | #define CONST_ASSIGN (1<<28) | ||
108 | |||
109 | #define CONST_DOWN (1<<29) | ||
110 | #define CONST_RIGHT (1<<30) | ||
111 | |||
112 | #endif /* INT_H */ | ||
diff --git a/src/daemon/https/minitasn1/libtasn1.h b/src/daemon/https/minitasn1/libtasn1.h new file mode 100644 index 00000000..0b48c305 --- /dev/null +++ b/src/daemon/https/minitasn1/libtasn1.h | |||
@@ -0,0 +1,246 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2005, 2006 Free Software Foundation | ||
3 | * Copyright (C) 2002 Fabio Fiorina | ||
4 | * | ||
5 | * This file is part of LIBTASN1. | ||
6 | * | ||
7 | * LIBTASN1 is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU Lesser General Public License as | ||
9 | * published by the Free Software Foundation; either version 2.1 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | * | ||
12 | * LIBTASN1 is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with LIBTASN1; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef LIBTASN1_H | ||
25 | # define LIBTASN1_H | ||
26 | |||
27 | #include <stdio.h> /* for FILE* */ | ||
28 | |||
29 | #ifdef __cplusplus | ||
30 | extern "C" | ||
31 | { | ||
32 | #endif | ||
33 | |||
34 | #define LIBTASN1_VERSION "1.2" | ||
35 | |||
36 | #include <sys/types.h> | ||
37 | #include <time.h> | ||
38 | |||
39 | #define MAX_NAME_SIZE 128 /* maximum number of characters of a name */ | ||
40 | /* inside a file with ASN1 definitons */ | ||
41 | #define MAX_ERROR_DESCRIPTION_SIZE 128 /* maximum number of characters */ | ||
42 | /* of a description message */ | ||
43 | /* (null character included) */ | ||
44 | |||
45 | |||
46 | typedef int asn1_retCode; /* type returned by libtasn1 functions */ | ||
47 | |||
48 | /*****************************************/ | ||
49 | /* Errors returned by libtasn1 functions */ | ||
50 | /*****************************************/ | ||
51 | #define ASN1_SUCCESS 0 | ||
52 | #define ASN1_FILE_NOT_FOUND 1 | ||
53 | #define ASN1_ELEMENT_NOT_FOUND 2 | ||
54 | #define ASN1_IDENTIFIER_NOT_FOUND 3 | ||
55 | #define ASN1_DER_ERROR 4 | ||
56 | #define ASN1_VALUE_NOT_FOUND 5 | ||
57 | #define ASN1_GENERIC_ERROR 6 | ||
58 | #define ASN1_VALUE_NOT_VALID 7 | ||
59 | #define ASN1_TAG_ERROR 8 | ||
60 | #define ASN1_TAG_IMPLICIT 9 | ||
61 | #define ASN1_ERROR_TYPE_ANY 10 | ||
62 | #define ASN1_SYNTAX_ERROR 11 | ||
63 | #define ASN1_MEM_ERROR 12 | ||
64 | #define ASN1_MEM_ALLOC_ERROR 13 | ||
65 | #define ASN1_DER_OVERFLOW 14 | ||
66 | #define ASN1_NAME_TOO_LONG 15 | ||
67 | #define ASN1_ARRAY_ERROR 16 | ||
68 | #define ASN1_ELEMENT_NOT_EMPTY 17 | ||
69 | |||
70 | /*************************************/ | ||
71 | /* Constants used in asn1_visit_tree */ | ||
72 | /*************************************/ | ||
73 | #define ASN1_PRINT_NAME 1 | ||
74 | #define ASN1_PRINT_NAME_TYPE 2 | ||
75 | #define ASN1_PRINT_NAME_TYPE_VALUE 3 | ||
76 | #define ASN1_PRINT_ALL 4 | ||
77 | |||
78 | /*****************************************/ | ||
79 | /* Constants returned by asn1_read_tag */ | ||
80 | /*****************************************/ | ||
81 | #define ASN1_CLASS_UNIVERSAL 0x00 /* old: 1 */ | ||
82 | #define ASN1_CLASS_APPLICATION 0x40 /* old: 2 */ | ||
83 | #define ASN1_CLASS_CONTEXT_SPECIFIC 0x80 /* old: 3 */ | ||
84 | #define ASN1_CLASS_PRIVATE 0xC0 /* old: 4 */ | ||
85 | #define ASN1_CLASS_STRUCTURED 0x20 | ||
86 | |||
87 | /*****************************************/ | ||
88 | /* Constants returned by asn1_read_tag */ | ||
89 | /*****************************************/ | ||
90 | #define ASN1_TAG_BOOLEAN 0x01 | ||
91 | #define ASN1_TAG_INTEGER 0x02 | ||
92 | #define ASN1_TAG_SEQUENCE 0x10 | ||
93 | #define ASN1_TAG_SET 0x11 | ||
94 | #define ASN1_TAG_OCTET_STRING 0x04 | ||
95 | #define ASN1_TAG_BIT_STRING 0x03 | ||
96 | #define ASN1_TAG_UTCTime 0x17 | ||
97 | #define ASN1_TAG_GENERALIZEDTime 0x18 | ||
98 | #define ASN1_TAG_OBJECT_ID 0x06 | ||
99 | #define ASN1_TAG_ENUMERATED 0x0A | ||
100 | #define ASN1_TAG_NULL 0x05 | ||
101 | #define ASN1_TAG_GENERALSTRING 0x1B | ||
102 | |||
103 | /******************************************************/ | ||
104 | /* Structure definition used for the node of the tree */ | ||
105 | /* that represent an ASN.1 DEFINITION. */ | ||
106 | /******************************************************/ | ||
107 | |||
108 | struct node_asn_struct | ||
109 | { | ||
110 | char *name; /* Node name */ | ||
111 | unsigned int type; /* Node type */ | ||
112 | unsigned char *value; /* Node value */ | ||
113 | int value_len; | ||
114 | struct node_asn_struct *down; /* Pointer to the son node */ | ||
115 | struct node_asn_struct *right; /* Pointer to the brother node */ | ||
116 | struct node_asn_struct *left; /* Pointer to the next list element */ | ||
117 | }; | ||
118 | |||
119 | typedef struct node_asn_struct node_asn; | ||
120 | |||
121 | typedef node_asn *ASN1_TYPE; | ||
122 | |||
123 | #define ASN1_TYPE_EMPTY NULL | ||
124 | |||
125 | struct static_struct_asn | ||
126 | { | ||
127 | const char *name; /* Node name */ | ||
128 | unsigned int type; /* Node type */ | ||
129 | const void *value; /* Node value */ | ||
130 | }; | ||
131 | |||
132 | typedef struct static_struct_asn ASN1_ARRAY_TYPE; | ||
133 | |||
134 | |||
135 | |||
136 | /***********************************/ | ||
137 | /* Functions definitions */ | ||
138 | /***********************************/ | ||
139 | |||
140 | asn1_retCode asn1_parser2tree (const char *file_name, | ||
141 | ASN1_TYPE * definitions, | ||
142 | char *errorDescription); | ||
143 | |||
144 | asn1_retCode asn1_parser2array (const char *inputFileName, | ||
145 | const char *outputFileName, | ||
146 | const char *vectorName, | ||
147 | char *errorDescription); | ||
148 | |||
149 | asn1_retCode asn1_array2tree (const ASN1_ARRAY_TYPE * array, | ||
150 | ASN1_TYPE * definitions, | ||
151 | char *errorDescription); | ||
152 | |||
153 | void asn1_print_structure (FILE *out, ASN1_TYPE structure, const char *name, | ||
154 | int mode); | ||
155 | |||
156 | asn1_retCode asn1_create_element (ASN1_TYPE definitions, | ||
157 | const char *source_name, | ||
158 | ASN1_TYPE * element); | ||
159 | |||
160 | asn1_retCode asn1_delete_structure (ASN1_TYPE * structure); | ||
161 | |||
162 | asn1_retCode asn1_delete_element (ASN1_TYPE structure, | ||
163 | const char *element_name); | ||
164 | |||
165 | asn1_retCode asn1_write_value (ASN1_TYPE node_root, const char *name, | ||
166 | const void *ivalue, int len); | ||
167 | |||
168 | asn1_retCode asn1_read_value (ASN1_TYPE root, const char *name, | ||
169 | void *ivalue, int *len); | ||
170 | |||
171 | asn1_retCode asn1_number_of_elements (ASN1_TYPE element, const char *name, | ||
172 | int *num); | ||
173 | |||
174 | asn1_retCode asn1_der_coding (ASN1_TYPE element, const char *name, | ||
175 | void *ider, int *len, char *ErrorDescription); | ||
176 | |||
177 | asn1_retCode asn1_der_decoding (ASN1_TYPE * element, const void *ider, | ||
178 | int len, char *errorDescription); | ||
179 | |||
180 | asn1_retCode asn1_der_decoding_element (ASN1_TYPE * structure, | ||
181 | const char *elementName, | ||
182 | const void *ider, int len, | ||
183 | char *errorDescription); | ||
184 | |||
185 | asn1_retCode asn1_der_decoding_startEnd (ASN1_TYPE element, | ||
186 | const void *ider, int len, | ||
187 | const char *name_element, | ||
188 | int *start, int *end); | ||
189 | |||
190 | asn1_retCode asn1_expand_any_defined_by (ASN1_TYPE definitions, | ||
191 | ASN1_TYPE * element); | ||
192 | |||
193 | asn1_retCode asn1_expand_octet_string (ASN1_TYPE definitions, | ||
194 | ASN1_TYPE * element, | ||
195 | const char *octetName, | ||
196 | const char *objectName); | ||
197 | |||
198 | asn1_retCode asn1_read_tag (node_asn * root, const char *name, | ||
199 | int *tagValue, int *classValue); | ||
200 | |||
201 | const char *asn1_find_structure_from_oid (ASN1_TYPE definitions, | ||
202 | const char *oidValue); | ||
203 | |||
204 | const char *asn1_check_version (const char *req_version); | ||
205 | |||
206 | const char *libtasn1_strerror (asn1_retCode error); | ||
207 | |||
208 | void libtasn1_perror (asn1_retCode error); | ||
209 | |||
210 | /* DER utility functions. */ | ||
211 | |||
212 | int asn1_get_tag_der (const unsigned char *der, int der_len, | ||
213 | unsigned char *cls, int *len, unsigned long *tag); | ||
214 | |||
215 | void asn1_octet_der (const unsigned char *str, int str_len, | ||
216 | unsigned char *der, int *der_len); | ||
217 | |||
218 | asn1_retCode asn1_get_octet_der (const unsigned char *der, int der_len, | ||
219 | int *ret_len, unsigned char *str, | ||
220 | int str_size, int *str_len); | ||
221 | |||
222 | void asn1_bit_der (const unsigned char *str, int bit_len, | ||
223 | unsigned char *der, int *der_len); | ||
224 | |||
225 | asn1_retCode asn1_get_bit_der (const unsigned char *der, int der_len, | ||
226 | int *ret_len, unsigned char *str, | ||
227 | int str_size, int *bit_len); | ||
228 | |||
229 | signed long asn1_get_length_der (const unsigned char *der, int der_len, | ||
230 | int *len); | ||
231 | |||
232 | void asn1_length_der (unsigned long int len, unsigned char *ans, | ||
233 | int *ans_len); | ||
234 | |||
235 | /* Other utility functions. */ | ||
236 | |||
237 | ASN1_TYPE asn1_find_node (ASN1_TYPE pointer, const char *name); | ||
238 | |||
239 | asn1_retCode asn1_copy_node (ASN1_TYPE dst, const char *dst_name, | ||
240 | ASN1_TYPE src, const char *src_name); | ||
241 | |||
242 | #ifdef __cplusplus | ||
243 | } | ||
244 | #endif | ||
245 | |||
246 | #endif /* LIBTASN1_H */ | ||
diff --git a/src/daemon/https/minitasn1/mem.h b/src/daemon/https/minitasn1/mem.h new file mode 100644 index 00000000..267f62f3 --- /dev/null +++ b/src/daemon/https/minitasn1/mem.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #ifndef MEM_H | ||
2 | # define MEM_H | ||
3 | |||
4 | /* Use _asn1_afree() when calling alloca, or | ||
5 | * memory leaks may occur in systems which do not | ||
6 | * support alloca. | ||
7 | */ | ||
8 | #ifdef HAVE_ALLOCA | ||
9 | # ifdef HAVE_ALLOCA_H | ||
10 | # include <alloca.h> | ||
11 | # endif | ||
12 | # define _asn1_alloca alloca | ||
13 | # define _asn1_afree(x) | ||
14 | #else | ||
15 | # define _asn1_alloca _asn1_malloc | ||
16 | # define _asn1_afree _asn1_free | ||
17 | #endif /* HAVE_ALLOCA */ | ||
18 | |||
19 | #define _asn1_malloc malloc | ||
20 | #define _asn1_free free | ||
21 | #define _asn1_calloc calloc | ||
22 | #define _asn1_realloc realloc | ||
23 | #define _asn1_strdup strdup | ||
24 | |||
25 | #endif /* MEM_H */ | ||
26 | |||
27 | |||
diff --git a/src/daemon/https/minitasn1/parser_aux.c b/src/daemon/https/minitasn1/parser_aux.c new file mode 100644 index 00000000..7d975b3d --- /dev/null +++ b/src/daemon/https/minitasn1/parser_aux.c | |||
@@ -0,0 +1,1072 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2006, 2007 Free Software Foundation | ||
3 | * Copyright (C) 2000,2001 Fabio Fiorina | ||
4 | * | ||
5 | * This file is part of LIBTASN1. | ||
6 | * | ||
7 | * The LIBTASN1 library is free software; you can redistribute it | ||
8 | * and/or modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | */ | ||
22 | |||
23 | #include <int.h> | ||
24 | #include <errors.h> | ||
25 | #include "parser_aux.h" | ||
26 | #include "gstr.h" | ||
27 | #include "structure.h" | ||
28 | #include "element.h" | ||
29 | |||
30 | char _asn1_identifierMissing[MAX_NAME_SIZE + 1]; /* identifier name not found */ | ||
31 | |||
32 | /***********************************************/ | ||
33 | /* Type: list_type */ | ||
34 | /* Description: type used in the list during */ | ||
35 | /* the structure creation. */ | ||
36 | /***********************************************/ | ||
37 | typedef struct list_struct | ||
38 | { | ||
39 | node_asn *node; | ||
40 | struct list_struct *next; | ||
41 | } list_type; | ||
42 | |||
43 | |||
44 | /* Pointer to the first element of the list */ | ||
45 | list_type *firstElement = NULL; | ||
46 | |||
47 | /******************************************************/ | ||
48 | /* Function : _asn1_add_node */ | ||
49 | /* Description: creates a new NODE_ASN element and */ | ||
50 | /* puts it in the list pointed by firstElement. */ | ||
51 | /* Parameters: */ | ||
52 | /* type: type of the new element (see TYPE_ */ | ||
53 | /* and CONST_ constants). */ | ||
54 | /* Return: pointer to the new element. */ | ||
55 | /******************************************************/ | ||
56 | node_asn * | ||
57 | _asn1_add_node (unsigned int type) | ||
58 | { | ||
59 | list_type *listElement; | ||
60 | node_asn *punt; | ||
61 | |||
62 | punt = (node_asn *) _asn1_calloc (1, sizeof (node_asn)); | ||
63 | if (punt == NULL) | ||
64 | return NULL; | ||
65 | |||
66 | listElement = (list_type *) _asn1_malloc (sizeof (list_type)); | ||
67 | if (listElement == NULL) | ||
68 | { | ||
69 | _asn1_free (punt); | ||
70 | return NULL; | ||
71 | } | ||
72 | |||
73 | listElement->node = punt; | ||
74 | listElement->next = firstElement; | ||
75 | firstElement = listElement; | ||
76 | |||
77 | punt->type = type; | ||
78 | |||
79 | return punt; | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * asn1_find_node: | ||
84 | * @pointer: NODE_ASN element pointer. | ||
85 | * @name: null terminated string with the element's name to find. | ||
86 | * | ||
87 | * Searches for an element called NAME starting from POINTER. The | ||
88 | * name is composed by differents identifiers separated by dots. When | ||
89 | * *POINTER has a name, the first identifier must be the name of | ||
90 | * *POINTER, otherwise it must be the name of one child of *POINTER. | ||
91 | * | ||
92 | * Return value: the searching result. NULL if not found. | ||
93 | **/ | ||
94 | ASN1_TYPE | ||
95 | asn1_find_node (ASN1_TYPE pointer, const char *name) | ||
96 | { | ||
97 | node_asn *p; | ||
98 | char *n_end, n[MAX_NAME_SIZE + 1]; | ||
99 | const char *n_start; | ||
100 | |||
101 | if (pointer == NULL) | ||
102 | return NULL; | ||
103 | |||
104 | if (name == NULL) | ||
105 | return NULL; | ||
106 | |||
107 | p = pointer; | ||
108 | n_start = name; | ||
109 | |||
110 | if (p->name != NULL) | ||
111 | { /* has *pointer got a name ? */ | ||
112 | n_end = strchr (n_start, '.'); /* search the first dot */ | ||
113 | if (n_end) | ||
114 | { | ||
115 | memcpy (n, n_start, n_end - n_start); | ||
116 | n[n_end - n_start] = 0; | ||
117 | n_start = n_end; | ||
118 | n_start++; | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | _asn1_str_cpy (n, sizeof (n), n_start); | ||
123 | n_start = NULL; | ||
124 | } | ||
125 | |||
126 | while (p) | ||
127 | { | ||
128 | if ((p->name) && (!strcmp (p->name, n))) | ||
129 | break; | ||
130 | else | ||
131 | p = p->right; | ||
132 | } /* while */ | ||
133 | |||
134 | if (p == NULL) | ||
135 | return NULL; | ||
136 | } | ||
137 | else | ||
138 | { /* *pointer doesn't have a name */ | ||
139 | if (n_start[0] == 0) | ||
140 | return p; | ||
141 | } | ||
142 | |||
143 | while (n_start) | ||
144 | { /* Has the end of NAME been reached? */ | ||
145 | n_end = strchr (n_start, '.'); /* search the next dot */ | ||
146 | if (n_end) | ||
147 | { | ||
148 | memcpy (n, n_start, n_end - n_start); | ||
149 | n[n_end - n_start] = 0; | ||
150 | n_start = n_end; | ||
151 | n_start++; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | _asn1_str_cpy (n, sizeof (n), n_start); | ||
156 | n_start = NULL; | ||
157 | } | ||
158 | |||
159 | if (p->down == NULL) | ||
160 | return NULL; | ||
161 | |||
162 | p = p->down; | ||
163 | |||
164 | /* The identifier "?LAST" indicates the last element | ||
165 | in the right chain. */ | ||
166 | if (!strcmp (n, "?LAST")) | ||
167 | { | ||
168 | if (p == NULL) | ||
169 | return NULL; | ||
170 | while (p->right) | ||
171 | p = p->right; | ||
172 | } | ||
173 | else | ||
174 | { /* no "?LAST" */ | ||
175 | while (p) | ||
176 | { | ||
177 | if ((p->name) && (!strcmp (p->name, n))) | ||
178 | break; | ||
179 | else | ||
180 | p = p->right; | ||
181 | } | ||
182 | if (p == NULL) | ||
183 | return NULL; | ||
184 | } | ||
185 | } /* while */ | ||
186 | |||
187 | return p; | ||
188 | } | ||
189 | |||
190 | |||
191 | /******************************************************************/ | ||
192 | /* Function : _asn1_set_value */ | ||
193 | /* Description: sets the field VALUE in a NODE_ASN element. The */ | ||
194 | /* previous value (if exist) will be lost */ | ||
195 | /* Parameters: */ | ||
196 | /* node: element pointer. */ | ||
197 | /* value: pointer to the value that you want to set. */ | ||
198 | /* len: character number of value. */ | ||
199 | /* Return: pointer to the NODE_ASN element. */ | ||
200 | /******************************************************************/ | ||
201 | node_asn * | ||
202 | _asn1_set_value (node_asn * node, const void *_value, unsigned int len) | ||
203 | { | ||
204 | const unsigned char *value = _value; | ||
205 | |||
206 | if (node == NULL) | ||
207 | return node; | ||
208 | if (node->value) | ||
209 | { | ||
210 | _asn1_free (node->value); | ||
211 | node->value = NULL; | ||
212 | node->value_len = 0; | ||
213 | } | ||
214 | if (!len) | ||
215 | return node; | ||
216 | node->value = (unsigned char *) _asn1_malloc (len); | ||
217 | if (node->value == NULL) | ||
218 | return NULL; | ||
219 | node->value_len = len; | ||
220 | |||
221 | memcpy (node->value, value, len); | ||
222 | return node; | ||
223 | } | ||
224 | |||
225 | /******************************************************************/ | ||
226 | /* Function : _asn1_set_name */ | ||
227 | /* Description: sets the field NAME in a NODE_ASN element. The */ | ||
228 | /* previous value (if exist) will be lost */ | ||
229 | /* Parameters: */ | ||
230 | /* node: element pointer. */ | ||
231 | /* name: a null terminated string with the name that you want */ | ||
232 | /* to set. */ | ||
233 | /* Return: pointer to the NODE_ASN element. */ | ||
234 | /******************************************************************/ | ||
235 | node_asn * | ||
236 | _asn1_set_name (node_asn * node, const char *name) | ||
237 | { | ||
238 | if (node == NULL) | ||
239 | return node; | ||
240 | |||
241 | if (node->name) | ||
242 | { | ||
243 | _asn1_free (node->name); | ||
244 | node->name = NULL; | ||
245 | } | ||
246 | |||
247 | if (name == NULL) | ||
248 | return node; | ||
249 | |||
250 | if (strlen (name)) | ||
251 | { | ||
252 | node->name = (char *) _asn1_strdup (name); | ||
253 | if (node->name == NULL) | ||
254 | return NULL; | ||
255 | } | ||
256 | else | ||
257 | node->name = NULL; | ||
258 | return node; | ||
259 | } | ||
260 | |||
261 | /******************************************************************/ | ||
262 | /* Function : _asn1_set_right */ | ||
263 | /* Description: sets the field RIGHT in a NODE_ASN element. */ | ||
264 | /* Parameters: */ | ||
265 | /* node: element pointer. */ | ||
266 | /* right: pointer to a NODE_ASN element that you want be pointed*/ | ||
267 | /* by NODE. */ | ||
268 | /* Return: pointer to *NODE. */ | ||
269 | /******************************************************************/ | ||
270 | node_asn * | ||
271 | _asn1_set_right (node_asn * node, node_asn * right) | ||
272 | { | ||
273 | if (node == NULL) | ||
274 | return node; | ||
275 | node->right = right; | ||
276 | if (right) | ||
277 | right->left = node; | ||
278 | return node; | ||
279 | } | ||
280 | |||
281 | /******************************************************************/ | ||
282 | /* Function : _asn1_get_right */ | ||
283 | /* Description: returns the element pointed by the RIGHT field of */ | ||
284 | /* a NODE_ASN element. */ | ||
285 | /* Parameters: */ | ||
286 | /* node: NODE_ASN element pointer. */ | ||
287 | /* Return: field RIGHT of NODE. */ | ||
288 | /******************************************************************/ | ||
289 | node_asn * | ||
290 | _asn1_get_right (node_asn * node) | ||
291 | { | ||
292 | if (node == NULL) | ||
293 | return NULL; | ||
294 | return node->right; | ||
295 | } | ||
296 | |||
297 | /******************************************************************/ | ||
298 | /* Function : _asn1_get_last_right */ | ||
299 | /* Description: return the last element along the right chain. */ | ||
300 | /* Parameters: */ | ||
301 | /* node: starting element pointer. */ | ||
302 | /* Return: pointer to the last element along the right chain. */ | ||
303 | /******************************************************************/ | ||
304 | node_asn * | ||
305 | _asn1_get_last_right (node_asn * node) | ||
306 | { | ||
307 | node_asn *p; | ||
308 | |||
309 | if (node == NULL) | ||
310 | return NULL; | ||
311 | p = node; | ||
312 | while (p->right) | ||
313 | p = p->right; | ||
314 | return p; | ||
315 | } | ||
316 | |||
317 | /******************************************************************/ | ||
318 | /* Function : _asn1_set_down */ | ||
319 | /* Description: sets the field DOWN in a NODE_ASN element. */ | ||
320 | /* Parameters: */ | ||
321 | /* node: element pointer. */ | ||
322 | /* down: pointer to a NODE_ASN element that you want be pointed */ | ||
323 | /* by NODE. */ | ||
324 | /* Return: pointer to *NODE. */ | ||
325 | /******************************************************************/ | ||
326 | node_asn * | ||
327 | _asn1_set_down (node_asn * node, node_asn * down) | ||
328 | { | ||
329 | if (node == NULL) | ||
330 | return node; | ||
331 | node->down = down; | ||
332 | if (down) | ||
333 | down->left = node; | ||
334 | return node; | ||
335 | } | ||
336 | |||
337 | /******************************************************************/ | ||
338 | /* Function : _asn1_get_down */ | ||
339 | /* Description: returns the element pointed by the DOWN field of */ | ||
340 | /* a NODE_ASN element. */ | ||
341 | /* Parameters: */ | ||
342 | /* node: NODE_ASN element pointer. */ | ||
343 | /* Return: field DOWN of NODE. */ | ||
344 | /******************************************************************/ | ||
345 | node_asn * | ||
346 | _asn1_get_down (node_asn * node) | ||
347 | { | ||
348 | if (node == NULL) | ||
349 | return NULL; | ||
350 | return node->down; | ||
351 | } | ||
352 | |||
353 | /******************************************************************/ | ||
354 | /* Function : _asn1_get_name */ | ||
355 | /* Description: returns the name of a NODE_ASN element. */ | ||
356 | /* Parameters: */ | ||
357 | /* node: NODE_ASN element pointer. */ | ||
358 | /* Return: a null terminated string. */ | ||
359 | /******************************************************************/ | ||
360 | char * | ||
361 | _asn1_get_name (node_asn * node) | ||
362 | { | ||
363 | if (node == NULL) | ||
364 | return NULL; | ||
365 | return node->name; | ||
366 | } | ||
367 | |||
368 | /******************************************************************/ | ||
369 | /* Function : _asn1_mod_type */ | ||
370 | /* Description: change the field TYPE of an NODE_ASN element. */ | ||
371 | /* The new value is the old one | (bitwise or) the */ | ||
372 | /* paramener VALUE. */ | ||
373 | /* Parameters: */ | ||
374 | /* node: NODE_ASN element pointer. */ | ||
375 | /* value: the integer value that must be or-ed with the current */ | ||
376 | /* value of field TYPE. */ | ||
377 | /* Return: NODE pointer. */ | ||
378 | /******************************************************************/ | ||
379 | node_asn * | ||
380 | _asn1_mod_type (node_asn * node, unsigned int value) | ||
381 | { | ||
382 | if (node == NULL) | ||
383 | return node; | ||
384 | node->type |= value; | ||
385 | return node; | ||
386 | } | ||
387 | |||
388 | |||
389 | /******************************************************************/ | ||
390 | /* Function : _asn1_remove_node */ | ||
391 | /* Description: gets free the memory allocated for an NODE_ASN */ | ||
392 | /* element (not the elements pointed by it). */ | ||
393 | /* Parameters: */ | ||
394 | /* node: NODE_ASN element pointer. */ | ||
395 | /******************************************************************/ | ||
396 | void | ||
397 | _asn1_remove_node (node_asn * node) | ||
398 | { | ||
399 | if (node == NULL) | ||
400 | return; | ||
401 | |||
402 | if (node->name != NULL) | ||
403 | _asn1_free (node->name); | ||
404 | if (node->value != NULL) | ||
405 | _asn1_free (node->value); | ||
406 | _asn1_free (node); | ||
407 | } | ||
408 | |||
409 | /******************************************************************/ | ||
410 | /* Function : _asn1_find_up */ | ||
411 | /* Description: return the father of the NODE_ASN element. */ | ||
412 | /* Parameters: */ | ||
413 | /* node: NODE_ASN element pointer. */ | ||
414 | /* Return: Null if not found. */ | ||
415 | /******************************************************************/ | ||
416 | node_asn * | ||
417 | _asn1_find_up (node_asn * node) | ||
418 | { | ||
419 | node_asn *p; | ||
420 | |||
421 | if (node == NULL) | ||
422 | return NULL; | ||
423 | |||
424 | p = node; | ||
425 | |||
426 | while ((p->left != NULL) && (p->left->right == p)) | ||
427 | p = p->left; | ||
428 | |||
429 | return p->left; | ||
430 | } | ||
431 | |||
432 | /******************************************************************/ | ||
433 | /* Function : _asn1_delete_list */ | ||
434 | /* Description: deletes the list elements (not the elements */ | ||
435 | /* pointed by them). */ | ||
436 | /******************************************************************/ | ||
437 | void | ||
438 | _asn1_delete_list (void) | ||
439 | { | ||
440 | list_type *listElement; | ||
441 | |||
442 | while (firstElement) | ||
443 | { | ||
444 | listElement = firstElement; | ||
445 | firstElement = firstElement->next; | ||
446 | _asn1_free (listElement); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | /******************************************************************/ | ||
451 | /* Function : _asn1_delete_list_and nodes */ | ||
452 | /* Description: deletes the list elements and the elements */ | ||
453 | /* pointed by them. */ | ||
454 | /******************************************************************/ | ||
455 | void | ||
456 | _asn1_delete_list_and_nodes (void) | ||
457 | { | ||
458 | list_type *listElement; | ||
459 | |||
460 | while (firstElement) | ||
461 | { | ||
462 | listElement = firstElement; | ||
463 | firstElement = firstElement->next; | ||
464 | _asn1_remove_node (listElement->node); | ||
465 | _asn1_free (listElement); | ||
466 | } | ||
467 | } | ||
468 | |||
469 | |||
470 | char * | ||
471 | _asn1_ltostr (long v, char *str) | ||
472 | { | ||
473 | long d, r; | ||
474 | char temp[20]; | ||
475 | int count, k, start; | ||
476 | |||
477 | if (v < 0) | ||
478 | { | ||
479 | str[0] = '-'; | ||
480 | start = 1; | ||
481 | v = -v; | ||
482 | } | ||
483 | else | ||
484 | start = 0; | ||
485 | |||
486 | count = 0; | ||
487 | do | ||
488 | { | ||
489 | d = v / 10; | ||
490 | r = v - d * 10; | ||
491 | temp[start + count] = '0' + (char) r; | ||
492 | count++; | ||
493 | v = d; | ||
494 | } | ||
495 | while (v); | ||
496 | |||
497 | for (k = 0; k < count; k++) | ||
498 | str[k + start] = temp[start + count - k - 1]; | ||
499 | str[count + start] = 0; | ||
500 | return str; | ||
501 | } | ||
502 | |||
503 | |||
504 | /******************************************************************/ | ||
505 | /* Function : _asn1_change_integer_value */ | ||
506 | /* Description: converts into DER coding the value assign to an */ | ||
507 | /* INTEGER constant. */ | ||
508 | /* Parameters: */ | ||
509 | /* node: root of an ASN1element. */ | ||
510 | /* Return: */ | ||
511 | /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ | ||
512 | /* otherwise ASN1_SUCCESS */ | ||
513 | /******************************************************************/ | ||
514 | asn1_retCode | ||
515 | _asn1_change_integer_value (ASN1_TYPE node) | ||
516 | { | ||
517 | node_asn *p; | ||
518 | unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; | ||
519 | unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1]; | ||
520 | int len; | ||
521 | |||
522 | if (node == NULL) | ||
523 | return ASN1_ELEMENT_NOT_FOUND; | ||
524 | |||
525 | p = node; | ||
526 | while (p) | ||
527 | { | ||
528 | if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN)) | ||
529 | { | ||
530 | if (p->value) | ||
531 | { | ||
532 | _asn1_convert_integer (p->value, val, sizeof (val), &len); | ||
533 | asn1_octet_der (val, len, val2, &len); | ||
534 | _asn1_set_value (p, val2, len); | ||
535 | } | ||
536 | } | ||
537 | |||
538 | if (p->down) | ||
539 | { | ||
540 | p = p->down; | ||
541 | } | ||
542 | else | ||
543 | { | ||
544 | if (p == node) | ||
545 | p = NULL; | ||
546 | else if (p->right) | ||
547 | p = p->right; | ||
548 | else | ||
549 | { | ||
550 | while (1) | ||
551 | { | ||
552 | p = _asn1_find_up (p); | ||
553 | if (p == node) | ||
554 | { | ||
555 | p = NULL; | ||
556 | break; | ||
557 | } | ||
558 | if (p->right) | ||
559 | { | ||
560 | p = p->right; | ||
561 | break; | ||
562 | } | ||
563 | } | ||
564 | } | ||
565 | } | ||
566 | } | ||
567 | |||
568 | return ASN1_SUCCESS; | ||
569 | } | ||
570 | |||
571 | |||
572 | /******************************************************************/ | ||
573 | /* Function : _asn1_expand_object_id */ | ||
574 | /* Description: expand the IDs of an OBJECT IDENTIFIER constant. */ | ||
575 | /* Parameters: */ | ||
576 | /* node: root of an ASN1 element. */ | ||
577 | /* Return: */ | ||
578 | /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ | ||
579 | /* otherwise ASN1_SUCCESS */ | ||
580 | /******************************************************************/ | ||
581 | asn1_retCode | ||
582 | _asn1_expand_object_id (ASN1_TYPE node) | ||
583 | { | ||
584 | node_asn *p, *p2, *p3, *p4, *p5; | ||
585 | char name_root[MAX_NAME_SIZE], name2[2 * MAX_NAME_SIZE + 1]; | ||
586 | int move, tlen; | ||
587 | |||
588 | if (node == NULL) | ||
589 | return ASN1_ELEMENT_NOT_FOUND; | ||
590 | |||
591 | _asn1_str_cpy (name_root, sizeof (name_root), node->name); | ||
592 | |||
593 | p = node; | ||
594 | move = DOWN; | ||
595 | |||
596 | while (!((p == node) && (move == UP))) | ||
597 | { | ||
598 | if (move != UP) | ||
599 | { | ||
600 | if ((type_field (p->type) == TYPE_OBJECT_ID) | ||
601 | && (p->type & CONST_ASSIGN)) | ||
602 | { | ||
603 | p2 = p->down; | ||
604 | if (p2 && (type_field (p2->type) == TYPE_CONSTANT)) | ||
605 | { | ||
606 | if (p2->value && !isdigit (p2->value[0])) | ||
607 | { | ||
608 | _asn1_str_cpy (name2, sizeof (name2), name_root); | ||
609 | _asn1_str_cat (name2, sizeof (name2), "."); | ||
610 | _asn1_str_cat (name2, sizeof (name2), p2->value); | ||
611 | p3 = asn1_find_node (node, name2); | ||
612 | if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) || | ||
613 | !(p3->type & CONST_ASSIGN)) | ||
614 | return ASN1_ELEMENT_NOT_FOUND; | ||
615 | _asn1_set_down (p, p2->right); | ||
616 | _asn1_remove_node (p2); | ||
617 | p2 = p; | ||
618 | p4 = p3->down; | ||
619 | while (p4) | ||
620 | { | ||
621 | if (type_field (p4->type) == TYPE_CONSTANT) | ||
622 | { | ||
623 | p5 = _asn1_add_node_only (TYPE_CONSTANT); | ||
624 | _asn1_set_name (p5, p4->name); | ||
625 | tlen = strlen (p4->value); | ||
626 | if (tlen > 0) | ||
627 | _asn1_set_value (p5, p4->value, tlen + 1); | ||
628 | if (p2 == p) | ||
629 | { | ||
630 | _asn1_set_right (p5, p->down); | ||
631 | _asn1_set_down (p, p5); | ||
632 | } | ||
633 | else | ||
634 | { | ||
635 | _asn1_set_right (p5, p2->right); | ||
636 | _asn1_set_right (p2, p5); | ||
637 | } | ||
638 | p2 = p5; | ||
639 | } | ||
640 | p4 = p4->right; | ||
641 | } | ||
642 | move = DOWN; | ||
643 | continue; | ||
644 | } | ||
645 | } | ||
646 | } | ||
647 | move = DOWN; | ||
648 | } | ||
649 | else | ||
650 | move = RIGHT; | ||
651 | |||
652 | if (move == DOWN) | ||
653 | { | ||
654 | if (p->down) | ||
655 | p = p->down; | ||
656 | else | ||
657 | move = RIGHT; | ||
658 | } | ||
659 | |||
660 | if (p == node) | ||
661 | { | ||
662 | move = UP; | ||
663 | continue; | ||
664 | } | ||
665 | |||
666 | if (move == RIGHT) | ||
667 | { | ||
668 | if (p->right) | ||
669 | p = p->right; | ||
670 | else | ||
671 | move = UP; | ||
672 | } | ||
673 | if (move == UP) | ||
674 | p = _asn1_find_up (p); | ||
675 | } | ||
676 | |||
677 | |||
678 | /*******************************/ | ||
679 | /* expand DEFAULT */ | ||
680 | /*******************************/ | ||
681 | p = node; | ||
682 | move = DOWN; | ||
683 | |||
684 | while (!((p == node) && (move == UP))) | ||
685 | { | ||
686 | if (move != UP) | ||
687 | { | ||
688 | if ((type_field (p->type) == TYPE_OBJECT_ID) && | ||
689 | (p->type & CONST_DEFAULT)) | ||
690 | { | ||
691 | p2 = p->down; | ||
692 | if (p2 && (type_field (p2->type) == TYPE_DEFAULT)) | ||
693 | { | ||
694 | _asn1_str_cpy (name2, sizeof (name2), name_root); | ||
695 | _asn1_str_cat (name2, sizeof (name2), "."); | ||
696 | _asn1_str_cat (name2, sizeof (name2), p2->value); | ||
697 | p3 = asn1_find_node (node, name2); | ||
698 | if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) || | ||
699 | !(p3->type & CONST_ASSIGN)) | ||
700 | return ASN1_ELEMENT_NOT_FOUND; | ||
701 | p4 = p3->down; | ||
702 | name2[0] = 0; | ||
703 | while (p4) | ||
704 | { | ||
705 | if (type_field (p4->type) == TYPE_CONSTANT) | ||
706 | { | ||
707 | if (name2[0]) | ||
708 | _asn1_str_cat (name2, sizeof (name2), "."); | ||
709 | _asn1_str_cat (name2, sizeof (name2), p4->value); | ||
710 | } | ||
711 | p4 = p4->right; | ||
712 | } | ||
713 | tlen = strlen (name2); | ||
714 | if (tlen > 0) | ||
715 | _asn1_set_value (p2, name2, tlen + 1); | ||
716 | } | ||
717 | } | ||
718 | move = DOWN; | ||
719 | } | ||
720 | else | ||
721 | move = RIGHT; | ||
722 | |||
723 | if (move == DOWN) | ||
724 | { | ||
725 | if (p->down) | ||
726 | p = p->down; | ||
727 | else | ||
728 | move = RIGHT; | ||
729 | } | ||
730 | |||
731 | if (p == node) | ||
732 | { | ||
733 | move = UP; | ||
734 | continue; | ||
735 | } | ||
736 | |||
737 | if (move == RIGHT) | ||
738 | { | ||
739 | if (p->right) | ||
740 | p = p->right; | ||
741 | else | ||
742 | move = UP; | ||
743 | } | ||
744 | if (move == UP) | ||
745 | p = _asn1_find_up (p); | ||
746 | } | ||
747 | |||
748 | return ASN1_SUCCESS; | ||
749 | } | ||
750 | |||
751 | |||
752 | /******************************************************************/ | ||
753 | /* Function : _asn1_type_set_config */ | ||
754 | /* Description: sets the CONST_SET and CONST_NOT_USED properties */ | ||
755 | /* in the fields of the SET elements. */ | ||
756 | /* Parameters: */ | ||
757 | /* node: root of an ASN1 element. */ | ||
758 | /* Return: */ | ||
759 | /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ | ||
760 | /* otherwise ASN1_SUCCESS */ | ||
761 | /******************************************************************/ | ||
762 | asn1_retCode | ||
763 | _asn1_type_set_config (ASN1_TYPE node) | ||
764 | { | ||
765 | node_asn *p, *p2; | ||
766 | int move; | ||
767 | |||
768 | if (node == NULL) | ||
769 | return ASN1_ELEMENT_NOT_FOUND; | ||
770 | |||
771 | p = node; | ||
772 | move = DOWN; | ||
773 | |||
774 | while (!((p == node) && (move == UP))) | ||
775 | { | ||
776 | if (move != UP) | ||
777 | { | ||
778 | if (type_field (p->type) == TYPE_SET) | ||
779 | { | ||
780 | p2 = p->down; | ||
781 | while (p2) | ||
782 | { | ||
783 | if (type_field (p2->type) != TYPE_TAG) | ||
784 | p2->type |= CONST_SET | CONST_NOT_USED; | ||
785 | p2 = p2->right; | ||
786 | } | ||
787 | } | ||
788 | move = DOWN; | ||
789 | } | ||
790 | else | ||
791 | move = RIGHT; | ||
792 | |||
793 | if (move == DOWN) | ||
794 | { | ||
795 | if (p->down) | ||
796 | p = p->down; | ||
797 | else | ||
798 | move = RIGHT; | ||
799 | } | ||
800 | |||
801 | if (p == node) | ||
802 | { | ||
803 | move = UP; | ||
804 | continue; | ||
805 | } | ||
806 | |||
807 | if (move == RIGHT) | ||
808 | { | ||
809 | if (p->right) | ||
810 | p = p->right; | ||
811 | else | ||
812 | move = UP; | ||
813 | } | ||
814 | if (move == UP) | ||
815 | p = _asn1_find_up (p); | ||
816 | } | ||
817 | |||
818 | return ASN1_SUCCESS; | ||
819 | } | ||
820 | |||
821 | |||
822 | /******************************************************************/ | ||
823 | /* Function : _asn1_check_identifier */ | ||
824 | /* Description: checks the definitions of all the identifiers */ | ||
825 | /* and the first element of an OBJECT_ID (e.g. {pkix 0 4}). */ | ||
826 | /* The _asn1_identifierMissing global variable is filled if */ | ||
827 | /* necessary. */ | ||
828 | /* Parameters: */ | ||
829 | /* node: root of an ASN1 element. */ | ||
830 | /* Return: */ | ||
831 | /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ | ||
832 | /* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */ | ||
833 | /* otherwise ASN1_SUCCESS */ | ||
834 | /******************************************************************/ | ||
835 | asn1_retCode | ||
836 | _asn1_check_identifier (ASN1_TYPE node) | ||
837 | { | ||
838 | node_asn *p, *p2; | ||
839 | char name2[MAX_NAME_SIZE * 2 + 2]; | ||
840 | |||
841 | if (node == NULL) | ||
842 | return ASN1_ELEMENT_NOT_FOUND; | ||
843 | |||
844 | p = node; | ||
845 | while (p) | ||
846 | { | ||
847 | if (type_field (p->type) == TYPE_IDENTIFIER) | ||
848 | { | ||
849 | _asn1_str_cpy (name2, sizeof (name2), node->name); | ||
850 | _asn1_str_cat (name2, sizeof (name2), "."); | ||
851 | _asn1_str_cat (name2, sizeof (name2), p->value); | ||
852 | p2 = asn1_find_node (node, name2); | ||
853 | if (p2 == NULL) | ||
854 | { | ||
855 | strcpy (_asn1_identifierMissing, p->value); | ||
856 | return ASN1_IDENTIFIER_NOT_FOUND; | ||
857 | } | ||
858 | } | ||
859 | else if ((type_field (p->type) == TYPE_OBJECT_ID) && | ||
860 | (p->type & CONST_DEFAULT)) | ||
861 | { | ||
862 | p2 = p->down; | ||
863 | if (p2 && (type_field (p2->type) == TYPE_DEFAULT)) | ||
864 | { | ||
865 | _asn1_str_cpy (name2, sizeof (name2), node->name); | ||
866 | _asn1_str_cat (name2, sizeof (name2), "."); | ||
867 | _asn1_str_cat (name2, sizeof (name2), p2->value); | ||
868 | strcpy (_asn1_identifierMissing, p2->value); | ||
869 | p2 = asn1_find_node (node, name2); | ||
870 | if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) || | ||
871 | !(p2->type & CONST_ASSIGN)) | ||
872 | return ASN1_IDENTIFIER_NOT_FOUND; | ||
873 | else | ||
874 | _asn1_identifierMissing[0] = 0; | ||
875 | } | ||
876 | } | ||
877 | else if ((type_field (p->type) == TYPE_OBJECT_ID) && | ||
878 | (p->type & CONST_ASSIGN)) | ||
879 | { | ||
880 | p2 = p->down; | ||
881 | if (p2 && (type_field (p2->type) == TYPE_CONSTANT)) | ||
882 | { | ||
883 | if (p2->value && !isdigit (p2->value[0])) | ||
884 | { | ||
885 | _asn1_str_cpy (name2, sizeof (name2), node->name); | ||
886 | _asn1_str_cat (name2, sizeof (name2), "."); | ||
887 | _asn1_str_cat (name2, sizeof (name2), p2->value); | ||
888 | strcpy (_asn1_identifierMissing, p2->value); | ||
889 | p2 = asn1_find_node (node, name2); | ||
890 | if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) || | ||
891 | !(p2->type & CONST_ASSIGN)) | ||
892 | return ASN1_IDENTIFIER_NOT_FOUND; | ||
893 | else | ||
894 | _asn1_identifierMissing[0] = 0; | ||
895 | } | ||
896 | } | ||
897 | } | ||
898 | |||
899 | if (p->down) | ||
900 | { | ||
901 | p = p->down; | ||
902 | } | ||
903 | else if (p->right) | ||
904 | p = p->right; | ||
905 | else | ||
906 | { | ||
907 | while (1) | ||
908 | { | ||
909 | p = _asn1_find_up (p); | ||
910 | if (p == node) | ||
911 | { | ||
912 | p = NULL; | ||
913 | break; | ||
914 | } | ||
915 | if (p->right) | ||
916 | { | ||
917 | p = p->right; | ||
918 | break; | ||
919 | } | ||
920 | } | ||
921 | } | ||
922 | } | ||
923 | |||
924 | return ASN1_SUCCESS; | ||
925 | } | ||
926 | |||
927 | |||
928 | /******************************************************************/ | ||
929 | /* Function : _asn1_set_default_tag */ | ||
930 | /* Description: sets the default IMPLICIT or EXPLICIT property in */ | ||
931 | /* the tagged elements that don't have this declaration. */ | ||
932 | /* Parameters: */ | ||
933 | /* node: pointer to a DEFINITIONS element. */ | ||
934 | /* Return: */ | ||
935 | /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to */ | ||
936 | /* a DEFINITIONS element, */ | ||
937 | /* otherwise ASN1_SUCCESS */ | ||
938 | /******************************************************************/ | ||
939 | asn1_retCode | ||
940 | _asn1_set_default_tag (ASN1_TYPE node) | ||
941 | { | ||
942 | node_asn *p; | ||
943 | |||
944 | if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS)) | ||
945 | return ASN1_ELEMENT_NOT_FOUND; | ||
946 | |||
947 | p = node; | ||
948 | while (p) | ||
949 | { | ||
950 | if ((type_field (p->type) == TYPE_TAG) && | ||
951 | !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT)) | ||
952 | { | ||
953 | if (node->type & CONST_EXPLICIT) | ||
954 | p->type |= CONST_EXPLICIT; | ||
955 | else | ||
956 | p->type |= CONST_IMPLICIT; | ||
957 | } | ||
958 | |||
959 | if (p->down) | ||
960 | { | ||
961 | p = p->down; | ||
962 | } | ||
963 | else if (p->right) | ||
964 | p = p->right; | ||
965 | else | ||
966 | { | ||
967 | while (1) | ||
968 | { | ||
969 | p = _asn1_find_up (p); | ||
970 | if (p == node) | ||
971 | { | ||
972 | p = NULL; | ||
973 | break; | ||
974 | } | ||
975 | if (p->right) | ||
976 | { | ||
977 | p = p->right; | ||
978 | break; | ||
979 | } | ||
980 | } | ||
981 | } | ||
982 | } | ||
983 | |||
984 | return ASN1_SUCCESS; | ||
985 | } | ||
986 | |||
987 | |||
988 | |||
989 | static const char * | ||
990 | parse_version_number (const char *s, int *number) | ||
991 | { | ||
992 | int val = 0; | ||
993 | |||
994 | if (*s == '0' && isdigit (s[1])) | ||
995 | return NULL; /* leading zeros are not allowed */ | ||
996 | for (; isdigit (*s); s++) | ||
997 | { | ||
998 | val *= 10; | ||
999 | val += *s - '0'; | ||
1000 | } | ||
1001 | *number = val; | ||
1002 | return val < 0 ? NULL : s; | ||
1003 | } | ||
1004 | |||
1005 | /* The parse version functions were copied from libgcrypt. | ||
1006 | */ | ||
1007 | static const char * | ||
1008 | parse_version_string (const char *s, int *major, int *minor, int *micro) | ||
1009 | { | ||
1010 | s = parse_version_number (s, major); | ||
1011 | if (!s || *s != '.') | ||
1012 | return NULL; | ||
1013 | s++; | ||
1014 | s = parse_version_number (s, minor); | ||
1015 | if (!s) | ||
1016 | return NULL; | ||
1017 | if (*s != '.') | ||
1018 | { | ||
1019 | *micro = 0; | ||
1020 | return s; | ||
1021 | } | ||
1022 | s++; | ||
1023 | s = parse_version_number (s, micro); | ||
1024 | if (!s) | ||
1025 | return NULL; | ||
1026 | return s; /* patchlevel */ | ||
1027 | } | ||
1028 | |||
1029 | /** | ||
1030 | * asn1_check_version - check for library version | ||
1031 | * @req_version: Required version number, or NULL. | ||
1032 | * | ||
1033 | * Check that the the version of the library is at minimum the | ||
1034 | * requested one and return the version string; return %NULL if the | ||
1035 | * condition is not satisfied. If a %NULL is passed to this function, | ||
1036 | * no check is done, but the version string is simply returned. | ||
1037 | * | ||
1038 | * See %LIBTASN1_VERSION for a suitable @req_version string. | ||
1039 | * | ||
1040 | * Return value: Version string of run-time library, or %NULL if the | ||
1041 | * run-time library does not meet the required version number. | ||
1042 | */ | ||
1043 | const char * | ||
1044 | asn1_check_version (const char *req_version) | ||
1045 | { | ||
1046 | const char *ver = LIBTASN1_VERSION; | ||
1047 | int my_major, my_minor, my_micro; | ||
1048 | int rq_major, rq_minor, rq_micro; | ||
1049 | const char *my_plvl, *rq_plvl; | ||
1050 | |||
1051 | if (!req_version) | ||
1052 | return ver; | ||
1053 | |||
1054 | my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro); | ||
1055 | if (!my_plvl) | ||
1056 | return NULL; /* very strange our own version is bogus */ | ||
1057 | rq_plvl = parse_version_string (req_version, &rq_major, &rq_minor, | ||
1058 | &rq_micro); | ||
1059 | if (!rq_plvl) | ||
1060 | return NULL; /* req version string is invalid */ | ||
1061 | |||
1062 | if (my_major > rq_major | ||
1063 | || (my_major == rq_major && my_minor > rq_minor) | ||
1064 | || (my_major == rq_major && my_minor == rq_minor | ||
1065 | && my_micro > rq_micro) | ||
1066 | || (my_major == rq_major && my_minor == rq_minor | ||
1067 | && my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0)) | ||
1068 | { | ||
1069 | return ver; | ||
1070 | } | ||
1071 | return NULL; | ||
1072 | } | ||
diff --git a/src/daemon/https/minitasn1/parser_aux.h b/src/daemon/https/minitasn1/parser_aux.h new file mode 100644 index 00000000..3055510c --- /dev/null +++ b/src/daemon/https/minitasn1/parser_aux.h | |||
@@ -0,0 +1,63 @@ | |||
1 | |||
2 | #ifndef _PARSER_AUX_H | ||
3 | #define _PARSER_AUX_H | ||
4 | |||
5 | |||
6 | /***************************************/ | ||
7 | /* Functions used by ASN.1 parser */ | ||
8 | /***************************************/ | ||
9 | node_asn * | ||
10 | _asn1_add_node(unsigned int type); | ||
11 | |||
12 | node_asn * | ||
13 | _asn1_set_value(node_asn *node,const void *value,unsigned int len); | ||
14 | |||
15 | node_asn * | ||
16 | _asn1_set_name(node_asn *node,const char *name); | ||
17 | |||
18 | node_asn * | ||
19 | _asn1_set_right(node_asn *node,node_asn *right); | ||
20 | |||
21 | node_asn * | ||
22 | _asn1_get_right(node_asn *node); | ||
23 | |||
24 | node_asn * | ||
25 | _asn1_get_last_right(node_asn *node); | ||
26 | |||
27 | node_asn * | ||
28 | _asn1_set_down(node_asn *node,node_asn *down); | ||
29 | |||
30 | char * | ||
31 | _asn1_get_name(node_asn *node); | ||
32 | |||
33 | node_asn * | ||
34 | _asn1_get_down(node_asn *node); | ||
35 | |||
36 | node_asn * | ||
37 | _asn1_mod_type(node_asn *node,unsigned int value); | ||
38 | |||
39 | void | ||
40 | _asn1_remove_node(node_asn *node); | ||
41 | |||
42 | void _asn1_delete_list(void); | ||
43 | |||
44 | void _asn1_delete_list_and_nodes(void); | ||
45 | |||
46 | char * _asn1_ltostr(long v,char *str); | ||
47 | |||
48 | node_asn * _asn1_find_up(node_asn *node); | ||
49 | |||
50 | asn1_retCode _asn1_change_integer_value(ASN1_TYPE node); | ||
51 | |||
52 | asn1_retCode _asn1_expand_object_id(ASN1_TYPE node); | ||
53 | |||
54 | asn1_retCode _asn1_type_set_config(ASN1_TYPE node); | ||
55 | |||
56 | asn1_retCode _asn1_check_identifier(ASN1_TYPE node); | ||
57 | |||
58 | asn1_retCode _asn1_set_default_tag(ASN1_TYPE node); | ||
59 | |||
60 | #endif | ||
61 | |||
62 | |||
63 | |||
diff --git a/src/daemon/https/minitasn1/structure.c b/src/daemon/https/minitasn1/structure.c new file mode 100644 index 00000000..264793c1 --- /dev/null +++ b/src/daemon/https/minitasn1/structure.c | |||
@@ -0,0 +1,1221 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2006, 2007 Free Software Foundation | ||
3 | * Copyright (C) 2002 Fabio Fiorina | ||
4 | * | ||
5 | * This file is part of LIBTASN1. | ||
6 | * | ||
7 | * The LIBTASN1 library is free software; you can redistribute it | ||
8 | * and/or modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | */ | ||
22 | |||
23 | |||
24 | /*****************************************************/ | ||
25 | /* File: structure.c */ | ||
26 | /* Description: Functions to create and delete an */ | ||
27 | /* ASN1 tree. */ | ||
28 | /*****************************************************/ | ||
29 | |||
30 | |||
31 | #include <int.h> | ||
32 | #include <errors.h> | ||
33 | #include <structure.h> | ||
34 | #include "parser_aux.h" | ||
35 | #include <gstr.h> | ||
36 | |||
37 | |||
38 | extern char _asn1_identifierMissing[]; | ||
39 | |||
40 | |||
41 | /******************************************************/ | ||
42 | /* Function : _asn1_add_node_only */ | ||
43 | /* Description: creates a new NODE_ASN element. */ | ||
44 | /* Parameters: */ | ||
45 | /* type: type of the new element (see TYPE_ */ | ||
46 | /* and CONST_ constants). */ | ||
47 | /* Return: pointer to the new element. */ | ||
48 | /******************************************************/ | ||
49 | node_asn * | ||
50 | _asn1_add_node_only (unsigned int type) | ||
51 | { | ||
52 | node_asn *punt; | ||
53 | |||
54 | punt = (node_asn *) _asn1_calloc (1, sizeof (node_asn)); | ||
55 | if (punt == NULL) | ||
56 | return NULL; | ||
57 | |||
58 | punt->type = type; | ||
59 | |||
60 | return punt; | ||
61 | } | ||
62 | |||
63 | |||
64 | /******************************************************************/ | ||
65 | /* Function : _asn1_find_left */ | ||
66 | /* Description: returns the NODE_ASN element with RIGHT field that*/ | ||
67 | /* points the element NODE. */ | ||
68 | /* Parameters: */ | ||
69 | /* node: NODE_ASN element pointer. */ | ||
70 | /* Return: NULL if not found. */ | ||
71 | /******************************************************************/ | ||
72 | node_asn * | ||
73 | _asn1_find_left (node_asn * node) | ||
74 | { | ||
75 | if ((node == NULL) || (node->left == NULL) || (node->left->down == node)) | ||
76 | return NULL; | ||
77 | |||
78 | return node->left; | ||
79 | } | ||
80 | |||
81 | |||
82 | asn1_retCode | ||
83 | _asn1_create_static_structure (ASN1_TYPE pointer, char *output_file_name, | ||
84 | char *vector_name) | ||
85 | { | ||
86 | FILE *file; | ||
87 | node_asn *p; | ||
88 | unsigned long t; | ||
89 | |||
90 | file = fopen (output_file_name, "w"); | ||
91 | |||
92 | if (file == NULL) | ||
93 | return ASN1_FILE_NOT_FOUND; | ||
94 | |||
95 | fprintf (file, "#if HAVE_CONFIG_H\n"); | ||
96 | fprintf (file, "# include \"config.h\"\n"); | ||
97 | fprintf (file, "#endif\n\n"); | ||
98 | |||
99 | fprintf (file, "#include <libtasn1.h>\n\n"); | ||
100 | |||
101 | fprintf (file, "extern const ASN1_ARRAY_TYPE %s[]={\n", vector_name); | ||
102 | |||
103 | p = pointer; | ||
104 | |||
105 | while (p) | ||
106 | { | ||
107 | fprintf (file, " {"); | ||
108 | |||
109 | if (p->name) | ||
110 | fprintf (file, "\"%s\",", p->name); | ||
111 | else | ||
112 | fprintf (file, "0,"); | ||
113 | |||
114 | t = p->type; | ||
115 | if (p->down) | ||
116 | t |= CONST_DOWN; | ||
117 | if (p->right) | ||
118 | t |= CONST_RIGHT; | ||
119 | |||
120 | fprintf (file, "%lu,", t); | ||
121 | |||
122 | if (p->value) | ||
123 | fprintf (file, "\"%s\"},\n", p->value); | ||
124 | else | ||
125 | fprintf (file, "0},\n"); | ||
126 | |||
127 | if (p->down) | ||
128 | { | ||
129 | p = p->down; | ||
130 | } | ||
131 | else if (p->right) | ||
132 | { | ||
133 | p = p->right; | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | while (1) | ||
138 | { | ||
139 | p = _asn1_find_up (p); | ||
140 | if (p == pointer) | ||
141 | { | ||
142 | p = NULL; | ||
143 | break; | ||
144 | } | ||
145 | if (p->right) | ||
146 | { | ||
147 | p = p->right; | ||
148 | break; | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | fprintf (file, " {0,0,0}\n};\n"); | ||
155 | |||
156 | fclose (file); | ||
157 | |||
158 | return ASN1_SUCCESS; | ||
159 | } | ||
160 | |||
161 | |||
162 | /** | ||
163 | * asn1_array2tree - Creates the structures needed to manage the ASN1 definitions. | ||
164 | * @array: specify the array that contains ASN.1 declarations | ||
165 | * @definitions: return the pointer to the structure created by | ||
166 | * *ARRAY ASN.1 declarations | ||
167 | * @errorDescription: return the error description. | ||
168 | * | ||
169 | * Creates the structures needed to manage the ASN.1 definitions. | ||
170 | * @array is a vector created by asn1_parser2array(). | ||
171 | * | ||
172 | * Returns: | ||
173 | * | ||
174 | * ASN1_SUCCESS: Structure created correctly. | ||
175 | * | ||
176 | * ASN1_ELEMENT_NOT_EMPTY: *@definitions not ASN1_TYPE_EMPTY. | ||
177 | * | ||
178 | * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that | ||
179 | * is not defined (see @errorDescription for more information). | ||
180 | * | ||
181 | * ASN1_ARRAY_ERROR: The array pointed by @array is wrong. | ||
182 | **/ | ||
183 | asn1_retCode | ||
184 | asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions, | ||
185 | char *errorDescription) | ||
186 | { | ||
187 | node_asn *p, *p_last = NULL; | ||
188 | unsigned long k; | ||
189 | int move; | ||
190 | asn1_retCode result; | ||
191 | |||
192 | |||
193 | if (*definitions != ASN1_TYPE_EMPTY) | ||
194 | return ASN1_ELEMENT_NOT_EMPTY; | ||
195 | |||
196 | move = UP; | ||
197 | |||
198 | k = 0; | ||
199 | while (array[k].value || array[k].type || array[k].name) | ||
200 | { | ||
201 | p = _asn1_add_node (array[k].type & (~CONST_DOWN)); | ||
202 | if (array[k].name) | ||
203 | _asn1_set_name (p, array[k].name); | ||
204 | if (array[k].value) | ||
205 | _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1); | ||
206 | |||
207 | if (*definitions == NULL) | ||
208 | *definitions = p; | ||
209 | |||
210 | if (move == DOWN) | ||
211 | _asn1_set_down (p_last, p); | ||
212 | else if (move == RIGHT) | ||
213 | _asn1_set_right (p_last, p); | ||
214 | |||
215 | p_last = p; | ||
216 | |||
217 | if (array[k].type & CONST_DOWN) | ||
218 | move = DOWN; | ||
219 | else if (array[k].type & CONST_RIGHT) | ||
220 | move = RIGHT; | ||
221 | else | ||
222 | { | ||
223 | while (1) | ||
224 | { | ||
225 | if (p_last == *definitions) | ||
226 | break; | ||
227 | |||
228 | p_last = _asn1_find_up (p_last); | ||
229 | |||
230 | if (p_last == NULL) | ||
231 | break; | ||
232 | |||
233 | if (p_last->type & CONST_RIGHT) | ||
234 | { | ||
235 | p_last->type &= ~CONST_RIGHT; | ||
236 | move = RIGHT; | ||
237 | break; | ||
238 | } | ||
239 | } /* while */ | ||
240 | } | ||
241 | k++; | ||
242 | } /* while */ | ||
243 | |||
244 | if (p_last == *definitions) | ||
245 | { | ||
246 | result = _asn1_check_identifier (*definitions); | ||
247 | if (result == ASN1_SUCCESS) | ||
248 | { | ||
249 | _asn1_change_integer_value (*definitions); | ||
250 | _asn1_expand_object_id (*definitions); | ||
251 | } | ||
252 | } | ||
253 | else | ||
254 | { | ||
255 | result = ASN1_ARRAY_ERROR; | ||
256 | } | ||
257 | |||
258 | if (errorDescription != NULL) | ||
259 | { | ||
260 | if (result == ASN1_IDENTIFIER_NOT_FOUND) | ||
261 | { | ||
262 | Estrcpy (errorDescription, ":: identifier '"); | ||
263 | Estrcat (errorDescription, _asn1_identifierMissing); | ||
264 | Estrcat (errorDescription, "' not found"); | ||
265 | } | ||
266 | else | ||
267 | errorDescription[0] = 0; | ||
268 | } | ||
269 | |||
270 | if (result != ASN1_SUCCESS) | ||
271 | { | ||
272 | _asn1_delete_list_and_nodes (); | ||
273 | *definitions = ASN1_TYPE_EMPTY; | ||
274 | } | ||
275 | else | ||
276 | _asn1_delete_list (); | ||
277 | |||
278 | return result; | ||
279 | } | ||
280 | |||
281 | /** | ||
282 | * asn1_delete_structure - Deletes the structure pointed by *ROOT. | ||
283 | * @structure: pointer to the structure that you want to delete. | ||
284 | * | ||
285 | * Deletes the structure *@structure. At the end, *@structure is set | ||
286 | * to ASN1_TYPE_EMPTY. | ||
287 | * | ||
288 | * Returns: | ||
289 | * | ||
290 | * ASN1_SUCCESS: Everything OK. | ||
291 | * | ||
292 | * ASN1_ELEMENT_NOT_FOUND: *@structure was ASN1_TYPE_EMPTY. | ||
293 | * | ||
294 | **/ | ||
295 | asn1_retCode | ||
296 | asn1_delete_structure (ASN1_TYPE * structure) | ||
297 | { | ||
298 | node_asn *p, *p2, *p3; | ||
299 | |||
300 | if (*structure == ASN1_TYPE_EMPTY) | ||
301 | return ASN1_ELEMENT_NOT_FOUND; | ||
302 | |||
303 | p = *structure; | ||
304 | while (p) | ||
305 | { | ||
306 | if (p->down) | ||
307 | { | ||
308 | p = p->down; | ||
309 | } | ||
310 | else | ||
311 | { /* no down */ | ||
312 | p2 = p->right; | ||
313 | if (p != *structure) | ||
314 | { | ||
315 | p3 = _asn1_find_up (p); | ||
316 | _asn1_set_down (p3, p2); | ||
317 | _asn1_remove_node (p); | ||
318 | p = p3; | ||
319 | } | ||
320 | else | ||
321 | { /* p==root */ | ||
322 | p3 = _asn1_find_left (p); | ||
323 | if (!p3) | ||
324 | { | ||
325 | p3 = _asn1_find_up (p); | ||
326 | if (p3) | ||
327 | _asn1_set_down (p3, p2); | ||
328 | else | ||
329 | { | ||
330 | if (p->right) | ||
331 | p->right->left = NULL; | ||
332 | } | ||
333 | } | ||
334 | else | ||
335 | _asn1_set_right (p3, p2); | ||
336 | _asn1_remove_node (p); | ||
337 | p = NULL; | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | |||
342 | *structure = ASN1_TYPE_EMPTY; | ||
343 | return ASN1_SUCCESS; | ||
344 | } | ||
345 | |||
346 | |||
347 | |||
348 | /** | ||
349 | * asn1_delete_element - Deletes the element of a structure. | ||
350 | * @structure: pointer to the structure that contains the element you | ||
351 | * want to delete. | ||
352 | * @element_name: element's name you want to delete. | ||
353 | * | ||
354 | * Deletes the element named *@element_name inside *@structure. | ||
355 | * | ||
356 | * Returns: | ||
357 | * | ||
358 | * ASN1_SUCCESS: Everything OK. | ||
359 | * | ||
360 | * ASN1_ELEMENT_NOT_FOUND: The name element was not found. | ||
361 | * | ||
362 | **/ | ||
363 | asn1_retCode | ||
364 | asn1_delete_element (ASN1_TYPE structure, const char *element_name) | ||
365 | { | ||
366 | node_asn *p2, *p3, *source_node; | ||
367 | |||
368 | source_node = asn1_find_node (structure, element_name); | ||
369 | |||
370 | if (source_node == ASN1_TYPE_EMPTY) | ||
371 | return ASN1_ELEMENT_NOT_FOUND; | ||
372 | |||
373 | p2 = source_node->right; | ||
374 | p3 = _asn1_find_left (source_node); | ||
375 | if (!p3) | ||
376 | { | ||
377 | p3 = _asn1_find_up (source_node); | ||
378 | if (p3) | ||
379 | _asn1_set_down (p3, p2); | ||
380 | else if (source_node->right) | ||
381 | source_node->right->left = NULL; | ||
382 | } | ||
383 | else | ||
384 | _asn1_set_right (p3, p2); | ||
385 | |||
386 | return asn1_delete_structure (&source_node); | ||
387 | } | ||
388 | |||
389 | node_asn * | ||
390 | _asn1_copy_structure3 (node_asn * source_node) | ||
391 | { | ||
392 | node_asn *dest_node, *p_s, *p_d, *p_d_prev; | ||
393 | int move; | ||
394 | |||
395 | if (source_node == NULL) | ||
396 | return NULL; | ||
397 | |||
398 | dest_node = _asn1_add_node_only (source_node->type); | ||
399 | |||
400 | p_s = source_node; | ||
401 | p_d = dest_node; | ||
402 | |||
403 | move = DOWN; | ||
404 | |||
405 | do | ||
406 | { | ||
407 | if (move != UP) | ||
408 | { | ||
409 | if (p_s->name) | ||
410 | _asn1_set_name (p_d, p_s->name); | ||
411 | if (p_s->value) | ||
412 | _asn1_set_value (p_d, p_s->value, p_s->value_len); | ||
413 | move = DOWN; | ||
414 | } | ||
415 | else | ||
416 | move = RIGHT; | ||
417 | |||
418 | if (move == DOWN) | ||
419 | { | ||
420 | if (p_s->down) | ||
421 | { | ||
422 | p_s = p_s->down; | ||
423 | p_d_prev = p_d; | ||
424 | p_d = _asn1_add_node_only (p_s->type); | ||
425 | _asn1_set_down (p_d_prev, p_d); | ||
426 | } | ||
427 | else | ||
428 | move = RIGHT; | ||
429 | } | ||
430 | |||
431 | if (p_s == source_node) | ||
432 | break; | ||
433 | |||
434 | if (move == RIGHT) | ||
435 | { | ||
436 | if (p_s->right) | ||
437 | { | ||
438 | p_s = p_s->right; | ||
439 | p_d_prev = p_d; | ||
440 | p_d = _asn1_add_node_only (p_s->type); | ||
441 | _asn1_set_right (p_d_prev, p_d); | ||
442 | } | ||
443 | else | ||
444 | move = UP; | ||
445 | } | ||
446 | if (move == UP) | ||
447 | { | ||
448 | p_s = _asn1_find_up (p_s); | ||
449 | p_d = _asn1_find_up (p_d); | ||
450 | } | ||
451 | } | ||
452 | while (p_s != source_node); | ||
453 | |||
454 | return dest_node; | ||
455 | } | ||
456 | |||
457 | |||
458 | node_asn * | ||
459 | _asn1_copy_structure2 (node_asn * root, const char *source_name) | ||
460 | { | ||
461 | node_asn *source_node; | ||
462 | |||
463 | source_node = asn1_find_node (root, source_name); | ||
464 | |||
465 | return _asn1_copy_structure3 (source_node); | ||
466 | |||
467 | } | ||
468 | |||
469 | |||
470 | asn1_retCode | ||
471 | _asn1_type_choice_config (node_asn * node) | ||
472 | { | ||
473 | node_asn *p, *p2, *p3, *p4; | ||
474 | int move, tlen; | ||
475 | |||
476 | if (node == NULL) | ||
477 | return ASN1_ELEMENT_NOT_FOUND; | ||
478 | |||
479 | p = node; | ||
480 | move = DOWN; | ||
481 | |||
482 | while (!((p == node) && (move == UP))) | ||
483 | { | ||
484 | if (move != UP) | ||
485 | { | ||
486 | if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG)) | ||
487 | { | ||
488 | p2 = p->down; | ||
489 | while (p2) | ||
490 | { | ||
491 | if (type_field (p2->type) != TYPE_TAG) | ||
492 | { | ||
493 | p2->type |= CONST_TAG; | ||
494 | p3 = _asn1_find_left (p2); | ||
495 | while (p3) | ||
496 | { | ||
497 | if (type_field (p3->type) == TYPE_TAG) | ||
498 | { | ||
499 | p4 = _asn1_add_node_only (p3->type); | ||
500 | tlen = strlen (p3->value); | ||
501 | if (tlen > 0) | ||
502 | _asn1_set_value (p4, p3->value, tlen + 1); | ||
503 | _asn1_set_right (p4, p2->down); | ||
504 | _asn1_set_down (p2, p4); | ||
505 | } | ||
506 | p3 = _asn1_find_left (p3); | ||
507 | } | ||
508 | } | ||
509 | p2 = p2->right; | ||
510 | } | ||
511 | p->type &= ~(CONST_TAG); | ||
512 | p2 = p->down; | ||
513 | while (p2) | ||
514 | { | ||
515 | p3 = p2->right; | ||
516 | if (type_field (p2->type) == TYPE_TAG) | ||
517 | asn1_delete_structure (&p2); | ||
518 | p2 = p3; | ||
519 | } | ||
520 | } | ||
521 | move = DOWN; | ||
522 | } | ||
523 | else | ||
524 | move = RIGHT; | ||
525 | |||
526 | if (move == DOWN) | ||
527 | { | ||
528 | if (p->down) | ||
529 | p = p->down; | ||
530 | else | ||
531 | move = RIGHT; | ||
532 | } | ||
533 | |||
534 | if (p == node) | ||
535 | { | ||
536 | move = UP; | ||
537 | continue; | ||
538 | } | ||
539 | |||
540 | if (move == RIGHT) | ||
541 | { | ||
542 | if (p->right) | ||
543 | p = p->right; | ||
544 | else | ||
545 | move = UP; | ||
546 | } | ||
547 | if (move == UP) | ||
548 | p = _asn1_find_up (p); | ||
549 | } | ||
550 | |||
551 | return ASN1_SUCCESS; | ||
552 | } | ||
553 | |||
554 | |||
555 | asn1_retCode | ||
556 | _asn1_expand_identifier (node_asn ** node, node_asn * root) | ||
557 | { | ||
558 | node_asn *p, *p2, *p3; | ||
559 | char name2[MAX_NAME_SIZE + 2]; | ||
560 | int move; | ||
561 | |||
562 | if (node == NULL) | ||
563 | return ASN1_ELEMENT_NOT_FOUND; | ||
564 | |||
565 | p = *node; | ||
566 | move = DOWN; | ||
567 | |||
568 | while (!((p == *node) && (move == UP))) | ||
569 | { | ||
570 | if (move != UP) | ||
571 | { | ||
572 | if (type_field (p->type) == TYPE_IDENTIFIER) | ||
573 | { | ||
574 | _asn1_str_cpy (name2, sizeof (name2), root->name); | ||
575 | _asn1_str_cat (name2, sizeof (name2), "."); | ||
576 | _asn1_str_cat (name2, sizeof (name2), p->value); | ||
577 | p2 = _asn1_copy_structure2 (root, name2); | ||
578 | if (p2 == NULL) | ||
579 | { | ||
580 | return ASN1_IDENTIFIER_NOT_FOUND; | ||
581 | } | ||
582 | _asn1_set_name (p2, p->name); | ||
583 | p2->right = p->right; | ||
584 | p2->left = p->left; | ||
585 | if (p->right) | ||
586 | p->right->left = p2; | ||
587 | p3 = p->down; | ||
588 | if (p3) | ||
589 | { | ||
590 | while (p3->right) | ||
591 | p3 = p3->right; | ||
592 | _asn1_set_right (p3, p2->down); | ||
593 | _asn1_set_down (p2, p->down); | ||
594 | } | ||
595 | |||
596 | p3 = _asn1_find_left (p); | ||
597 | if (p3) | ||
598 | _asn1_set_right (p3, p2); | ||
599 | else | ||
600 | { | ||
601 | p3 = _asn1_find_up (p); | ||
602 | if (p3) | ||
603 | _asn1_set_down (p3, p2); | ||
604 | else | ||
605 | { | ||
606 | p2->left = NULL; | ||
607 | } | ||
608 | } | ||
609 | |||
610 | if (p->type & CONST_SIZE) | ||
611 | p2->type |= CONST_SIZE; | ||
612 | if (p->type & CONST_TAG) | ||
613 | p2->type |= CONST_TAG; | ||
614 | if (p->type & CONST_OPTION) | ||
615 | p2->type |= CONST_OPTION; | ||
616 | if (p->type & CONST_DEFAULT) | ||
617 | p2->type |= CONST_DEFAULT; | ||
618 | if (p->type & CONST_SET) | ||
619 | p2->type |= CONST_SET; | ||
620 | if (p->type & CONST_NOT_USED) | ||
621 | p2->type |= CONST_NOT_USED; | ||
622 | |||
623 | if (p == *node) | ||
624 | *node = p2; | ||
625 | _asn1_remove_node (p); | ||
626 | p = p2; | ||
627 | move = DOWN; | ||
628 | continue; | ||
629 | } | ||
630 | move = DOWN; | ||
631 | } | ||
632 | else | ||
633 | move = RIGHT; | ||
634 | |||
635 | if (move == DOWN) | ||
636 | { | ||
637 | if (p->down) | ||
638 | p = p->down; | ||
639 | else | ||
640 | move = RIGHT; | ||
641 | } | ||
642 | |||
643 | if (p == *node) | ||
644 | { | ||
645 | move = UP; | ||
646 | continue; | ||
647 | } | ||
648 | |||
649 | if (move == RIGHT) | ||
650 | { | ||
651 | if (p->right) | ||
652 | p = p->right; | ||
653 | else | ||
654 | move = UP; | ||
655 | } | ||
656 | if (move == UP) | ||
657 | p = _asn1_find_up (p); | ||
658 | } | ||
659 | |||
660 | return ASN1_SUCCESS; | ||
661 | } | ||
662 | |||
663 | |||
664 | /** | ||
665 | * asn1_create_element - Creates a structure of type SOURCE_NAME. | ||
666 | * @definitions: pointer to the structure returned by "parser_asn1" function | ||
667 | * @source_name: the name of the type of the new structure (must be | ||
668 | * inside p_structure). | ||
669 | * @element: pointer to the structure created. | ||
670 | * | ||
671 | * Creates a structure of type @source_name. Example using | ||
672 | * "pkix.asn": | ||
673 | * | ||
674 | * rc = asn1_create_structure(cert_def, "PKIX1.Certificate", | ||
675 | * certptr); | ||
676 | * | ||
677 | * Returns: | ||
678 | * | ||
679 | * ASN1_SUCCESS: Creation OK. | ||
680 | * | ||
681 | * ASN1_ELEMENT_NOT_FOUND: SOURCE_NAME isn't known | ||
682 | **/ | ||
683 | asn1_retCode | ||
684 | asn1_create_element (ASN1_TYPE definitions, const char *source_name, | ||
685 | ASN1_TYPE * element) | ||
686 | { | ||
687 | node_asn *dest_node; | ||
688 | int res; | ||
689 | |||
690 | dest_node = _asn1_copy_structure2 (definitions, source_name); | ||
691 | |||
692 | if (dest_node == NULL) | ||
693 | return ASN1_ELEMENT_NOT_FOUND; | ||
694 | |||
695 | _asn1_set_name (dest_node, ""); | ||
696 | |||
697 | res = _asn1_expand_identifier (&dest_node, definitions); | ||
698 | _asn1_type_choice_config (dest_node); | ||
699 | |||
700 | *element = dest_node; | ||
701 | |||
702 | return res; | ||
703 | } | ||
704 | |||
705 | |||
706 | /** | ||
707 | * asn1_print_structure - Prints on the standard output the structure's tree | ||
708 | * @out: pointer to the output file (e.g. stdout). | ||
709 | * @structure: pointer to the structure that you want to visit. | ||
710 | * @name: an element of the structure | ||
711 | * @mode: specify how much of the structure to print, can be | ||
712 | * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE, | ||
713 | * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL. | ||
714 | * | ||
715 | * Prints on the @out file descriptor the structure's tree starting | ||
716 | * from the @name element inside the structure @structure. | ||
717 | **/ | ||
718 | void | ||
719 | asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name, | ||
720 | int mode) | ||
721 | { | ||
722 | node_asn *p, *root; | ||
723 | int k, indent = 0, len, len2, len3; | ||
724 | |||
725 | if (out == NULL) | ||
726 | return; | ||
727 | |||
728 | root = asn1_find_node (structure, name); | ||
729 | |||
730 | if (root == NULL) | ||
731 | return; | ||
732 | |||
733 | p = root; | ||
734 | while (p) | ||
735 | { | ||
736 | if (mode == ASN1_PRINT_ALL) | ||
737 | { | ||
738 | for (k = 0; k < indent; k++) | ||
739 | fprintf (out, " "); | ||
740 | fprintf (out, "name:"); | ||
741 | if (p->name) | ||
742 | fprintf (out, "%s ", p->name); | ||
743 | else | ||
744 | fprintf (out, "NULL "); | ||
745 | } | ||
746 | else | ||
747 | { | ||
748 | switch (type_field (p->type)) | ||
749 | { | ||
750 | case TYPE_CONSTANT: | ||
751 | case TYPE_TAG: | ||
752 | case TYPE_SIZE: | ||
753 | break; | ||
754 | default: | ||
755 | for (k = 0; k < indent; k++) | ||
756 | fprintf (out, " "); | ||
757 | fprintf (out, "name:"); | ||
758 | if (p->name) | ||
759 | fprintf (out, "%s ", p->name); | ||
760 | else | ||
761 | fprintf (out, "NULL "); | ||
762 | } | ||
763 | } | ||
764 | |||
765 | if (mode != ASN1_PRINT_NAME) | ||
766 | { | ||
767 | switch (type_field (p->type)) | ||
768 | { | ||
769 | case TYPE_CONSTANT: | ||
770 | if (mode == ASN1_PRINT_ALL) | ||
771 | fprintf (out, "type:CONST"); | ||
772 | break; | ||
773 | case TYPE_TAG: | ||
774 | if (mode == ASN1_PRINT_ALL) | ||
775 | fprintf (out, "type:TAG"); | ||
776 | break; | ||
777 | case TYPE_SIZE: | ||
778 | if (mode == ASN1_PRINT_ALL) | ||
779 | fprintf (out, "type:SIZE"); | ||
780 | break; | ||
781 | case TYPE_DEFAULT: | ||
782 | fprintf (out, "type:DEFAULT"); | ||
783 | break; | ||
784 | case TYPE_NULL: | ||
785 | fprintf (out, "type:NULL"); | ||
786 | break; | ||
787 | case TYPE_IDENTIFIER: | ||
788 | fprintf (out, "type:IDENTIFIER"); | ||
789 | break; | ||
790 | case TYPE_INTEGER: | ||
791 | fprintf (out, "type:INTEGER"); | ||
792 | break; | ||
793 | case TYPE_ENUMERATED: | ||
794 | fprintf (out, "type:ENUMERATED"); | ||
795 | break; | ||
796 | case TYPE_TIME: | ||
797 | fprintf (out, "type:TIME"); | ||
798 | break; | ||
799 | case TYPE_BOOLEAN: | ||
800 | fprintf (out, "type:BOOLEAN"); | ||
801 | break; | ||
802 | case TYPE_SEQUENCE: | ||
803 | fprintf (out, "type:SEQUENCE"); | ||
804 | break; | ||
805 | case TYPE_BIT_STRING: | ||
806 | fprintf (out, "type:BIT_STR"); | ||
807 | break; | ||
808 | case TYPE_OCTET_STRING: | ||
809 | fprintf (out, "type:OCT_STR"); | ||
810 | break; | ||
811 | case TYPE_GENERALSTRING: | ||
812 | fprintf (out, "type:GENERALSTRING"); | ||
813 | break; | ||
814 | case TYPE_SEQUENCE_OF: | ||
815 | fprintf (out, "type:SEQ_OF"); | ||
816 | break; | ||
817 | case TYPE_OBJECT_ID: | ||
818 | fprintf (out, "type:OBJ_ID"); | ||
819 | break; | ||
820 | case TYPE_ANY: | ||
821 | fprintf (out, "type:ANY"); | ||
822 | break; | ||
823 | case TYPE_SET: | ||
824 | fprintf (out, "type:SET"); | ||
825 | break; | ||
826 | case TYPE_SET_OF: | ||
827 | fprintf (out, "type:SET_OF"); | ||
828 | break; | ||
829 | case TYPE_CHOICE: | ||
830 | fprintf (out, "type:CHOICE"); | ||
831 | break; | ||
832 | case TYPE_DEFINITIONS: | ||
833 | fprintf (out, "type:DEFINITIONS"); | ||
834 | break; | ||
835 | default: | ||
836 | break; | ||
837 | } | ||
838 | } | ||
839 | |||
840 | if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL)) | ||
841 | { | ||
842 | switch (type_field (p->type)) | ||
843 | { | ||
844 | case TYPE_CONSTANT: | ||
845 | if (mode == ASN1_PRINT_ALL) | ||
846 | if (p->value) | ||
847 | fprintf (out, " value:%s", p->value); | ||
848 | break; | ||
849 | case TYPE_TAG: | ||
850 | if (mode == ASN1_PRINT_ALL) | ||
851 | if (p->value) | ||
852 | fprintf (out, " value:%s", p->value); | ||
853 | break; | ||
854 | case TYPE_SIZE: | ||
855 | if (mode == ASN1_PRINT_ALL) | ||
856 | if (p->value) | ||
857 | fprintf (out, " value:%s", p->value); | ||
858 | break; | ||
859 | case TYPE_DEFAULT: | ||
860 | if (p->value) | ||
861 | fprintf (out, " value:%s", p->value); | ||
862 | else if (p->type & CONST_TRUE) | ||
863 | fprintf (out, " value:TRUE"); | ||
864 | else if (p->type & CONST_FALSE) | ||
865 | fprintf (out, " value:FALSE"); | ||
866 | break; | ||
867 | case TYPE_IDENTIFIER: | ||
868 | if (p->value) | ||
869 | fprintf (out, " value:%s", p->value); | ||
870 | break; | ||
871 | case TYPE_INTEGER: | ||
872 | if (p->value) | ||
873 | { | ||
874 | len2 = -1; | ||
875 | len = asn1_get_length_der (p->value, p->value_len, &len2); | ||
876 | fprintf (out, " value:0x"); | ||
877 | if (len > 0) | ||
878 | for (k = 0; k < len; k++) | ||
879 | fprintf (out, "%02x", (p->value)[k + len2]); | ||
880 | } | ||
881 | break; | ||
882 | case TYPE_ENUMERATED: | ||
883 | if (p->value) | ||
884 | { | ||
885 | len2 = -1; | ||
886 | len = asn1_get_length_der (p->value, p->value_len, &len2); | ||
887 | fprintf (out, " value:0x"); | ||
888 | if (len > 0) | ||
889 | for (k = 0; k < len; k++) | ||
890 | fprintf (out, "%02x", (p->value)[k + len2]); | ||
891 | } | ||
892 | break; | ||
893 | case TYPE_TIME: | ||
894 | if (p->value) | ||
895 | fprintf (out, " value:%s", p->value); | ||
896 | break; | ||
897 | case TYPE_BOOLEAN: | ||
898 | if (p->value) | ||
899 | { | ||
900 | if (p->value[0] == 'T') | ||
901 | fprintf (out, " value:TRUE"); | ||
902 | else if (p->value[0] == 'F') | ||
903 | fprintf (out, " value:FALSE"); | ||
904 | } | ||
905 | break; | ||
906 | case TYPE_BIT_STRING: | ||
907 | if (p->value) | ||
908 | { | ||
909 | len2 = -1; | ||
910 | len = asn1_get_length_der (p->value, p->value_len, &len2); | ||
911 | if (len > 0) | ||
912 | { | ||
913 | fprintf (out, " value(%i):", | ||
914 | (len - 1) * 8 - (p->value[len2])); | ||
915 | for (k = 1; k < len; k++) | ||
916 | fprintf (out, "%02x", (p->value)[k + len2]); | ||
917 | } | ||
918 | } | ||
919 | break; | ||
920 | case TYPE_OCTET_STRING: | ||
921 | if (p->value) | ||
922 | { | ||
923 | len2 = -1; | ||
924 | len = asn1_get_length_der (p->value, p->value_len, &len2); | ||
925 | fprintf (out, " value:"); | ||
926 | if (len > 0) | ||
927 | for (k = 0; k < len; k++) | ||
928 | fprintf (out, "%02x", (p->value)[k + len2]); | ||
929 | } | ||
930 | break; | ||
931 | case TYPE_GENERALSTRING: | ||
932 | if (p->value) | ||
933 | { | ||
934 | len2 = -1; | ||
935 | len = asn1_get_length_der (p->value, p->value_len, &len2); | ||
936 | fprintf (out, " value:"); | ||
937 | if (len > 0) | ||
938 | for (k = 0; k < len; k++) | ||
939 | fprintf (out, "%02x", (p->value)[k + len2]); | ||
940 | } | ||
941 | break; | ||
942 | case TYPE_OBJECT_ID: | ||
943 | if (p->value) | ||
944 | fprintf (out, " value:%s", p->value); | ||
945 | break; | ||
946 | case TYPE_ANY: | ||
947 | if (p->value) | ||
948 | { | ||
949 | len3 = -1; | ||
950 | len2 = asn1_get_length_der (p->value, p->value_len, &len3); | ||
951 | fprintf (out, " value:"); | ||
952 | if (len2 > 0) | ||
953 | for (k = 0; k < len2; k++) | ||
954 | fprintf (out, "%02x", (p->value)[k + len3]); | ||
955 | } | ||
956 | break; | ||
957 | case TYPE_SET: | ||
958 | case TYPE_SET_OF: | ||
959 | case TYPE_CHOICE: | ||
960 | case TYPE_DEFINITIONS: | ||
961 | case TYPE_SEQUENCE_OF: | ||
962 | case TYPE_SEQUENCE: | ||
963 | case TYPE_NULL: | ||
964 | break; | ||
965 | default: | ||
966 | break; | ||
967 | } | ||
968 | } | ||
969 | |||
970 | if (mode == ASN1_PRINT_ALL) | ||
971 | { | ||
972 | if (p->type & 0x1FFFFF00) | ||
973 | { | ||
974 | fprintf (out, " attr:"); | ||
975 | if (p->type & CONST_UNIVERSAL) | ||
976 | fprintf (out, "UNIVERSAL,"); | ||
977 | if (p->type & CONST_PRIVATE) | ||
978 | fprintf (out, "PRIVATE,"); | ||
979 | if (p->type & CONST_APPLICATION) | ||
980 | fprintf (out, "APPLICATION,"); | ||
981 | if (p->type & CONST_EXPLICIT) | ||
982 | fprintf (out, "EXPLICIT,"); | ||
983 | if (p->type & CONST_IMPLICIT) | ||
984 | fprintf (out, "IMPLICIT,"); | ||
985 | if (p->type & CONST_TAG) | ||
986 | fprintf (out, "TAG,"); | ||
987 | if (p->type & CONST_DEFAULT) | ||
988 | fprintf (out, "DEFAULT,"); | ||
989 | if (p->type & CONST_TRUE) | ||
990 | fprintf (out, "TRUE,"); | ||
991 | if (p->type & CONST_FALSE) | ||
992 | fprintf (out, "FALSE,"); | ||
993 | if (p->type & CONST_LIST) | ||
994 | fprintf (out, "LIST,"); | ||
995 | if (p->type & CONST_MIN_MAX) | ||
996 | fprintf (out, "MIN_MAX,"); | ||
997 | if (p->type & CONST_OPTION) | ||
998 | fprintf (out, "OPTION,"); | ||
999 | if (p->type & CONST_1_PARAM) | ||
1000 | fprintf (out, "1_PARAM,"); | ||
1001 | if (p->type & CONST_SIZE) | ||
1002 | fprintf (out, "SIZE,"); | ||
1003 | if (p->type & CONST_DEFINED_BY) | ||
1004 | fprintf (out, "DEF_BY,"); | ||
1005 | if (p->type & CONST_GENERALIZED) | ||
1006 | fprintf (out, "GENERALIZED,"); | ||
1007 | if (p->type & CONST_UTC) | ||
1008 | fprintf (out, "UTC,"); | ||
1009 | if (p->type & CONST_SET) | ||
1010 | fprintf (out, "SET,"); | ||
1011 | if (p->type & CONST_NOT_USED) | ||
1012 | fprintf (out, "NOT_USED,"); | ||
1013 | if (p->type & CONST_ASSIGN) | ||
1014 | fprintf (out, "ASSIGNMENT,"); | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | if (mode == ASN1_PRINT_ALL) | ||
1019 | { | ||
1020 | fprintf (out, "\n"); | ||
1021 | } | ||
1022 | else | ||
1023 | { | ||
1024 | switch (type_field (p->type)) | ||
1025 | { | ||
1026 | case TYPE_CONSTANT: | ||
1027 | case TYPE_TAG: | ||
1028 | case TYPE_SIZE: | ||
1029 | break; | ||
1030 | default: | ||
1031 | fprintf (out, "\n"); | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | if (p->down) | ||
1036 | { | ||
1037 | p = p->down; | ||
1038 | indent += 2; | ||
1039 | } | ||
1040 | else if (p == root) | ||
1041 | { | ||
1042 | p = NULL; | ||
1043 | break; | ||
1044 | } | ||
1045 | else if (p->right) | ||
1046 | p = p->right; | ||
1047 | else | ||
1048 | { | ||
1049 | while (1) | ||
1050 | { | ||
1051 | p = _asn1_find_up (p); | ||
1052 | if (p == root) | ||
1053 | { | ||
1054 | p = NULL; | ||
1055 | break; | ||
1056 | } | ||
1057 | indent -= 2; | ||
1058 | if (p->right) | ||
1059 | { | ||
1060 | p = p->right; | ||
1061 | break; | ||
1062 | } | ||
1063 | } | ||
1064 | } | ||
1065 | } | ||
1066 | } | ||
1067 | |||
1068 | |||
1069 | |||
1070 | /** | ||
1071 | * asn1_number_of_elements - Counts the number of elements of a structure. | ||
1072 | * @element: pointer to the root of an ASN1 structure. | ||
1073 | * @name: the name of a sub-structure of ROOT. | ||
1074 | * @num: pointer to an integer where the result will be stored | ||
1075 | * | ||
1076 | * Counts the number of elements of a sub-structure called NAME with | ||
1077 | * names equal to "?1","?2", ... | ||
1078 | * | ||
1079 | * Returns: | ||
1080 | * | ||
1081 | * ASN1_SUCCESS: Creation OK. | ||
1082 | * | ||
1083 | * ASN1_ELEMENT_NOT_FOUND: NAME isn't known. | ||
1084 | * | ||
1085 | * ASN1_GENERIC_ERROR: Pointer num equal to NULL. | ||
1086 | * | ||
1087 | **/ | ||
1088 | asn1_retCode | ||
1089 | asn1_number_of_elements (ASN1_TYPE element, const char *name, int *num) | ||
1090 | { | ||
1091 | node_asn *node, *p; | ||
1092 | |||
1093 | if (num == NULL) | ||
1094 | return ASN1_GENERIC_ERROR; | ||
1095 | |||
1096 | *num = 0; | ||
1097 | |||
1098 | node = asn1_find_node (element, name); | ||
1099 | if (node == NULL) | ||
1100 | return ASN1_ELEMENT_NOT_FOUND; | ||
1101 | |||
1102 | p = node->down; | ||
1103 | |||
1104 | while (p) | ||
1105 | { | ||
1106 | if ((p->name) && (p->name[0] == '?')) | ||
1107 | (*num)++; | ||
1108 | p = p->right; | ||
1109 | } | ||
1110 | |||
1111 | return ASN1_SUCCESS; | ||
1112 | } | ||
1113 | |||
1114 | |||
1115 | /** | ||
1116 | * asn1_find_structure_from_oid - Locate structure defined by a specific OID. | ||
1117 | * @definitions: ASN1 definitions | ||
1118 | * @oidValue: value of the OID to search (e.g. "1.2.3.4"). | ||
1119 | * | ||
1120 | * Search the structure that is defined just after an OID definition. | ||
1121 | * | ||
1122 | * Returns: NULL when OIDVALUE not found, otherwise the pointer to a | ||
1123 | * constant string that contains the element name defined just | ||
1124 | * after the OID. | ||
1125 | * | ||
1126 | **/ | ||
1127 | const char * | ||
1128 | asn1_find_structure_from_oid (ASN1_TYPE definitions, const char *oidValue) | ||
1129 | { | ||
1130 | char definitionsName[MAX_NAME_SIZE], name[2 * MAX_NAME_SIZE + 1]; | ||
1131 | char value[MAX_NAME_SIZE]; | ||
1132 | ASN1_TYPE p; | ||
1133 | int len; | ||
1134 | asn1_retCode result; | ||
1135 | |||
1136 | if ((definitions == ASN1_TYPE_EMPTY) || (oidValue == NULL)) | ||
1137 | return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ | ||
1138 | |||
1139 | |||
1140 | strcpy (definitionsName, definitions->name); | ||
1141 | strcat (definitionsName, "."); | ||
1142 | |||
1143 | /* search the OBJECT_ID into definitions */ | ||
1144 | p = definitions->down; | ||
1145 | while (p) | ||
1146 | { | ||
1147 | if ((type_field (p->type) == TYPE_OBJECT_ID) && | ||
1148 | (p->type & CONST_ASSIGN)) | ||
1149 | { | ||
1150 | strcpy (name, definitionsName); | ||
1151 | strcat (name, p->name); | ||
1152 | |||
1153 | len = MAX_NAME_SIZE; | ||
1154 | result = asn1_read_value (definitions, name, value, &len); | ||
1155 | |||
1156 | if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value))) | ||
1157 | { | ||
1158 | p = p->right; | ||
1159 | if (p == NULL) /* reach the end of ASN1 definitions */ | ||
1160 | return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ | ||
1161 | |||
1162 | return p->name; | ||
1163 | } | ||
1164 | } | ||
1165 | p = p->right; | ||
1166 | } | ||
1167 | |||
1168 | return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ | ||
1169 | } | ||
1170 | |||
1171 | /** | ||
1172 | * asn1_copy_node: | ||
1173 | * @dst: Destination ASN1_TYPE node. | ||
1174 | * @dst_name: Field name in destination node. | ||
1175 | * @src: Source ASN1_TYPE node. | ||
1176 | * @src_name: Field name in source node. | ||
1177 | * | ||
1178 | * Create a deep copy of a ASN1_TYPE variable. | ||
1179 | * | ||
1180 | * Return value: Return ASN1_SUCCESS on success. | ||
1181 | **/ | ||
1182 | asn1_retCode | ||
1183 | asn1_copy_node (ASN1_TYPE dst, const char *dst_name, | ||
1184 | ASN1_TYPE src, const char *src_name) | ||
1185 | { | ||
1186 | /* FIXME: rewrite using copy_structure(). | ||
1187 | * It seems quite hard to do. | ||
1188 | */ | ||
1189 | int result; | ||
1190 | ASN1_TYPE dst_node; | ||
1191 | void *data = NULL; | ||
1192 | int size = 0; | ||
1193 | |||
1194 | result = asn1_der_coding (src, src_name, NULL, &size, NULL); | ||
1195 | if (result != ASN1_MEM_ERROR) | ||
1196 | return result; | ||
1197 | |||
1198 | data = _asn1_malloc (size); | ||
1199 | if (data == NULL) | ||
1200 | return ASN1_MEM_ERROR; | ||
1201 | |||
1202 | result = asn1_der_coding (src, src_name, data, &size, NULL); | ||
1203 | if (result != ASN1_SUCCESS) | ||
1204 | { | ||
1205 | _asn1_free (data); | ||
1206 | return result; | ||
1207 | } | ||
1208 | |||
1209 | dst_node = asn1_find_node (dst, dst_name); | ||
1210 | if (dst_node == NULL) | ||
1211 | { | ||
1212 | _asn1_free (data); | ||
1213 | return ASN1_ELEMENT_NOT_FOUND; | ||
1214 | } | ||
1215 | |||
1216 | result = asn1_der_decoding (&dst_node, data, size, NULL); | ||
1217 | |||
1218 | _asn1_free (data); | ||
1219 | |||
1220 | return result; | ||
1221 | } | ||
diff --git a/src/daemon/https/minitasn1/structure.h b/src/daemon/https/minitasn1/structure.h new file mode 100644 index 00000000..4c78391e --- /dev/null +++ b/src/daemon/https/minitasn1/structure.h | |||
@@ -0,0 +1,23 @@ | |||
1 | |||
2 | /*************************************************/ | ||
3 | /* File: structure.h */ | ||
4 | /* Description: list of exported object by */ | ||
5 | /* "structure.c" */ | ||
6 | /*************************************************/ | ||
7 | |||
8 | #ifndef _STRUCTURE_H | ||
9 | #define _STRUCTURE_H | ||
10 | |||
11 | asn1_retCode _asn1_create_static_structure(node_asn *pointer, | ||
12 | char* output_file_name,char *vector_name); | ||
13 | |||
14 | node_asn* _asn1_copy_structure3(node_asn *source_node); | ||
15 | |||
16 | node_asn* _asn1_copy_structure2(node_asn *root,const char *source_name); | ||
17 | |||
18 | node_asn * _asn1_add_node_only(unsigned int type); | ||
19 | |||
20 | node_asn * _asn1_find_left(node_asn *node); | ||
21 | |||
22 | #endif | ||
23 | |||