Initialize Tizen 2.3
[external/libtasn1.git] / lib / coding.c
1 /*
2  * Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010 Free Software
3  * Foundation, Inc.
4  *
5  * This file is part of LIBTASN1.
6  *
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.
11  *
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.
16  *
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
21  */
22
23
24 /*****************************************************/
25 /* File: coding.c                                    */
26 /* Description: Functions to create a DER coding of  */
27 /*   an ASN1 type.                                   */
28 /*****************************************************/
29
30 #include <int.h>
31 #include "parser_aux.h"
32 #include <gstr.h>
33 #include "element.h"
34 #include <structure.h>
35
36 #define MAX_TAG_LEN 16
37
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)
50 {
51
52   if (ErrorDescription == NULL)
53     return;
54
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");
59
60 }
61
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]).
67  *
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)
73 {
74   int k;
75   unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
76
77   if (len < 128)
78     {
79       /* short form */
80       if (ans != NULL)
81         ans[0] = (unsigned char) len;
82       *ans_len = 1;
83     }
84   else
85     {
86       /* Long form */
87       k = 0;
88       while (len)
89         {
90           temp[k++] = len & 0xFF;
91           len = len >> 8;
92         }
93       *ans_len = k + 1;
94       if (ans != NULL)
95         {
96           ans[0] = ((unsigned char) k & 0x7F) + 128;
97           while (k--)
98             ans[*ans_len - 1 - k] = temp[k];
99         }
100     }
101 }
102
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)
118 {
119   int k;
120   unsigned char temp[SIZEOF_UNSIGNED_INT];
121
122   if (tag_value < 31)
123     {
124       /* short form */
125       ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
126       *ans_len = 1;
127     }
128   else
129     {
130       /* Long form */
131       ans[0] = (class & 0xE0) + 31;
132       k = 0;
133       while (tag_value)
134         {
135           temp[k++] = tag_value & 0x7F;
136           tag_value = tag_value >> 7;
137         }
138       *ans_len = k + 1;
139       while (k--)
140         ans[*ans_len - 1 - k] = temp[k] + 128;
141       ans[*ans_len - 1] -= 128;
142     }
143 }
144
145 /**
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]).
151  *
152  * Creates the DER coding for an OCTET type (length included).
153  **/
154 void
155 asn1_octet_der (const unsigned char *str, int str_len,
156                 unsigned char *der, int *der_len)
157 {
158   int len_len;
159
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;
165 }
166
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)
183 {
184   int len_len;
185   int max_len;
186
187   max_len = *der_len;
188
189   asn1_length_der (strlen (str), (max_len > 0) ? der : NULL, &len_len);
190
191   if ((len_len + (int) strlen (str)) <= max_len)
192     memcpy (der + len_len, str, strlen (str));
193   *der_len = len_len + strlen (str);
194
195   if ((*der_len) > max_len)
196     return ASN1_MEM_ERROR;
197
198   return ASN1_SUCCESS;
199 }
200
201
202 /*
203 void
204 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
205 {
206   int len_len,str_len;
207   char temp[20];
208
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;
233   }
234   strcpy(str,temp);
235 }
236 */
237
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)
254 {
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
260   max_len = *der_len;
261
262   temp = (char *) _asn1_malloc (strlen (str) + 2);
263   if (temp == NULL)
264     return ASN1_MEM_ALLOC_ERROR;
265
266   strcpy (temp, str);
267   strcat (temp, ".");
268
269   counter = 0;
270   n_start = temp;
271   while ((n_end = strchr (n_start, '.')))
272     {
273       *n_end = 0;
274       val = strtoul (n_start, NULL, 10);
275       counter++;
276
277       if (counter == 1)
278         val1 = val;
279       else if (counter == 2)
280         {
281           if (max_len > 0)
282             der[0] = 40 * val1 + val;
283           *der_len = 1;
284         }
285       else
286         {
287           first = 0;
288           for (k = 4; k >= 0; k--)
289             {
290               bit7 = (val >> (k * 7)) & 0x7F;
291               if (bit7 || first || !k)
292                 {
293                   if (k)
294                     bit7 |= 0x80;
295                   if (max_len > (*der_len))
296                     der[*der_len] = bit7;
297                   (*der_len)++;
298                   first = 1;
299                 }
300             }
301
302         }
303       n_start = n_end + 1;
304     }
305
306   asn1_length_der (*der_len, NULL, &len_len);
307   if (max_len >= (*der_len + len_len))
308     {
309       memmove (der + len_len, der, *der_len);
310       asn1_length_der (*der_len, der, &len_len);
311     }
312   *der_len += len_len;
313
314   _asn1_free (temp);
315
316   if (max_len < (*der_len))
317     return ASN1_MEM_ERROR;
318
319   return ASN1_SUCCESS;
320 }
321
322
323 const char bit_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
324
325 /**
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]).
332  *
333  * Creates the DER coding for a BIT STRING type (length and pad
334  * included).
335  **/
336 void
337 asn1_bit_der (const unsigned char *str, int bit_len,
338               unsigned char *der, int *der_len)
339 {
340   int len_len, len_byte, len_pad;
341
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;
355 }
356
357
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)
375 {
376   ASN1_TYPE p;
377   int is_tag_implicit, len2, len3;
378   unsigned char temp[SIZEOF_UNSIGNED_INT];
379
380   is_tag_implicit = 0;
381
382   if (node->type & CONST_TAG)
383     {
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
389        */
390       while (p->right)
391         p = p->right;
392       while (p && p != node->down->left)
393         {
394           if (type_field (p->type) == TYPE_TAG)
395             {
396               if (p->type & CONST_EXPLICIT)
397                 {
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))
402                     {
403                       memmove (der + len2 + len3, der + len2,
404                                *counter - len2);
405                       memcpy (der + len2, temp, len3);
406                     }
407                   *max_len -= len3;
408                   *counter += len3;
409                   is_tag_implicit = 0;
410                 }
411               else
412                 {               /* CONST_IMPLICIT */
413                   if (!is_tag_implicit)
414                     {
415                       is_tag_implicit = 1;
416                     }
417                 }
418             }
419           p = p->left;
420         }
421     }
422
423   if (*max_len < 0)
424     return ASN1_MEM_ERROR;
425
426   return ASN1_SUCCESS;
427 }
428
429
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)
448 {
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];
454
455   is_tag_implicit = 0;
456
457   if (node->type & CONST_TAG)
458     {
459       p = node->down;
460       while (p)
461         {
462           if (type_field (p->type) == TYPE_TAG)
463             {
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;
472
473               if (p->type & CONST_EXPLICIT)
474                 {
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);
482
483                   *max_len -= tag_len;
484                   if (*max_len >= 0)
485                     memcpy (der + *counter, tag_der, tag_len);
486                   *counter += tag_len;
487
488                   _asn1_ltostr (*counter, temp);
489                   _asn1_set_name (p, temp);
490
491                   is_tag_implicit = 0;
492                 }
493               else
494                 {               /* CONST_IMPLICIT */
495                   if (!is_tag_implicit)
496                     {
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;
505                     }
506                 }
507             }
508           p = p->right;
509         }
510     }
511
512   if (is_tag_implicit)
513     {
514       _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
515     }
516   else
517     {
518       switch (type_field (node->type))
519         {
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)
542             {
543               _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
544                              &tag_len);
545             }
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;
583         }
584     }
585
586   *max_len -= tag_len;
587   if (*max_len >= 0)
588     memcpy (der + *counter, tag_der, tag_len);
589   *counter += tag_len;
590
591   if (*max_len < 0)
592     return ASN1_MEM_ERROR;
593
594   return ASN1_SUCCESS;
595 }
596
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)
608 {
609   struct vet
610   {
611     int end;
612     unsigned long value;
613     struct vet *next, *prev;
614   };
615
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;
621
622   counter = 0;
623
624   if (type_field (node->type) != TYPE_SET)
625     return;
626
627   p = node->down;
628   while ((type_field (p->type) == TYPE_TAG)
629          || (type_field (p->type) == TYPE_SIZE))
630     p = p->right;
631
632   if ((p == NULL) || (p->right == NULL))
633     return;
634
635   first = last = NULL;
636   while (p)
637     {
638       p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
639       if (p_vet == NULL)
640         return;
641
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;
649
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;
657
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;
663
664       p_vet->end = counter;
665       p = p->right;
666     }
667
668   p_vet = first;
669
670   while (p_vet)
671     {
672       p2_vet = p_vet->next;
673       counter = 0;
674       while (p2_vet)
675         {
676           if (p_vet->value > p2_vet->value)
677             {
678               /* change position */
679               temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
680               if (temp == NULL)
681                 return;
682
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);
689
690               tag = p_vet->value;
691               p_vet->value = p2_vet->value;
692               p2_vet->value = tag;
693
694               p_vet->end = counter + (p2_vet->end - p_vet->end);
695             }
696           counter = p_vet->end;
697
698           p2_vet = p2_vet->next;
699           p_vet = p_vet->next;
700         }
701
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;
708     }
709 }
710
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)
722 {
723   struct vet
724   {
725     int end;
726     struct vet *next, *prev;
727   };
728
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;
734
735   counter = 0;
736
737   if (type_field (node->type) != TYPE_SET_OF)
738     return;
739
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;
745
746   if ((p == NULL) || (p->right == NULL))
747     return;
748
749   first = last = NULL;
750   while (p)
751     {
752       p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
753       if (p_vet == NULL)
754         return;
755
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;
763
764       /* extraction of tag and length */
765       if (der_len - counter > 0)
766         {
767
768           if (asn1_get_tag_der
769               (der + counter, der_len - counter, &class, &len,
770                NULL) != ASN1_SUCCESS)
771             return;
772           counter += len;
773
774           len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
775           if (len2 < 0)
776             return;
777           counter += len + len2;
778         }
779
780       p_vet->end = counter;
781       p = p->right;
782     }
783
784   p_vet = first;
785
786   while (p_vet)
787     {
788       p2_vet = p_vet->next;
789       counter = 0;
790       while (p2_vet)
791         {
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;
796
797           change = -1;
798           for (k = 0; k < max; k++)
799             if (der[counter + k] > der[p_vet->end + k])
800               {
801                 change = 1;
802                 break;
803               }
804             else if (der[counter + k] < der[p_vet->end + k])
805               {
806                 change = 0;
807                 break;
808               }
809
810           if ((change == -1)
811               && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
812             change = 1;
813
814           if (change == 1)
815             {
816               /* change position */
817               temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
818               if (temp == NULL)
819                 return;
820
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);
827
828               p_vet->end = counter + (p2_vet->end - p_vet->end);
829             }
830           counter = p_vet->end;
831
832           p2_vet = p2_vet->next;
833           p_vet = p_vet->next;
834         }
835
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;
842     }
843 }
844
845 /**
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.
856  *
857  * Creates the DER encoding for the NAME structure (inside *POINTER
858  * structure).
859  *
860  * Returns:
861  *
862  *   %ASN1_SUCCESS: DER encoding OK.
863  *
864  *   %ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
865  *
866  *   %ASN1_VALUE_NOT_FOUND: There is an element without a value.
867  *
868  *   %ASN1_MEM_ERROR: @ider vector isn't big enough. Also in this case
869  *     LEN will contain the length needed.
870  **/
871 asn1_retCode
872 asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
873                  char *ErrorDescription)
874 {
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;
880
881   node = asn1_find_node (element, name);
882   if (node == NULL)
883     return ASN1_ELEMENT_NOT_FOUND;
884
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
888    */
889   node = _asn1_copy_structure3 (node);
890   if (node == NULL)
891     return ASN1_ELEMENT_NOT_FOUND;
892
893   max_len = *len;
894
895   counter = 0;
896   move = DOWN;
897   p = node;
898   while (1)
899     {
900
901       counter_old = counter;
902       max_len_old = max_len;
903       if (move != UP)
904         {
905           err = _asn1_insert_tag_der (p, der, &counter, &max_len);
906           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
907             goto error;
908         }
909       switch (type_field (p->type))
910         {
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))
920             {
921               counter = counter_old;
922               max_len = max_len_old;
923             }
924           else
925             {
926               if (p->value == NULL)
927                 {
928                   _asn1_error_description_value_not_found (p,
929                                                            ErrorDescription);
930                   err = ASN1_VALUE_NOT_FOUND;
931                   goto error;
932                 }
933               max_len -= 2;
934               if (max_len >= 0)
935                 {
936                   der[counter++] = 1;
937                   if (p->value[0] == 'F')
938                     der[counter++] = 0;
939                   else
940                     der[counter++] = 0xFF;
941                 }
942               else
943                 counter += 2;
944             }
945           move = RIGHT;
946           break;
947         case TYPE_INTEGER:
948         case TYPE_ENUMERATED:
949           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
950             {
951               counter = counter_old;
952               max_len = max_len_old;
953             }
954           else
955             {
956               if (p->value == NULL)
957                 {
958                   _asn1_error_description_value_not_found (p,
959                                                            ErrorDescription);
960                   err = ASN1_VALUE_NOT_FOUND;
961                   goto error;
962                 }
963               len2 = asn1_get_length_der (p->value, p->value_len, &len3);
964               if (len2 < 0)
965                 {
966                   err = ASN1_DER_ERROR;
967                   goto error;
968                 }
969               max_len -= len2 + len3;
970               if (max_len >= 0)
971                 memcpy (der + counter, p->value, len3 + len2);
972               counter += len3 + len2;
973             }
974           move = RIGHT;
975           break;
976         case TYPE_OBJECT_ID:
977           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
978             {
979               counter = counter_old;
980               max_len = max_len_old;
981             }
982           else
983             {
984               if (p->value == NULL)
985                 {
986                   _asn1_error_description_value_not_found (p,
987                                                            ErrorDescription);
988                   err = ASN1_VALUE_NOT_FOUND;
989                   goto error;
990                 }
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;
995
996               max_len -= len2;
997               counter += len2;
998             }
999           move = RIGHT;
1000           break;
1001         case TYPE_TIME:
1002           if (p->value == NULL)
1003             {
1004               _asn1_error_description_value_not_found (p, ErrorDescription);
1005               err = ASN1_VALUE_NOT_FOUND;
1006               goto error;
1007             }
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;
1012
1013           max_len -= len2;
1014           counter += len2;
1015           move = RIGHT;
1016           break;
1017         case TYPE_OCTET_STRING:
1018           if (p->value == NULL)
1019             {
1020               _asn1_error_description_value_not_found (p, ErrorDescription);
1021               err = ASN1_VALUE_NOT_FOUND;
1022               goto error;
1023             }
1024           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1025           if (len2 < 0)
1026             {
1027               err = ASN1_DER_ERROR;
1028               goto error;
1029             }
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)
1038             {
1039               _asn1_error_description_value_not_found (p, ErrorDescription);
1040               err = ASN1_VALUE_NOT_FOUND;
1041               goto error;
1042             }
1043           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1044           if (len2 < 0)
1045             {
1046               err = ASN1_DER_ERROR;
1047               goto error;
1048             }
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)
1057             {
1058               _asn1_error_description_value_not_found (p, ErrorDescription);
1059               err = ASN1_VALUE_NOT_FOUND;
1060               goto error;
1061             }
1062           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1063           if (len2 < 0)
1064             {
1065               err = ASN1_DER_ERROR;
1066               goto error;
1067             }
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)
1077             {
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)
1083                 {
1084                   move = UP;
1085                   continue;
1086                 }
1087               else
1088                 {
1089                   p2 = p->down;
1090                   while (p2 && (type_field (p2->type) == TYPE_TAG))
1091                     p2 = p2->right;
1092                   if (p2)
1093                     {
1094                       p = p2;
1095                       move = RIGHT;
1096                       continue;
1097                     }
1098                   move = UP;
1099                   continue;
1100                 }
1101             }
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)
1111                 {
1112                   memmove (der + len2 + len3, der + len2, counter - len2);
1113                   memcpy (der + len2, temp, len3);
1114                 }
1115               counter += len3;
1116               move = RIGHT;
1117             }
1118           break;
1119         case TYPE_SEQUENCE_OF:
1120         case TYPE_SET_OF:
1121           if (move != UP)
1122             {
1123               _asn1_ltostr (counter, temp);
1124               tlen = strlen (temp);
1125
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)
1133                 {
1134                   p = p->right;
1135                   move = RIGHT;
1136                   continue;
1137                 }
1138               else
1139                 p = _asn1_find_up (p);
1140               move = UP;
1141             }
1142           if (move == UP)
1143             {
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))
1148                 {
1149                   _asn1_ordering_set_of (der + len2, max_len - len2, p);
1150                 }
1151               asn1_length_der (counter - len2, temp, &len3);
1152               max_len -= len3;
1153               if (max_len >= 0)
1154                 {
1155                   memmove (der + len2 + len3, der + len2, counter - len2);
1156                   memcpy (der + len2, temp, len3);
1157                 }
1158               counter += len3;
1159               move = RIGHT;
1160             }
1161           break;
1162         case TYPE_ANY:
1163           if (p->value == NULL)
1164             {
1165               _asn1_error_description_value_not_found (p, ErrorDescription);
1166               err = ASN1_VALUE_NOT_FOUND;
1167               goto error;
1168             }
1169           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1170           if (len2 < 0)
1171             {
1172               err = ASN1_DER_ERROR;
1173               goto error;
1174             }
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;
1184         }
1185
1186       if ((move != DOWN) && (counter != counter_old))
1187         {
1188           err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
1189           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1190             goto error;
1191         }
1192
1193       if (p == node && move != DOWN)
1194         break;
1195
1196       if (move == DOWN)
1197         {
1198           if (p->down)
1199             p = p->down;
1200           else
1201             move = RIGHT;
1202         }
1203       if (move == RIGHT)
1204         {
1205           if (p->right)
1206             p = p->right;
1207           else
1208             move = UP;
1209         }
1210       if (move == UP)
1211         p = _asn1_find_up (p);
1212     }
1213
1214   *len = counter;
1215
1216   if (max_len < 0)
1217     {
1218       err = ASN1_MEM_ERROR;
1219       goto error;
1220     }
1221
1222   err = ASN1_SUCCESS;
1223
1224 error:
1225   asn1_delete_structure (&node);
1226   return err;
1227 }