Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2002-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 : : /*****************************************************/
24 : : /* File: coding.c */
25 : : /* Description: Functions to create a DER coding of */
26 : : /* an ASN1 type. */
27 : : /*****************************************************/
28 : :
29 : : #include <int.h>
30 : : #include "parser_aux.h"
31 : : #include <gstr.h>
32 : : #include "element.h"
33 : : #include <structure.h>
34 : :
35 : : #define MAX_TAG_LEN 16
36 : :
37 : : /******************************************************/
38 : : /* Function : _asn1_error_description_value_not_found */
39 : : /* Description: creates the ErrorDescription string */
40 : : /* for the ASN1_VALUE_NOT_FOUND error. */
41 : : /* Parameters: */
42 : : /* node: node of the tree where the value is NULL. */
43 : : /* ErrorDescription: string returned. */
44 : : /* Return: */
45 : : /******************************************************/
46 : : static void
47 : 0 : _asn1_error_description_value_not_found (ASN1_TYPE node,
48 : : char *ErrorDescription)
49 : : {
50 : :
51 [ # # ]: 0 : if (ErrorDescription == NULL)
52 : 0 : return;
53 : :
54 : 0 : Estrcpy (ErrorDescription, ":: value of element '");
55 : 0 : _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
56 : : ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
57 : 0 : Estrcat (ErrorDescription, "' not found");
58 : :
59 : : }
60 : :
61 : : /**
62 : : * asn1_length_der:
63 : : * @len: value to convert.
64 : : * @ans: string returned.
65 : : * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
66 : : *
67 : : * Creates the DER coding for the LEN parameter (only the length).
68 : : * The @ans buffer is pre-allocated and must have room for the output.
69 : : **/
70 : : void
71 : 440 : asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
72 : : {
73 : : int k;
74 : : unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
75 : :
76 [ + + ]: 440 : if (len < 128)
77 : : {
78 : : /* short form */
79 [ + + ]: 429 : if (ans != NULL)
80 : 330 : ans[0] = (unsigned char) len;
81 : 429 : *ans_len = 1;
82 : : }
83 : : else
84 : : {
85 : : /* Long form */
86 : 11 : k = 0;
87 [ + + ]: 34 : while (len)
88 : : {
89 : 23 : temp[k++] = len & 0xFF;
90 : 23 : len = len >> 8;
91 : : }
92 : 11 : *ans_len = k + 1;
93 [ + + ]: 11 : if (ans != NULL)
94 : : {
95 : 10 : ans[0] = ((unsigned char) k & 0x7F) + 128;
96 [ + + ]: 31 : while (k--)
97 : 21 : ans[*ans_len - 1 - k] = temp[k];
98 : : }
99 : : }
100 : 440 : }
101 : :
102 : : /******************************************************/
103 : : /* Function : _asn1_tag_der */
104 : : /* Description: creates the DER coding for the CLASS */
105 : : /* and TAG parameters. */
106 : : /* Parameters: */
107 : : /* class: value to convert. */
108 : : /* tag_value: value to convert. */
109 : : /* ans: string returned. */
110 : : /* ans_len: number of meaningful bytes of ANS */
111 : : /* (ans[0]..ans[ans_len-1]). */
112 : : /* Return: */
113 : : /******************************************************/
114 : : static void
115 : 222 : _asn1_tag_der (unsigned char class, unsigned int tag_value,
116 : : unsigned char *ans, int *ans_len)
117 : : {
118 : : int k;
119 : : unsigned char temp[SIZEOF_UNSIGNED_INT];
120 : :
121 [ + - ]: 222 : if (tag_value < 31)
122 : : {
123 : : /* short form */
124 : 222 : ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
125 : 222 : *ans_len = 1;
126 : : }
127 : : else
128 : : {
129 : : /* Long form */
130 : 0 : ans[0] = (class & 0xE0) + 31;
131 : 0 : k = 0;
132 [ # # ]: 0 : while (tag_value)
133 : : {
134 : 0 : temp[k++] = tag_value & 0x7F;
135 : 0 : tag_value = tag_value >> 7;
136 : : }
137 : 0 : *ans_len = k + 1;
138 [ # # ]: 0 : while (k--)
139 : 0 : ans[*ans_len - 1 - k] = temp[k] + 128;
140 : 0 : ans[*ans_len - 1] -= 128;
141 : : }
142 : 222 : }
143 : :
144 : : /**
145 : : * asn1_octet_der:
146 : : * @str: OCTET string.
147 : : * @str_len: STR length (str[0]..str[str_len-1]).
148 : : * @der: string returned.
149 : : * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]).
150 : : *
151 : : * Creates the DER coding for an OCTET type (length included).
152 : : **/
153 : : void
154 : 181 : asn1_octet_der (const unsigned char *str, int str_len,
155 : : unsigned char *der, int *der_len)
156 : : {
157 : : int len_len;
158 : :
159 [ + - ][ - + ]: 181 : if (der == NULL || str_len < 0)
160 : 181 : return;
161 : 181 : asn1_length_der (str_len, der, &len_len);
162 : 181 : memcpy (der + len_len, str, str_len);
163 : 181 : *der_len = str_len + len_len;
164 : : }
165 : :
166 : : /******************************************************/
167 : : /* Function : _asn1_time_der */
168 : : /* Description: creates the DER coding for a TIME */
169 : : /* type (length included). */
170 : : /* Parameters: */
171 : : /* str: TIME null-terminated string. */
172 : : /* der: string returned. */
173 : : /* der_len: number of meaningful bytes of DER */
174 : : /* (der[0]..der[ans_len-1]). Initially it */
175 : : /* if must store the lenght of DER. */
176 : : /* Return: */
177 : : /* ASN1_MEM_ERROR when DER isn't big enough */
178 : : /* ASN1_SUCCESS otherwise */
179 : : /******************************************************/
180 : : static asn1_retCode
181 : 6 : _asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
182 : : {
183 : : int len_len;
184 : : int max_len;
185 : 6 : int str_len = _asn1_strlen (str);
186 : :
187 : 6 : max_len = *der_len;
188 : :
189 [ + + ]: 6 : asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len);
190 : :
191 [ + + ]: 6 : if ((len_len + str_len) <= max_len)
192 : 4 : memcpy (der + len_len, str, str_len);
193 : 6 : *der_len = len_len + str_len;
194 : :
195 [ + + ]: 6 : if ((*der_len) > max_len)
196 : 2 : return ASN1_MEM_ERROR;
197 : :
198 : 6 : return ASN1_SUCCESS;
199 : : }
200 : :
201 : :
202 : : /*
203 : : void
204 : : _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
205 : : {
206 : : int len_len,str_len;
207 : : char temp[20];
208 : :
209 : : if(str==NULL) return;
210 : : str_len=asn1_get_length_der(der,*der_len,&len_len);
211 : : if (str_len<0) return;
212 : : memcpy(temp,der+len_len,str_len);
213 : : *der_len=str_len+len_len;
214 : : switch(str_len){
215 : : case 11:
216 : : temp[10]=0;
217 : : strcat(temp,"00+0000");
218 : : break;
219 : : case 13:
220 : : temp[12]=0;
221 : : strcat(temp,"+0000");
222 : : break;
223 : : case 15:
224 : : temp[15]=0;
225 : : memmove(temp+12,temp+10,6);
226 : : temp[10]=temp[11]='0';
227 : : break;
228 : : case 17:
229 : : temp[17]=0;
230 : : break;
231 : : default:
232 : : return;
233 : : }
234 : : strcpy(str,temp);
235 : : }
236 : : */
237 : :
238 : : /******************************************************/
239 : : /* Function : _asn1_objectid_der */
240 : : /* Description: creates the DER coding for an */
241 : : /* OBJECT IDENTIFIER type (length included). */
242 : : /* Parameters: */
243 : : /* str: OBJECT IDENTIFIER null-terminated string. */
244 : : /* der: string returned. */
245 : : /* der_len: number of meaningful bytes of DER */
246 : : /* (der[0]..der[ans_len-1]). Initially it */
247 : : /* must store the length of DER. */
248 : : /* Return: */
249 : : /* ASN1_MEM_ERROR when DER isn't big enough */
250 : : /* ASN1_SUCCESS otherwise */
251 : : /******************************************************/
252 : : static asn1_retCode
253 : 35 : _asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
254 : : {
255 : : int len_len, counter, k, first, max_len;
256 : : char *temp, *n_end, *n_start;
257 : : unsigned char bit7;
258 : 35 : unsigned long val, val1 = 0;
259 : 35 : int str_len = _asn1_strlen (str);
260 : :
261 : 35 : max_len = *der_len;
262 : :
263 : 35 : temp = _asn1_malloc (str_len + 2);
264 [ - + ]: 35 : if (temp == NULL)
265 : 0 : return ASN1_MEM_ALLOC_ERROR;
266 : :
267 : 35 : memcpy (temp, str, str_len);
268 : 35 : temp[str_len] = '.';
269 : 35 : temp[str_len + 1] = 0;
270 : :
271 : 35 : counter = 0;
272 : 35 : n_start = temp;
273 [ + + ]: 184 : while ((n_end = strchr (n_start, '.')))
274 : : {
275 : 149 : *n_end = 0;
276 : 149 : val = strtoul (n_start, NULL, 10);
277 : 149 : counter++;
278 : :
279 [ + + ]: 149 : if (counter == 1)
280 : 35 : val1 = val;
281 [ + + ]: 114 : else if (counter == 2)
282 : : {
283 [ + + ]: 35 : if (max_len > 0)
284 : 24 : der[0] = 40 * val1 + val;
285 : 35 : *der_len = 1;
286 : : }
287 : : else
288 : : {
289 : 79 : first = 0;
290 [ + + ]: 474 : for (k = 4; k >= 0; k--)
291 : : {
292 : 395 : bit7 = (val >> (k * 7)) & 0x7F;
293 [ + + ][ + - ]: 395 : if (bit7 || first || !k)
[ - + ]
294 : : {
295 [ + + ]: 88 : if (k)
296 : 9 : bit7 |= 0x80;
297 [ + + ]: 88 : if (max_len > (*der_len))
298 : 60 : der[*der_len] = bit7;
299 : 88 : (*der_len)++;
300 : 88 : first = 1;
301 : : }
302 : : }
303 : :
304 : : }
305 : 149 : n_start = n_end + 1;
306 : : }
307 : :
308 : 35 : asn1_length_der (*der_len, NULL, &len_len);
309 [ + + ]: 35 : if (max_len >= (*der_len + len_len))
310 : : {
311 : 24 : memmove (der + len_len, der, *der_len);
312 : 24 : asn1_length_der (*der_len, der, &len_len);
313 : : }
314 : 35 : *der_len += len_len;
315 : :
316 : 35 : _asn1_free (temp);
317 : :
318 [ + + ]: 35 : if (max_len < (*der_len))
319 : 11 : return ASN1_MEM_ERROR;
320 : :
321 : 35 : return ASN1_SUCCESS;
322 : : }
323 : :
324 : :
325 : : static const unsigned char bit_mask[] =
326 : : { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
327 : :
328 : : /**
329 : : * asn1_bit_der:
330 : : * @str: BIT string.
331 : : * @bit_len: number of meaningful bits in STR.
332 : : * @der: string returned.
333 : : * @der_len: number of meaningful bytes of DER
334 : : * (der[0]..der[ans_len-1]).
335 : : *
336 : : * Creates the DER coding for a BIT STRING type (length and pad
337 : : * included).
338 : : **/
339 : : void
340 : 44 : asn1_bit_der (const unsigned char *str, int bit_len,
341 : : unsigned char *der, int *der_len)
342 : : {
343 : : int len_len, len_byte, len_pad;
344 : :
345 [ - + ]: 44 : if (der == NULL)
346 : 44 : return;
347 : 44 : len_byte = bit_len >> 3;
348 : 44 : len_pad = 8 - (bit_len & 7);
349 [ + + ]: 44 : if (len_pad == 8)
350 : 6 : len_pad = 0;
351 : : else
352 : 38 : len_byte++;
353 : 44 : asn1_length_der (len_byte + 1, der, &len_len);
354 : 44 : der[len_len] = len_pad;
355 : 44 : memcpy (der + len_len + 1, str, len_byte);
356 : 44 : der[len_len + len_byte] &= bit_mask[len_pad];
357 : 44 : *der_len = len_byte + len_len + 1;
358 : : }
359 : :
360 : :
361 : : /******************************************************/
362 : : /* Function : _asn1_complete_explicit_tag */
363 : : /* Description: add the length coding to the EXPLICIT */
364 : : /* tags. */
365 : : /* Parameters: */
366 : : /* node: pointer to the tree element. */
367 : : /* der: string with the DER coding of the whole tree*/
368 : : /* counter: number of meaningful bytes of DER */
369 : : /* (der[0]..der[*counter-1]). */
370 : : /* max_len: size of der vector */
371 : : /* Return: */
372 : : /* ASN1_MEM_ERROR if der vector isn't big enough, */
373 : : /* otherwise ASN1_SUCCESS. */
374 : : /******************************************************/
375 : : static asn1_retCode
376 : 222 : _asn1_complete_explicit_tag (ASN1_TYPE node, unsigned char *der,
377 : : int *counter, int *max_len)
378 : : {
379 : : ASN1_TYPE p;
380 : : int is_tag_implicit, len2, len3;
381 : : unsigned char temp[SIZEOF_UNSIGNED_INT];
382 : :
383 : 222 : is_tag_implicit = 0;
384 : :
385 [ + + ]: 222 : if (node->type & CONST_TAG)
386 : : {
387 : 31 : p = node->down;
388 : : /* When there are nested tags we must complete them reverse to
389 : : the order they were created. This is because completing a tag
390 : : modifies all data within it, including the incomplete tags
391 : : which store buffer positions -- simon@josefsson.org 2002-09-06
392 : : */
393 [ + + ]: 71 : while (p->right)
394 : 40 : p = p->right;
395 [ + - ][ + + ]: 102 : while (p && p != node->down->left)
396 : : {
397 [ + + ]: 71 : if (type_field (p->type) == TYPE_TAG)
398 : : {
399 [ + + ]: 34 : if (p->type & CONST_EXPLICIT)
400 : : {
401 : 9 : len2 = strtol (p->name, NULL, 10);
402 : 9 : _asn1_set_name (p, NULL);
403 : 9 : asn1_length_der (*counter - len2, temp, &len3);
404 [ + + ]: 9 : if (len3 <= (*max_len))
405 : : {
406 : 6 : memmove (der + len2 + len3, der + len2,
407 : 6 : *counter - len2);
408 : 6 : memcpy (der + len2, temp, len3);
409 : : }
410 : 9 : *max_len -= len3;
411 : 9 : *counter += len3;
412 : 9 : is_tag_implicit = 0;
413 : : }
414 : : else
415 : : { /* CONST_IMPLICIT */
416 [ + - ]: 25 : if (!is_tag_implicit)
417 : : {
418 : 25 : is_tag_implicit = 1;
419 : : }
420 : : }
421 : : }
422 : 71 : p = p->left;
423 : : }
424 : : }
425 : :
426 [ + + ]: 222 : if (*max_len < 0)
427 : 80 : return ASN1_MEM_ERROR;
428 : :
429 : 222 : return ASN1_SUCCESS;
430 : : }
431 : :
432 : :
433 : : /******************************************************/
434 : : /* Function : _asn1_insert_tag_der */
435 : : /* Description: creates the DER coding of tags of one */
436 : : /* NODE. */
437 : : /* Parameters: */
438 : : /* node: pointer to the tree element. */
439 : : /* der: string returned */
440 : : /* counter: number of meaningful bytes of DER */
441 : : /* (counter[0]..der[*counter-1]). */
442 : : /* max_len: size of der vector */
443 : : /* Return: */
444 : : /* ASN1_GENERIC_ERROR if the type is unknown, */
445 : : /* ASN1_MEM_ERROR if der vector isn't big enough, */
446 : : /* otherwise ASN1_SUCCESS. */
447 : : /******************************************************/
448 : : static asn1_retCode
449 : 252 : _asn1_insert_tag_der (ASN1_TYPE node, unsigned char *der, int *counter,
450 : : int *max_len)
451 : : {
452 : : ASN1_TYPE p;
453 : : int tag_len, is_tag_implicit;
454 : 252 : unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
455 : 252 : unsigned long tag_implicit = 0;
456 : : unsigned char tag_der[MAX_TAG_LEN];
457 : :
458 : 252 : is_tag_implicit = 0;
459 : :
460 [ + + ]: 252 : if (node->type & CONST_TAG)
461 : : {
462 : 43 : p = node->down;
463 [ + + ]: 156 : while (p)
464 : : {
465 [ + + ]: 113 : if (type_field (p->type) == TYPE_TAG)
466 : : {
467 [ + + ]: 46 : if (p->type & CONST_APPLICATION)
468 : 3 : class = ASN1_CLASS_APPLICATION;
469 [ + + ]: 43 : else if (p->type & CONST_UNIVERSAL)
470 : 3 : class = ASN1_CLASS_UNIVERSAL;
471 [ - + ]: 40 : else if (p->type & CONST_PRIVATE)
472 : 0 : class = ASN1_CLASS_PRIVATE;
473 : : else
474 : 40 : class = ASN1_CLASS_CONTEXT_SPECIFIC;
475 : :
476 [ + + ]: 46 : if (p->type & CONST_EXPLICIT)
477 : : {
478 [ - + ]: 9 : if (is_tag_implicit)
479 : 0 : _asn1_tag_der (class_implicit, tag_implicit, tag_der,
480 : : &tag_len);
481 : : else
482 : 9 : _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
483 : 9 : _asn1_strtoul (p->value, NULL, 10),
484 : : tag_der, &tag_len);
485 : :
486 : 9 : *max_len -= tag_len;
487 [ + + ]: 9 : if (*max_len >= 0)
488 : 6 : memcpy (der + *counter, tag_der, tag_len);
489 : 9 : *counter += tag_len;
490 : :
491 : 9 : _asn1_ltostr (*counter, (char *) temp);
492 : 9 : _asn1_set_name (p, (const char *) temp);
493 : :
494 : 9 : is_tag_implicit = 0;
495 : : }
496 : : else
497 : : { /* CONST_IMPLICIT */
498 [ + - ]: 37 : if (!is_tag_implicit)
499 : : {
500 [ + + ][ + - ]: 37 : if ((type_field (node->type) == TYPE_SEQUENCE) ||
501 [ + - ]: 30 : (type_field (node->type) == TYPE_SEQUENCE_OF) ||
502 [ + + ]: 30 : (type_field (node->type) == TYPE_SET) ||
503 : 30 : (type_field (node->type) == TYPE_SET_OF))
504 : 10 : class |= ASN1_CLASS_STRUCTURED;
505 : 37 : class_implicit = class;
506 : 37 : tag_implicit = _asn1_strtoul (p->value, NULL, 10);
507 : 37 : is_tag_implicit = 1;
508 : : }
509 : : }
510 : : }
511 : 113 : p = p->right;
512 : : }
513 : : }
514 : :
515 [ + + ]: 252 : if (is_tag_implicit)
516 : : {
517 : 37 : _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
518 : : }
519 : : else
520 : : {
521 [ - + + + : 215 : switch (type_field (node->type))
+ + + + +
+ + - + +
- ]
522 : : {
523 : : case TYPE_NULL:
524 : 0 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
525 : : &tag_len);
526 : 0 : break;
527 : : case TYPE_BOOLEAN:
528 : 6 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
529 : : &tag_len);
530 : 6 : break;
531 : : case TYPE_INTEGER:
532 : 46 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
533 : : &tag_len);
534 : 46 : break;
535 : : case TYPE_ENUMERATED:
536 : 3 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
537 : : &tag_len);
538 : 3 : break;
539 : : case TYPE_OBJECT_ID:
540 : 32 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
541 : : &tag_len);
542 : 32 : break;
543 : : case TYPE_TIME:
544 [ + + ]: 6 : if (node->type & CONST_UTC)
545 : : {
546 : 3 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
547 : : &tag_len);
548 : : }
549 : : else
550 : 3 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
551 : : tag_der, &tag_len);
552 : 6 : break;
553 : : case TYPE_OCTET_STRING:
554 : 10 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
555 : : &tag_len);
556 : 10 : break;
557 : : case TYPE_GENERALSTRING:
558 : 6 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
559 : : tag_der, &tag_len);
560 : 6 : break;
561 : : case TYPE_BIT_STRING:
562 : 3 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
563 : : &tag_len);
564 : 3 : break;
565 : : case TYPE_SEQUENCE:
566 : : case TYPE_SEQUENCE_OF:
567 : 51 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
568 : : ASN1_TAG_SEQUENCE, tag_der, &tag_len);
569 : 51 : break;
570 : : case TYPE_SET:
571 : : case TYPE_SET_OF:
572 : 13 : _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
573 : : ASN1_TAG_SET, tag_der, &tag_len);
574 : 13 : break;
575 : : case TYPE_TAG:
576 : 0 : tag_len = 0;
577 : 0 : break;
578 : : case TYPE_CHOICE:
579 : 15 : tag_len = 0;
580 : 15 : break;
581 : : case TYPE_ANY:
582 : 24 : tag_len = 0;
583 : 24 : break;
584 : : default:
585 : 0 : return ASN1_GENERIC_ERROR;
586 : : }
587 : : }
588 : :
589 : 252 : *max_len -= tag_len;
590 [ + + ]: 252 : if (*max_len >= 0)
591 : 178 : memcpy (der + *counter, tag_der, tag_len);
592 : 252 : *counter += tag_len;
593 : :
594 [ + + ]: 252 : if (*max_len < 0)
595 : 74 : return ASN1_MEM_ERROR;
596 : :
597 : 252 : return ASN1_SUCCESS;
598 : : }
599 : :
600 : : /******************************************************/
601 : : /* Function : _asn1_ordering_set */
602 : : /* Description: puts the elements of a SET type in */
603 : : /* the correct order according to DER rules. */
604 : : /* Parameters: */
605 : : /* der: string with the DER coding. */
606 : : /* node: pointer to the SET element. */
607 : : /* Return: */
608 : : /******************************************************/
609 : : static void
610 : 0 : _asn1_ordering_set (unsigned char *der, int der_len, ASN1_TYPE node)
611 : : {
612 : : struct vet
613 : : {
614 : : int end;
615 : : unsigned long value;
616 : : struct vet *next, *prev;
617 : : };
618 : :
619 : : int counter, len, len2;
620 : : struct vet *first, *last, *p_vet, *p2_vet;
621 : : ASN1_TYPE p;
622 : : unsigned char class, *temp;
623 : : unsigned long tag;
624 : :
625 : 0 : counter = 0;
626 : :
627 [ # # ]: 0 : if (type_field (node->type) != TYPE_SET)
628 : 0 : return;
629 : :
630 : 0 : p = node->down;
631 [ # # ]: 0 : while ((type_field (p->type) == TYPE_TAG)
632 [ # # ]: 0 : || (type_field (p->type) == TYPE_SIZE))
633 : 0 : p = p->right;
634 : :
635 [ # # ][ # # ]: 0 : if ((p == NULL) || (p->right == NULL))
636 : 0 : return;
637 : :
638 : 0 : first = last = NULL;
639 [ # # ]: 0 : while (p)
640 : : {
641 : 0 : p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
642 [ # # ]: 0 : if (p_vet == NULL)
643 : 0 : return;
644 : :
645 : 0 : p_vet->next = NULL;
646 : 0 : p_vet->prev = last;
647 [ # # ]: 0 : if (first == NULL)
648 : 0 : first = p_vet;
649 : : else
650 : 0 : last->next = p_vet;
651 : 0 : last = p_vet;
652 : :
653 : : /* tag value calculation */
654 [ # # ]: 0 : if (asn1_get_tag_der
655 : 0 : (der + counter, der_len - counter, &class, &len2,
656 : : &tag) != ASN1_SUCCESS)
657 : 0 : return;
658 : 0 : p_vet->value = (class << 24) | tag;
659 : 0 : counter += len2;
660 : :
661 : : /* extraction and length */
662 : 0 : len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
663 [ # # ]: 0 : if (len2 < 0)
664 : 0 : return;
665 : 0 : counter += len + len2;
666 : :
667 : 0 : p_vet->end = counter;
668 : 0 : p = p->right;
669 : : }
670 : :
671 : 0 : p_vet = first;
672 : :
673 [ # # ]: 0 : while (p_vet)
674 : : {
675 : 0 : p2_vet = p_vet->next;
676 : 0 : counter = 0;
677 [ # # ]: 0 : while (p2_vet)
678 : : {
679 [ # # ]: 0 : if (p_vet->value > p2_vet->value)
680 : : {
681 : : /* change position */
682 : 0 : temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
683 [ # # ]: 0 : if (temp == NULL)
684 : 0 : return;
685 : :
686 : 0 : memcpy (temp, der + counter, p_vet->end - counter);
687 : 0 : memcpy (der + counter, der + p_vet->end,
688 : 0 : p2_vet->end - p_vet->end);
689 : 0 : memcpy (der + counter + p2_vet->end - p_vet->end, temp,
690 : 0 : p_vet->end - counter);
691 : 0 : _asn1_free (temp);
692 : :
693 : 0 : tag = p_vet->value;
694 : 0 : p_vet->value = p2_vet->value;
695 : 0 : p2_vet->value = tag;
696 : :
697 : 0 : p_vet->end = counter + (p2_vet->end - p_vet->end);
698 : : }
699 : 0 : counter = p_vet->end;
700 : :
701 : 0 : p2_vet = p2_vet->next;
702 : 0 : p_vet = p_vet->next;
703 : : }
704 : :
705 [ # # ]: 0 : if (p_vet != first)
706 : 0 : p_vet->prev->next = NULL;
707 : : else
708 : 0 : first = NULL;
709 : 0 : _asn1_free (p_vet);
710 : 0 : p_vet = first;
711 : : }
712 : : }
713 : :
714 : : /******************************************************/
715 : : /* Function : _asn1_ordering_set_of */
716 : : /* Description: puts the elements of a SET OF type in */
717 : : /* the correct order according to DER rules. */
718 : : /* Parameters: */
719 : : /* der: string with the DER coding. */
720 : : /* node: pointer to the SET OF element. */
721 : : /* Return: */
722 : : /******************************************************/
723 : : static void
724 : 9 : _asn1_ordering_set_of (unsigned char *der, int der_len, ASN1_TYPE node)
725 : : {
726 : : struct vet
727 : : {
728 : : int end;
729 : : struct vet *next, *prev;
730 : : };
731 : :
732 : : int counter, len, len2, change;
733 : : struct vet *first, *last, *p_vet, *p2_vet;
734 : : ASN1_TYPE p;
735 : : unsigned char *temp, class;
736 : : unsigned long k, max;
737 : :
738 : 9 : counter = 0;
739 : :
740 [ - + ]: 9 : if (type_field (node->type) != TYPE_SET_OF)
741 : 0 : return;
742 : :
743 : 9 : p = node->down;
744 [ + + ]: 13 : while ((type_field (p->type) == TYPE_TAG)
745 [ + + ]: 11 : || (type_field (p->type) == TYPE_SIZE))
746 : 4 : p = p->right;
747 : 9 : p = p->right;
748 : :
749 [ + + ][ - + ]: 9 : if ((p == NULL) || (p->right == NULL))
750 : 2 : return;
751 : :
752 : 7 : first = last = NULL;
753 [ + + ]: 17 : while (p)
754 : : {
755 : 12 : p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
756 [ - + ]: 12 : if (p_vet == NULL)
757 : 0 : return;
758 : :
759 : 12 : p_vet->next = NULL;
760 : 12 : p_vet->prev = last;
761 [ + + ]: 12 : if (first == NULL)
762 : 7 : first = p_vet;
763 : : else
764 : 5 : last->next = p_vet;
765 : 12 : last = p_vet;
766 : :
767 : : /* extraction of tag and length */
768 [ + - ]: 12 : if (der_len - counter > 0)
769 : : {
770 : :
771 [ + + ]: 12 : if (asn1_get_tag_der
772 : 12 : (der + counter, der_len - counter, &class, &len,
773 : : NULL) != ASN1_SUCCESS)
774 : 1 : return;
775 : 11 : counter += len;
776 : :
777 : 11 : len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
778 [ + + ]: 11 : if (len2 < 0)
779 : 1 : return;
780 : 10 : counter += len + len2;
781 : : }
782 : :
783 : 10 : p_vet->end = counter;
784 : 10 : p = p->right;
785 : : }
786 : :
787 : 5 : p_vet = first;
788 : :
789 [ + + ]: 19 : while (p_vet)
790 : : {
791 : 10 : p2_vet = p_vet->next;
792 : 10 : counter = 0;
793 [ + + ]: 15 : while (p2_vet)
794 : : {
795 [ - + ]: 5 : if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
796 : 0 : max = p_vet->end - counter;
797 : : else
798 : 5 : max = p2_vet->end - p_vet->end;
799 : :
800 : 5 : change = -1;
801 [ + - ]: 16 : for (k = 0; k < max; k++)
802 [ + + ]: 16 : if (der[counter + k] > der[p_vet->end + k])
803 : : {
804 : 2 : change = 1;
805 : 2 : break;
806 : : }
807 [ + + ]: 14 : else if (der[counter + k] < der[p_vet->end + k])
808 : : {
809 : 3 : change = 0;
810 : 3 : break;
811 : : }
812 : :
813 [ - + ]: 5 : if ((change == -1)
814 [ # # ]: 0 : && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
815 : 0 : change = 1;
816 : :
817 [ + + ]: 5 : if (change == 1)
818 : : {
819 : : /* change position */
820 : 2 : temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
821 [ - + ]: 2 : if (temp == NULL)
822 : 0 : return;
823 : :
824 : 2 : memcpy (temp, der + counter, (p_vet->end) - counter);
825 : 2 : memcpy (der + counter, der + (p_vet->end),
826 : 2 : (p2_vet->end) - (p_vet->end));
827 : 2 : memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
828 : 2 : (p_vet->end) - counter);
829 : 2 : _asn1_free (temp);
830 : :
831 : 2 : p_vet->end = counter + (p2_vet->end - p_vet->end);
832 : : }
833 : 5 : counter = p_vet->end;
834 : :
835 : 5 : p2_vet = p2_vet->next;
836 : 5 : p_vet = p_vet->next;
837 : : }
838 : :
839 [ + + ]: 10 : if (p_vet != first)
840 : 5 : p_vet->prev->next = NULL;
841 : : else
842 : 5 : first = NULL;
843 : 10 : _asn1_free (p_vet);
844 : 10 : p_vet = first;
845 : : }
846 : : }
847 : :
848 : : /**
849 : : * asn1_der_coding:
850 : : * @element: pointer to an ASN1 element
851 : : * @name: the name of the structure you want to encode (it must be
852 : : * inside *POINTER).
853 : : * @ider: vector that will contain the DER encoding. DER must be a
854 : : * pointer to memory cells already allocated.
855 : : * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
856 : : * holds the sizeof of der vector.
857 : : * @errorDescription : return the error description or an empty
858 : : * string if success.
859 : : *
860 : : * Creates the DER encoding for the NAME structure (inside *POINTER
861 : : * structure).
862 : : *
863 : : * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
864 : : * if @name is not a valid element, %ASN1_VALUE_NOT_FOUND if there
865 : : * is an element without a value, %ASN1_MEM_ERROR if the @ider
866 : : * vector isn't big enough and in this case @len will contain the
867 : : * length needed.
868 : : **/
869 : : asn1_retCode
870 : 47 : asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
871 : : char *ErrorDescription)
872 : : {
873 : : ASN1_TYPE node, p, p2;
874 : : unsigned char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
875 : : int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
876 : : asn1_retCode err;
877 : 47 : unsigned char *der = ider;
878 : :
879 : 47 : node = asn1_find_node (element, name);
880 [ - + ]: 47 : if (node == NULL)
881 : 0 : return ASN1_ELEMENT_NOT_FOUND;
882 : :
883 : : /* Node is now a locally allocated variable.
884 : : * That is because in some point we modify the
885 : : * structure, and I don't know why! --nmav
886 : : */
887 : 47 : node = _asn1_copy_structure3 (node);
888 [ - + ]: 47 : if (node == NULL)
889 : 0 : return ASN1_ELEMENT_NOT_FOUND;
890 : :
891 : 47 : max_len = *len;
892 : :
893 : 47 : counter = 0;
894 : 47 : move = DOWN;
895 : 47 : p = node;
896 : : while (1)
897 : : {
898 : :
899 : 335 : counter_old = counter;
900 : 335 : max_len_old = max_len;
901 [ + + ]: 335 : if (move != UP)
902 : : {
903 : 252 : err = _asn1_insert_tag_der (p, der, &counter, &max_len);
904 [ + + ][ - + ]: 252 : if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
905 : 0 : goto error;
906 : : }
907 [ - + + + : 335 : switch (type_field (p->type))
+ + + + +
+ + + ]
908 : : {
909 : : case TYPE_NULL:
910 : 0 : max_len--;
911 [ # # ]: 0 : if (max_len >= 0)
912 : 0 : der[counter] = 0;
913 : 0 : counter++;
914 : 0 : move = RIGHT;
915 : 0 : break;
916 : : case TYPE_BOOLEAN:
917 [ + + ][ + - ]: 6 : if ((p->type & CONST_DEFAULT) && (p->value == NULL))
918 : : {
919 : 3 : counter = counter_old;
920 : 3 : max_len = max_len_old;
921 : : }
922 : : else
923 : : {
924 [ - + ]: 3 : if (p->value == NULL)
925 : : {
926 : 0 : _asn1_error_description_value_not_found (p,
927 : : ErrorDescription);
928 : 0 : err = ASN1_VALUE_NOT_FOUND;
929 : 0 : goto error;
930 : : }
931 : 3 : max_len -= 2;
932 [ + + ]: 3 : if (max_len >= 0)
933 : : {
934 : 2 : der[counter++] = 1;
935 [ - + ]: 2 : if (p->value[0] == 'F')
936 : 0 : der[counter++] = 0;
937 : : else
938 : 2 : der[counter++] = 0xFF;
939 : : }
940 : : else
941 : 1 : counter += 2;
942 : : }
943 : 6 : move = RIGHT;
944 : 6 : break;
945 : : case TYPE_INTEGER:
946 : : case TYPE_ENUMERATED:
947 [ + + ][ + + ]: 58 : if ((p->type & CONST_DEFAULT) && (p->value == NULL))
948 : : {
949 : 6 : counter = counter_old;
950 : 6 : max_len = max_len_old;
951 : : }
952 : : else
953 : : {
954 [ - + ]: 52 : if (p->value == NULL)
955 : : {
956 : 0 : _asn1_error_description_value_not_found (p,
957 : : ErrorDescription);
958 : 0 : err = ASN1_VALUE_NOT_FOUND;
959 : 0 : goto error;
960 : : }
961 : 52 : len2 = asn1_get_length_der (p->value, p->value_len, &len3);
962 [ - + ]: 52 : if (len2 < 0)
963 : : {
964 : 0 : err = ASN1_DER_ERROR;
965 : 0 : goto error;
966 : : }
967 : 52 : max_len -= len2 + len3;
968 [ + + ]: 52 : if (max_len >= 0)
969 : 37 : memcpy (der + counter, p->value, len3 + len2);
970 : 52 : counter += len3 + len2;
971 : : }
972 : 58 : move = RIGHT;
973 : 58 : break;
974 : : case TYPE_OBJECT_ID:
975 [ + + ][ + + ]: 41 : if ((p->type & CONST_DEFAULT) && (p->value == NULL))
976 : : {
977 : 6 : counter = counter_old;
978 : 6 : max_len = max_len_old;
979 : : }
980 : : else
981 : : {
982 [ - + ]: 35 : if (p->value == NULL)
983 : : {
984 : 0 : _asn1_error_description_value_not_found (p,
985 : : ErrorDescription);
986 : 0 : err = ASN1_VALUE_NOT_FOUND;
987 : 0 : goto error;
988 : : }
989 : 35 : len2 = max_len;
990 : 35 : err = _asn1_objectid_der (p->value, der + counter, &len2);
991 [ + + ][ - + ]: 35 : if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
992 : 0 : goto error;
993 : :
994 : 35 : max_len -= len2;
995 : 35 : counter += len2;
996 : : }
997 : 41 : move = RIGHT;
998 : 41 : break;
999 : : case TYPE_TIME:
1000 [ - + ]: 6 : if (p->value == NULL)
1001 : : {
1002 : 0 : _asn1_error_description_value_not_found (p, ErrorDescription);
1003 : 0 : err = ASN1_VALUE_NOT_FOUND;
1004 : 0 : goto error;
1005 : : }
1006 : 6 : len2 = max_len;
1007 : 6 : err = _asn1_time_der (p->value, der + counter, &len2);
1008 [ + + ][ - + ]: 6 : if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1009 : 0 : goto error;
1010 : :
1011 : 6 : max_len -= len2;
1012 : 6 : counter += len2;
1013 : 6 : move = RIGHT;
1014 : 6 : break;
1015 : : case TYPE_OCTET_STRING:
1016 [ - + ]: 16 : if (p->value == NULL)
1017 : : {
1018 : 0 : _asn1_error_description_value_not_found (p, ErrorDescription);
1019 : 0 : err = ASN1_VALUE_NOT_FOUND;
1020 : 0 : goto error;
1021 : : }
1022 : 16 : len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1023 [ - + ]: 16 : if (len2 < 0)
1024 : : {
1025 : 0 : err = ASN1_DER_ERROR;
1026 : 0 : goto error;
1027 : : }
1028 : 16 : max_len -= len2 + len3;
1029 [ + + ]: 16 : if (max_len >= 0)
1030 : 10 : memcpy (der + counter, p->value, len3 + len2);
1031 : 16 : counter += len3 + len2;
1032 : 16 : move = RIGHT;
1033 : 16 : break;
1034 : : case TYPE_GENERALSTRING:
1035 [ - + ]: 6 : if (p->value == NULL)
1036 : : {
1037 : 0 : _asn1_error_description_value_not_found (p, ErrorDescription);
1038 : 0 : err = ASN1_VALUE_NOT_FOUND;
1039 : 0 : goto error;
1040 : : }
1041 : 6 : len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1042 [ - + ]: 6 : if (len2 < 0)
1043 : : {
1044 : 0 : err = ASN1_DER_ERROR;
1045 : 0 : goto error;
1046 : : }
1047 : 6 : max_len -= len2 + len3;
1048 [ + + ]: 6 : if (max_len >= 0)
1049 : 4 : memcpy (der + counter, p->value, len3 + len2);
1050 : 6 : counter += len3 + len2;
1051 : 6 : move = RIGHT;
1052 : 6 : break;
1053 : : case TYPE_BIT_STRING:
1054 [ - + ]: 3 : if (p->value == NULL)
1055 : : {
1056 : 0 : _asn1_error_description_value_not_found (p, ErrorDescription);
1057 : 0 : err = ASN1_VALUE_NOT_FOUND;
1058 : 0 : goto error;
1059 : : }
1060 : 3 : len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1061 [ - + ]: 3 : if (len2 < 0)
1062 : : {
1063 : 0 : err = ASN1_DER_ERROR;
1064 : 0 : goto error;
1065 : : }
1066 : 3 : max_len -= len2 + len3;
1067 [ + + ]: 3 : if (max_len >= 0)
1068 : 2 : memcpy (der + counter, p->value, len3 + len2);
1069 : 3 : counter += len3 + len2;
1070 : 3 : move = RIGHT;
1071 : 3 : break;
1072 : : case TYPE_SEQUENCE:
1073 : : case TYPE_SET:
1074 [ + + ]: 114 : if (move != UP)
1075 : : {
1076 : 57 : _asn1_ltostr (counter, (char *) temp);
1077 : 57 : tlen = _asn1_strlen (temp);
1078 [ + - ]: 57 : if (tlen > 0)
1079 : 57 : _asn1_set_value (p, temp, tlen + 1);
1080 [ - + ]: 57 : if (p->down == NULL)
1081 : : {
1082 : 0 : move = UP;
1083 : 0 : continue;
1084 : : }
1085 : : else
1086 : : {
1087 : 57 : p2 = p->down;
1088 [ + + ][ + + ]: 64 : while (p2 && (type_field (p2->type) == TYPE_TAG))
1089 : 7 : p2 = p2->right;
1090 [ + + ]: 57 : if (p2)
1091 : : {
1092 : 54 : p = p2;
1093 : 54 : move = RIGHT;
1094 : 54 : continue;
1095 : : }
1096 : 3 : move = UP;
1097 : 3 : continue;
1098 : : }
1099 : : }
1100 : : else
1101 : : { /* move==UP */
1102 : 57 : len2 = _asn1_strtol (p->value, NULL, 10);
1103 : 57 : _asn1_set_value (p, NULL, 0);
1104 [ - + ][ # # ]: 57 : if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
1105 : 0 : _asn1_ordering_set (der + len2, max_len - len2, p);
1106 : 57 : asn1_length_der (counter - len2, temp, &len3);
1107 : 57 : max_len -= len3;
1108 [ + + ]: 57 : if (max_len >= 0)
1109 : : {
1110 : 29 : memmove (der + len2 + len3, der + len2, counter - len2);
1111 : 29 : memcpy (der + len2, temp, len3);
1112 : : }
1113 : 57 : counter += len3;
1114 : 57 : move = RIGHT;
1115 : : }
1116 : 57 : break;
1117 : : case TYPE_SEQUENCE_OF:
1118 : : case TYPE_SET_OF:
1119 [ + + ]: 28 : if (move != UP)
1120 : : {
1121 : 17 : _asn1_ltostr (counter, (char *) temp);
1122 : 17 : tlen = _asn1_strlen (temp);
1123 : :
1124 [ + - ]: 17 : if (tlen > 0)
1125 : 17 : _asn1_set_value (p, temp, tlen + 1);
1126 : 17 : p = p->down;
1127 [ + + ]: 26 : while ((type_field (p->type) == TYPE_TAG)
1128 [ + + ]: 20 : || (type_field (p->type) == TYPE_SIZE))
1129 : 9 : p = p->right;
1130 [ + + ]: 17 : if (p->right)
1131 : : {
1132 : 11 : p = p->right;
1133 : 11 : move = RIGHT;
1134 : 11 : continue;
1135 : : }
1136 : : else
1137 : 6 : p = _asn1_find_up (p);
1138 : 6 : move = UP;
1139 : : }
1140 [ + - ]: 17 : if (move == UP)
1141 : : {
1142 : 17 : len2 = _asn1_strtol (p->value, NULL, 10);
1143 : 17 : _asn1_set_value (p, NULL, 0);
1144 [ + + ]: 17 : if ((type_field (p->type) == TYPE_SET_OF)
1145 [ + + ]: 16 : && (max_len - len2 > 0))
1146 : : {
1147 : 9 : _asn1_ordering_set_of (der + len2, max_len - len2, p);
1148 : : }
1149 : 17 : asn1_length_der (counter - len2, temp, &len3);
1150 : 17 : max_len -= len3;
1151 [ + + ]: 17 : if (max_len >= 0)
1152 : : {
1153 : 12 : memmove (der + len2 + len3, der + len2, counter - len2);
1154 : 12 : memcpy (der + len2, temp, len3);
1155 : : }
1156 : 17 : counter += len3;
1157 : 17 : move = RIGHT;
1158 : : }
1159 : 17 : break;
1160 : : case TYPE_ANY:
1161 [ - + ]: 27 : if (p->value == NULL)
1162 : : {
1163 : 0 : _asn1_error_description_value_not_found (p, ErrorDescription);
1164 : 0 : err = ASN1_VALUE_NOT_FOUND;
1165 : 0 : goto error;
1166 : : }
1167 : 27 : len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1168 [ - + ]: 27 : if (len2 < 0)
1169 : : {
1170 : 0 : err = ASN1_DER_ERROR;
1171 : 0 : goto error;
1172 : : }
1173 : 27 : max_len -= len2;
1174 [ + + ]: 27 : if (max_len >= 0)
1175 : 18 : memcpy (der + counter, p->value + len3, len2);
1176 : 27 : counter += len2;
1177 : 27 : move = RIGHT;
1178 : 27 : break;
1179 : : default:
1180 [ + + ]: 30 : move = (move == UP) ? RIGHT : DOWN;
1181 : 30 : break;
1182 : : }
1183 : :
1184 [ + + ][ + + ]: 267 : if ((move != DOWN) && (counter != counter_old))
1185 : : {
1186 : 222 : err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
1187 [ + + ][ - + ]: 222 : if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1188 : 0 : goto error;
1189 : : }
1190 : :
1191 [ + + ][ + + ]: 267 : if (p == node && move != DOWN)
1192 : 47 : break;
1193 : :
1194 [ + + ]: 220 : if (move == DOWN)
1195 : : {
1196 [ + - ]: 15 : if (p->down)
1197 : 15 : p = p->down;
1198 : : else
1199 : 0 : move = RIGHT;
1200 : : }
1201 [ + + ]: 220 : if (move == RIGHT)
1202 : : {
1203 [ + + ]: 205 : if (p->right)
1204 : 125 : p = p->right;
1205 : : else
1206 : 80 : move = UP;
1207 : : }
1208 [ + + ]: 220 : if (move == UP)
1209 : 80 : p = _asn1_find_up (p);
1210 : 288 : }
1211 : :
1212 : 47 : *len = counter;
1213 : :
1214 [ + + ]: 47 : if (max_len < 0)
1215 : : {
1216 : 25 : err = ASN1_MEM_ERROR;
1217 : 25 : goto error;
1218 : : }
1219 : :
1220 : 22 : err = ASN1_SUCCESS;
1221 : :
1222 : : error:
1223 : 47 : asn1_delete_structure (&node);
1224 : 47 : return err;
1225 : : }
|