2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
4 * This file is part of LIBTASN1.
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.
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.
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
23 /*****************************************************/
25 /* Description: Functions to create a DER coding of */
27 /*****************************************************/
30 #include "parser_aux.h"
33 #include <structure.h>
35 #define MAX_TAG_LEN 16
37 /******************************************************/
38 /* Function : _asn1_error_description_value_not_found */
39 /* Description: creates the ErrorDescription string */
40 /* for the ASN1_VALUE_NOT_FOUND error. */
42 /* node: node of the tree where the value is NULL. */
43 /* ErrorDescription: string returned. */
45 /******************************************************/
47 _asn1_error_description_value_not_found (asn1_node node
,
48 char *ErrorDescription
)
51 if (ErrorDescription
== NULL
)
54 Estrcpy (ErrorDescription
, ":: value of element '");
55 _asn1_hierarchical_name (node
, ErrorDescription
+ strlen (ErrorDescription
),
56 ASN1_MAX_ERROR_DESCRIPTION_SIZE
- 40);
57 Estrcat (ErrorDescription
, "' not found");
63 * @len: value to convert.
64 * @der: the encoding (may be %NULL).
65 * @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]).
67 * Creates the DER encoding of the provided length value.
68 * The @der buffer must have enough room for the output. The maximum
69 * length this function will encode is %ASN1_MAX_LENGTH_SIZE.
71 * To know the size of the DER encoding use a %NULL value for @der.
74 asn1_length_der (unsigned long int len
, unsigned char *der
, int *der_len
)
77 unsigned char temp
[ASN1_MAX_LENGTH_SIZE
];
78 #if SIZEOF_UNSIGNED_LONG_INT > 8
79 len
&= 0xFFFFFFFFFFFFFFFF;
86 der
[0] = (unsigned char) len
;
95 temp
[k
++] = len
& 0xFF;
101 der
[0] = ((unsigned char) k
& 0x7F) + 128;
103 der
[*der_len
- 1 - k
] = temp
[k
];
108 /******************************************************/
109 /* Function : _asn1_tag_der */
110 /* Description: creates the DER coding for the CLASS */
111 /* and TAG parameters. */
112 /* It is limited by the ASN1_MAX_TAG_SIZE variable */
114 /* class: value to convert. */
115 /* tag_value: value to convert. */
116 /* ans: string returned. */
117 /* ans_len: number of meaningful bytes of ANS */
118 /* (ans[0]..ans[ans_len-1]). */
120 /******************************************************/
122 _asn1_tag_der (unsigned char class, unsigned int tag_value
,
123 unsigned char *ans
, int *ans_len
)
126 unsigned char temp
[ASN1_MAX_TAG_SIZE
];
131 ans
[0] = (class & 0xE0) + ((unsigned char) (tag_value
& 0x1F));
137 ans
[0] = (class & 0xE0) + 31;
139 while (tag_value
!= 0)
141 temp
[k
++] = tag_value
& 0x7F;
144 if (k
> ASN1_MAX_TAG_SIZE
-1)
145 break; /* will not encode larger tags */
149 ans
[*ans_len
- 1 - k
] = temp
[k
] + 128;
150 ans
[*ans_len
- 1] -= 128;
156 * @str: the input data.
157 * @str_len: STR length (str[0]..str[*str_len-1]).
158 * @der: encoded string returned.
159 * @der_len: number of meaningful bytes of DER (der[0]..der[der_len-1]).
161 * Creates a length-value DER encoding for the input data.
162 * The DER encoding of the input data will be placed in the @der variable.
164 * Note that the OCTET STRING tag is not included in the output.
166 * This function does not return any value because it is expected
167 * that @der_len will contain enough bytes to store the string
168 * plus the DER encoding. The DER encoding size can be obtained using
172 asn1_octet_der (const unsigned char *str
, int str_len
,
173 unsigned char *der
, int *der_len
)
177 if (der
== NULL
|| str_len
< 0)
180 asn1_length_der (str_len
, der
, &len_len
);
181 memcpy (der
+ len_len
, str
, str_len
);
182 *der_len
= str_len
+ len_len
;
187 * asn1_encode_simple_der:
188 * @etype: The type of the string to be encoded (ASN1_ETYPE_)
189 * @str: the string data.
190 * @str_len: the string length
191 * @tl: the encoded tag and length
192 * @tl_len: the bytes of the @tl field
194 * Creates the DER encoding for various simple ASN.1 types like strings etc.
195 * It stores the tag and length in @tl, which should have space for at least
196 * %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl.
198 * The complete DER encoding should consist of the value in @tl appended
199 * with the provided @str.
201 * Returns: %ASN1_SUCCESS if successful or an error value.
204 asn1_encode_simple_der (unsigned int etype
, const unsigned char *str
, unsigned int str_len
,
205 unsigned char *tl
, unsigned int *tl_len
)
207 int tag_len
, len_len
;
209 unsigned char der_tag
[ASN1_MAX_TAG_SIZE
];
210 unsigned char der_length
[ASN1_MAX_LENGTH_SIZE
];
214 return ASN1_VALUE_NOT_VALID
;
216 if (ETYPE_OK(etype
) == 0)
217 return ASN1_VALUE_NOT_VALID
;
219 /* doesn't handle constructed classes */
220 if (ETYPE_CLASS(etype
) != ASN1_CLASS_UNIVERSAL
)
221 return ASN1_VALUE_NOT_VALID
;
223 _asn1_tag_der (ETYPE_CLASS(etype
), ETYPE_TAG(etype
),
226 asn1_length_der(str_len
, der_length
, &len_len
);
228 if (tag_len
<= 0 || len_len
<= 0)
229 return ASN1_VALUE_NOT_VALID
;
231 tlen
= tag_len
+ len_len
;
234 return ASN1_MEM_ERROR
;
237 memcpy(p
, der_tag
, tag_len
);
239 memcpy(p
, der_length
, len_len
);
246 /******************************************************/
247 /* Function : _asn1_time_der */
248 /* Description: creates the DER coding for a TIME */
249 /* type (length included). */
251 /* str: TIME null-terminated string. */
252 /* der: string returned. */
253 /* der_len: number of meaningful bytes of DER */
254 /* (der[0]..der[ans_len-1]). Initially it */
255 /* if must store the lenght of DER. */
257 /* ASN1_MEM_ERROR when DER isn't big enough */
258 /* ASN1_SUCCESS otherwise */
259 /******************************************************/
261 _asn1_time_der (unsigned char *str
, int str_len
, unsigned char *der
, int *der_len
)
268 asn1_length_der (str_len
, (max_len
> 0) ? der
: NULL
, &len_len
);
270 if ((len_len
+ str_len
) <= max_len
)
271 memcpy (der
+ len_len
, str
, str_len
);
272 *der_len
= len_len
+ str_len
;
274 if ((*der_len
) > max_len
)
275 return ASN1_MEM_ERROR
;
283 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
288 if(str==NULL) return;
289 str_len=asn1_get_length_der(der,*der_len,&len_len);
290 if (str_len<0) return;
291 memcpy(temp,der+len_len,str_len);
292 *der_len=str_len+len_len;
296 strcat(temp,"00+0000");
300 strcat(temp,"+0000");
304 memmove(temp+12,temp+10,6);
305 temp[10]=temp[11]='0';
317 /******************************************************/
318 /* Function : _asn1_objectid_der */
319 /* Description: creates the DER coding for an */
320 /* OBJECT IDENTIFIER type (length included). */
322 /* str: OBJECT IDENTIFIER null-terminated string. */
323 /* der: string returned. */
324 /* der_len: number of meaningful bytes of DER */
325 /* (der[0]..der[ans_len-1]). Initially it */
326 /* must store the length of DER. */
328 /* ASN1_MEM_ERROR when DER isn't big enough */
329 /* ASN1_SUCCESS otherwise */
330 /******************************************************/
332 _asn1_objectid_der (unsigned char *str
, unsigned char *der
, int *der_len
)
334 int len_len
, counter
, k
, first
, max_len
;
335 char *temp
, *n_end
, *n_start
;
337 unsigned long val
, val1
= 0;
338 int str_len
= _asn1_strlen (str
);
342 temp
= malloc (str_len
+ 2);
344 return ASN1_MEM_ALLOC_ERROR
;
346 memcpy (temp
, str
, str_len
);
348 temp
[str_len
+ 1] = 0;
352 while ((n_end
= strchr (n_start
, '.')))
355 val
= strtoul (n_start
, NULL
, 10);
360 else if (counter
== 2)
363 der
[0] = 40 * val1
+ val
;
369 for (k
= 4; k
>= 0; k
--)
371 bit7
= (val
>> (k
* 7)) & 0x7F;
372 if (bit7
|| first
|| !k
)
376 if (max_len
> (*der_len
))
377 der
[*der_len
] = bit7
;
387 asn1_length_der (*der_len
, NULL
, &len_len
);
388 if (max_len
>= (*der_len
+ len_len
))
390 memmove (der
+ len_len
, der
, *der_len
);
391 asn1_length_der (*der_len
, der
, &len_len
);
397 if (max_len
< (*der_len
))
398 return ASN1_MEM_ERROR
;
404 static const unsigned char bit_mask
[] =
405 { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
410 * @bit_len: number of meaningful bits in STR.
411 * @der: string returned.
412 * @der_len: number of meaningful bytes of DER
413 * (der[0]..der[ans_len-1]).
415 * Creates a length-value DER encoding for the input data
416 * as it would have been for a BIT STRING.
417 * The DER encoded data will be copied in @der.
419 * Note that the BIT STRING tag is not included in the output.
421 * This function does not return any value because it is expected
422 * that @der_len will contain enough bytes to store the string
423 * plus the DER encoding. The DER encoding size can be obtained using
427 asn1_bit_der (const unsigned char *str
, int bit_len
,
428 unsigned char *der
, int *der_len
)
430 int len_len
, len_byte
, len_pad
;
435 len_byte
= bit_len
>> 3;
436 len_pad
= 8 - (bit_len
& 7);
441 asn1_length_der (len_byte
+ 1, der
, &len_len
);
442 der
[len_len
] = len_pad
;
443 memcpy (der
+ len_len
+ 1, str
, len_byte
);
444 der
[len_len
+ len_byte
] &= bit_mask
[len_pad
];
445 *der_len
= len_byte
+ len_len
+ 1;
449 /******************************************************/
450 /* Function : _asn1_complete_explicit_tag */
451 /* Description: add the length coding to the EXPLICIT */
454 /* node: pointer to the tree element. */
455 /* der: string with the DER coding of the whole tree*/
456 /* counter: number of meaningful bytes of DER */
457 /* (der[0]..der[*counter-1]). */
458 /* max_len: size of der vector */
460 /* ASN1_MEM_ERROR if der vector isn't big enough, */
461 /* otherwise ASN1_SUCCESS. */
462 /******************************************************/
464 _asn1_complete_explicit_tag (asn1_node node
, unsigned char *der
,
465 int *counter
, int *max_len
)
468 int is_tag_implicit
, len2
, len3
;
469 unsigned char temp
[SIZEOF_UNSIGNED_INT
];
473 if (node
->type
& CONST_TAG
)
476 /* When there are nested tags we must complete them reverse to
477 the order they were created. This is because completing a tag
478 modifies all data within it, including the incomplete tags
479 which store buffer positions -- simon@josefsson.org 2002-09-06
483 while (p
&& p
!= node
->down
->left
)
485 if (type_field (p
->type
) == ASN1_ETYPE_TAG
)
487 if (p
->type
& CONST_EXPLICIT
)
489 len2
= strtol (p
->name
, NULL
, 10);
490 _asn1_set_name (p
, NULL
);
491 asn1_length_der (*counter
- len2
, temp
, &len3
);
492 if (len3
<= (*max_len
))
494 memmove (der
+ len2
+ len3
, der
+ len2
,
496 memcpy (der
+ len2
, temp
, len3
);
503 { /* CONST_IMPLICIT */
504 if (!is_tag_implicit
)
515 return ASN1_MEM_ERROR
;
520 const tag_and_class_st _asn1_tags
[] =
522 [ASN1_ETYPE_GENERALSTRING
] = {ASN1_TAG_GENERALSTRING
, ASN1_CLASS_UNIVERSAL
, "type:GENERALSTRING"},
523 [ASN1_ETYPE_NUMERIC_STRING
] = {ASN1_TAG_NUMERIC_STRING
, ASN1_CLASS_UNIVERSAL
, "type:NUMERIC_STR"},
524 [ASN1_ETYPE_IA5_STRING
] = {ASN1_TAG_IA5_STRING
, ASN1_CLASS_UNIVERSAL
, "type:IA5_STR"},
525 [ASN1_ETYPE_TELETEX_STRING
] = {ASN1_TAG_TELETEX_STRING
, ASN1_CLASS_UNIVERSAL
, "type:TELETEX_STR"},
526 [ASN1_ETYPE_PRINTABLE_STRING
] = {ASN1_TAG_PRINTABLE_STRING
, ASN1_CLASS_UNIVERSAL
, "type:PRINTABLE_STR"},
527 [ASN1_ETYPE_UNIVERSAL_STRING
] = {ASN1_TAG_UNIVERSAL_STRING
, ASN1_CLASS_UNIVERSAL
, "type:UNIVERSAL_STR"},
528 [ASN1_ETYPE_BMP_STRING
] = {ASN1_TAG_BMP_STRING
, ASN1_CLASS_UNIVERSAL
, "type:BMP_STR"},
529 [ASN1_ETYPE_UTF8_STRING
] = {ASN1_TAG_UTF8_STRING
, ASN1_CLASS_UNIVERSAL
, "type:UTF8_STR"},
530 [ASN1_ETYPE_VISIBLE_STRING
] = {ASN1_TAG_VISIBLE_STRING
, ASN1_CLASS_UNIVERSAL
, "type:VISIBLE_STR"},
531 [ASN1_ETYPE_OCTET_STRING
] = {ASN1_TAG_OCTET_STRING
, ASN1_CLASS_UNIVERSAL
, "type:OCT_STR"},
532 [ASN1_ETYPE_BIT_STRING
] = {ASN1_TAG_BIT_STRING
, ASN1_CLASS_UNIVERSAL
, "type:BIT_STR"},
533 [ASN1_ETYPE_OBJECT_ID
] = {ASN1_TAG_OBJECT_ID
, ASN1_CLASS_UNIVERSAL
, "type:OBJ_ID"},
534 [ASN1_ETYPE_NULL
] = {ASN1_TAG_NULL
, ASN1_CLASS_UNIVERSAL
, "type:NULL"},
535 [ASN1_ETYPE_BOOLEAN
] = {ASN1_TAG_BOOLEAN
, ASN1_CLASS_UNIVERSAL
, "type:BOOLEAN"},
536 [ASN1_ETYPE_INTEGER
] = {ASN1_TAG_INTEGER
, ASN1_CLASS_UNIVERSAL
, "type:INTEGER"},
537 [ASN1_ETYPE_ENUMERATED
] = {ASN1_TAG_ENUMERATED
, ASN1_CLASS_UNIVERSAL
, "type:ENUMERATED"},
538 [ASN1_ETYPE_SEQUENCE
] = {ASN1_TAG_SEQUENCE
, ASN1_CLASS_UNIVERSAL
| ASN1_CLASS_STRUCTURED
, "type:SEQUENCE"},
539 [ASN1_ETYPE_SEQUENCE_OF
] ={ASN1_TAG_SEQUENCE
, ASN1_CLASS_UNIVERSAL
| ASN1_CLASS_STRUCTURED
, "type:SEQ_OF"},
540 [ASN1_ETYPE_SET
] = {ASN1_TAG_SET
, ASN1_CLASS_UNIVERSAL
| ASN1_CLASS_STRUCTURED
, "type:SET"},
541 [ASN1_ETYPE_SET_OF
] = {ASN1_TAG_SET
, ASN1_CLASS_UNIVERSAL
| ASN1_CLASS_STRUCTURED
, "type:SET_OF"},
542 [ASN1_ETYPE_GENERALIZED_TIME
] = {ASN1_TAG_GENERALIZEDTime
, ASN1_CLASS_UNIVERSAL
, "type:GENERALIZED_TIME"},
543 [ASN1_ETYPE_UTC_TIME
] = {ASN1_TAG_UTCTime
, ASN1_CLASS_UNIVERSAL
, "type:UTC_TIME"},
546 unsigned int _asn1_tags_size
= sizeof(_asn1_tags
)/sizeof(_asn1_tags
[0]);
548 /******************************************************/
549 /* Function : _asn1_insert_tag_der */
550 /* Description: creates the DER coding of tags of one */
553 /* node: pointer to the tree element. */
554 /* der: string returned */
555 /* counter: number of meaningful bytes of DER */
556 /* (counter[0]..der[*counter-1]). */
557 /* max_len: size of der vector */
559 /* ASN1_GENERIC_ERROR if the type is unknown, */
560 /* ASN1_MEM_ERROR if der vector isn't big enough, */
561 /* otherwise ASN1_SUCCESS. */
562 /******************************************************/
564 _asn1_insert_tag_der (asn1_node node
, unsigned char *der
, int *counter
,
568 int tag_len
, is_tag_implicit
;
569 unsigned char class, class_implicit
= 0, temp
[SIZEOF_UNSIGNED_INT
* 3 + 1];
570 unsigned long tag_implicit
= 0;
571 unsigned char tag_der
[MAX_TAG_LEN
];
575 if (node
->type
& CONST_TAG
)
580 if (type_field (p
->type
) == ASN1_ETYPE_TAG
)
582 if (p
->type
& CONST_APPLICATION
)
583 class = ASN1_CLASS_APPLICATION
;
584 else if (p
->type
& CONST_UNIVERSAL
)
585 class = ASN1_CLASS_UNIVERSAL
;
586 else if (p
->type
& CONST_PRIVATE
)
587 class = ASN1_CLASS_PRIVATE
;
589 class = ASN1_CLASS_CONTEXT_SPECIFIC
;
591 if (p
->type
& CONST_EXPLICIT
)
594 _asn1_tag_der (class_implicit
, tag_implicit
, tag_der
,
597 _asn1_tag_der (class | ASN1_CLASS_STRUCTURED
,
598 _asn1_strtoul (p
->value
, NULL
, 10),
603 memcpy (der
+ *counter
, tag_der
, tag_len
);
606 _asn1_ltostr (*counter
, (char *) temp
);
607 _asn1_set_name (p
, (const char *) temp
);
612 { /* CONST_IMPLICIT */
613 if (!is_tag_implicit
)
615 if ((type_field (node
->type
) == ASN1_ETYPE_SEQUENCE
) ||
616 (type_field (node
->type
) == ASN1_ETYPE_SEQUENCE_OF
) ||
617 (type_field (node
->type
) == ASN1_ETYPE_SET
) ||
618 (type_field (node
->type
) == ASN1_ETYPE_SET_OF
))
619 class |= ASN1_CLASS_STRUCTURED
;
620 class_implicit
= class;
621 tag_implicit
= _asn1_strtoul (p
->value
, NULL
, 10);
632 _asn1_tag_der (class_implicit
, tag_implicit
, tag_der
, &tag_len
);
636 unsigned type
= type_field (node
->type
);
640 _asn1_tag_der (_asn1_tags
[type
].class, _asn1_tags
[type
].tag
,
644 case ASN1_ETYPE_CHOICE
:
649 return ASN1_GENERIC_ERROR
;
655 memcpy (der
+ *counter
, tag_der
, tag_len
);
659 return ASN1_MEM_ERROR
;
664 /******************************************************/
665 /* Function : _asn1_ordering_set */
666 /* Description: puts the elements of a SET type in */
667 /* the correct order according to DER rules. */
669 /* der: string with the DER coding. */
670 /* node: pointer to the SET element. */
672 /******************************************************/
674 _asn1_ordering_set (unsigned char *der
, int der_len
, asn1_node node
)
680 struct vet
*next
, *prev
;
683 int counter
, len
, len2
;
684 struct vet
*first
, *last
, *p_vet
, *p2_vet
;
686 unsigned char class, *temp
;
691 if (type_field (node
->type
) != ASN1_ETYPE_SET
)
695 while ((type_field (p
->type
) == ASN1_ETYPE_TAG
)
696 || (type_field (p
->type
) == ASN1_ETYPE_SIZE
))
699 if ((p
== NULL
) || (p
->right
== NULL
))
705 p_vet
= malloc (sizeof (struct vet
));
717 /* tag value calculation */
719 (der
+ counter
, der_len
- counter
, &class, &len2
,
720 &tag
) != ASN1_SUCCESS
)
722 p_vet
->value
= (class << 24) | tag
;
725 /* extraction and length */
726 len2
= asn1_get_length_der (der
+ counter
, der_len
- counter
, &len
);
729 counter
+= len
+ len2
;
731 p_vet
->end
= counter
;
739 p2_vet
= p_vet
->next
;
743 if (p_vet
->value
> p2_vet
->value
)
745 /* change position */
746 temp
= malloc (p_vet
->end
- counter
);
750 memcpy (temp
, der
+ counter
, p_vet
->end
- counter
);
751 memcpy (der
+ counter
, der
+ p_vet
->end
,
752 p2_vet
->end
- p_vet
->end
);
753 memcpy (der
+ counter
+ p2_vet
->end
- p_vet
->end
, temp
,
754 p_vet
->end
- counter
);
758 p_vet
->value
= p2_vet
->value
;
761 p_vet
->end
= counter
+ (p2_vet
->end
- p_vet
->end
);
763 counter
= p_vet
->end
;
765 p2_vet
= p2_vet
->next
;
770 p_vet
->prev
->next
= NULL
;
778 /******************************************************/
779 /* Function : _asn1_ordering_set_of */
780 /* Description: puts the elements of a SET OF type in */
781 /* the correct order according to DER rules. */
783 /* der: string with the DER coding. */
784 /* node: pointer to the SET OF element. */
786 /******************************************************/
788 _asn1_ordering_set_of (unsigned char *der
, int der_len
, asn1_node node
)
793 struct vet
*next
, *prev
;
796 int counter
, len
, len2
, change
;
797 struct vet
*first
, *last
, *p_vet
, *p2_vet
;
799 unsigned char *temp
, class;
800 unsigned long k
, max
;
804 if (type_field (node
->type
) != ASN1_ETYPE_SET_OF
)
808 while ((type_field (p
->type
) == ASN1_ETYPE_TAG
)
809 || (type_field (p
->type
) == ASN1_ETYPE_SIZE
))
813 if ((p
== NULL
) || (p
->right
== NULL
))
819 p_vet
= malloc (sizeof (struct vet
));
831 /* extraction of tag and length */
832 if (der_len
- counter
> 0)
836 (der
+ counter
, der_len
- counter
, &class, &len
,
837 NULL
) != ASN1_SUCCESS
)
841 len2
= asn1_get_length_der (der
+ counter
, der_len
- counter
, &len
);
844 counter
+= len
+ len2
;
847 p_vet
->end
= counter
;
855 p2_vet
= p_vet
->next
;
859 if ((p_vet
->end
- counter
) > (p2_vet
->end
- p_vet
->end
))
860 max
= p_vet
->end
- counter
;
862 max
= p2_vet
->end
- p_vet
->end
;
865 for (k
= 0; k
< max
; k
++)
866 if (der
[counter
+ k
] > der
[p_vet
->end
+ k
])
871 else if (der
[counter
+ k
] < der
[p_vet
->end
+ k
])
878 && ((p_vet
->end
- counter
) > (p2_vet
->end
- p_vet
->end
)))
883 /* change position */
884 temp
= malloc (p_vet
->end
- counter
);
888 memcpy (temp
, der
+ counter
, (p_vet
->end
) - counter
);
889 memcpy (der
+ counter
, der
+ (p_vet
->end
),
890 (p2_vet
->end
) - (p_vet
->end
));
891 memcpy (der
+ counter
+ (p2_vet
->end
) - (p_vet
->end
), temp
,
892 (p_vet
->end
) - counter
);
895 p_vet
->end
= counter
+ (p2_vet
->end
- p_vet
->end
);
897 counter
= p_vet
->end
;
899 p2_vet
= p2_vet
->next
;
904 p_vet
->prev
->next
= NULL
;
914 * @element: pointer to an ASN1 element
915 * @name: the name of the structure you want to encode (it must be
917 * @ider: vector that will contain the DER encoding. DER must be a
918 * pointer to memory cells already allocated.
919 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
920 * holds the sizeof of der vector.
921 * @errorDescription : return the error description or an empty
924 * Creates the DER encoding for the NAME structure (inside *POINTER
927 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
928 * if @name is not a valid element, %ASN1_VALUE_NOT_FOUND if there
929 * is an element without a value, %ASN1_MEM_ERROR if the @ider
930 * vector isn't big enough and in this case @len will contain the
934 asn1_der_coding (asn1_node element
, const char *name
, void *ider
, int *len
,
935 char *ErrorDescription
)
937 asn1_node node
, p
, p2
;
938 unsigned char temp
[SIZEOF_UNSIGNED_LONG_INT
* 3 + 1];
939 int counter
, counter_old
, len2
, len3
, tlen
, move
, max_len
, max_len_old
;
941 unsigned char *der
= ider
;
943 node
= asn1_find_node (element
, name
);
945 return ASN1_ELEMENT_NOT_FOUND
;
947 /* Node is now a locally allocated variable.
948 * That is because in some point we modify the
949 * structure, and I don't know why! --nmav
951 node
= _asn1_copy_structure3 (node
);
953 return ASN1_ELEMENT_NOT_FOUND
;
963 counter_old
= counter
;
964 max_len_old
= max_len
;
967 err
= _asn1_insert_tag_der (p
, der
, &counter
, &max_len
);
968 if (err
!= ASN1_SUCCESS
&& err
!= ASN1_MEM_ERROR
)
971 switch (type_field (p
->type
))
973 case ASN1_ETYPE_NULL
:
980 case ASN1_ETYPE_BOOLEAN
:
981 if ((p
->type
& CONST_DEFAULT
) && (p
->value
== NULL
))
983 counter
= counter_old
;
984 max_len
= max_len_old
;
988 if (p
->value
== NULL
)
990 _asn1_error_description_value_not_found (p
,
992 err
= ASN1_VALUE_NOT_FOUND
;
999 if (p
->value
[0] == 'F')
1002 der
[counter
++] = 0xFF;
1009 case ASN1_ETYPE_INTEGER
:
1010 case ASN1_ETYPE_ENUMERATED
:
1011 if ((p
->type
& CONST_DEFAULT
) && (p
->value
== NULL
))
1013 counter
= counter_old
;
1014 max_len
= max_len_old
;
1018 if (p
->value
== NULL
)
1020 _asn1_error_description_value_not_found (p
,
1022 err
= ASN1_VALUE_NOT_FOUND
;
1025 len2
= asn1_get_length_der (p
->value
, p
->value_len
, &len3
);
1028 err
= ASN1_DER_ERROR
;
1031 max_len
-= len2
+ len3
;
1033 memcpy (der
+ counter
, p
->value
, len3
+ len2
);
1034 counter
+= len3
+ len2
;
1038 case ASN1_ETYPE_OBJECT_ID
:
1039 if ((p
->type
& CONST_DEFAULT
) && (p
->value
== NULL
))
1041 counter
= counter_old
;
1042 max_len
= max_len_old
;
1046 if (p
->value
== NULL
)
1048 _asn1_error_description_value_not_found (p
,
1050 err
= ASN1_VALUE_NOT_FOUND
;
1054 err
= _asn1_objectid_der (p
->value
, der
+ counter
, &len2
);
1055 if (err
!= ASN1_SUCCESS
&& err
!= ASN1_MEM_ERROR
)
1063 case ASN1_ETYPE_GENERALIZED_TIME
:
1064 case ASN1_ETYPE_UTC_TIME
:
1065 if (p
->value
== NULL
)
1067 _asn1_error_description_value_not_found (p
, ErrorDescription
);
1068 err
= ASN1_VALUE_NOT_FOUND
;
1072 err
= _asn1_time_der (p
->value
, p
->value_len
, der
+ counter
, &len2
);
1073 if (err
!= ASN1_SUCCESS
&& err
!= ASN1_MEM_ERROR
)
1080 case ASN1_ETYPE_OCTET_STRING
:
1081 case ASN1_ETYPE_GENERALSTRING
:
1082 case ASN1_ETYPE_NUMERIC_STRING
:
1083 case ASN1_ETYPE_IA5_STRING
:
1084 case ASN1_ETYPE_TELETEX_STRING
:
1085 case ASN1_ETYPE_PRINTABLE_STRING
:
1086 case ASN1_ETYPE_UNIVERSAL_STRING
:
1087 case ASN1_ETYPE_BMP_STRING
:
1088 case ASN1_ETYPE_UTF8_STRING
:
1089 case ASN1_ETYPE_VISIBLE_STRING
:
1090 case ASN1_ETYPE_BIT_STRING
:
1091 if (p
->value
== NULL
)
1093 _asn1_error_description_value_not_found (p
, ErrorDescription
);
1094 err
= ASN1_VALUE_NOT_FOUND
;
1097 len2
= asn1_get_length_der (p
->value
, p
->value_len
, &len3
);
1100 err
= ASN1_DER_ERROR
;
1103 max_len
-= len2
+ len3
;
1105 memcpy (der
+ counter
, p
->value
, len3
+ len2
);
1106 counter
+= len3
+ len2
;
1109 case ASN1_ETYPE_SEQUENCE
:
1110 case ASN1_ETYPE_SET
:
1113 _asn1_ltostr (counter
, (char *) temp
);
1114 tlen
= _asn1_strlen (temp
);
1116 _asn1_set_value (p
, temp
, tlen
+ 1);
1117 if (p
->down
== NULL
)
1125 while (p2
&& (type_field (p2
->type
) == ASN1_ETYPE_TAG
))
1139 len2
= _asn1_strtol (p
->value
, NULL
, 10);
1140 _asn1_set_value (p
, NULL
, 0);
1141 if ((type_field (p
->type
) == ASN1_ETYPE_SET
) && (max_len
>= 0))
1142 _asn1_ordering_set (der
+ len2
, max_len
- len2
, p
);
1143 asn1_length_der (counter
- len2
, temp
, &len3
);
1147 memmove (der
+ len2
+ len3
, der
+ len2
, counter
- len2
);
1148 memcpy (der
+ len2
, temp
, len3
);
1154 case ASN1_ETYPE_SEQUENCE_OF
:
1155 case ASN1_ETYPE_SET_OF
:
1158 _asn1_ltostr (counter
, (char *) temp
);
1159 tlen
= _asn1_strlen (temp
);
1162 _asn1_set_value (p
, temp
, tlen
+ 1);
1164 while ((type_field (p
->type
) == ASN1_ETYPE_TAG
)
1165 || (type_field (p
->type
) == ASN1_ETYPE_SIZE
))
1174 p
= _asn1_find_up (p
);
1179 len2
= _asn1_strtol (p
->value
, NULL
, 10);
1180 _asn1_set_value (p
, NULL
, 0);
1181 if ((type_field (p
->type
) == ASN1_ETYPE_SET_OF
)
1182 && (max_len
- len2
> 0))
1184 _asn1_ordering_set_of (der
+ len2
, max_len
- len2
, p
);
1186 asn1_length_der (counter
- len2
, temp
, &len3
);
1190 memmove (der
+ len2
+ len3
, der
+ len2
, counter
- len2
);
1191 memcpy (der
+ len2
, temp
, len3
);
1197 case ASN1_ETYPE_ANY
:
1198 if (p
->value
== NULL
)
1200 _asn1_error_description_value_not_found (p
, ErrorDescription
);
1201 err
= ASN1_VALUE_NOT_FOUND
;
1204 len2
= asn1_get_length_der (p
->value
, p
->value_len
, &len3
);
1207 err
= ASN1_DER_ERROR
;
1212 memcpy (der
+ counter
, p
->value
+ len3
, len2
);
1217 move
= (move
== UP
) ? RIGHT
: DOWN
;
1221 if ((move
!= DOWN
) && (counter
!= counter_old
))
1223 err
= _asn1_complete_explicit_tag (p
, der
, &counter
, &max_len
);
1224 if (err
!= ASN1_SUCCESS
&& err
!= ASN1_MEM_ERROR
)
1228 if (p
== node
&& move
!= DOWN
)
1246 p
= _asn1_find_up (p
);
1253 err
= ASN1_MEM_ERROR
;
1260 asn1_delete_structure (&node
);