added new functions
[gnutls.git] / lib / minitasn1 / coding.c
blob581ef9675f2d9cf8b8bf39229f5878353a585c45
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 * @ans: string returned.
65 * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
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 asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
73 int k;
74 unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
76 if (len < 128)
78 /* short form */
79 if (ans != NULL)
80 ans[0] = (unsigned char) len;
81 *ans_len = 1;
83 else
85 /* Long form */
86 k = 0;
87 while (len)
89 temp[k++] = len & 0xFF;
90 len = len >> 8;
92 *ans_len = k + 1;
93 if (ans != NULL)
95 ans[0] = ((unsigned char) k & 0x7F) + 128;
96 while (k--)
97 ans[*ans_len - 1 - k] = temp[k];
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 _asn1_tag_der (unsigned char class, unsigned int tag_value,
116 unsigned char *ans, int *ans_len)
118 int k;
119 unsigned char temp[SIZEOF_UNSIGNED_INT];
121 if (tag_value < 31)
123 /* short form */
124 ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
125 *ans_len = 1;
127 else
129 /* Long form */
130 ans[0] = (class & 0xE0) + 31;
131 k = 0;
132 while (tag_value)
134 temp[k++] = tag_value & 0x7F;
135 tag_value = tag_value >> 7;
137 *ans_len = k + 1;
138 while (k--)
139 ans[*ans_len - 1 - k] = temp[k] + 128;
140 ans[*ans_len - 1] -= 128;
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]).
151 * Creates the DER coding for an OCTET type (length included).
153 void
154 asn1_octet_der (const unsigned char *str, int str_len,
155 unsigned char *der, int *der_len)
157 int len_len;
159 if (der == NULL || str_len < 0)
160 return;
161 asn1_length_der (str_len, der, &len_len);
162 memcpy (der + len_len, str, str_len);
163 *der_len = str_len + len_len;
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 int
181 _asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
183 int len_len;
184 int max_len;
185 int str_len = _asn1_strlen (str);
187 max_len = *der_len;
189 asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len);
191 if ((len_len + str_len) <= max_len)
192 memcpy (der + len_len, str, str_len);
193 *der_len = len_len + str_len;
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 int
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;
259 int str_len = _asn1_strlen (str);
261 max_len = *der_len;
263 temp = malloc (str_len + 2);
264 if (temp == NULL)
265 return ASN1_MEM_ALLOC_ERROR;
267 memcpy (temp, str, str_len);
268 temp[str_len] = '.';
269 temp[str_len + 1] = 0;
271 counter = 0;
272 n_start = temp;
273 while ((n_end = strchr (n_start, '.')))
275 *n_end = 0;
276 val = strtoul (n_start, NULL, 10);
277 counter++;
279 if (counter == 1)
280 val1 = val;
281 else if (counter == 2)
283 if (max_len > 0)
284 der[0] = 40 * val1 + val;
285 *der_len = 1;
287 else
289 first = 0;
290 for (k = 4; k >= 0; k--)
292 bit7 = (val >> (k * 7)) & 0x7F;
293 if (bit7 || first || !k)
295 if (k)
296 bit7 |= 0x80;
297 if (max_len > (*der_len))
298 der[*der_len] = bit7;
299 (*der_len)++;
300 first = 1;
305 n_start = n_end + 1;
308 asn1_length_der (*der_len, NULL, &len_len);
309 if (max_len >= (*der_len + len_len))
311 memmove (der + len_len, der, *der_len);
312 asn1_length_der (*der_len, der, &len_len);
314 *der_len += len_len;
316 free (temp);
318 if (max_len < (*der_len))
319 return ASN1_MEM_ERROR;
321 return ASN1_SUCCESS;
325 static const unsigned char bit_mask[] =
326 { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
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]).
336 * Creates the DER coding for a BIT STRING type (length and pad
337 * included).
339 void
340 asn1_bit_der (const unsigned char *str, int bit_len,
341 unsigned char *der, int *der_len)
343 int len_len, len_byte, len_pad;
345 if (der == NULL)
346 return;
347 len_byte = bit_len >> 3;
348 len_pad = 8 - (bit_len & 7);
349 if (len_pad == 8)
350 len_pad = 0;
351 else
352 len_byte++;
353 asn1_length_der (len_byte + 1, der, &len_len);
354 der[len_len] = len_pad;
355 memcpy (der + len_len + 1, str, len_byte);
356 der[len_len + len_byte] &= bit_mask[len_pad];
357 *der_len = len_byte + len_len + 1;
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 int
376 _asn1_complete_explicit_tag (asn1_node node, unsigned char *der,
377 int *counter, int *max_len)
379 asn1_node p;
380 int is_tag_implicit, len2, len3;
381 unsigned char temp[SIZEOF_UNSIGNED_INT];
383 is_tag_implicit = 0;
385 if (node->type & CONST_TAG)
387 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
393 while (p->right)
394 p = p->right;
395 while (p && p != node->down->left)
397 if (type_field (p->type) == TYPE_TAG)
399 if (p->type & CONST_EXPLICIT)
401 len2 = strtol (p->name, NULL, 10);
402 _asn1_set_name (p, NULL);
403 asn1_length_der (*counter - len2, temp, &len3);
404 if (len3 <= (*max_len))
406 memmove (der + len2 + len3, der + len2,
407 *counter - len2);
408 memcpy (der + len2, temp, len3);
410 *max_len -= len3;
411 *counter += len3;
412 is_tag_implicit = 0;
414 else
415 { /* CONST_IMPLICIT */
416 if (!is_tag_implicit)
418 is_tag_implicit = 1;
422 p = p->left;
426 if (*max_len < 0)
427 return ASN1_MEM_ERROR;
429 return ASN1_SUCCESS;
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 int
449 _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
450 int *max_len)
452 asn1_node p;
453 int tag_len, is_tag_implicit;
454 unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
455 unsigned long tag_implicit = 0;
456 unsigned char tag_der[MAX_TAG_LEN];
458 is_tag_implicit = 0;
460 if (node->type & CONST_TAG)
462 p = node->down;
463 while (p)
465 if (type_field (p->type) == TYPE_TAG)
467 if (p->type & CONST_APPLICATION)
468 class = ASN1_CLASS_APPLICATION;
469 else if (p->type & CONST_UNIVERSAL)
470 class = ASN1_CLASS_UNIVERSAL;
471 else if (p->type & CONST_PRIVATE)
472 class = ASN1_CLASS_PRIVATE;
473 else
474 class = ASN1_CLASS_CONTEXT_SPECIFIC;
476 if (p->type & CONST_EXPLICIT)
478 if (is_tag_implicit)
479 _asn1_tag_der (class_implicit, tag_implicit, tag_der,
480 &tag_len);
481 else
482 _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
483 _asn1_strtoul (p->value, NULL, 10),
484 tag_der, &tag_len);
486 *max_len -= tag_len;
487 if (*max_len >= 0)
488 memcpy (der + *counter, tag_der, tag_len);
489 *counter += tag_len;
491 _asn1_ltostr (*counter, (char *) temp);
492 _asn1_set_name (p, (const char *) temp);
494 is_tag_implicit = 0;
496 else
497 { /* CONST_IMPLICIT */
498 if (!is_tag_implicit)
500 if ((type_field (node->type) == TYPE_SEQUENCE) ||
501 (type_field (node->type) == TYPE_SEQUENCE_OF) ||
502 (type_field (node->type) == TYPE_SET) ||
503 (type_field (node->type) == TYPE_SET_OF))
504 class |= ASN1_CLASS_STRUCTURED;
505 class_implicit = class;
506 tag_implicit = _asn1_strtoul (p->value, NULL, 10);
507 is_tag_implicit = 1;
511 p = p->right;
515 if (is_tag_implicit)
517 _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
519 else
521 switch (type_field (node->type))
523 case TYPE_NULL:
524 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
525 &tag_len);
526 break;
527 case TYPE_BOOLEAN:
528 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
529 &tag_len);
530 break;
531 case TYPE_INTEGER:
532 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
533 &tag_len);
534 break;
535 case TYPE_ENUMERATED:
536 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
537 &tag_len);
538 break;
539 case TYPE_OBJECT_ID:
540 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
541 &tag_len);
542 break;
543 case TYPE_TIME:
544 if (node->type & CONST_UTC)
546 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
547 &tag_len);
549 else
550 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
551 tag_der, &tag_len);
552 break;
553 case TYPE_OCTET_STRING:
554 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
555 &tag_len);
556 break;
557 case TYPE_GENERALSTRING:
558 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
559 tag_der, &tag_len);
560 break;
561 case TYPE_BIT_STRING:
562 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
563 &tag_len);
564 break;
565 case TYPE_SEQUENCE:
566 case TYPE_SEQUENCE_OF:
567 _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
568 ASN1_TAG_SEQUENCE, tag_der, &tag_len);
569 break;
570 case TYPE_SET:
571 case TYPE_SET_OF:
572 _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
573 ASN1_TAG_SET, tag_der, &tag_len);
574 break;
575 case TYPE_TAG:
576 tag_len = 0;
577 break;
578 case TYPE_CHOICE:
579 tag_len = 0;
580 break;
581 case TYPE_ANY:
582 tag_len = 0;
583 break;
584 default:
585 return ASN1_GENERIC_ERROR;
589 *max_len -= tag_len;
590 if (*max_len >= 0)
591 memcpy (der + *counter, tag_der, tag_len);
592 *counter += tag_len;
594 if (*max_len < 0)
595 return ASN1_MEM_ERROR;
597 return ASN1_SUCCESS;
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 _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node)
612 struct vet
614 int end;
615 unsigned long value;
616 struct vet *next, *prev;
619 int counter, len, len2;
620 struct vet *first, *last, *p_vet, *p2_vet;
621 asn1_node p;
622 unsigned char class, *temp;
623 unsigned long tag;
625 counter = 0;
627 if (type_field (node->type) != TYPE_SET)
628 return;
630 p = node->down;
631 while ((type_field (p->type) == TYPE_TAG)
632 || (type_field (p->type) == TYPE_SIZE))
633 p = p->right;
635 if ((p == NULL) || (p->right == NULL))
636 return;
638 first = last = NULL;
639 while (p)
641 p_vet = malloc (sizeof (struct vet));
642 if (p_vet == NULL)
643 return;
645 p_vet->next = NULL;
646 p_vet->prev = last;
647 if (first == NULL)
648 first = p_vet;
649 else
650 last->next = p_vet;
651 last = p_vet;
653 /* tag value calculation */
654 if (asn1_get_tag_der
655 (der + counter, der_len - counter, &class, &len2,
656 &tag) != ASN1_SUCCESS)
657 return;
658 p_vet->value = (class << 24) | tag;
659 counter += len2;
661 /* extraction and length */
662 len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
663 if (len2 < 0)
664 return;
665 counter += len + len2;
667 p_vet->end = counter;
668 p = p->right;
671 p_vet = first;
673 while (p_vet)
675 p2_vet = p_vet->next;
676 counter = 0;
677 while (p2_vet)
679 if (p_vet->value > p2_vet->value)
681 /* change position */
682 temp = malloc (p_vet->end - counter);
683 if (temp == NULL)
684 return;
686 memcpy (temp, der + counter, p_vet->end - counter);
687 memcpy (der + counter, der + p_vet->end,
688 p2_vet->end - p_vet->end);
689 memcpy (der + counter + p2_vet->end - p_vet->end, temp,
690 p_vet->end - counter);
691 free (temp);
693 tag = p_vet->value;
694 p_vet->value = p2_vet->value;
695 p2_vet->value = tag;
697 p_vet->end = counter + (p2_vet->end - p_vet->end);
699 counter = p_vet->end;
701 p2_vet = p2_vet->next;
702 p_vet = p_vet->next;
705 if (p_vet != first)
706 p_vet->prev->next = NULL;
707 else
708 first = NULL;
709 free (p_vet);
710 p_vet = first;
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 _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
726 struct vet
728 int end;
729 struct vet *next, *prev;
732 int counter, len, len2, change;
733 struct vet *first, *last, *p_vet, *p2_vet;
734 asn1_node p;
735 unsigned char *temp, class;
736 unsigned long k, max;
738 counter = 0;
740 if (type_field (node->type) != TYPE_SET_OF)
741 return;
743 p = node->down;
744 while ((type_field (p->type) == TYPE_TAG)
745 || (type_field (p->type) == TYPE_SIZE))
746 p = p->right;
747 p = p->right;
749 if ((p == NULL) || (p->right == NULL))
750 return;
752 first = last = NULL;
753 while (p)
755 p_vet = malloc (sizeof (struct vet));
756 if (p_vet == NULL)
757 return;
759 p_vet->next = NULL;
760 p_vet->prev = last;
761 if (first == NULL)
762 first = p_vet;
763 else
764 last->next = p_vet;
765 last = p_vet;
767 /* extraction of tag and length */
768 if (der_len - counter > 0)
771 if (asn1_get_tag_der
772 (der + counter, der_len - counter, &class, &len,
773 NULL) != ASN1_SUCCESS)
774 return;
775 counter += len;
777 len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
778 if (len2 < 0)
779 return;
780 counter += len + len2;
783 p_vet->end = counter;
784 p = p->right;
787 p_vet = first;
789 while (p_vet)
791 p2_vet = p_vet->next;
792 counter = 0;
793 while (p2_vet)
795 if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
796 max = p_vet->end - counter;
797 else
798 max = p2_vet->end - p_vet->end;
800 change = -1;
801 for (k = 0; k < max; k++)
802 if (der[counter + k] > der[p_vet->end + k])
804 change = 1;
805 break;
807 else if (der[counter + k] < der[p_vet->end + k])
809 change = 0;
810 break;
813 if ((change == -1)
814 && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
815 change = 1;
817 if (change == 1)
819 /* change position */
820 temp = malloc (p_vet->end - counter);
821 if (temp == NULL)
822 return;
824 memcpy (temp, der + counter, (p_vet->end) - counter);
825 memcpy (der + counter, der + (p_vet->end),
826 (p2_vet->end) - (p_vet->end));
827 memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
828 (p_vet->end) - counter);
829 free (temp);
831 p_vet->end = counter + (p2_vet->end - p_vet->end);
833 counter = p_vet->end;
835 p2_vet = p2_vet->next;
836 p_vet = p_vet->next;
839 if (p_vet != first)
840 p_vet->prev->next = NULL;
841 else
842 first = NULL;
843 free (p_vet);
844 p_vet = first;
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.
860 * Creates the DER encoding for the NAME structure (inside *POINTER
861 * structure).
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.
870 asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
871 char *ErrorDescription)
873 asn1_node 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 int err;
877 unsigned char *der = ider;
879 node = asn1_find_node (element, name);
880 if (node == NULL)
881 return ASN1_ELEMENT_NOT_FOUND;
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
887 node = _asn1_copy_structure3 (node);
888 if (node == NULL)
889 return ASN1_ELEMENT_NOT_FOUND;
891 max_len = *len;
893 counter = 0;
894 move = DOWN;
895 p = node;
896 while (1)
899 counter_old = counter;
900 max_len_old = max_len;
901 if (move != UP)
903 err = _asn1_insert_tag_der (p, der, &counter, &max_len);
904 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
905 goto error;
907 switch (type_field (p->type))
909 case TYPE_NULL:
910 max_len--;
911 if (max_len >= 0)
912 der[counter] = 0;
913 counter++;
914 move = RIGHT;
915 break;
916 case TYPE_BOOLEAN:
917 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
919 counter = counter_old;
920 max_len = max_len_old;
922 else
924 if (p->value == NULL)
926 _asn1_error_description_value_not_found (p,
927 ErrorDescription);
928 err = ASN1_VALUE_NOT_FOUND;
929 goto error;
931 max_len -= 2;
932 if (max_len >= 0)
934 der[counter++] = 1;
935 if (p->value[0] == 'F')
936 der[counter++] = 0;
937 else
938 der[counter++] = 0xFF;
940 else
941 counter += 2;
943 move = RIGHT;
944 break;
945 case TYPE_INTEGER:
946 case TYPE_ENUMERATED:
947 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
949 counter = counter_old;
950 max_len = max_len_old;
952 else
954 if (p->value == NULL)
956 _asn1_error_description_value_not_found (p,
957 ErrorDescription);
958 err = ASN1_VALUE_NOT_FOUND;
959 goto error;
961 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
962 if (len2 < 0)
964 err = ASN1_DER_ERROR;
965 goto error;
967 max_len -= len2 + len3;
968 if (max_len >= 0)
969 memcpy (der + counter, p->value, len3 + len2);
970 counter += len3 + len2;
972 move = RIGHT;
973 break;
974 case TYPE_OBJECT_ID:
975 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
977 counter = counter_old;
978 max_len = max_len_old;
980 else
982 if (p->value == NULL)
984 _asn1_error_description_value_not_found (p,
985 ErrorDescription);
986 err = ASN1_VALUE_NOT_FOUND;
987 goto error;
989 len2 = max_len;
990 err = _asn1_objectid_der (p->value, der + counter, &len2);
991 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
992 goto error;
994 max_len -= len2;
995 counter += len2;
997 move = RIGHT;
998 break;
999 case TYPE_TIME:
1000 if (p->value == NULL)
1002 _asn1_error_description_value_not_found (p, ErrorDescription);
1003 err = ASN1_VALUE_NOT_FOUND;
1004 goto error;
1006 len2 = max_len;
1007 err = _asn1_time_der (p->value, der + counter, &len2);
1008 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1009 goto error;
1011 max_len -= len2;
1012 counter += len2;
1013 move = RIGHT;
1014 break;
1015 case TYPE_OCTET_STRING:
1016 if (p->value == NULL)
1018 _asn1_error_description_value_not_found (p, ErrorDescription);
1019 err = ASN1_VALUE_NOT_FOUND;
1020 goto error;
1022 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1023 if (len2 < 0)
1025 err = ASN1_DER_ERROR;
1026 goto error;
1028 max_len -= len2 + len3;
1029 if (max_len >= 0)
1030 memcpy (der + counter, p->value, len3 + len2);
1031 counter += len3 + len2;
1032 move = RIGHT;
1033 break;
1034 case TYPE_GENERALSTRING:
1035 if (p->value == NULL)
1037 _asn1_error_description_value_not_found (p, ErrorDescription);
1038 err = ASN1_VALUE_NOT_FOUND;
1039 goto error;
1041 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1042 if (len2 < 0)
1044 err = ASN1_DER_ERROR;
1045 goto error;
1047 max_len -= len2 + len3;
1048 if (max_len >= 0)
1049 memcpy (der + counter, p->value, len3 + len2);
1050 counter += len3 + len2;
1051 move = RIGHT;
1052 break;
1053 case TYPE_BIT_STRING:
1054 if (p->value == NULL)
1056 _asn1_error_description_value_not_found (p, ErrorDescription);
1057 err = ASN1_VALUE_NOT_FOUND;
1058 goto error;
1060 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1061 if (len2 < 0)
1063 err = ASN1_DER_ERROR;
1064 goto error;
1066 max_len -= len2 + len3;
1067 if (max_len >= 0)
1068 memcpy (der + counter, p->value, len3 + len2);
1069 counter += len3 + len2;
1070 move = RIGHT;
1071 break;
1072 case TYPE_SEQUENCE:
1073 case TYPE_SET:
1074 if (move != UP)
1076 _asn1_ltostr (counter, (char *) temp);
1077 tlen = _asn1_strlen (temp);
1078 if (tlen > 0)
1079 _asn1_set_value (p, temp, tlen + 1);
1080 if (p->down == NULL)
1082 move = UP;
1083 continue;
1085 else
1087 p2 = p->down;
1088 while (p2 && (type_field (p2->type) == TYPE_TAG))
1089 p2 = p2->right;
1090 if (p2)
1092 p = p2;
1093 move = RIGHT;
1094 continue;
1096 move = UP;
1097 continue;
1100 else
1101 { /* move==UP */
1102 len2 = _asn1_strtol (p->value, NULL, 10);
1103 _asn1_set_value (p, NULL, 0);
1104 if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
1105 _asn1_ordering_set (der + len2, max_len - len2, p);
1106 asn1_length_der (counter - len2, temp, &len3);
1107 max_len -= len3;
1108 if (max_len >= 0)
1110 memmove (der + len2 + len3, der + len2, counter - len2);
1111 memcpy (der + len2, temp, len3);
1113 counter += len3;
1114 move = RIGHT;
1116 break;
1117 case TYPE_SEQUENCE_OF:
1118 case TYPE_SET_OF:
1119 if (move != UP)
1121 _asn1_ltostr (counter, (char *) temp);
1122 tlen = _asn1_strlen (temp);
1124 if (tlen > 0)
1125 _asn1_set_value (p, temp, tlen + 1);
1126 p = p->down;
1127 while ((type_field (p->type) == TYPE_TAG)
1128 || (type_field (p->type) == TYPE_SIZE))
1129 p = p->right;
1130 if (p->right)
1132 p = p->right;
1133 move = RIGHT;
1134 continue;
1136 else
1137 p = _asn1_find_up (p);
1138 move = UP;
1140 if (move == UP)
1142 len2 = _asn1_strtol (p->value, NULL, 10);
1143 _asn1_set_value (p, NULL, 0);
1144 if ((type_field (p->type) == TYPE_SET_OF)
1145 && (max_len - len2 > 0))
1147 _asn1_ordering_set_of (der + len2, max_len - len2, p);
1149 asn1_length_der (counter - len2, temp, &len3);
1150 max_len -= len3;
1151 if (max_len >= 0)
1153 memmove (der + len2 + len3, der + len2, counter - len2);
1154 memcpy (der + len2, temp, len3);
1156 counter += len3;
1157 move = RIGHT;
1159 break;
1160 case TYPE_ANY:
1161 if (p->value == NULL)
1163 _asn1_error_description_value_not_found (p, ErrorDescription);
1164 err = ASN1_VALUE_NOT_FOUND;
1165 goto error;
1167 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1168 if (len2 < 0)
1170 err = ASN1_DER_ERROR;
1171 goto error;
1173 max_len -= len2;
1174 if (max_len >= 0)
1175 memcpy (der + counter, p->value + len3, len2);
1176 counter += len2;
1177 move = RIGHT;
1178 break;
1179 default:
1180 move = (move == UP) ? RIGHT : DOWN;
1181 break;
1184 if ((move != DOWN) && (counter != counter_old))
1186 err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
1187 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1188 goto error;
1191 if (p == node && move != DOWN)
1192 break;
1194 if (move == DOWN)
1196 if (p->down)
1197 p = p->down;
1198 else
1199 move = RIGHT;
1201 if (move == RIGHT)
1203 if (p->right)
1204 p = p->right;
1205 else
1206 move = UP;
1208 if (move == UP)
1209 p = _asn1_find_up (p);
1212 *len = counter;
1214 if (max_len < 0)
1216 err = ASN1_MEM_ERROR;
1217 goto error;
1220 err = ASN1_SUCCESS;
1222 error:
1223 asn1_delete_structure (&node);
1224 return err;