Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2000-2012 Free Software Foundation, Inc.
3 : : *
4 : : * This file is part of LIBTASN1.
5 : : *
6 : : * The LIBTASN1 library is free software; you can redistribute it
7 : : * and/or modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * This library is distributed in the hope that it will be useful, but
12 : : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General Public
17 : : * License along with this library; if not, write to the Free Software
18 : : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 : : * 02110-1301, USA
20 : : */
21 : :
22 : : /*****************************************************/
23 : : /* File: element.c */
24 : : /* Description: Functions with the read and write */
25 : : /* functions. */
26 : : /*****************************************************/
27 : :
28 : :
29 : : #include <int.h>
30 : : #include "parser_aux.h"
31 : : #include <gstr.h>
32 : : #include "structure.h"
33 : :
34 : : #include "element.h"
35 : :
36 : : void
37 : 0 : _asn1_hierarchical_name (ASN1_TYPE node, char *name, int name_size)
38 : : {
39 : : ASN1_TYPE p;
40 : : char tmp_name[64];
41 : :
42 : 0 : p = node;
43 : :
44 : 0 : name[0] = 0;
45 : :
46 [ # # ]: 0 : while (p != NULL)
47 : : {
48 [ # # ]: 0 : if (p->name != NULL)
49 : : {
50 : 0 : _asn1_str_cpy (tmp_name, sizeof (tmp_name), name),
51 : 0 : _asn1_str_cpy (name, name_size, p->name);
52 : 0 : _asn1_str_cat (name, name_size, ".");
53 : 0 : _asn1_str_cat (name, name_size, tmp_name);
54 : : }
55 : 0 : p = _asn1_find_up (p);
56 : : }
57 : :
58 [ # # ]: 0 : if (name[0] == 0)
59 : 0 : _asn1_str_cpy (name, name_size, "ROOT");
60 : 0 : }
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 : 145 : _asn1_convert_integer (const unsigned 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 : 145 : valtmp = _asn1_strtol (value, NULL, 10);
87 : :
88 [ + + ]: 1305 : for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
89 : : {
90 : 1160 : val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
91 : : }
92 : :
93 [ + + ]: 145 : if (val[0] & 0x80)
94 : 4 : negative = 1;
95 : : else
96 : 141 : negative = 0;
97 : :
98 [ + + ]: 1138 : for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
99 : : {
100 [ + + ][ + + ]: 1005 : if (negative && (val[k] != 0xFF))
101 : : break;
102 [ + + ][ + + ]: 1003 : else if (!negative && val[k])
103 : 10 : break;
104 : : }
105 : :
106 [ + + ][ + - ]: 145 : if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
[ + + ][ + + ]
107 : 15 : k--;
108 : :
109 : 145 : *len = SIZEOF_UNSIGNED_LONG_INT - k;
110 : :
111 [ - + ]: 145 : if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
112 : : /* VALUE_OUT is too short to contain the value conversion */
113 : 0 : return ASN1_MEM_ERROR;
114 : :
115 [ + + ]: 327 : for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
116 : 182 : value_out[k2 - k] = val[k2];
117 : :
118 : : #if 0
119 : : printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
120 : : for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
121 : : printf (", vOut[%d]=%d", k, value_out[k]);
122 : : printf ("\n");
123 : : #endif
124 : :
125 : 145 : return ASN1_SUCCESS;
126 : : }
127 : :
128 : :
129 : : int
130 : 41 : _asn1_append_sequence_set (ASN1_TYPE node)
131 : : {
132 : : ASN1_TYPE p, p2;
133 : : char temp[10];
134 : : long n;
135 : :
136 [ + - ][ - + ]: 41 : if (!node || !(node->down))
137 : 0 : return ASN1_GENERIC_ERROR;
138 : :
139 : 41 : p = node->down;
140 [ + + ]: 79 : while ((type_field (p->type) == TYPE_TAG)
141 [ + + ]: 63 : || (type_field (p->type) == TYPE_SIZE))
142 : 38 : p = p->right;
143 : 41 : p2 = _asn1_copy_structure3 (p);
144 [ + + ]: 96 : while (p->right)
145 : 55 : p = p->right;
146 : 41 : _asn1_set_right (p, p2);
147 : :
148 [ + + ]: 41 : if (p->name == NULL)
149 : 18 : _asn1_str_cpy (temp, sizeof (temp), "?1");
150 : : else
151 : : {
152 : 23 : n = strtol (p->name + 1, NULL, 0);
153 : 23 : n++;
154 : 23 : temp[0] = '?';
155 : 23 : _asn1_ltostr (n, temp + 1);
156 : : }
157 : 41 : _asn1_set_name (p2, temp);
158 : : /* p2->type |= CONST_OPTION; */
159 : :
160 : 41 : return ASN1_SUCCESS;
161 : : }
162 : :
163 : :
164 : : /**
165 : : * asn1_write_value:
166 : : * @node_root: pointer to a structure
167 : : * @name: the name of the element inside the structure that you want to set.
168 : : * @ivalue: vector used to specify the value to set. If len is >0,
169 : : * VALUE must be a two's complement form integer. if len=0 *VALUE
170 : : * must be a null terminated string with an integer value.
171 : : * @len: number of bytes of *value to use to set the value:
172 : : * value[0]..value[len-1] or 0 if value is a null terminated string
173 : : *
174 : : * Set the value of one element inside a structure.
175 : : *
176 : : * If an element is OPTIONAL and you want to delete it, you must use
177 : : * the value=NULL and len=0. Using "pkix.asn":
178 : : *
179 : : * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
180 : : * NULL, 0);
181 : : *
182 : : * Description for each type:
183 : : *
184 : : * INTEGER: VALUE must contain a two's complement form integer.
185 : : *
186 : : * value[0]=0xFF , len=1 -> integer=-1.
187 : : * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
188 : : * value[0]=0x01 , len=1 -> integer= 1.
189 : : * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
190 : : * value="123" , len=0 -> integer= 123.
191 : : *
192 : : * ENUMERATED: As INTEGER (but only with not negative numbers).
193 : : *
194 : : * BOOLEAN: VALUE must be the null terminated string "TRUE" or
195 : : * "FALSE" and LEN != 0.
196 : : *
197 : : * value="TRUE" , len=1 -> boolean=TRUE.
198 : : * value="FALSE" , len=1 -> boolean=FALSE.
199 : : *
200 : : * OBJECT IDENTIFIER: VALUE must be a null terminated string with
201 : : * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0.
202 : : *
203 : : * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
204 : : *
205 : : * UTCTime: VALUE must be a null terminated string in one of these
206 : : * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
207 : : * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
208 : : * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0.
209 : : *
210 : : * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
211 : : * at 12h 00m Greenwich Mean Time
212 : : *
213 : : * GeneralizedTime: VALUE must be in one of this format:
214 : : * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
215 : : * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
216 : : * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
217 : : * indicates the seconds with any precision like "10.1" or "01.02".
218 : : * LEN != 0
219 : : *
220 : : * value="2001010112001.12-0700" , len=1 -> time=Jannuary
221 : : * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
222 : : *
223 : : * OCTET STRING: VALUE contains the octet string and LEN is the
224 : : * number of octets.
225 : : *
226 : : * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
227 : : * len=3 -> three bytes octet string
228 : : *
229 : : * GeneralString: VALUE contains the generalstring and LEN is the
230 : : * number of octets.
231 : : *
232 : : * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
233 : : * len=3 -> three bytes generalstring
234 : : *
235 : : * BIT STRING: VALUE contains the bit string organized by bytes and
236 : : * LEN is the number of bits.
237 : : *
238 : : * value="$\backslash$xCF" , len=6 -> bit string="110011" (six
239 : : * bits)
240 : : *
241 : : * CHOICE: if NAME indicates a choice type, VALUE must specify one of
242 : : * the alternatives with a null terminated string. LEN != 0. Using
243 : : * "pkix.asn"\:
244 : : *
245 : : * result=asn1_write_value(cert,
246 : : * "certificate1.tbsCertificate.subject", "rdnSequence",
247 : : * 1);
248 : : *
249 : : * ANY: VALUE indicates the der encoding of a structure. LEN != 0.
250 : : *
251 : : * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
252 : : * LEN != 0. With this instruction another element is appended in
253 : : * the sequence. The name of this element will be "?1" if it's the
254 : : * first one, "?2" for the second and so on.
255 : : *
256 : : * Using "pkix.asn"\:
257 : : *
258 : : * result=asn1_write_value(cert,
259 : : * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
260 : : *
261 : : * SET OF: the same as SEQUENCE OF. Using "pkix.asn":
262 : : *
263 : : * result=asn1_write_value(cert,
264 : : * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
265 : : *
266 : : * Returns: %ASN1_SUCCESS if the value was set,
267 : : * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, and
268 : : * %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format.
269 : : **/
270 : : asn1_retCode
271 : 85 : asn1_write_value (ASN1_TYPE node_root, const char *name,
272 : : const void *ivalue, int len)
273 : : {
274 : : ASN1_TYPE node, p, p2;
275 : 85 : unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
276 : : int len2, k, k2, negative;
277 : : size_t i;
278 : 85 : const unsigned char *value = ivalue;
279 : :
280 : 85 : node = asn1_find_node (node_root, name);
281 [ - + ]: 85 : if (node == NULL)
282 : 0 : return ASN1_ELEMENT_NOT_FOUND;
283 : :
284 [ + + ][ + + ]: 85 : if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
[ + - ]
285 : : {
286 : 5 : asn1_delete_structure (&node);
287 : 5 : return ASN1_SUCCESS;
288 : : }
289 : :
290 [ + + ][ - + ]: 80 : if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
291 [ # # ]: 0 : && (len == 0))
292 : : {
293 : 0 : p = node->down;
294 [ # # ]: 0 : while ((type_field (p->type) == TYPE_TAG)
295 [ # # ]: 0 : || (type_field (p->type) == TYPE_SIZE))
296 : 0 : p = p->right;
297 : :
298 [ # # ]: 0 : while (p->right)
299 : 0 : asn1_delete_structure (&p->right);
300 : :
301 : 0 : return ASN1_SUCCESS;
302 : : }
303 : :
304 [ + + + + : 80 : switch (type_field (node->type))
+ + + + +
+ - ]
305 : : {
306 : : case TYPE_BOOLEAN:
307 [ + - ]: 1 : if (!_asn1_strcmp (value, "TRUE"))
308 : : {
309 [ - + ]: 1 : if (node->type & CONST_DEFAULT)
310 : : {
311 : 0 : p = node->down;
312 [ # # ]: 0 : while (type_field (p->type) != TYPE_DEFAULT)
313 : 0 : p = p->right;
314 [ # # ]: 0 : if (p->type & CONST_TRUE)
315 : 0 : _asn1_set_value (node, NULL, 0);
316 : : else
317 : 0 : _asn1_set_value (node, "T", 1);
318 : : }
319 : : else
320 : 1 : _asn1_set_value (node, "T", 1);
321 : : }
322 [ # # ]: 0 : else if (!_asn1_strcmp (value, "FALSE"))
323 : : {
324 [ # # ]: 0 : if (node->type & CONST_DEFAULT)
325 : : {
326 : 0 : p = node->down;
327 [ # # ]: 0 : while (type_field (p->type) != TYPE_DEFAULT)
328 : 0 : p = p->right;
329 [ # # ]: 0 : if (p->type & CONST_FALSE)
330 : 0 : _asn1_set_value (node, NULL, 0);
331 : : else
332 : 0 : _asn1_set_value (node, "F", 1);
333 : : }
334 : : else
335 : 0 : _asn1_set_value (node, "F", 1);
336 : : }
337 : : else
338 : 0 : return ASN1_VALUE_NOT_VALID;
339 : 1 : break;
340 : : case TYPE_INTEGER:
341 : : case TYPE_ENUMERATED:
342 [ + + ]: 24 : if (len == 0)
343 : : {
344 [ + + ][ + + ]: 23 : if ((isdigit (value[0])) || (value[0] == '-'))
345 : : {
346 : 22 : value_temp =
347 : : (unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
348 [ - + ]: 22 : if (value_temp == NULL)
349 : 0 : return ASN1_MEM_ALLOC_ERROR;
350 : :
351 : 22 : _asn1_convert_integer (value, value_temp,
352 : : SIZEOF_UNSIGNED_LONG_INT, &len);
353 : : }
354 : : else
355 : : { /* is an identifier like v1 */
356 [ - + ]: 1 : if (!(node->type & CONST_LIST))
357 : 0 : return ASN1_VALUE_NOT_VALID;
358 : 1 : p = node->down;
359 [ + - ]: 4 : while (p)
360 : : {
361 [ + + ]: 4 : if (type_field (p->type) == TYPE_CONSTANT)
362 : : {
363 [ + - ][ + + ]: 2 : if ((p->name) && (!_asn1_strcmp (p->name, value)))
364 : : {
365 : 1 : value_temp =
366 : : (unsigned char *)
367 : : _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
368 [ - + ]: 1 : if (value_temp == NULL)
369 : 0 : return ASN1_MEM_ALLOC_ERROR;
370 : :
371 : 1 : _asn1_convert_integer (p->value,
372 : : value_temp,
373 : : SIZEOF_UNSIGNED_LONG_INT,
374 : : &len);
375 : 1 : break;
376 : : }
377 : : }
378 : 3 : p = p->right;
379 : : }
380 [ - + ]: 1 : if (p == NULL)
381 : 23 : return ASN1_VALUE_NOT_VALID;
382 : : }
383 : : }
384 : : else
385 : : { /* len != 0 */
386 : 1 : value_temp = (unsigned char *) _asn1_malloc (len);
387 [ - + ]: 1 : if (value_temp == NULL)
388 : 0 : return ASN1_MEM_ALLOC_ERROR;
389 : 1 : memcpy (value_temp, value, len);
390 : : }
391 : :
392 : :
393 [ + + ]: 24 : if (value_temp[0] & 0x80)
394 : 3 : negative = 1;
395 : : else
396 : 21 : negative = 0;
397 : :
398 [ + + ][ - + ]: 24 : if (negative && (type_field (node->type) == TYPE_ENUMERATED))
399 : : {
400 : 0 : _asn1_free (value_temp);
401 : 0 : return ASN1_VALUE_NOT_VALID;
402 : : }
403 : :
404 [ + + ]: 24 : for (k = 0; k < len - 1; k++)
405 [ + + ][ - + ]: 7 : if (negative && (value_temp[k] != 0xFF))
406 : : break;
407 [ + - ][ + - ]: 5 : else if (!negative && value_temp[k])
408 : 5 : break;
409 : :
410 [ + + ][ + - ]: 24 : if ((negative && !(value_temp[k] & 0x80)) ||
[ + + ]
411 [ - + ]: 21 : (!negative && (value_temp[k] & 0x80)))
412 : 0 : k--;
413 : :
414 : 24 : _asn1_set_value_octet (node, value_temp + k, len - k);
415 : :
416 [ + + ]: 24 : if (node->type & CONST_DEFAULT)
417 : : {
418 : 2 : p = node->down;
419 [ - + ]: 2 : while (type_field (p->type) != TYPE_DEFAULT)
420 : 0 : p = p->right;
421 [ + - ][ - + ]: 2 : if ((isdigit (p->value[0])) || (p->value[0] == '-'))
422 : : {
423 : 0 : default_temp =
424 : : (unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
425 [ # # ]: 0 : if (default_temp == NULL)
426 : : {
427 : 0 : _asn1_free (value_temp);
428 : 0 : return ASN1_MEM_ALLOC_ERROR;
429 : : }
430 : :
431 : 0 : _asn1_convert_integer (p->value, default_temp,
432 : : SIZEOF_UNSIGNED_LONG_INT, &len2);
433 : : }
434 : : else
435 : : { /* is an identifier like v1 */
436 [ - + ]: 2 : if (!(node->type & CONST_LIST))
437 : : {
438 : 0 : _asn1_free (value_temp);
439 : 0 : return ASN1_VALUE_NOT_VALID;
440 : : }
441 : 2 : p2 = node->down;
442 [ + - ]: 6 : while (p2)
443 : : {
444 [ + + ]: 6 : if (type_field (p2->type) == TYPE_CONSTANT)
445 : : {
446 [ + - ][ + + ]: 3 : if ((p2->name) && (!_asn1_strcmp (p2->name, p->value)))
447 : : {
448 : 2 : default_temp =
449 : : (unsigned char *)
450 : : _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
451 [ - + ]: 2 : if (default_temp == NULL)
452 : : {
453 : 0 : _asn1_free (value_temp);
454 : 0 : return ASN1_MEM_ALLOC_ERROR;
455 : : }
456 : :
457 : 2 : _asn1_convert_integer (p2->value,
458 : : default_temp,
459 : : SIZEOF_UNSIGNED_LONG_INT,
460 : : &len2);
461 : 2 : break;
462 : : }
463 : : }
464 : 4 : p2 = p2->right;
465 : : }
466 [ - + ]: 2 : if (p2 == NULL)
467 : : {
468 : 0 : _asn1_free (value_temp);
469 : 0 : return ASN1_VALUE_NOT_VALID;
470 : : }
471 : : }
472 : :
473 : :
474 [ + - ]: 2 : if ((len - k) == len2)
475 : : {
476 [ + + ]: 3 : for (k2 = 0; k2 < len2; k2++)
477 [ + + ]: 2 : if (value_temp[k + k2] != default_temp[k2])
478 : : {
479 : 1 : break;
480 : : }
481 [ + + ]: 2 : if (k2 == len2)
482 : 1 : _asn1_set_value (node, NULL, 0);
483 : : }
484 : 2 : _asn1_free (default_temp);
485 : : }
486 : 24 : _asn1_free (value_temp);
487 : 24 : break;
488 : : case TYPE_OBJECT_ID:
489 [ + + ]: 148 : for (i = 0; i < _asn1_strlen (value); i++)
490 [ + + ][ + + ]: 132 : if ((!isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
[ + - ]
491 : 1 : return ASN1_VALUE_NOT_VALID;
492 [ + + ]: 16 : if (node->type & CONST_DEFAULT)
493 : : {
494 : 4 : p = node->down;
495 [ - + ]: 4 : while (type_field (p->type) != TYPE_DEFAULT)
496 : 0 : p = p->right;
497 [ + + ]: 4 : if (!_asn1_strcmp (value, p->value))
498 : : {
499 : 2 : _asn1_set_value (node, NULL, 0);
500 : 2 : break;
501 : : }
502 : : }
503 : 14 : _asn1_set_value (node, value, _asn1_strlen (value) + 1);
504 : 14 : break;
505 : : case TYPE_TIME:
506 [ + + ]: 2 : if (node->type & CONST_UTC)
507 : : {
508 [ - + ]: 1 : if (_asn1_strlen (value) < 11)
509 : 0 : return ASN1_VALUE_NOT_VALID;
510 [ + + ]: 11 : for (k = 0; k < 10; k++)
511 [ - + ]: 10 : if (!isdigit (value[k]))
512 : 0 : return ASN1_VALUE_NOT_VALID;
513 [ + - - - : 1 : switch (_asn1_strlen (value))
- ]
514 : : {
515 : : case 11:
516 [ - + ]: 1 : if (value[10] != 'Z')
517 : 0 : return ASN1_VALUE_NOT_VALID;
518 : 1 : break;
519 : : case 13:
520 [ # # ][ # # ]: 0 : if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
[ # # ]
521 : 0 : (value[12] != 'Z'))
522 : 0 : return ASN1_VALUE_NOT_VALID;
523 : 0 : break;
524 : : case 15:
525 [ # # ][ # # ]: 0 : if ((value[10] != '+') && (value[10] != '-'))
526 : 0 : return ASN1_VALUE_NOT_VALID;
527 [ # # ]: 0 : for (k = 11; k < 15; k++)
528 [ # # ]: 0 : if (!isdigit (value[k]))
529 : 0 : return ASN1_VALUE_NOT_VALID;
530 : 0 : break;
531 : : case 17:
532 [ # # ][ # # ]: 0 : if ((!isdigit (value[10])) || (!isdigit (value[11])))
533 : 0 : return ASN1_VALUE_NOT_VALID;
534 [ # # ][ # # ]: 0 : if ((value[12] != '+') && (value[12] != '-'))
535 : 0 : return ASN1_VALUE_NOT_VALID;
536 [ # # ]: 0 : for (k = 13; k < 17; k++)
537 [ # # ]: 0 : if (!isdigit (value[k]))
538 : 0 : return ASN1_VALUE_NOT_VALID;
539 : 0 : break;
540 : : default:
541 : 0 : return ASN1_VALUE_NOT_FOUND;
542 : : }
543 : 1 : _asn1_set_value (node, value, _asn1_strlen (value) + 1);
544 : : }
545 : : else
546 : : { /* GENERALIZED TIME */
547 [ + - ]: 1 : if (value)
548 : 1 : _asn1_set_value (node, value, _asn1_strlen (value) + 1);
549 : : }
550 : 2 : break;
551 : : case TYPE_OCTET_STRING:
552 [ + + ]: 7 : if (len == 0)
553 : 2 : len = _asn1_strlen (value);
554 : 7 : _asn1_set_value_octet (node, value, len);
555 : 7 : break;
556 : : case TYPE_GENERALSTRING:
557 [ - + ]: 2 : if (len == 0)
558 : 0 : len = _asn1_strlen (value);
559 : 2 : _asn1_set_value_octet (node, value, len);
560 : 2 : break;
561 : : case TYPE_BIT_STRING:
562 [ - + ]: 1 : if (len == 0)
563 : 0 : len = _asn1_strlen (value);
564 : 1 : asn1_length_der ((len >> 3) + 2, NULL, &len2);
565 : 1 : temp = (unsigned char *) _asn1_malloc ((len >> 3) + 2 + len2);
566 [ - + ]: 1 : if (temp == NULL)
567 : 0 : return ASN1_MEM_ALLOC_ERROR;
568 : :
569 : 1 : asn1_bit_der (value, len, temp, &len2);
570 : 1 : _asn1_set_value_m (node, temp, len2);
571 : 1 : temp = NULL;
572 : 1 : break;
573 : : case TYPE_CHOICE:
574 : 3 : p = node->down;
575 [ + - ]: 4 : while (p)
576 : : {
577 [ + + ]: 4 : if (!_asn1_strcmp (p->name, value))
578 : : {
579 : 3 : p2 = node->down;
580 [ + + ]: 15 : while (p2)
581 : : {
582 [ + + ]: 12 : if (p2 != p)
583 : : {
584 : 5 : asn1_delete_structure (&p2);
585 : 5 : p2 = node->down;
586 : : }
587 : : else
588 : 7 : p2 = p2->right;
589 : : }
590 : 3 : break;
591 : : }
592 : 1 : p = p->right;
593 : : }
594 [ - + ]: 3 : if (!p)
595 : 0 : return ASN1_ELEMENT_NOT_FOUND;
596 : 3 : break;
597 : : case TYPE_ANY:
598 : 9 : _asn1_set_value_octet (node, value, len);
599 : 9 : break;
600 : : case TYPE_SEQUENCE_OF:
601 : : case TYPE_SET_OF:
602 [ - + ]: 14 : if (_asn1_strcmp (value, "NEW"))
603 : 0 : return ASN1_VALUE_NOT_VALID;
604 : 14 : _asn1_append_sequence_set (node);
605 : 14 : break;
606 : : default:
607 : 0 : return ASN1_ELEMENT_NOT_FOUND;
608 : : break;
609 : : }
610 : :
611 : 85 : return ASN1_SUCCESS;
612 : : }
613 : :
614 : :
615 : : #define PUT_VALUE( ptr, ptr_size, data, data_size) \
616 : : *len = data_size; \
617 : : if (ptr_size < data_size) { \
618 : : return ASN1_MEM_ERROR; \
619 : : } else { \
620 : : memcpy( ptr, data, data_size); \
621 : : }
622 : :
623 : : #define PUT_STR_VALUE( ptr, ptr_size, data) \
624 : : *len = _asn1_strlen(data) + 1; \
625 : : if (ptr_size < *len) { \
626 : : return ASN1_MEM_ERROR; \
627 : : } else { \
628 : : /* this strcpy is checked */ \
629 : : _asn1_strcpy(ptr, data); \
630 : : }
631 : :
632 : : #define ADD_STR_VALUE( ptr, ptr_size, data) \
633 : : *len = (int) _asn1_strlen(data) + 1; \
634 : : if (ptr_size < (int) _asn1_strlen(ptr)+(*len)) { \
635 : : return ASN1_MEM_ERROR; \
636 : : } else { \
637 : : /* this strcat is checked */ \
638 : : _asn1_strcat(ptr, data); \
639 : : }
640 : :
641 : : /**
642 : : * asn1_read_value:
643 : : * @root: pointer to a structure.
644 : : * @name: the name of the element inside a structure that you want to read.
645 : : * @ivalue: vector that will contain the element's content, must be a
646 : : * pointer to memory cells already allocated.
647 : : * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
648 : : * holds the sizeof value.
649 : : *
650 : : * Returns the value of one element inside a structure.
651 : : *
652 : : * If an element is OPTIONAL and the function "read_value" returns
653 : : * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
654 : : * in the der encoding that created the structure. The first element
655 : : * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
656 : : * so on.
657 : : *
658 : : * INTEGER: VALUE will contain a two's complement form integer.
659 : : *
660 : : * integer=-1 -> value[0]=0xFF , len=1.
661 : : * integer=1 -> value[0]=0x01 , len=1.
662 : : *
663 : : * ENUMERATED: As INTEGER (but only with not negative numbers).
664 : : *
665 : : * BOOLEAN: VALUE will be the null terminated string "TRUE" or
666 : : * "FALSE" and LEN=5 or LEN=6.
667 : : *
668 : : * OBJECT IDENTIFIER: VALUE will be a null terminated string with
669 : : * each number separated by a dot (i.e. "1.2.3.543.1").
670 : : *
671 : : * LEN = strlen(VALUE)+1
672 : : *
673 : : * UTCTime: VALUE will be a null terminated string in one of these
674 : : * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
675 : : * LEN=strlen(VALUE)+1.
676 : : *
677 : : * GeneralizedTime: VALUE will be a null terminated string in the
678 : : * same format used to set the value.
679 : : *
680 : : * OCTET STRING: VALUE will contain the octet string and LEN will be
681 : : * the number of octets.
682 : : *
683 : : * GeneralString: VALUE will contain the generalstring and LEN will
684 : : * be the number of octets.
685 : : *
686 : : * BIT STRING: VALUE will contain the bit string organized by bytes
687 : : * and LEN will be the number of bits.
688 : : *
689 : : * CHOICE: If NAME indicates a choice type, VALUE will specify the
690 : : * alternative selected.
691 : : *
692 : : * ANY: If NAME indicates an any type, VALUE will indicate the DER
693 : : * encoding of the structure actually used.
694 : : *
695 : : * Returns: %ASN1_SUCCESS if value is returned,
696 : : * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
697 : : * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
698 : : * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
699 : : * to store the result, and in this case @len will contain the number of
700 : : * bytes needed.
701 : : **/
702 : : asn1_retCode
703 : 48 : asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len)
704 : : {
705 : : ASN1_TYPE node, p, p2;
706 : : int len2, len3;
707 : 48 : int value_size = *len;
708 : 48 : unsigned char *value = ivalue;
709 : :
710 : 48 : node = asn1_find_node (root, name);
711 [ - + ]: 48 : if (node == NULL)
712 : 0 : return ASN1_ELEMENT_NOT_FOUND;
713 : :
714 [ + - ][ + - ]: 48 : if ((type_field (node->type) != TYPE_NULL) &&
715 [ + + ]: 48 : (type_field (node->type) != TYPE_CHOICE) &&
716 [ + + ][ - + ]: 42 : !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
717 : 18 : (node->value == NULL))
718 : 0 : return ASN1_VALUE_NOT_FOUND;
719 : :
720 [ - + + + : 48 : switch (type_field (node->type))
+ + + + -
+ - ]
721 : : {
722 : : case TYPE_NULL:
723 [ # # ]: 0 : PUT_STR_VALUE (value, value_size, "NULL");
724 : 0 : break;
725 : : case TYPE_BOOLEAN:
726 [ - + ][ # # ]: 1 : if ((node->type & CONST_DEFAULT) && (node->value == NULL))
727 : : {
728 : 0 : p = node->down;
729 [ # # ]: 0 : while (type_field (p->type) != TYPE_DEFAULT)
730 : 0 : p = p->right;
731 [ # # ]: 0 : if (p->type & CONST_TRUE)
732 : : {
733 [ # # ]: 0 : PUT_STR_VALUE (value, value_size, "TRUE");
734 : : }
735 : : else
736 : : {
737 [ # # ]: 0 : PUT_STR_VALUE (value, value_size, "FALSE");
738 : : }
739 : : }
740 [ + - ]: 1 : else if (node->value[0] == 'T')
741 : : {
742 [ + - ]: 1 : PUT_STR_VALUE (value, value_size, "TRUE");
743 : : }
744 : : else
745 : : {
746 [ # # ]: 0 : PUT_STR_VALUE (value, value_size, "FALSE");
747 : : }
748 : 0 : break;
749 : : case TYPE_INTEGER:
750 : : case TYPE_ENUMERATED:
751 [ + + ][ + + ]: 4 : if ((node->type & CONST_DEFAULT) && (node->value == NULL))
752 : : {
753 : 1 : p = node->down;
754 [ - + ]: 1 : while (type_field (p->type) != TYPE_DEFAULT)
755 : 0 : p = p->right;
756 [ + - ][ + - ]: 2 : if ((isdigit (p->value[0])) || (p->value[0] == '-')
757 [ - + ]: 1 : || (p->value[0] == '+'))
758 : : {
759 [ # # ]: 0 : if (_asn1_convert_integer
760 : 0 : (p->value, value, value_size, len) != ASN1_SUCCESS)
761 : 0 : return ASN1_MEM_ERROR;
762 : : }
763 : : else
764 : : { /* is an identifier like v1 */
765 : 1 : p2 = node->down;
766 [ + - ]: 4 : while (p2)
767 : : {
768 [ + + ]: 4 : if (type_field (p2->type) == TYPE_CONSTANT)
769 : : {
770 [ + - ][ + + ]: 2 : if ((p2->name) && (!_asn1_strcmp (p2->name, p->value)))
771 : : {
772 [ - + ]: 1 : if (_asn1_convert_integer
773 : 1 : (p2->value, value, value_size,
774 : : len) != ASN1_SUCCESS)
775 : 0 : return ASN1_MEM_ERROR;
776 : 1 : break;
777 : : }
778 : : }
779 : 3 : p2 = p2->right;
780 : : }
781 : : }
782 : : }
783 : : else
784 : : {
785 : 3 : len2 = -1;
786 [ + + ]: 3 : if (asn1_get_octet_der
787 : 3 : (node->value, node->value_len, &len2, value, value_size,
788 : : len) != ASN1_SUCCESS)
789 : 2 : return ASN1_MEM_ERROR;
790 : : }
791 : 2 : break;
792 : : case TYPE_OBJECT_ID:
793 [ + + ]: 32 : if (node->type & CONST_ASSIGN)
794 : : {
795 : 24 : value[0] = 0;
796 : 24 : p = node->down;
797 [ + + ]: 110 : while (p)
798 : : {
799 [ + - ]: 86 : if (type_field (p->type) == TYPE_CONSTANT)
800 : : {
801 [ - + ]: 86 : ADD_STR_VALUE (value, value_size, p->value);
802 [ + + ]: 86 : if (p->right)
803 : : {
804 [ - + ]: 62 : ADD_STR_VALUE (value, value_size, ".");
805 : : }
806 : : }
807 : 86 : p = p->right;
808 : : }
809 : 24 : *len = _asn1_strlen (value) + 1;
810 : : }
811 [ + + ][ + - ]: 8 : else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
812 : : {
813 : 4 : p = node->down;
814 [ - + ]: 4 : while (type_field (p->type) != TYPE_DEFAULT)
815 : 0 : p = p->right;
816 [ + + ]: 4 : PUT_STR_VALUE (value, value_size, p->value);
817 : : }
818 : : else
819 : : {
820 [ + + ]: 4 : PUT_STR_VALUE (value, value_size, node->value);
821 : : }
822 : 29 : break;
823 : : case TYPE_TIME:
824 [ + - ]: 2 : PUT_STR_VALUE (value, value_size, node->value);
825 : 0 : break;
826 : : case TYPE_OCTET_STRING:
827 : 3 : len2 = -1;
828 [ + + ]: 3 : if (asn1_get_octet_der
829 : 3 : (node->value, node->value_len, &len2, value, value_size,
830 : : len) != ASN1_SUCCESS)
831 : 1 : return ASN1_MEM_ERROR;
832 : 2 : break;
833 : : case TYPE_GENERALSTRING:
834 : 3 : len2 = -1;
835 [ + + ]: 3 : if (asn1_get_octet_der
836 : 3 : (node->value, node->value_len, &len2, value, value_size,
837 : : len) != ASN1_SUCCESS)
838 : 2 : return ASN1_MEM_ERROR;
839 : 1 : break;
840 : : case TYPE_BIT_STRING:
841 : 2 : len2 = -1;
842 [ + + ]: 2 : if (asn1_get_bit_der
843 : 2 : (node->value, node->value_len, &len2, value, value_size,
844 : : len) != ASN1_SUCCESS)
845 : 1 : return ASN1_MEM_ERROR;
846 : 1 : break;
847 : : case TYPE_CHOICE:
848 [ # # ]: 0 : PUT_STR_VALUE (value, value_size, node->down->name);
849 : 0 : break;
850 : : case TYPE_ANY:
851 : 1 : len3 = -1;
852 : 1 : len2 = asn1_get_length_der (node->value, node->value_len, &len3);
853 [ - + ]: 1 : if (len2 < 0)
854 : 0 : return ASN1_DER_ERROR;
855 [ + - ]: 1 : PUT_VALUE (value, value_size, node->value + len3, len2);
856 : 0 : break;
857 : : default:
858 : 0 : return ASN1_ELEMENT_NOT_FOUND;
859 : : break;
860 : : }
861 : 48 : return ASN1_SUCCESS;
862 : : }
863 : :
864 : :
865 : : /**
866 : : * asn1_read_tag:
867 : : * @root: pointer to a structure
868 : : * @name: the name of the element inside a structure.
869 : : * @tagValue: variable that will contain the TAG value.
870 : : * @classValue: variable that will specify the TAG type.
871 : : *
872 : : * Returns the TAG and the CLASS of one element inside a structure.
873 : : * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
874 : : * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
875 : : * %ASN1_CLASS_CONTEXT_SPECIFIC.
876 : : *
877 : : * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
878 : : * @name is not a valid element.
879 : : **/
880 : : asn1_retCode
881 : 11 : asn1_read_tag (ASN1_TYPE root, const char *name, int *tagValue,
882 : : int *classValue)
883 : : {
884 : : ASN1_TYPE node, p, pTag;
885 : :
886 : 11 : node = asn1_find_node (root, name);
887 [ + + ]: 11 : if (node == NULL)
888 : 1 : return ASN1_ELEMENT_NOT_FOUND;
889 : :
890 : 10 : p = node->down;
891 : :
892 : : /* pTag will points to the IMPLICIT TAG */
893 : 10 : pTag = NULL;
894 [ + - ]: 10 : if (node->type & CONST_TAG)
895 : : {
896 [ + + ]: 24 : while (p)
897 : : {
898 [ + - ]: 14 : if (type_field (p->type) == TYPE_TAG)
899 : : {
900 [ + + ][ + + ]: 14 : if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
901 : 8 : pTag = p;
902 [ + + ]: 6 : else if (p->type & CONST_EXPLICIT)
903 : 4 : pTag = NULL;
904 : : }
905 : 14 : p = p->right;
906 : : }
907 : : }
908 : :
909 [ + + ]: 10 : if (pTag)
910 : : {
911 : 8 : *tagValue = _asn1_strtoul (pTag->value, NULL, 10);
912 : :
913 [ - + ]: 8 : if (pTag->type & CONST_APPLICATION)
914 : 0 : *classValue = ASN1_CLASS_APPLICATION;
915 [ + + ]: 8 : else if (pTag->type & CONST_UNIVERSAL)
916 : 4 : *classValue = ASN1_CLASS_UNIVERSAL;
917 [ - + ]: 4 : else if (pTag->type & CONST_PRIVATE)
918 : 0 : *classValue = ASN1_CLASS_PRIVATE;
919 : : else
920 : 4 : *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
921 : : }
922 : : else
923 : : {
924 : 2 : *classValue = ASN1_CLASS_UNIVERSAL;
925 : :
926 [ - - + - : 2 : switch (type_field (node->type))
- - - - -
- - - - ]
927 : : {
928 : : case TYPE_NULL:
929 : 0 : *tagValue = ASN1_TAG_NULL;
930 : 0 : break;
931 : : case TYPE_BOOLEAN:
932 : 0 : *tagValue = ASN1_TAG_BOOLEAN;
933 : 0 : break;
934 : : case TYPE_INTEGER:
935 : 2 : *tagValue = ASN1_TAG_INTEGER;
936 : 2 : break;
937 : : case TYPE_ENUMERATED:
938 : 0 : *tagValue = ASN1_TAG_ENUMERATED;
939 : 0 : break;
940 : : case TYPE_OBJECT_ID:
941 : 0 : *tagValue = ASN1_TAG_OBJECT_ID;
942 : 0 : break;
943 : : case TYPE_TIME:
944 [ # # ]: 0 : if (node->type & CONST_UTC)
945 : : {
946 : 0 : *tagValue = ASN1_TAG_UTCTime;
947 : : }
948 : : else
949 : 0 : *tagValue = ASN1_TAG_GENERALIZEDTime;
950 : 0 : break;
951 : : case TYPE_OCTET_STRING:
952 : 0 : *tagValue = ASN1_TAG_OCTET_STRING;
953 : 0 : break;
954 : : case TYPE_GENERALSTRING:
955 : 0 : *tagValue = ASN1_TAG_GENERALSTRING;
956 : 0 : break;
957 : : case TYPE_BIT_STRING:
958 : 0 : *tagValue = ASN1_TAG_BIT_STRING;
959 : 0 : break;
960 : : case TYPE_SEQUENCE:
961 : : case TYPE_SEQUENCE_OF:
962 : 0 : *tagValue = ASN1_TAG_SEQUENCE;
963 : 0 : break;
964 : : case TYPE_SET:
965 : : case TYPE_SET_OF:
966 : 0 : *tagValue = ASN1_TAG_SET;
967 : 0 : break;
968 : : case TYPE_TAG:
969 : : case TYPE_CHOICE:
970 : : case TYPE_ANY:
971 : 0 : break;
972 : : default:
973 : 0 : break;
974 : : }
975 : : }
976 : :
977 : 11 : return ASN1_SUCCESS;
978 : : }
979 : :
980 : : /**
981 : : * asn1_read_node_value:
982 : : * @node: pointer to a node.
983 : : * @data: a pointer to an asn1_data_node struct.
984 : : *
985 : : * Returns the value a data node inside a ASN1_TYPE structure.
986 : : * The data returned should be handled as constant values.
987 : : *
988 : : * Returns: %ASN1_SUCCESS if the node exists.
989 : : *
990 : : * Since: 2.14
991 : : **/
992 : : asn1_retCode
993 : 0 : asn1_read_node_value (ASN1_TYPE node, ASN1_DATA_NODE* data)
994 : : {
995 : 0 : data->name = node->name;
996 : 0 : data->value = node->value;
997 : 0 : data->value_len = node->value_len;
998 : 0 : data->type = type_field(node->type);
999 : :
1000 : 0 : return ASN1_SUCCESS;
1001 : : }
|