Add `gnutls/dtls.h' to the distribution.
[gnutls.git] / lib / minitasn1 / coding.c
blob31b5ebb1762ba827cda12879735e240929602dbb
1 /*
2 * Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010 Free Software
3 * Foundation, Inc.
5 * This file is part of LIBTASN1.
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
24 /*****************************************************/
25 /* File: coding.c */
26 /* Description: Functions to create a DER coding of */
27 /* an ASN1 type. */
28 /*****************************************************/
30 #include <int.h>
31 #include "parser_aux.h"
32 #include <gstr.h>
33 #include "element.h"
34 #include <structure.h>
36 #define MAX_TAG_LEN 16
38 /******************************************************/
39 /* Function : _asn1_error_description_value_not_found */
40 /* Description: creates the ErrorDescription string */
41 /* for the ASN1_VALUE_NOT_FOUND error. */
42 /* Parameters: */
43 /* node: node of the tree where the value is NULL. */
44 /* ErrorDescription: string returned. */
45 /* Return: */
46 /******************************************************/
47 static void
48 _asn1_error_description_value_not_found (ASN1_TYPE node,
49 char *ErrorDescription)
52 if (ErrorDescription == NULL)
53 return;
55 Estrcpy (ErrorDescription, ":: value of element '");
56 _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
57 ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
58 Estrcat (ErrorDescription, "' not found");
62 /**
63 * asn1_length_der:
64 * @len: value to convert.
65 * @ans: string returned.
66 * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
68 * Creates the DER coding for the LEN parameter (only the length).
69 * The @ans buffer is pre-allocated and must have room for the output.
70 **/
71 void
72 asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
74 int k;
75 unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
77 if (len < 128)
79 /* short form */
80 if (ans != NULL)
81 ans[0] = (unsigned char) len;
82 *ans_len = 1;
84 else
86 /* Long form */
87 k = 0;
88 while (len)
90 temp[k++] = len & 0xFF;
91 len = len >> 8;
93 *ans_len = k + 1;
94 if (ans != NULL)
96 ans[0] = ((unsigned char) k & 0x7F) + 128;
97 while (k--)
98 ans[*ans_len - 1 - k] = temp[k];
103 /******************************************************/
104 /* Function : _asn1_tag_der */
105 /* Description: creates the DER coding for the CLASS */
106 /* and TAG parameters. */
107 /* Parameters: */
108 /* class: value to convert. */
109 /* tag_value: value to convert. */
110 /* ans: string returned. */
111 /* ans_len: number of meaningful bytes of ANS */
112 /* (ans[0]..ans[ans_len-1]). */
113 /* Return: */
114 /******************************************************/
115 static void
116 _asn1_tag_der (unsigned char class, unsigned int tag_value,
117 unsigned char *ans, int *ans_len)
119 int k;
120 unsigned char temp[SIZEOF_UNSIGNED_INT];
122 if (tag_value < 31)
124 /* short form */
125 ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
126 *ans_len = 1;
128 else
130 /* Long form */
131 ans[0] = (class & 0xE0) + 31;
132 k = 0;
133 while (tag_value)
135 temp[k++] = tag_value & 0x7F;
136 tag_value = tag_value >> 7;
138 *ans_len = k + 1;
139 while (k--)
140 ans[*ans_len - 1 - k] = temp[k] + 128;
141 ans[*ans_len - 1] -= 128;
146 * asn1_octet_der:
147 * @str: OCTET string.
148 * @str_len: STR length (str[0]..str[str_len-1]).
149 * @der: string returned.
150 * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]).
152 * Creates the DER coding for an OCTET type (length included).
154 void
155 asn1_octet_der (const unsigned char *str, int str_len,
156 unsigned char *der, int *der_len)
158 int len_len;
160 if (der == NULL || str_len < 0)
161 return;
162 asn1_length_der (str_len, der, &len_len);
163 memcpy (der + len_len, str, str_len);
164 *der_len = str_len + len_len;
167 /******************************************************/
168 /* Function : _asn1_time_der */
169 /* Description: creates the DER coding for a TIME */
170 /* type (length included). */
171 /* Parameters: */
172 /* str: TIME null-terminated string. */
173 /* der: string returned. */
174 /* der_len: number of meaningful bytes of DER */
175 /* (der[0]..der[ans_len-1]). Initially it */
176 /* if must store the lenght of DER. */
177 /* Return: */
178 /* ASN1_MEM_ERROR when DER isn't big enough */
179 /* ASN1_SUCCESS otherwise */
180 /******************************************************/
181 static asn1_retCode
182 _asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
184 int len_len;
185 int max_len;
187 max_len = *der_len;
189 asn1_length_der (strlen (str), (max_len > 0) ? der : NULL, &len_len);
191 if ((len_len + (int) strlen (str)) <= max_len)
192 memcpy (der + len_len, str, strlen (str));
193 *der_len = len_len + strlen (str);
195 if ((*der_len) > max_len)
196 return ASN1_MEM_ERROR;
198 return ASN1_SUCCESS;
203 void
204 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
206 int len_len,str_len;
207 char temp[20];
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;
234 strcpy(str,temp);
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 _asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
255 int len_len, counter, k, first, max_len;
256 char *temp, *n_end, *n_start;
257 unsigned char bit7;
258 unsigned long val, val1 = 0;
260 max_len = *der_len;
262 temp = (char *) _asn1_malloc (strlen (str) + 2);
263 if (temp == NULL)
264 return ASN1_MEM_ALLOC_ERROR;
266 strcpy (temp, str);
267 strcat (temp, ".");
269 counter = 0;
270 n_start = temp;
271 while ((n_end = strchr (n_start, '.')))
273 *n_end = 0;
274 val = strtoul (n_start, NULL, 10);
275 counter++;
277 if (counter == 1)
278 val1 = val;
279 else if (counter == 2)
281 if (max_len > 0)
282 der[0] = 40 * val1 + val;
283 *der_len = 1;
285 else
287 first = 0;
288 for (k = 4; k >= 0; k--)
290 bit7 = (val >> (k * 7)) & 0x7F;
291 if (bit7 || first || !k)
293 if (k)
294 bit7 |= 0x80;
295 if (max_len > (*der_len))
296 der[*der_len] = bit7;
297 (*der_len)++;
298 first = 1;
303 n_start = n_end + 1;
306 asn1_length_der (*der_len, NULL, &len_len);
307 if (max_len >= (*der_len + len_len))
309 memmove (der + len_len, der, *der_len);
310 asn1_length_der (*der_len, der, &len_len);
312 *der_len += len_len;
314 _asn1_free (temp);
316 if (max_len < (*der_len))
317 return ASN1_MEM_ERROR;
319 return ASN1_SUCCESS;
323 const char bit_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
326 * asn1_bit_der:
327 * @str: BIT string.
328 * @bit_len: number of meaningful bits in STR.
329 * @der: string returned.
330 * @der_len: number of meaningful bytes of DER
331 * (der[0]..der[ans_len-1]).
333 * Creates the DER coding for a BIT STRING type (length and pad
334 * included).
336 void
337 asn1_bit_der (const unsigned char *str, int bit_len,
338 unsigned char *der, int *der_len)
340 int len_len, len_byte, len_pad;
342 if (der == NULL)
343 return;
344 len_byte = bit_len >> 3;
345 len_pad = 8 - (bit_len & 7);
346 if (len_pad == 8)
347 len_pad = 0;
348 else
349 len_byte++;
350 asn1_length_der (len_byte + 1, der, &len_len);
351 der[len_len] = len_pad;
352 memcpy (der + len_len + 1, str, len_byte);
353 der[len_len + len_byte] &= bit_mask[len_pad];
354 *der_len = len_byte + len_len + 1;
358 /******************************************************/
359 /* Function : _asn1_complete_explicit_tag */
360 /* Description: add the length coding to the EXPLICIT */
361 /* tags. */
362 /* Parameters: */
363 /* node: pointer to the tree element. */
364 /* der: string with the DER coding of the whole tree*/
365 /* counter: number of meaningful bytes of DER */
366 /* (der[0]..der[*counter-1]). */
367 /* max_len: size of der vector */
368 /* Return: */
369 /* ASN1_MEM_ERROR if der vector isn't big enough, */
370 /* otherwise ASN1_SUCCESS. */
371 /******************************************************/
372 static asn1_retCode
373 _asn1_complete_explicit_tag (ASN1_TYPE node, unsigned char *der,
374 int *counter, int *max_len)
376 ASN1_TYPE p;
377 int is_tag_implicit, len2, len3;
378 unsigned char temp[SIZEOF_UNSIGNED_INT];
380 is_tag_implicit = 0;
382 if (node->type & CONST_TAG)
384 p = node->down;
385 /* When there are nested tags we must complete them reverse to
386 the order they were created. This is because completing a tag
387 modifies all data within it, including the incomplete tags
388 which store buffer positions -- simon@josefsson.org 2002-09-06
390 while (p->right)
391 p = p->right;
392 while (p && p != node->down->left)
394 if (type_field (p->type) == TYPE_TAG)
396 if (p->type & CONST_EXPLICIT)
398 len2 = strtol (p->name, NULL, 10);
399 _asn1_set_name (p, NULL);
400 asn1_length_der (*counter - len2, temp, &len3);
401 if (len3 <= (*max_len))
403 memmove (der + len2 + len3, der + len2,
404 *counter - len2);
405 memcpy (der + len2, temp, len3);
407 *max_len -= len3;
408 *counter += len3;
409 is_tag_implicit = 0;
411 else
412 { /* CONST_IMPLICIT */
413 if (!is_tag_implicit)
415 is_tag_implicit = 1;
419 p = p->left;
423 if (*max_len < 0)
424 return ASN1_MEM_ERROR;
426 return ASN1_SUCCESS;
430 /******************************************************/
431 /* Function : _asn1_insert_tag_der */
432 /* Description: creates the DER coding of tags of one */
433 /* NODE. */
434 /* Parameters: */
435 /* node: pointer to the tree element. */
436 /* der: string returned */
437 /* counter: number of meaningful bytes of DER */
438 /* (counter[0]..der[*counter-1]). */
439 /* max_len: size of der vector */
440 /* Return: */
441 /* ASN1_GENERIC_ERROR if the type is unknown, */
442 /* ASN1_MEM_ERROR if der vector isn't big enough, */
443 /* otherwise ASN1_SUCCESS. */
444 /******************************************************/
445 static asn1_retCode
446 _asn1_insert_tag_der (ASN1_TYPE node, unsigned char *der, int *counter,
447 int *max_len)
449 ASN1_TYPE p;
450 int tag_len, is_tag_implicit;
451 unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
452 unsigned long tag_implicit = 0;
453 char tag_der[MAX_TAG_LEN];
455 is_tag_implicit = 0;
457 if (node->type & CONST_TAG)
459 p = node->down;
460 while (p)
462 if (type_field (p->type) == TYPE_TAG)
464 if (p->type & CONST_APPLICATION)
465 class = ASN1_CLASS_APPLICATION;
466 else if (p->type & CONST_UNIVERSAL)
467 class = ASN1_CLASS_UNIVERSAL;
468 else if (p->type & CONST_PRIVATE)
469 class = ASN1_CLASS_PRIVATE;
470 else
471 class = ASN1_CLASS_CONTEXT_SPECIFIC;
473 if (p->type & CONST_EXPLICIT)
475 if (is_tag_implicit)
476 _asn1_tag_der (class_implicit, tag_implicit, tag_der,
477 &tag_len);
478 else
479 _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
480 strtoul (p->value, NULL, 10), tag_der,
481 &tag_len);
483 *max_len -= tag_len;
484 if (*max_len >= 0)
485 memcpy (der + *counter, tag_der, tag_len);
486 *counter += tag_len;
488 _asn1_ltostr (*counter, temp);
489 _asn1_set_name (p, temp);
491 is_tag_implicit = 0;
493 else
494 { /* CONST_IMPLICIT */
495 if (!is_tag_implicit)
497 if ((type_field (node->type) == TYPE_SEQUENCE) ||
498 (type_field (node->type) == TYPE_SEQUENCE_OF) ||
499 (type_field (node->type) == TYPE_SET) ||
500 (type_field (node->type) == TYPE_SET_OF))
501 class |= ASN1_CLASS_STRUCTURED;
502 class_implicit = class;
503 tag_implicit = strtoul (p->value, NULL, 10);
504 is_tag_implicit = 1;
508 p = p->right;
512 if (is_tag_implicit)
514 _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
516 else
518 switch (type_field (node->type))
520 case TYPE_NULL:
521 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
522 &tag_len);
523 break;
524 case TYPE_BOOLEAN:
525 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
526 &tag_len);
527 break;
528 case TYPE_INTEGER:
529 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
530 &tag_len);
531 break;
532 case TYPE_ENUMERATED:
533 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
534 &tag_len);
535 break;
536 case TYPE_OBJECT_ID:
537 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
538 &tag_len);
539 break;
540 case TYPE_TIME:
541 if (node->type & CONST_UTC)
543 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
544 &tag_len);
546 else
547 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
548 tag_der, &tag_len);
549 break;
550 case TYPE_OCTET_STRING:
551 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
552 &tag_len);
553 break;
554 case TYPE_GENERALSTRING:
555 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
556 tag_der, &tag_len);
557 break;
558 case TYPE_BIT_STRING:
559 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
560 &tag_len);
561 break;
562 case TYPE_SEQUENCE:
563 case TYPE_SEQUENCE_OF:
564 _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
565 ASN1_TAG_SEQUENCE, tag_der, &tag_len);
566 break;
567 case TYPE_SET:
568 case TYPE_SET_OF:
569 _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
570 ASN1_TAG_SET, tag_der, &tag_len);
571 break;
572 case TYPE_TAG:
573 tag_len = 0;
574 break;
575 case TYPE_CHOICE:
576 tag_len = 0;
577 break;
578 case TYPE_ANY:
579 tag_len = 0;
580 break;
581 default:
582 return ASN1_GENERIC_ERROR;
586 *max_len -= tag_len;
587 if (*max_len >= 0)
588 memcpy (der + *counter, tag_der, tag_len);
589 *counter += tag_len;
591 if (*max_len < 0)
592 return ASN1_MEM_ERROR;
594 return ASN1_SUCCESS;
597 /******************************************************/
598 /* Function : _asn1_ordering_set */
599 /* Description: puts the elements of a SET type in */
600 /* the correct order according to DER rules. */
601 /* Parameters: */
602 /* der: string with the DER coding. */
603 /* node: pointer to the SET element. */
604 /* Return: */
605 /******************************************************/
606 static void
607 _asn1_ordering_set (unsigned char *der, int der_len, ASN1_TYPE node)
609 struct vet
611 int end;
612 unsigned long value;
613 struct vet *next, *prev;
616 int counter, len, len2;
617 struct vet *first, *last, *p_vet, *p2_vet;
618 ASN1_TYPE p;
619 unsigned char class, *temp;
620 unsigned long tag;
622 counter = 0;
624 if (type_field (node->type) != TYPE_SET)
625 return;
627 p = node->down;
628 while ((type_field (p->type) == TYPE_TAG)
629 || (type_field (p->type) == TYPE_SIZE))
630 p = p->right;
632 if ((p == NULL) || (p->right == NULL))
633 return;
635 first = last = NULL;
636 while (p)
638 p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
639 if (p_vet == NULL)
640 return;
642 p_vet->next = NULL;
643 p_vet->prev = last;
644 if (first == NULL)
645 first = p_vet;
646 else
647 last->next = p_vet;
648 last = p_vet;
650 /* tag value calculation */
651 if (asn1_get_tag_der
652 (der + counter, der_len - counter, &class, &len2,
653 &tag) != ASN1_SUCCESS)
654 return;
655 p_vet->value = (class << 24) | tag;
656 counter += len2;
658 /* extraction and length */
659 len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
660 if (len2 < 0)
661 return;
662 counter += len + len2;
664 p_vet->end = counter;
665 p = p->right;
668 p_vet = first;
670 while (p_vet)
672 p2_vet = p_vet->next;
673 counter = 0;
674 while (p2_vet)
676 if (p_vet->value > p2_vet->value)
678 /* change position */
679 temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
680 if (temp == NULL)
681 return;
683 memcpy (temp, der + counter, p_vet->end - counter);
684 memcpy (der + counter, der + p_vet->end,
685 p2_vet->end - p_vet->end);
686 memcpy (der + counter + p2_vet->end - p_vet->end, temp,
687 p_vet->end - counter);
688 _asn1_free (temp);
690 tag = p_vet->value;
691 p_vet->value = p2_vet->value;
692 p2_vet->value = tag;
694 p_vet->end = counter + (p2_vet->end - p_vet->end);
696 counter = p_vet->end;
698 p2_vet = p2_vet->next;
699 p_vet = p_vet->next;
702 if (p_vet != first)
703 p_vet->prev->next = NULL;
704 else
705 first = NULL;
706 _asn1_free (p_vet);
707 p_vet = first;
711 /******************************************************/
712 /* Function : _asn1_ordering_set_of */
713 /* Description: puts the elements of a SET OF type in */
714 /* the correct order according to DER rules. */
715 /* Parameters: */
716 /* der: string with the DER coding. */
717 /* node: pointer to the SET OF element. */
718 /* Return: */
719 /******************************************************/
720 static void
721 _asn1_ordering_set_of (unsigned char *der, int der_len, ASN1_TYPE node)
723 struct vet
725 int end;
726 struct vet *next, *prev;
729 int counter, len, len2, change;
730 struct vet *first, *last, *p_vet, *p2_vet;
731 ASN1_TYPE p;
732 unsigned char *temp, class;
733 unsigned long k, max;
735 counter = 0;
737 if (type_field (node->type) != TYPE_SET_OF)
738 return;
740 p = node->down;
741 while ((type_field (p->type) == TYPE_TAG)
742 || (type_field (p->type) == TYPE_SIZE))
743 p = p->right;
744 p = p->right;
746 if ((p == NULL) || (p->right == NULL))
747 return;
749 first = last = NULL;
750 while (p)
752 p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
753 if (p_vet == NULL)
754 return;
756 p_vet->next = NULL;
757 p_vet->prev = last;
758 if (first == NULL)
759 first = p_vet;
760 else
761 last->next = p_vet;
762 last = p_vet;
764 /* extraction of tag and length */
765 if (der_len - counter > 0)
768 if (asn1_get_tag_der
769 (der + counter, der_len - counter, &class, &len,
770 NULL) != ASN1_SUCCESS)
771 return;
772 counter += len;
774 len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
775 if (len2 < 0)
776 return;
777 counter += len + len2;
780 p_vet->end = counter;
781 p = p->right;
784 p_vet = first;
786 while (p_vet)
788 p2_vet = p_vet->next;
789 counter = 0;
790 while (p2_vet)
792 if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
793 max = p_vet->end - counter;
794 else
795 max = p2_vet->end - p_vet->end;
797 change = -1;
798 for (k = 0; k < max; k++)
799 if (der[counter + k] > der[p_vet->end + k])
801 change = 1;
802 break;
804 else if (der[counter + k] < der[p_vet->end + k])
806 change = 0;
807 break;
810 if ((change == -1)
811 && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
812 change = 1;
814 if (change == 1)
816 /* change position */
817 temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
818 if (temp == NULL)
819 return;
821 memcpy (temp, der + counter, (p_vet->end) - counter);
822 memcpy (der + counter, der + (p_vet->end),
823 (p2_vet->end) - (p_vet->end));
824 memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
825 (p_vet->end) - counter);
826 _asn1_free (temp);
828 p_vet->end = counter + (p2_vet->end - p_vet->end);
830 counter = p_vet->end;
832 p2_vet = p2_vet->next;
833 p_vet = p_vet->next;
836 if (p_vet != first)
837 p_vet->prev->next = NULL;
838 else
839 first = NULL;
840 _asn1_free (p_vet);
841 p_vet = first;
846 * asn1_der_coding:
847 * @element: pointer to an ASN1 element
848 * @name: the name of the structure you want to encode (it must be
849 * inside *POINTER).
850 * @ider: vector that will contain the DER encoding. DER must be a
851 * pointer to memory cells already allocated.
852 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
853 * holds the sizeof of der vector.
854 * @errorDescription : return the error description or an empty
855 * string if success.
857 * Creates the DER encoding for the NAME structure (inside *POINTER
858 * structure).
860 * Returns:
862 * %ASN1_SUCCESS: DER encoding OK.
864 * %ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
866 * %ASN1_VALUE_NOT_FOUND: There is an element without a value.
868 * %ASN1_MEM_ERROR: @ider vector isn't big enough. Also in this case
869 * LEN will contain the length needed.
871 asn1_retCode
872 asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
873 char *ErrorDescription)
875 ASN1_TYPE node, p, p2;
876 char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
877 int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
878 asn1_retCode err;
879 unsigned char *der = ider;
881 node = asn1_find_node (element, name);
882 if (node == NULL)
883 return ASN1_ELEMENT_NOT_FOUND;
885 /* Node is now a locally allocated variable.
886 * That is because in some point we modify the
887 * structure, and I don't know why! --nmav
889 node = _asn1_copy_structure3 (node);
890 if (node == NULL)
891 return ASN1_ELEMENT_NOT_FOUND;
893 max_len = *len;
895 counter = 0;
896 move = DOWN;
897 p = node;
898 while (1)
901 counter_old = counter;
902 max_len_old = max_len;
903 if (move != UP)
905 err = _asn1_insert_tag_der (p, der, &counter, &max_len);
906 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
907 goto error;
909 switch (type_field (p->type))
911 case TYPE_NULL:
912 max_len--;
913 if (max_len >= 0)
914 der[counter] = 0;
915 counter++;
916 move = RIGHT;
917 break;
918 case TYPE_BOOLEAN:
919 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
921 counter = counter_old;
922 max_len = max_len_old;
924 else
926 if (p->value == NULL)
928 _asn1_error_description_value_not_found (p,
929 ErrorDescription);
930 err = ASN1_VALUE_NOT_FOUND;
931 goto error;
933 max_len -= 2;
934 if (max_len >= 0)
936 der[counter++] = 1;
937 if (p->value[0] == 'F')
938 der[counter++] = 0;
939 else
940 der[counter++] = 0xFF;
942 else
943 counter += 2;
945 move = RIGHT;
946 break;
947 case TYPE_INTEGER:
948 case TYPE_ENUMERATED:
949 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
951 counter = counter_old;
952 max_len = max_len_old;
954 else
956 if (p->value == NULL)
958 _asn1_error_description_value_not_found (p,
959 ErrorDescription);
960 err = ASN1_VALUE_NOT_FOUND;
961 goto error;
963 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
964 if (len2 < 0)
966 err = ASN1_DER_ERROR;
967 goto error;
969 max_len -= len2 + len3;
970 if (max_len >= 0)
971 memcpy (der + counter, p->value, len3 + len2);
972 counter += len3 + len2;
974 move = RIGHT;
975 break;
976 case TYPE_OBJECT_ID:
977 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
979 counter = counter_old;
980 max_len = max_len_old;
982 else
984 if (p->value == NULL)
986 _asn1_error_description_value_not_found (p,
987 ErrorDescription);
988 err = ASN1_VALUE_NOT_FOUND;
989 goto error;
991 len2 = max_len;
992 err = _asn1_objectid_der (p->value, der + counter, &len2);
993 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
994 goto error;
996 max_len -= len2;
997 counter += len2;
999 move = RIGHT;
1000 break;
1001 case TYPE_TIME:
1002 if (p->value == NULL)
1004 _asn1_error_description_value_not_found (p, ErrorDescription);
1005 err = ASN1_VALUE_NOT_FOUND;
1006 goto error;
1008 len2 = max_len;
1009 err = _asn1_time_der (p->value, der + counter, &len2);
1010 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1011 goto error;
1013 max_len -= len2;
1014 counter += len2;
1015 move = RIGHT;
1016 break;
1017 case TYPE_OCTET_STRING:
1018 if (p->value == NULL)
1020 _asn1_error_description_value_not_found (p, ErrorDescription);
1021 err = ASN1_VALUE_NOT_FOUND;
1022 goto error;
1024 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1025 if (len2 < 0)
1027 err = ASN1_DER_ERROR;
1028 goto error;
1030 max_len -= len2 + len3;
1031 if (max_len >= 0)
1032 memcpy (der + counter, p->value, len3 + len2);
1033 counter += len3 + len2;
1034 move = RIGHT;
1035 break;
1036 case TYPE_GENERALSTRING:
1037 if (p->value == NULL)
1039 _asn1_error_description_value_not_found (p, ErrorDescription);
1040 err = ASN1_VALUE_NOT_FOUND;
1041 goto error;
1043 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1044 if (len2 < 0)
1046 err = ASN1_DER_ERROR;
1047 goto error;
1049 max_len -= len2 + len3;
1050 if (max_len >= 0)
1051 memcpy (der + counter, p->value, len3 + len2);
1052 counter += len3 + len2;
1053 move = RIGHT;
1054 break;
1055 case TYPE_BIT_STRING:
1056 if (p->value == NULL)
1058 _asn1_error_description_value_not_found (p, ErrorDescription);
1059 err = ASN1_VALUE_NOT_FOUND;
1060 goto error;
1062 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1063 if (len2 < 0)
1065 err = ASN1_DER_ERROR;
1066 goto error;
1068 max_len -= len2 + len3;
1069 if (max_len >= 0)
1070 memcpy (der + counter, p->value, len3 + len2);
1071 counter += len3 + len2;
1072 move = RIGHT;
1073 break;
1074 case TYPE_SEQUENCE:
1075 case TYPE_SET:
1076 if (move != UP)
1078 _asn1_ltostr (counter, temp);
1079 tlen = strlen (temp);
1080 if (tlen > 0)
1081 _asn1_set_value (p, temp, tlen + 1);
1082 if (p->down == NULL)
1084 move = UP;
1085 continue;
1087 else
1089 p2 = p->down;
1090 while (p2 && (type_field (p2->type) == TYPE_TAG))
1091 p2 = p2->right;
1092 if (p2)
1094 p = p2;
1095 move = RIGHT;
1096 continue;
1098 move = UP;
1099 continue;
1102 else
1103 { /* move==UP */
1104 len2 = strtol (p->value, NULL, 10);
1105 _asn1_set_value (p, NULL, 0);
1106 if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
1107 _asn1_ordering_set (der + len2, max_len - len2, p);
1108 asn1_length_der (counter - len2, temp, &len3);
1109 max_len -= len3;
1110 if (max_len >= 0)
1112 memmove (der + len2 + len3, der + len2, counter - len2);
1113 memcpy (der + len2, temp, len3);
1115 counter += len3;
1116 move = RIGHT;
1118 break;
1119 case TYPE_SEQUENCE_OF:
1120 case TYPE_SET_OF:
1121 if (move != UP)
1123 _asn1_ltostr (counter, temp);
1124 tlen = strlen (temp);
1126 if (tlen > 0)
1127 _asn1_set_value (p, temp, tlen + 1);
1128 p = p->down;
1129 while ((type_field (p->type) == TYPE_TAG)
1130 || (type_field (p->type) == TYPE_SIZE))
1131 p = p->right;
1132 if (p->right)
1134 p = p->right;
1135 move = RIGHT;
1136 continue;
1138 else
1139 p = _asn1_find_up (p);
1140 move = UP;
1142 if (move == UP)
1144 len2 = strtol (p->value, NULL, 10);
1145 _asn1_set_value (p, NULL, 0);
1146 if ((type_field (p->type) == TYPE_SET_OF)
1147 && (max_len - len2 > 0))
1149 _asn1_ordering_set_of (der + len2, max_len - len2, p);
1151 asn1_length_der (counter - len2, temp, &len3);
1152 max_len -= len3;
1153 if (max_len >= 0)
1155 memmove (der + len2 + len3, der + len2, counter - len2);
1156 memcpy (der + len2, temp, len3);
1158 counter += len3;
1159 move = RIGHT;
1161 break;
1162 case TYPE_ANY:
1163 if (p->value == NULL)
1165 _asn1_error_description_value_not_found (p, ErrorDescription);
1166 err = ASN1_VALUE_NOT_FOUND;
1167 goto error;
1169 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1170 if (len2 < 0)
1172 err = ASN1_DER_ERROR;
1173 goto error;
1175 max_len -= len2;
1176 if (max_len >= 0)
1177 memcpy (der + counter, p->value + len3, len2);
1178 counter += len2;
1179 move = RIGHT;
1180 break;
1181 default:
1182 move = (move == UP) ? RIGHT : DOWN;
1183 break;
1186 if ((move != DOWN) && (counter != counter_old))
1188 err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
1189 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1190 goto error;
1193 if (p == node && move != DOWN)
1194 break;
1196 if (move == DOWN)
1198 if (p->down)
1199 p = p->down;
1200 else
1201 move = RIGHT;
1203 if (move == RIGHT)
1205 if (p->right)
1206 p = p->right;
1207 else
1208 move = UP;
1210 if (move == UP)
1211 p = _asn1_find_up (p);
1214 *len = counter;
1216 if (max_len < 0)
1218 err = ASN1_MEM_ERROR;
1219 goto error;
1222 err = ASN1_SUCCESS;
1224 error:
1225 asn1_delete_structure (&node);
1226 return err;