corrected copyright notices
[gnutls.git] / lib / minitasn1 / coding.c
blob5361b3f068423dedddc8094643fbfe71dbcb3b55
1 /*
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
19 * 02110-1301, USA
23 /*****************************************************/
24 /* File: coding.c */
25 /* Description: Functions to create a DER coding of */
26 /* an ASN1 type. */
27 /*****************************************************/
29 #include <int.h>
30 #include "parser_aux.h"
31 #include <gstr.h>
32 #include "element.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. */
41 /* Parameters: */
42 /* node: node of the tree where the value is NULL. */
43 /* ErrorDescription: string returned. */
44 /* Return: */
45 /******************************************************/
46 static void
47 _asn1_error_description_value_not_found (asn1_node node,
48 char *ErrorDescription)
51 if (ErrorDescription == NULL)
52 return;
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");
61 /**
62 * asn1_length_der:
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.
72 **/
73 void
74 asn1_length_der (unsigned long int len, unsigned char *der, int *der_len)
76 int k;
77 unsigned char temp[ASN1_MAX_LENGTH_SIZE];
78 #if SIZEOF_UNSIGNED_LONG_INT > 8
79 len &= 0xFFFFFFFFFFFFFFFF;
80 #endif
82 if (len < 128)
84 /* short form */
85 if (der != NULL)
86 der[0] = (unsigned char) len;
87 *der_len = 1;
89 else
91 /* Long form */
92 k = 0;
93 while (len)
95 temp[k++] = len & 0xFF;
96 len = len >> 8;
98 *der_len = k + 1;
99 if (der != NULL)
101 der[0] = ((unsigned char) k & 0x7F) + 128;
102 while (k--)
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 */
113 /* Parameters: */
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]). */
119 /* Return: */
120 /******************************************************/
121 static void
122 _asn1_tag_der (unsigned char class, unsigned int tag_value,
123 unsigned char *ans, int *ans_len)
125 int k;
126 unsigned char temp[ASN1_MAX_TAG_SIZE];
128 if (tag_value < 31)
130 /* short form */
131 ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
132 *ans_len = 1;
134 else
136 /* Long form */
137 ans[0] = (class & 0xE0) + 31;
138 k = 0;
139 while (tag_value != 0)
141 temp[k++] = tag_value & 0x7F;
142 tag_value >>= 7;
144 if (k > ASN1_MAX_TAG_SIZE-1)
145 break; /* will not encode larger tags */
147 *ans_len = k + 1;
148 while (k--)
149 ans[*ans_len - 1 - k] = temp[k] + 128;
150 ans[*ans_len - 1] -= 128;
155 * asn1_octet_der:
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
169 * asn1_length_der().
171 void
172 asn1_octet_der (const unsigned char *str, int str_len,
173 unsigned char *der, int *der_len)
175 int len_len;
177 if (der == NULL || str_len < 0)
178 return;
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;
208 unsigned tlen;
209 unsigned char der_tag[ASN1_MAX_TAG_SIZE];
210 unsigned char der_length[ASN1_MAX_LENGTH_SIZE];
211 unsigned char* p;
213 if (str == NULL)
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),
224 der_tag, &tag_len);
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;
233 if (*tl_len < tlen)
234 return ASN1_MEM_ERROR;
236 p = tl;
237 memcpy(p, der_tag, tag_len);
238 p+=tag_len;
239 memcpy(p, der_length, len_len);
241 *tl_len = tlen;
243 return ASN1_SUCCESS;
246 /******************************************************/
247 /* Function : _asn1_time_der */
248 /* Description: creates the DER coding for a TIME */
249 /* type (length included). */
250 /* Parameters: */
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. */
256 /* Return: */
257 /* ASN1_MEM_ERROR when DER isn't big enough */
258 /* ASN1_SUCCESS otherwise */
259 /******************************************************/
260 static int
261 _asn1_time_der (unsigned char *str, int str_len, unsigned char *der, int *der_len)
263 int len_len;
264 int max_len;
266 max_len = *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;
277 return ASN1_SUCCESS;
282 void
283 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
285 int len_len,str_len;
286 char temp[20];
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;
293 switch(str_len){
294 case 11:
295 temp[10]=0;
296 strcat(temp,"00+0000");
297 break;
298 case 13:
299 temp[12]=0;
300 strcat(temp,"+0000");
301 break;
302 case 15:
303 temp[15]=0;
304 memmove(temp+12,temp+10,6);
305 temp[10]=temp[11]='0';
306 break;
307 case 17:
308 temp[17]=0;
309 break;
310 default:
311 return;
313 strcpy(str,temp);
317 /******************************************************/
318 /* Function : _asn1_objectid_der */
319 /* Description: creates the DER coding for an */
320 /* OBJECT IDENTIFIER type (length included). */
321 /* Parameters: */
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. */
327 /* Return: */
328 /* ASN1_MEM_ERROR when DER isn't big enough */
329 /* ASN1_SUCCESS otherwise */
330 /******************************************************/
331 static int
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;
336 unsigned char bit7;
337 unsigned long val, val1 = 0;
338 int str_len = _asn1_strlen (str);
340 max_len = *der_len;
342 temp = malloc (str_len + 2);
343 if (temp == NULL)
344 return ASN1_MEM_ALLOC_ERROR;
346 memcpy (temp, str, str_len);
347 temp[str_len] = '.';
348 temp[str_len + 1] = 0;
350 counter = 0;
351 n_start = temp;
352 while ((n_end = strchr (n_start, '.')))
354 *n_end = 0;
355 val = strtoul (n_start, NULL, 10);
356 counter++;
358 if (counter == 1)
359 val1 = val;
360 else if (counter == 2)
362 if (max_len > 0)
363 der[0] = 40 * val1 + val;
364 *der_len = 1;
366 else
368 first = 0;
369 for (k = 4; k >= 0; k--)
371 bit7 = (val >> (k * 7)) & 0x7F;
372 if (bit7 || first || !k)
374 if (k)
375 bit7 |= 0x80;
376 if (max_len > (*der_len))
377 der[*der_len] = bit7;
378 (*der_len)++;
379 first = 1;
384 n_start = n_end + 1;
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);
393 *der_len += len_len;
395 free (temp);
397 if (max_len < (*der_len))
398 return ASN1_MEM_ERROR;
400 return ASN1_SUCCESS;
404 static const unsigned char bit_mask[] =
405 { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
408 * asn1_bit_der:
409 * @str: BIT string.
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
424 * asn1_length_der().
426 void
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;
432 if (der == NULL)
433 return;
435 len_byte = bit_len >> 3;
436 len_pad = 8 - (bit_len & 7);
437 if (len_pad == 8)
438 len_pad = 0;
439 else
440 len_byte++;
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 */
452 /* tags. */
453 /* Parameters: */
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 */
459 /* Return: */
460 /* ASN1_MEM_ERROR if der vector isn't big enough, */
461 /* otherwise ASN1_SUCCESS. */
462 /******************************************************/
463 static int
464 _asn1_complete_explicit_tag (asn1_node node, unsigned char *der,
465 int *counter, int *max_len)
467 asn1_node p;
468 int is_tag_implicit, len2, len3;
469 unsigned char temp[SIZEOF_UNSIGNED_INT];
471 is_tag_implicit = 0;
473 if (node->type & CONST_TAG)
475 p = node->down;
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
481 while (p->right)
482 p = p->right;
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,
495 *counter - len2);
496 memcpy (der + len2, temp, len3);
498 *max_len -= len3;
499 *counter += len3;
500 is_tag_implicit = 0;
502 else
503 { /* CONST_IMPLICIT */
504 if (!is_tag_implicit)
506 is_tag_implicit = 1;
510 p = p->left;
514 if (*max_len < 0)
515 return ASN1_MEM_ERROR;
517 return ASN1_SUCCESS;
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 */
551 /* NODE. */
552 /* Parameters: */
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 */
558 /* Return: */
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 /******************************************************/
563 static int
564 _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
565 int *max_len)
567 asn1_node p;
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];
573 is_tag_implicit = 0;
575 if (node->type & CONST_TAG)
577 p = node->down;
578 while (p)
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;
588 else
589 class = ASN1_CLASS_CONTEXT_SPECIFIC;
591 if (p->type & CONST_EXPLICIT)
593 if (is_tag_implicit)
594 _asn1_tag_der (class_implicit, tag_implicit, tag_der,
595 &tag_len);
596 else
597 _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
598 _asn1_strtoul (p->value, NULL, 10),
599 tag_der, &tag_len);
601 *max_len -= tag_len;
602 if (*max_len >= 0)
603 memcpy (der + *counter, tag_der, tag_len);
604 *counter += tag_len;
606 _asn1_ltostr (*counter, (char *) temp);
607 _asn1_set_name (p, (const char *) temp);
609 is_tag_implicit = 0;
611 else
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);
622 is_tag_implicit = 1;
626 p = p->right;
630 if (is_tag_implicit)
632 _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
634 else
636 unsigned type = type_field (node->type);
637 switch (type)
639 CASE_HANDLED_ETYPES:
640 _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag,
641 tag_der, &tag_len);
642 break;
643 case ASN1_ETYPE_TAG:
644 case ASN1_ETYPE_CHOICE:
645 case ASN1_ETYPE_ANY:
646 tag_len = 0;
647 break;
648 default:
649 return ASN1_GENERIC_ERROR;
653 *max_len -= tag_len;
654 if (*max_len >= 0)
655 memcpy (der + *counter, tag_der, tag_len);
656 *counter += tag_len;
658 if (*max_len < 0)
659 return ASN1_MEM_ERROR;
661 return ASN1_SUCCESS;
664 /******************************************************/
665 /* Function : _asn1_ordering_set */
666 /* Description: puts the elements of a SET type in */
667 /* the correct order according to DER rules. */
668 /* Parameters: */
669 /* der: string with the DER coding. */
670 /* node: pointer to the SET element. */
671 /* Return: */
672 /******************************************************/
673 static void
674 _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node)
676 struct vet
678 int end;
679 unsigned long value;
680 struct vet *next, *prev;
683 int counter, len, len2;
684 struct vet *first, *last, *p_vet, *p2_vet;
685 asn1_node p;
686 unsigned char class, *temp;
687 unsigned long tag;
689 counter = 0;
691 if (type_field (node->type) != ASN1_ETYPE_SET)
692 return;
694 p = node->down;
695 while ((type_field (p->type) == ASN1_ETYPE_TAG)
696 || (type_field (p->type) == ASN1_ETYPE_SIZE))
697 p = p->right;
699 if ((p == NULL) || (p->right == NULL))
700 return;
702 first = last = NULL;
703 while (p)
705 p_vet = malloc (sizeof (struct vet));
706 if (p_vet == NULL)
707 return;
709 p_vet->next = NULL;
710 p_vet->prev = last;
711 if (first == NULL)
712 first = p_vet;
713 else
714 last->next = p_vet;
715 last = p_vet;
717 /* tag value calculation */
718 if (asn1_get_tag_der
719 (der + counter, der_len - counter, &class, &len2,
720 &tag) != ASN1_SUCCESS)
721 return;
722 p_vet->value = (class << 24) | tag;
723 counter += len2;
725 /* extraction and length */
726 len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
727 if (len2 < 0)
728 return;
729 counter += len + len2;
731 p_vet->end = counter;
732 p = p->right;
735 p_vet = first;
737 while (p_vet)
739 p2_vet = p_vet->next;
740 counter = 0;
741 while (p2_vet)
743 if (p_vet->value > p2_vet->value)
745 /* change position */
746 temp = malloc (p_vet->end - counter);
747 if (temp == NULL)
748 return;
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);
755 free (temp);
757 tag = p_vet->value;
758 p_vet->value = p2_vet->value;
759 p2_vet->value = tag;
761 p_vet->end = counter + (p2_vet->end - p_vet->end);
763 counter = p_vet->end;
765 p2_vet = p2_vet->next;
766 p_vet = p_vet->next;
769 if (p_vet != first)
770 p_vet->prev->next = NULL;
771 else
772 first = NULL;
773 free (p_vet);
774 p_vet = first;
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. */
782 /* Parameters: */
783 /* der: string with the DER coding. */
784 /* node: pointer to the SET OF element. */
785 /* Return: */
786 /******************************************************/
787 static void
788 _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
790 struct vet
792 int end;
793 struct vet *next, *prev;
796 int counter, len, len2, change;
797 struct vet *first, *last, *p_vet, *p2_vet;
798 asn1_node p;
799 unsigned char *temp, class;
800 unsigned long k, max;
802 counter = 0;
804 if (type_field (node->type) != ASN1_ETYPE_SET_OF)
805 return;
807 p = node->down;
808 while ((type_field (p->type) == ASN1_ETYPE_TAG)
809 || (type_field (p->type) == ASN1_ETYPE_SIZE))
810 p = p->right;
811 p = p->right;
813 if ((p == NULL) || (p->right == NULL))
814 return;
816 first = last = NULL;
817 while (p)
819 p_vet = malloc (sizeof (struct vet));
820 if (p_vet == NULL)
821 return;
823 p_vet->next = NULL;
824 p_vet->prev = last;
825 if (first == NULL)
826 first = p_vet;
827 else
828 last->next = p_vet;
829 last = p_vet;
831 /* extraction of tag and length */
832 if (der_len - counter > 0)
835 if (asn1_get_tag_der
836 (der + counter, der_len - counter, &class, &len,
837 NULL) != ASN1_SUCCESS)
838 return;
839 counter += len;
841 len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
842 if (len2 < 0)
843 return;
844 counter += len + len2;
847 p_vet->end = counter;
848 p = p->right;
851 p_vet = first;
853 while (p_vet)
855 p2_vet = p_vet->next;
856 counter = 0;
857 while (p2_vet)
859 if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
860 max = p_vet->end - counter;
861 else
862 max = p2_vet->end - p_vet->end;
864 change = -1;
865 for (k = 0; k < max; k++)
866 if (der[counter + k] > der[p_vet->end + k])
868 change = 1;
869 break;
871 else if (der[counter + k] < der[p_vet->end + k])
873 change = 0;
874 break;
877 if ((change == -1)
878 && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
879 change = 1;
881 if (change == 1)
883 /* change position */
884 temp = malloc (p_vet->end - counter);
885 if (temp == NULL)
886 return;
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);
893 free (temp);
895 p_vet->end = counter + (p2_vet->end - p_vet->end);
897 counter = p_vet->end;
899 p2_vet = p2_vet->next;
900 p_vet = p_vet->next;
903 if (p_vet != first)
904 p_vet->prev->next = NULL;
905 else
906 first = NULL;
907 free (p_vet);
908 p_vet = first;
913 * asn1_der_coding:
914 * @element: pointer to an ASN1 element
915 * @name: the name of the structure you want to encode (it must be
916 * inside *POINTER).
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
922 * string if success.
924 * Creates the DER encoding for the NAME structure (inside *POINTER
925 * structure).
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
931 * length needed.
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;
940 int err;
941 unsigned char *der = ider;
943 node = asn1_find_node (element, name);
944 if (node == NULL)
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);
952 if (node == NULL)
953 return ASN1_ELEMENT_NOT_FOUND;
955 max_len = *len;
957 counter = 0;
958 move = DOWN;
959 p = node;
960 while (1)
963 counter_old = counter;
964 max_len_old = max_len;
965 if (move != UP)
967 err = _asn1_insert_tag_der (p, der, &counter, &max_len);
968 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
969 goto error;
971 switch (type_field (p->type))
973 case ASN1_ETYPE_NULL:
974 max_len--;
975 if (max_len >= 0)
976 der[counter] = 0;
977 counter++;
978 move = RIGHT;
979 break;
980 case ASN1_ETYPE_BOOLEAN:
981 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
983 counter = counter_old;
984 max_len = max_len_old;
986 else
988 if (p->value == NULL)
990 _asn1_error_description_value_not_found (p,
991 ErrorDescription);
992 err = ASN1_VALUE_NOT_FOUND;
993 goto error;
995 max_len -= 2;
996 if (max_len >= 0)
998 der[counter++] = 1;
999 if (p->value[0] == 'F')
1000 der[counter++] = 0;
1001 else
1002 der[counter++] = 0xFF;
1004 else
1005 counter += 2;
1007 move = RIGHT;
1008 break;
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;
1016 else
1018 if (p->value == NULL)
1020 _asn1_error_description_value_not_found (p,
1021 ErrorDescription);
1022 err = ASN1_VALUE_NOT_FOUND;
1023 goto error;
1025 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1026 if (len2 < 0)
1028 err = ASN1_DER_ERROR;
1029 goto error;
1031 max_len -= len2 + len3;
1032 if (max_len >= 0)
1033 memcpy (der + counter, p->value, len3 + len2);
1034 counter += len3 + len2;
1036 move = RIGHT;
1037 break;
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;
1044 else
1046 if (p->value == NULL)
1048 _asn1_error_description_value_not_found (p,
1049 ErrorDescription);
1050 err = ASN1_VALUE_NOT_FOUND;
1051 goto error;
1053 len2 = max_len;
1054 err = _asn1_objectid_der (p->value, der + counter, &len2);
1055 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1056 goto error;
1058 max_len -= len2;
1059 counter += len2;
1061 move = RIGHT;
1062 break;
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;
1069 goto error;
1071 len2 = max_len;
1072 err = _asn1_time_der (p->value, p->value_len, der + counter, &len2);
1073 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1074 goto error;
1076 max_len -= len2;
1077 counter += len2;
1078 move = RIGHT;
1079 break;
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;
1095 goto error;
1097 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1098 if (len2 < 0)
1100 err = ASN1_DER_ERROR;
1101 goto error;
1103 max_len -= len2 + len3;
1104 if (max_len >= 0)
1105 memcpy (der + counter, p->value, len3 + len2);
1106 counter += len3 + len2;
1107 move = RIGHT;
1108 break;
1109 case ASN1_ETYPE_SEQUENCE:
1110 case ASN1_ETYPE_SET:
1111 if (move != UP)
1113 _asn1_ltostr (counter, (char *) temp);
1114 tlen = _asn1_strlen (temp);
1115 if (tlen > 0)
1116 _asn1_set_value (p, temp, tlen + 1);
1117 if (p->down == NULL)
1119 move = UP;
1120 continue;
1122 else
1124 p2 = p->down;
1125 while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG))
1126 p2 = p2->right;
1127 if (p2)
1129 p = p2;
1130 move = RIGHT;
1131 continue;
1133 move = UP;
1134 continue;
1137 else
1138 { /* move==UP */
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);
1144 max_len -= len3;
1145 if (max_len >= 0)
1147 memmove (der + len2 + len3, der + len2, counter - len2);
1148 memcpy (der + len2, temp, len3);
1150 counter += len3;
1151 move = RIGHT;
1153 break;
1154 case ASN1_ETYPE_SEQUENCE_OF:
1155 case ASN1_ETYPE_SET_OF:
1156 if (move != UP)
1158 _asn1_ltostr (counter, (char *) temp);
1159 tlen = _asn1_strlen (temp);
1161 if (tlen > 0)
1162 _asn1_set_value (p, temp, tlen + 1);
1163 p = p->down;
1164 while ((type_field (p->type) == ASN1_ETYPE_TAG)
1165 || (type_field (p->type) == ASN1_ETYPE_SIZE))
1166 p = p->right;
1167 if (p->right)
1169 p = p->right;
1170 move = RIGHT;
1171 continue;
1173 else
1174 p = _asn1_find_up (p);
1175 move = UP;
1177 if (move == UP)
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);
1187 max_len -= len3;
1188 if (max_len >= 0)
1190 memmove (der + len2 + len3, der + len2, counter - len2);
1191 memcpy (der + len2, temp, len3);
1193 counter += len3;
1194 move = RIGHT;
1196 break;
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;
1202 goto error;
1204 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1205 if (len2 < 0)
1207 err = ASN1_DER_ERROR;
1208 goto error;
1210 max_len -= len2;
1211 if (max_len >= 0)
1212 memcpy (der + counter, p->value + len3, len2);
1213 counter += len2;
1214 move = RIGHT;
1215 break;
1216 default:
1217 move = (move == UP) ? RIGHT : DOWN;
1218 break;
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)
1225 goto error;
1228 if (p == node && move != DOWN)
1229 break;
1231 if (move == DOWN)
1233 if (p->down)
1234 p = p->down;
1235 else
1236 move = RIGHT;
1238 if (move == RIGHT)
1240 if (p->right)
1241 p = p->right;
1242 else
1243 move = UP;
1245 if (move == UP)
1246 p = _asn1_find_up (p);
1249 *len = counter;
1251 if (max_len < 0)
1253 err = ASN1_MEM_ERROR;
1254 goto error;
1257 err = ASN1_SUCCESS;
1259 error:
1260 asn1_delete_structure (&node);
1261 return err;