Update gnulib files.
[shishi.git] / asn1 / coding.c
blob206b8c0c5f3ad5f89b990e1aad6ef808c835d3b2
1 /*
2 * Copyright (C) 2004, 2006 Free Software Foundation
3 * Copyright (C) 2002 Fabio Fiorina
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 <errors.h>
32 #include "parser_aux.h"
33 #include <gstr.h>
34 #include "element.h"
35 #include <structure.h>
37 #define MAX_TAG_LEN 16
39 /******************************************************/
40 /* Function : _asn1_error_description_value_not_found */
41 /* Description: creates the ErrorDescription string */
42 /* for the ASN1_VALUE_NOT_FOUND error. */
43 /* Parameters: */
44 /* node: node of the tree where the value is NULL. */
45 /* ErrorDescription: string returned. */
46 /* Return: */
47 /******************************************************/
48 void
49 _asn1_error_description_value_not_found (node_asn * node,
50 char *ErrorDescription)
53 if (ErrorDescription == NULL)
54 return;
56 Estrcpy (ErrorDescription, ":: value of element '");
57 _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
58 MAX_ERROR_DESCRIPTION_SIZE - 40);
59 Estrcat (ErrorDescription, "' not found");
63 /**
64 * asn1_length_der:
65 * @len: value to convert.
66 * @ans: string returned.
67 * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
69 * Creates the DER coding for the LEN parameter (only the length).
70 * The @ans buffer is pre-allocated and must have room for the output.
71 **/
72 void
73 asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
75 int k;
76 unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
78 if (len < 128)
80 /* short form */
81 if (ans != NULL)
82 ans[0] = (unsigned char) len;
83 *ans_len = 1;
85 else
87 /* Long form */
88 k = 0;
89 while (len)
91 temp[k++] = len & 0xFF;
92 len = len >> 8;
94 *ans_len = k + 1;
95 if (ans != NULL)
97 ans[0] = ((unsigned char) k & 0x7F) + 128;
98 while (k--)
99 ans[*ans_len - 1 - k] = temp[k];
104 /******************************************************/
105 /* Function : _asn1_tag_der */
106 /* Description: creates the DER coding for the CLASS */
107 /* and TAG parameters. */
108 /* Parameters: */
109 /* class: value to convert. */
110 /* tag_value: value to convert. */
111 /* ans: string returned. */
112 /* ans_len: number of meaningful bytes of ANS */
113 /* (ans[0]..ans[ans_len-1]). */
114 /* Return: */
115 /******************************************************/
116 void
117 _asn1_tag_der (unsigned char class, unsigned int tag_value,
118 unsigned char *ans, int *ans_len)
120 int k;
121 unsigned char temp[SIZEOF_UNSIGNED_INT];
123 if (tag_value < 31)
125 /* short form */
126 ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
127 *ans_len = 1;
129 else
131 /* Long form */
132 ans[0] = (class & 0xE0) + 31;
133 k = 0;
134 while (tag_value)
136 temp[k++] = tag_value & 0x7F;
137 tag_value = tag_value >> 7;
139 *ans_len = k + 1;
140 while (k--)
141 ans[*ans_len - 1 - k] = temp[k] + 128;
142 ans[*ans_len - 1] -= 128;
147 * asn1_octet_der:
148 * @str: OCTET string.
149 * @str_len: STR length (str[0]..str[str_len-1]).
150 * @der: string returned.
151 * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]).
153 * Creates the DER coding for an OCTET type (length included).
155 void
156 asn1_octet_der (const unsigned char *str, int str_len,
157 unsigned char *der, int *der_len)
159 int len_len;
161 if (der == NULL || str_len < 0)
162 return;
163 asn1_length_der (str_len, der, &len_len);
164 memcpy (der + len_len, str, str_len);
165 *der_len = str_len + len_len;
168 /******************************************************/
169 /* Function : _asn1_time_der */
170 /* Description: creates the DER coding for a TIME */
171 /* type (length included). */
172 /* Parameters: */
173 /* str: TIME null-terminated string. */
174 /* der: string returned. */
175 /* der_len: number of meaningful bytes of DER */
176 /* (der[0]..der[ans_len-1]). Initially it */
177 /* if must store the lenght of DER. */
178 /* Return: */
179 /* ASN1_MEM_ERROR when DER isn't big enough */
180 /* ASN1_SUCCESS otherwise */
181 /******************************************************/
182 asn1_retCode
183 _asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
185 int len_len;
186 int max_len;
188 max_len = *der_len;
190 asn1_length_der (strlen (str), (max_len > 0) ? der : NULL, &len_len);
192 if ((len_len + (int) strlen (str)) <= max_len)
193 memcpy (der + len_len, str, strlen (str));
194 *der_len = len_len + strlen (str);
196 if ((*der_len) > max_len)
197 return ASN1_MEM_ERROR;
199 return ASN1_SUCCESS;
204 void
205 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
207 int len_len,str_len;
208 char temp[20];
210 if(str==NULL) return;
211 str_len=asn1_get_length_der(der,*der_len,&len_len);
212 if (str_len<0) return;
213 memcpy(temp,der+len_len,str_len);
214 *der_len=str_len+len_len;
215 switch(str_len){
216 case 11:
217 temp[10]=0;
218 strcat(temp,"00+0000");
219 break;
220 case 13:
221 temp[12]=0;
222 strcat(temp,"+0000");
223 break;
224 case 15:
225 temp[15]=0;
226 memmove(temp+12,temp+10,6);
227 temp[10]=temp[11]='0';
228 break;
229 case 17:
230 temp[17]=0;
231 break;
232 default:
233 return;
235 strcpy(str,temp);
239 /******************************************************/
240 /* Function : _asn1_objectid_der */
241 /* Description: creates the DER coding for an */
242 /* OBJECT IDENTIFIER type (length included). */
243 /* Parameters: */
244 /* str: OBJECT IDENTIFIER null-terminated string. */
245 /* der: string returned. */
246 /* der_len: number of meaningful bytes of DER */
247 /* (der[0]..der[ans_len-1]). Initially it */
248 /* must store the length of DER. */
249 /* Return: */
250 /* ASN1_MEM_ERROR when DER isn't big enough */
251 /* ASN1_SUCCESS otherwise */
252 /******************************************************/
253 asn1_retCode
254 _asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
256 int len_len, counter, k, first, max_len;
257 char *temp, *n_end, *n_start;
258 unsigned char bit7;
259 unsigned long val, val1 = 0;
261 max_len = *der_len;
263 temp = (char *) _asn1_alloca (strlen (str) + 2);
264 if (temp == NULL)
265 return ASN1_MEM_ALLOC_ERROR;
267 strcpy (temp, str);
268 strcat (temp, ".");
270 counter = 0;
271 n_start = temp;
272 while ((n_end = strchr (n_start, '.')))
274 *n_end = 0;
275 val = strtoul (n_start, NULL, 10);
276 counter++;
278 if (counter == 1)
279 val1 = val;
280 else if (counter == 2)
282 if (max_len > 0)
283 der[0] = 40 * val1 + val;
284 *der_len = 1;
286 else
288 first = 0;
289 for (k = 4; k >= 0; k--)
291 bit7 = (val >> (k * 7)) & 0x7F;
292 if (bit7 || first || !k)
294 if (k)
295 bit7 |= 0x80;
296 if (max_len > (*der_len))
297 der[*der_len] = bit7;
298 (*der_len)++;
299 first = 1;
304 n_start = n_end + 1;
307 asn1_length_der (*der_len, NULL, &len_len);
308 if (max_len >= (*der_len + len_len))
310 memmove (der + len_len, der, *der_len);
311 asn1_length_der (*der_len, der, &len_len);
313 *der_len += len_len;
315 _asn1_afree (temp);
317 if (max_len < (*der_len))
318 return ASN1_MEM_ERROR;
320 return ASN1_SUCCESS;
324 const char bit_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
327 * asn1_bit_der:
328 * @str: BIT string.
329 * @bit_len: number of meaningful bits in STR.
330 * @der: string returned.
331 * @der_len: number of meaningful bytes of DER
332 * (der[0]..der[ans_len-1]).
334 * Creates the DER coding for a BIT STRING type (length and pad
335 * included).
337 void
338 asn1_bit_der (const unsigned char *str, int bit_len,
339 unsigned char *der, int *der_len)
341 int len_len, len_byte, len_pad;
343 if (der == NULL)
344 return;
345 len_byte = bit_len >> 3;
346 len_pad = 8 - (bit_len & 7);
347 if (len_pad == 8)
348 len_pad = 0;
349 else
350 len_byte++;
351 asn1_length_der (len_byte + 1, der, &len_len);
352 der[len_len] = len_pad;
353 memcpy (der + len_len + 1, str, len_byte);
354 der[len_len + len_byte] &= bit_mask[len_pad];
355 *der_len = len_byte + len_len + 1;
359 /******************************************************/
360 /* Function : _asn1_complete_explicit_tag */
361 /* Description: add the length coding to the EXPLICIT */
362 /* tags. */
363 /* Parameters: */
364 /* node: pointer to the tree element. */
365 /* der: string with the DER coding of the whole tree*/
366 /* counter: number of meaningful bytes of DER */
367 /* (der[0]..der[*counter-1]). */
368 /* max_len: size of der vector */
369 /* Return: */
370 /* ASN1_MEM_ERROR if der vector isn't big enough, */
371 /* otherwise ASN1_SUCCESS. */
372 /******************************************************/
373 asn1_retCode
374 _asn1_complete_explicit_tag (node_asn * node, unsigned char *der,
375 int *counter, int *max_len)
377 node_asn *p;
378 int is_tag_implicit, len2, len3;
379 unsigned char temp[SIZEOF_UNSIGNED_INT];
381 is_tag_implicit = 0;
383 if (node->type & CONST_TAG)
385 p = node->down;
386 /* When there are nested tags we must complete them reverse to
387 the order they were created. This is because completing a tag
388 modifies all data within it, including the incomplete tags
389 which store buffer positions -- simon@josefsson.org 2002-09-06
391 while (p->right)
392 p = p->right;
393 while (p && p != node->down->left)
395 if (type_field (p->type) == TYPE_TAG)
397 if (p->type & CONST_EXPLICIT)
399 len2 = strtol (p->name, NULL, 10);
400 _asn1_set_name (p, NULL);
401 asn1_length_der (*counter - len2, temp, &len3);
402 if (len3 <= (*max_len))
404 memmove (der + len2 + len3, der + len2,
405 *counter - len2);
406 memcpy (der + len2, temp, len3);
408 *max_len -= len3;
409 *counter += len3;
410 is_tag_implicit = 0;
412 else
413 { /* CONST_IMPLICIT */
414 if (!is_tag_implicit)
416 is_tag_implicit = 1;
420 p = p->left;
424 if (*max_len < 0)
425 return ASN1_MEM_ERROR;
427 return ASN1_SUCCESS;
431 /******************************************************/
432 /* Function : _asn1_insert_tag_der */
433 /* Description: creates the DER coding of tags of one */
434 /* NODE. */
435 /* Parameters: */
436 /* node: pointer to the tree element. */
437 /* der: string returned */
438 /* counter: number of meaningful bytes of DER */
439 /* (counter[0]..der[*counter-1]). */
440 /* max_len: size of der vector */
441 /* Return: */
442 /* ASN1_GENERIC_ERROR if the type is unknown, */
443 /* ASN1_MEM_ERROR if der vector isn't big enough, */
444 /* otherwise ASN1_SUCCESS. */
445 /******************************************************/
446 asn1_retCode
447 _asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter,
448 int *max_len)
450 node_asn *p;
451 int tag_len, is_tag_implicit;
452 unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
453 unsigned long tag_implicit = 0;
454 char tag_der[MAX_TAG_LEN];
456 is_tag_implicit = 0;
458 if (node->type & CONST_TAG)
460 p = node->down;
461 while (p)
463 if (type_field (p->type) == TYPE_TAG)
465 if (p->type & CONST_APPLICATION)
466 class = ASN1_CLASS_APPLICATION;
467 else if (p->type & CONST_UNIVERSAL)
468 class = ASN1_CLASS_UNIVERSAL;
469 else if (p->type & CONST_PRIVATE)
470 class = ASN1_CLASS_PRIVATE;
471 else
472 class = ASN1_CLASS_CONTEXT_SPECIFIC;
474 if (p->type & CONST_EXPLICIT)
476 if (is_tag_implicit)
477 _asn1_tag_der (class_implicit, tag_implicit, tag_der,
478 &tag_len);
479 else
480 _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
481 strtoul (p->value, NULL, 10), tag_der,
482 &tag_len);
484 *max_len -= tag_len;
485 if (*max_len >= 0)
486 memcpy (der + *counter, tag_der, tag_len);
487 *counter += tag_len;
489 _asn1_ltostr (*counter, temp);
490 _asn1_set_name (p, temp);
492 is_tag_implicit = 0;
494 else
495 { /* CONST_IMPLICIT */
496 if (!is_tag_implicit)
498 if ((type_field (node->type) == TYPE_SEQUENCE) ||
499 (type_field (node->type) == TYPE_SEQUENCE_OF) ||
500 (type_field (node->type) == TYPE_SET) ||
501 (type_field (node->type) == TYPE_SET_OF))
502 class |= ASN1_CLASS_STRUCTURED;
503 class_implicit = class;
504 tag_implicit = strtoul (p->value, NULL, 10);
505 is_tag_implicit = 1;
509 p = p->right;
513 if (is_tag_implicit)
515 _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
517 else
519 switch (type_field (node->type))
521 case TYPE_NULL:
522 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
523 &tag_len);
524 break;
525 case TYPE_BOOLEAN:
526 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
527 &tag_len);
528 break;
529 case TYPE_INTEGER:
530 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
531 &tag_len);
532 break;
533 case TYPE_ENUMERATED:
534 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
535 &tag_len);
536 break;
537 case TYPE_OBJECT_ID:
538 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
539 &tag_len);
540 break;
541 case TYPE_TIME:
542 if (node->type & CONST_UTC)
544 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
545 &tag_len);
547 else
548 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
549 tag_der, &tag_len);
550 break;
551 case TYPE_OCTET_STRING:
552 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
553 &tag_len);
554 break;
555 case TYPE_GENERALSTRING:
556 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
557 tag_der, &tag_len);
558 break;
559 case TYPE_BIT_STRING:
560 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
561 &tag_len);
562 break;
563 case TYPE_SEQUENCE:
564 case TYPE_SEQUENCE_OF:
565 _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
566 ASN1_TAG_SEQUENCE, tag_der, &tag_len);
567 break;
568 case TYPE_SET:
569 case TYPE_SET_OF:
570 _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
571 ASN1_TAG_SET, tag_der, &tag_len);
572 break;
573 case TYPE_TAG:
574 tag_len = 0;
575 break;
576 case TYPE_CHOICE:
577 tag_len = 0;
578 break;
579 case TYPE_ANY:
580 tag_len = 0;
581 break;
582 default:
583 return ASN1_GENERIC_ERROR;
587 *max_len -= tag_len;
588 if (*max_len >= 0)
589 memcpy (der + *counter, tag_der, tag_len);
590 *counter += tag_len;
592 if (*max_len < 0)
593 return ASN1_MEM_ERROR;
595 return ASN1_SUCCESS;
598 /******************************************************/
599 /* Function : _asn1_ordering_set */
600 /* Description: puts the elements of a SET type in */
601 /* the correct order according to DER rules. */
602 /* Parameters: */
603 /* der: string with the DER coding. */
604 /* node: pointer to the SET element. */
605 /* Return: */
606 /******************************************************/
607 void
608 _asn1_ordering_set (unsigned char *der, int der_len, node_asn * node)
610 struct vet
612 int end;
613 unsigned long value;
614 struct vet *next, *prev;
617 int counter, len, len2;
618 struct vet *first, *last, *p_vet, *p2_vet;
619 node_asn *p;
620 unsigned char class, *temp;
621 unsigned long tag;
623 counter = 0;
625 if (type_field (node->type) != TYPE_SET)
626 return;
628 p = node->down;
629 while ((type_field (p->type) == TYPE_TAG)
630 || (type_field (p->type) == TYPE_SIZE))
631 p = p->right;
633 if ((p == NULL) || (p->right == NULL))
634 return;
636 first = last = NULL;
637 while (p)
639 p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet));
640 if (p_vet == NULL)
641 return;
643 p_vet->next = NULL;
644 p_vet->prev = last;
645 if (first == NULL)
646 first = p_vet;
647 else
648 last->next = p_vet;
649 last = p_vet;
651 /* tag value calculation */
652 if (asn1_get_tag_der
653 (der + counter, der_len - counter, &class, &len2,
654 &tag) != ASN1_SUCCESS)
655 return;
656 p_vet->value = (class << 24) | tag;
657 counter += len2;
659 /* extraction and length */
660 len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
661 if (len2 < 0)
662 return;
663 counter += len + len2;
665 p_vet->end = counter;
666 p = p->right;
669 p_vet = first;
671 while (p_vet)
673 p2_vet = p_vet->next;
674 counter = 0;
675 while (p2_vet)
677 if (p_vet->value > p2_vet->value)
679 /* change position */
680 temp = (unsigned char *) _asn1_alloca (p_vet->end - counter);
681 if (temp == NULL)
682 return;
684 memcpy (temp, der + counter, p_vet->end - counter);
685 memcpy (der + counter, der + p_vet->end,
686 p2_vet->end - p_vet->end);
687 memcpy (der + counter + p2_vet->end - p_vet->end, temp,
688 p_vet->end - counter);
689 _asn1_afree (temp);
691 tag = p_vet->value;
692 p_vet->value = p2_vet->value;
693 p2_vet->value = tag;
695 p_vet->end = counter + (p2_vet->end - p_vet->end);
697 counter = p_vet->end;
699 p2_vet = p2_vet->next;
700 p_vet = p_vet->next;
703 if (p_vet != first)
704 p_vet->prev->next = NULL;
705 else
706 first = NULL;
707 _asn1_afree (p_vet);
708 p_vet = first;
712 /******************************************************/
713 /* Function : _asn1_ordering_set_of */
714 /* Description: puts the elements of a SET OF type in */
715 /* the correct order according to DER rules. */
716 /* Parameters: */
717 /* der: string with the DER coding. */
718 /* node: pointer to the SET OF element. */
719 /* Return: */
720 /******************************************************/
721 void
722 _asn1_ordering_set_of (unsigned char *der, int der_len, node_asn * node)
724 struct vet
726 int end;
727 struct vet *next, *prev;
730 int counter, len, len2, change;
731 struct vet *first, *last, *p_vet, *p2_vet;
732 node_asn *p;
733 unsigned char *temp, class;
734 unsigned long k, max;
736 counter = 0;
738 if (type_field (node->type) != TYPE_SET_OF)
739 return;
741 p = node->down;
742 while ((type_field (p->type) == TYPE_TAG)
743 || (type_field (p->type) == TYPE_SIZE))
744 p = p->right;
745 p = p->right;
747 if ((p == NULL) || (p->right == NULL))
748 return;
750 first = last = NULL;
751 while (p)
753 p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet));
754 if (p_vet == NULL)
755 return;
757 p_vet->next = NULL;
758 p_vet->prev = last;
759 if (first == NULL)
760 first = p_vet;
761 else
762 last->next = p_vet;
763 last = p_vet;
765 /* extraction of tag and length */
766 if (der_len - counter > 0)
769 if (asn1_get_tag_der
770 (der + counter, der_len - counter, &class, &len,
771 NULL) != ASN1_SUCCESS)
772 return;
773 counter += len;
775 len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
776 if (len2 < 0)
777 return;
778 counter += len + len2;
781 p_vet->end = counter;
782 p = p->right;
785 p_vet = first;
787 while (p_vet)
789 p2_vet = p_vet->next;
790 counter = 0;
791 while (p2_vet)
793 if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
794 max = p_vet->end - counter;
795 else
796 max = p2_vet->end - p_vet->end;
798 change = -1;
799 for (k = 0; k < max; k++)
800 if (der[counter + k] > der[p_vet->end + k])
802 change = 1;
803 break;
805 else if (der[counter + k] < der[p_vet->end + k])
807 change = 0;
808 break;
811 if ((change == -1)
812 && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
813 change = 1;
815 if (change == 1)
817 /* change position */
818 temp = (unsigned char *) _asn1_alloca (p_vet->end - counter);
819 if (temp == NULL)
820 return;
822 memcpy (temp, der + counter, (p_vet->end) - counter);
823 memcpy (der + counter, der + (p_vet->end),
824 (p2_vet->end) - (p_vet->end));
825 memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
826 (p_vet->end) - counter);
827 _asn1_afree (temp);
829 p_vet->end = counter + (p2_vet->end - p_vet->end);
831 counter = p_vet->end;
833 p2_vet = p2_vet->next;
834 p_vet = p_vet->next;
837 if (p_vet != first)
838 p_vet->prev->next = NULL;
839 else
840 first = NULL;
841 _asn1_afree (p_vet);
842 p_vet = first;
847 * asn1_der_coding - Creates the DER encoding for the NAME structure
848 * @element: pointer to an ASN1 element
849 * @name: the name of the structure you want to encode (it must be
850 * inside *POINTER).
851 * @ider: vector that will contain the DER encoding. DER must be a
852 * pointer to memory cells already allocated.
853 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
854 * holds the sizeof of der vector.
855 * @errorDescription : return the error description or an empty
856 * string if success.
858 * Creates the DER encoding for the NAME structure (inside *POINTER
859 * structure).
861 * Returns:
863 * ASN1_SUCCESS: DER encoding OK.
865 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
867 * ASN1_VALUE_NOT_FOUND: There is an element without a value.
869 * ASN1_MEM_ERROR: @ider vector isn't big enough. Also in this case
870 * LEN will contain the length needed.
873 asn1_retCode
874 asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
875 char *ErrorDescription)
877 node_asn *node, *p, *p2;
878 char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
879 int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
880 asn1_retCode err;
881 unsigned char *der = ider;
883 node = asn1_find_node (element, name);
884 if (node == NULL)
885 return ASN1_ELEMENT_NOT_FOUND;
887 /* Node is now a locally allocated variable.
888 * That is because in some point we modify the
889 * structure, and I don't know why! --nmav
891 node = _asn1_copy_structure3 (node);
892 if (node == NULL)
893 return ASN1_ELEMENT_NOT_FOUND;
895 max_len = *len;
897 counter = 0;
898 move = DOWN;
899 p = node;
900 while (1)
903 counter_old = counter;
904 max_len_old = max_len;
905 if (move != UP)
907 err = _asn1_insert_tag_der (p, der, &counter, &max_len);
908 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
909 goto error;
911 switch (type_field (p->type))
913 case TYPE_NULL:
914 max_len--;
915 if (max_len >= 0)
916 der[counter++] = 0;
917 move = RIGHT;
918 break;
919 case TYPE_BOOLEAN:
920 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
922 counter = counter_old;
923 max_len = max_len_old;
925 else
927 if (p->value == NULL)
929 _asn1_error_description_value_not_found (p,
930 ErrorDescription);
931 err = ASN1_VALUE_NOT_FOUND;
932 goto error;
934 max_len -= 2;
935 if (max_len >= 0)
937 der[counter++] = 1;
938 if (p->value[0] == 'F')
939 der[counter++] = 0;
940 else
941 der[counter++] = 0xFF;
943 else
944 counter += 2;
946 move = RIGHT;
947 break;
948 case TYPE_INTEGER:
949 case TYPE_ENUMERATED:
950 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
952 counter = counter_old;
953 max_len = max_len_old;
955 else
957 if (p->value == NULL)
959 _asn1_error_description_value_not_found (p,
960 ErrorDescription);
961 err = ASN1_VALUE_NOT_FOUND;
962 goto error;
964 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
965 if (len2 < 0)
967 err = ASN1_DER_ERROR;
968 goto error;
970 max_len -= len2 + len3;
971 if (max_len >= 0)
972 memcpy (der + counter, p->value, len3 + len2);
973 counter += len3 + len2;
975 move = RIGHT;
976 break;
977 case TYPE_OBJECT_ID:
978 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
980 counter = counter_old;
981 max_len = max_len_old;
983 else
985 if (p->value == NULL)
987 _asn1_error_description_value_not_found (p,
988 ErrorDescription);
989 err = ASN1_VALUE_NOT_FOUND;
990 goto error;
992 len2 = max_len;
993 err = _asn1_objectid_der (p->value, der + counter, &len2);
994 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
995 goto error;
997 max_len -= len2;
998 counter += len2;
1000 move = RIGHT;
1001 break;
1002 case TYPE_TIME:
1003 if (p->value == NULL)
1005 _asn1_error_description_value_not_found (p, ErrorDescription);
1006 err = ASN1_VALUE_NOT_FOUND;
1007 goto error;
1009 len2 = max_len;
1010 err = _asn1_time_der (p->value, der + counter, &len2);
1011 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1012 goto error;
1014 max_len -= len2;
1015 counter += len2;
1016 move = RIGHT;
1017 break;
1018 case TYPE_OCTET_STRING:
1019 if (p->value == NULL)
1021 _asn1_error_description_value_not_found (p, 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;
1035 move = RIGHT;
1036 break;
1037 case TYPE_GENERALSTRING:
1038 if (p->value == NULL)
1040 _asn1_error_description_value_not_found (p, ErrorDescription);
1041 err = ASN1_VALUE_NOT_FOUND;
1042 goto error;
1044 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1045 if (len2 < 0)
1047 err = ASN1_DER_ERROR;
1048 goto error;
1050 max_len -= len2 + len3;
1051 if (max_len >= 0)
1052 memcpy (der + counter, p->value, len3 + len2);
1053 counter += len3 + len2;
1054 move = RIGHT;
1055 break;
1056 case TYPE_BIT_STRING:
1057 if (p->value == NULL)
1059 _asn1_error_description_value_not_found (p, ErrorDescription);
1060 err = ASN1_VALUE_NOT_FOUND;
1061 goto error;
1063 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1064 if (len2 < 0)
1066 err = ASN1_DER_ERROR;
1067 goto error;
1069 max_len -= len2 + len3;
1070 if (max_len >= 0)
1071 memcpy (der + counter, p->value, len3 + len2);
1072 counter += len3 + len2;
1073 move = RIGHT;
1074 break;
1075 case TYPE_SEQUENCE:
1076 case TYPE_SET:
1077 if (move != UP)
1079 _asn1_ltostr (counter, temp);
1080 tlen = strlen (temp);
1081 if (tlen > 0)
1082 _asn1_set_value (p, temp, tlen + 1);
1083 if (p->down == NULL)
1085 move = UP;
1086 continue;
1088 else
1090 p2 = p->down;
1091 while (p2 && (type_field (p2->type) == TYPE_TAG))
1092 p2 = p2->right;
1093 if (p2)
1095 p = p2;
1096 move = RIGHT;
1097 continue;
1099 move = UP;
1100 continue;
1103 else
1104 { /* move==UP */
1105 len2 = strtol (p->value, NULL, 10);
1106 _asn1_set_value (p, NULL, 0);
1107 if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
1108 _asn1_ordering_set (der + len2, max_len - len2, p);
1109 asn1_length_der (counter - len2, temp, &len3);
1110 max_len -= len3;
1111 if (max_len >= 0)
1113 memmove (der + len2 + len3, der + len2, counter - len2);
1114 memcpy (der + len2, temp, len3);
1116 counter += len3;
1117 move = RIGHT;
1119 break;
1120 case TYPE_SEQUENCE_OF:
1121 case TYPE_SET_OF:
1122 if (move != UP)
1124 _asn1_ltostr (counter, temp);
1125 tlen = strlen (temp);
1127 if (tlen > 0)
1128 _asn1_set_value (p, temp, tlen + 1);
1129 p = p->down;
1130 while ((type_field (p->type) == TYPE_TAG)
1131 || (type_field (p->type) == TYPE_SIZE))
1132 p = p->right;
1133 if (p->right)
1135 p = p->right;
1136 move = RIGHT;
1137 continue;
1139 else
1140 p = _asn1_find_up (p);
1141 move = UP;
1143 if (move == UP)
1145 len2 = strtol (p->value, NULL, 10);
1146 _asn1_set_value (p, NULL, 0);
1147 if ((type_field (p->type) == TYPE_SET_OF)
1148 && (max_len - len2 > 0))
1150 _asn1_ordering_set_of (der + len2, max_len - len2, p);
1152 asn1_length_der (counter - len2, temp, &len3);
1153 max_len -= len3;
1154 if (max_len >= 0)
1156 memmove (der + len2 + len3, der + len2, counter - len2);
1157 memcpy (der + len2, temp, len3);
1159 counter += len3;
1160 move = RIGHT;
1162 break;
1163 case TYPE_ANY:
1164 if (p->value == NULL)
1166 _asn1_error_description_value_not_found (p, ErrorDescription);
1167 err = ASN1_VALUE_NOT_FOUND;
1168 goto error;
1170 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1171 if (len2 < 0)
1173 err = ASN1_DER_ERROR;
1174 goto error;
1176 max_len -= len2;
1177 if (max_len >= 0)
1178 memcpy (der + counter, p->value + len3, len2);
1179 counter += len2;
1180 move = RIGHT;
1181 break;
1182 default:
1183 move = (move == UP) ? RIGHT : DOWN;
1184 break;
1187 if ((move != DOWN) && (counter != counter_old))
1189 err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
1190 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1191 goto error;
1194 if (p == node && move != DOWN)
1195 break;
1197 if (move == DOWN)
1199 if (p->down)
1200 p = p->down;
1201 else
1202 move = RIGHT;
1204 if (move == RIGHT)
1206 if (p->right)
1207 p = p->right;
1208 else
1209 move = UP;
1211 if (move == UP)
1212 p = _asn1_find_up (p);
1215 *len = counter;
1217 if (max_len < 0)
1219 err = ASN1_MEM_ERROR;
1220 goto error;
1223 err = ASN1_SUCCESS;
1225 error:
1226 asn1_delete_structure (&node);
1227 return err;