Tizen 2.0 Release
[external/libgnutls26.git] / lib / minitasn1 / coding.c
1 /*
2  * Copyright (C) 2002-2012 Free Software Foundation, Inc.
3  *
4  * This file is part of LIBTASN1.
5  *
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.
10  *
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.
15  *
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
20  */
21
22
23 /*****************************************************/
24 /* File: coding.c                                    */
25 /* Description: Functions to create a DER coding of  */
26 /*   an ASN1 type.                                   */
27 /*****************************************************/
28
29 #include <int.h>
30 #include "parser_aux.h"
31 #include <gstr.h>
32 #include "element.h"
33 #include <structure.h>
34
35 #define MAX_TAG_LEN 16
36
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_TYPE node,
48                                          char *ErrorDescription)
49 {
50
51   if (ErrorDescription == NULL)
52     return;
53
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");
58
59 }
60
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]).
66  *
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)
72 {
73   int k;
74   unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
75
76   if (len < 128)
77     {
78       /* short form */
79       if (ans != NULL)
80         ans[0] = (unsigned char) len;
81       *ans_len = 1;
82     }
83   else
84     {
85       /* Long form */
86       k = 0;
87       while (len)
88         {
89           temp[k++] = len & 0xFF;
90           len = len >> 8;
91         }
92       *ans_len = k + 1;
93       if (ans != NULL)
94         {
95           ans[0] = ((unsigned char) k & 0x7F) + 128;
96           while (k--)
97             ans[*ans_len - 1 - k] = temp[k];
98         }
99     }
100 }
101
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)
117 {
118   int k;
119   unsigned char temp[SIZEOF_UNSIGNED_INT];
120
121   if (tag_value < 31)
122     {
123       /* short form */
124       ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
125       *ans_len = 1;
126     }
127   else
128     {
129       /* Long form */
130       ans[0] = (class & 0xE0) + 31;
131       k = 0;
132       while (tag_value)
133         {
134           temp[k++] = tag_value & 0x7F;
135           tag_value = tag_value >> 7;
136         }
137       *ans_len = k + 1;
138       while (k--)
139         ans[*ans_len - 1 - k] = temp[k] + 128;
140       ans[*ans_len - 1] -= 128;
141     }
142 }
143
144 /**
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]).
150  *
151  * Creates the DER coding for an OCTET type (length included).
152  **/
153 void
154 asn1_octet_der (const unsigned char *str, int str_len,
155                 unsigned char *der, int *der_len)
156 {
157   int len_len;
158
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;
164 }
165
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 asn1_retCode
181 _asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
182 {
183   int len_len;
184   int max_len;
185   int str_len = _asn1_strlen (str);
186
187   max_len = *der_len;
188
189   asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len);
190
191   if ((len_len + str_len) <= max_len)
192     memcpy (der + len_len, str, str_len);
193   *der_len = len_len + str_len;
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   int str_len = _asn1_strlen(str);
260
261   max_len = *der_len;
262
263   temp = _asn1_malloc (str_len + 2);
264   if (temp == NULL)
265     return ASN1_MEM_ALLOC_ERROR;
266
267   memcpy (temp, str, str_len);
268   temp[str_len] = '.';
269   temp[str_len+1] = 0;
270
271   counter = 0;
272   n_start = temp;
273   while ((n_end = strchr (n_start, '.')))
274     {
275       *n_end = 0;
276       val = strtoul (n_start, NULL, 10);
277       counter++;
278
279       if (counter == 1)
280         val1 = val;
281       else if (counter == 2)
282         {
283           if (max_len > 0)
284             der[0] = 40 * val1 + val;
285           *der_len = 1;
286         }
287       else
288         {
289           first = 0;
290           for (k = 4; k >= 0; k--)
291             {
292               bit7 = (val >> (k * 7)) & 0x7F;
293               if (bit7 || first || !k)
294                 {
295                   if (k)
296                     bit7 |= 0x80;
297                   if (max_len > (*der_len))
298                     der[*der_len] = bit7;
299                   (*der_len)++;
300                   first = 1;
301                 }
302             }
303
304         }
305       n_start = n_end + 1;
306     }
307
308   asn1_length_der (*der_len, NULL, &len_len);
309   if (max_len >= (*der_len + len_len))
310     {
311       memmove (der + len_len, der, *der_len);
312       asn1_length_der (*der_len, der, &len_len);
313     }
314   *der_len += len_len;
315
316   _asn1_free (temp);
317
318   if (max_len < (*der_len))
319     return ASN1_MEM_ERROR;
320
321   return ASN1_SUCCESS;
322 }
323
324
325 static const unsigned char bit_mask[] =
326   { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
327
328 /**
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]).
335  *
336  * Creates the DER coding for a BIT STRING type (length and pad
337  * included).
338  **/
339 void
340 asn1_bit_der (const unsigned char *str, int bit_len,
341               unsigned char *der, int *der_len)
342 {
343   int len_len, len_byte, len_pad;
344
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;
358 }
359
360
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 asn1_retCode
376 _asn1_complete_explicit_tag (ASN1_TYPE node, unsigned char *der,
377                              int *counter, int *max_len)
378 {
379   ASN1_TYPE p;
380   int is_tag_implicit, len2, len3;
381   unsigned char temp[SIZEOF_UNSIGNED_INT];
382
383   is_tag_implicit = 0;
384
385   if (node->type & CONST_TAG)
386     {
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
392        */
393       while (p->right)
394         p = p->right;
395       while (p && p != node->down->left)
396         {
397           if (type_field (p->type) == TYPE_TAG)
398             {
399               if (p->type & CONST_EXPLICIT)
400                 {
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))
405                     {
406                       memmove (der + len2 + len3, der + len2,
407                                *counter - len2);
408                       memcpy (der + len2, temp, len3);
409                     }
410                   *max_len -= len3;
411                   *counter += len3;
412                   is_tag_implicit = 0;
413                 }
414               else
415                 {               /* CONST_IMPLICIT */
416                   if (!is_tag_implicit)
417                     {
418                       is_tag_implicit = 1;
419                     }
420                 }
421             }
422           p = p->left;
423         }
424     }
425
426   if (*max_len < 0)
427     return ASN1_MEM_ERROR;
428
429   return ASN1_SUCCESS;
430 }
431
432
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 asn1_retCode
449 _asn1_insert_tag_der (ASN1_TYPE node, unsigned char *der, int *counter,
450                       int *max_len)
451 {
452   ASN1_TYPE 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];
457
458   is_tag_implicit = 0;
459
460   if (node->type & CONST_TAG)
461     {
462       p = node->down;
463       while (p)
464         {
465           if (type_field (p->type) == TYPE_TAG)
466             {
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;
475
476               if (p->type & CONST_EXPLICIT)
477                 {
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);
485
486                   *max_len -= tag_len;
487                   if (*max_len >= 0)
488                     memcpy (der + *counter, tag_der, tag_len);
489                   *counter += tag_len;
490
491                   _asn1_ltostr (*counter, (char *) temp);
492                   _asn1_set_name (p, (const char *) temp);
493
494                   is_tag_implicit = 0;
495                 }
496               else
497                 {               /* CONST_IMPLICIT */
498                   if (!is_tag_implicit)
499                     {
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;
508                     }
509                 }
510             }
511           p = p->right;
512         }
513     }
514
515   if (is_tag_implicit)
516     {
517       _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
518     }
519   else
520     {
521       switch (type_field (node->type))
522         {
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)
545             {
546               _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
547                              &tag_len);
548             }
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;
586         }
587     }
588
589   *max_len -= tag_len;
590   if (*max_len >= 0)
591     memcpy (der + *counter, tag_der, tag_len);
592   *counter += tag_len;
593
594   if (*max_len < 0)
595     return ASN1_MEM_ERROR;
596
597   return ASN1_SUCCESS;
598 }
599
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_TYPE node)
611 {
612   struct vet
613   {
614     int end;
615     unsigned long value;
616     struct vet *next, *prev;
617   };
618
619   int counter, len, len2;
620   struct vet *first, *last, *p_vet, *p2_vet;
621   ASN1_TYPE p;
622   unsigned char class, *temp;
623   unsigned long tag;
624
625   counter = 0;
626
627   if (type_field (node->type) != TYPE_SET)
628     return;
629
630   p = node->down;
631   while ((type_field (p->type) == TYPE_TAG)
632          || (type_field (p->type) == TYPE_SIZE))
633     p = p->right;
634
635   if ((p == NULL) || (p->right == NULL))
636     return;
637
638   first = last = NULL;
639   while (p)
640     {
641       p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
642       if (p_vet == NULL)
643         return;
644
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;
652
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;
660
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;
666
667       p_vet->end = counter;
668       p = p->right;
669     }
670
671   p_vet = first;
672
673   while (p_vet)
674     {
675       p2_vet = p_vet->next;
676       counter = 0;
677       while (p2_vet)
678         {
679           if (p_vet->value > p2_vet->value)
680             {
681               /* change position */
682               temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
683               if (temp == NULL)
684                 return;
685
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               _asn1_free (temp);
692
693               tag = p_vet->value;
694               p_vet->value = p2_vet->value;
695               p2_vet->value = tag;
696
697               p_vet->end = counter + (p2_vet->end - p_vet->end);
698             }
699           counter = p_vet->end;
700
701           p2_vet = p2_vet->next;
702           p_vet = p_vet->next;
703         }
704
705       if (p_vet != first)
706         p_vet->prev->next = NULL;
707       else
708         first = NULL;
709       _asn1_free (p_vet);
710       p_vet = first;
711     }
712 }
713
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_TYPE node)
725 {
726   struct vet
727   {
728     int end;
729     struct vet *next, *prev;
730   };
731
732   int counter, len, len2, change;
733   struct vet *first, *last, *p_vet, *p2_vet;
734   ASN1_TYPE p;
735   unsigned char *temp, class;
736   unsigned long k, max;
737
738   counter = 0;
739
740   if (type_field (node->type) != TYPE_SET_OF)
741     return;
742
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;
748
749   if ((p == NULL) || (p->right == NULL))
750     return;
751
752   first = last = NULL;
753   while (p)
754     {
755       p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
756       if (p_vet == NULL)
757         return;
758
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;
766
767       /* extraction of tag and length */
768       if (der_len - counter > 0)
769         {
770
771           if (asn1_get_tag_der
772               (der + counter, der_len - counter, &class, &len,
773                NULL) != ASN1_SUCCESS)
774             return;
775           counter += len;
776
777           len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
778           if (len2 < 0)
779             return;
780           counter += len + len2;
781         }
782
783       p_vet->end = counter;
784       p = p->right;
785     }
786
787   p_vet = first;
788
789   while (p_vet)
790     {
791       p2_vet = p_vet->next;
792       counter = 0;
793       while (p2_vet)
794         {
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;
799
800           change = -1;
801           for (k = 0; k < max; k++)
802             if (der[counter + k] > der[p_vet->end + k])
803               {
804                 change = 1;
805                 break;
806               }
807             else if (der[counter + k] < der[p_vet->end + k])
808               {
809                 change = 0;
810                 break;
811               }
812
813           if ((change == -1)
814               && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
815             change = 1;
816
817           if (change == 1)
818             {
819               /* change position */
820               temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
821               if (temp == NULL)
822                 return;
823
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               _asn1_free (temp);
830
831               p_vet->end = counter + (p2_vet->end - p_vet->end);
832             }
833           counter = p_vet->end;
834
835           p2_vet = p2_vet->next;
836           p_vet = p_vet->next;
837         }
838
839       if (p_vet != first)
840         p_vet->prev->next = NULL;
841       else
842         first = NULL;
843       _asn1_free (p_vet);
844       p_vet = first;
845     }
846 }
847
848 /**
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.
859  *
860  * Creates the DER encoding for the NAME structure (inside *POINTER
861  * structure).
862  *
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.
868  **/
869 asn1_retCode
870 asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
871                  char *ErrorDescription)
872 {
873   ASN1_TYPE 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   asn1_retCode err;
877   unsigned char *der = ider;
878
879   node = asn1_find_node (element, name);
880   if (node == NULL)
881     return ASN1_ELEMENT_NOT_FOUND;
882
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
886    */
887   node = _asn1_copy_structure3 (node);
888   if (node == NULL)
889     return ASN1_ELEMENT_NOT_FOUND;
890
891   max_len = *len;
892
893   counter = 0;
894   move = DOWN;
895   p = node;
896   while (1)
897     {
898
899       counter_old = counter;
900       max_len_old = max_len;
901       if (move != UP)
902         {
903           err = _asn1_insert_tag_der (p, der, &counter, &max_len);
904           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
905             goto error;
906         }
907       switch (type_field (p->type))
908         {
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))
918             {
919               counter = counter_old;
920               max_len = max_len_old;
921             }
922           else
923             {
924               if (p->value == NULL)
925                 {
926                   _asn1_error_description_value_not_found (p,
927                                                            ErrorDescription);
928                   err = ASN1_VALUE_NOT_FOUND;
929                   goto error;
930                 }
931               max_len -= 2;
932               if (max_len >= 0)
933                 {
934                   der[counter++] = 1;
935                   if (p->value[0] == 'F')
936                     der[counter++] = 0;
937                   else
938                     der[counter++] = 0xFF;
939                 }
940               else
941                 counter += 2;
942             }
943           move = RIGHT;
944           break;
945         case TYPE_INTEGER:
946         case TYPE_ENUMERATED:
947           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
948             {
949               counter = counter_old;
950               max_len = max_len_old;
951             }
952           else
953             {
954               if (p->value == NULL)
955                 {
956                   _asn1_error_description_value_not_found (p,
957                                                            ErrorDescription);
958                   err = ASN1_VALUE_NOT_FOUND;
959                   goto error;
960                 }
961               len2 = asn1_get_length_der (p->value, p->value_len, &len3);
962               if (len2 < 0)
963                 {
964                   err = ASN1_DER_ERROR;
965                   goto error;
966                 }
967               max_len -= len2 + len3;
968               if (max_len >= 0)
969                 memcpy (der + counter, p->value, len3 + len2);
970               counter += len3 + len2;
971             }
972           move = RIGHT;
973           break;
974         case TYPE_OBJECT_ID:
975           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
976             {
977               counter = counter_old;
978               max_len = max_len_old;
979             }
980           else
981             {
982               if (p->value == NULL)
983                 {
984                   _asn1_error_description_value_not_found (p,
985                                                            ErrorDescription);
986                   err = ASN1_VALUE_NOT_FOUND;
987                   goto error;
988                 }
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;
993
994               max_len -= len2;
995               counter += len2;
996             }
997           move = RIGHT;
998           break;
999         case TYPE_TIME:
1000           if (p->value == NULL)
1001             {
1002               _asn1_error_description_value_not_found (p, ErrorDescription);
1003               err = ASN1_VALUE_NOT_FOUND;
1004               goto error;
1005             }
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;
1010
1011           max_len -= len2;
1012           counter += len2;
1013           move = RIGHT;
1014           break;
1015         case TYPE_OCTET_STRING:
1016           if (p->value == NULL)
1017             {
1018               _asn1_error_description_value_not_found (p, ErrorDescription);
1019               err = ASN1_VALUE_NOT_FOUND;
1020               goto error;
1021             }
1022           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1023           if (len2 < 0)
1024             {
1025               err = ASN1_DER_ERROR;
1026               goto error;
1027             }
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)
1036             {
1037               _asn1_error_description_value_not_found (p, ErrorDescription);
1038               err = ASN1_VALUE_NOT_FOUND;
1039               goto error;
1040             }
1041           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1042           if (len2 < 0)
1043             {
1044               err = ASN1_DER_ERROR;
1045               goto error;
1046             }
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)
1055             {
1056               _asn1_error_description_value_not_found (p, ErrorDescription);
1057               err = ASN1_VALUE_NOT_FOUND;
1058               goto error;
1059             }
1060           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1061           if (len2 < 0)
1062             {
1063               err = ASN1_DER_ERROR;
1064               goto error;
1065             }
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)
1075             {
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)
1081                 {
1082                   move = UP;
1083                   continue;
1084                 }
1085               else
1086                 {
1087                   p2 = p->down;
1088                   while (p2 && (type_field (p2->type) == TYPE_TAG))
1089                     p2 = p2->right;
1090                   if (p2)
1091                     {
1092                       p = p2;
1093                       move = RIGHT;
1094                       continue;
1095                     }
1096                   move = UP;
1097                   continue;
1098                 }
1099             }
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)
1109                 {
1110                   memmove (der + len2 + len3, der + len2, counter - len2);
1111                   memcpy (der + len2, temp, len3);
1112                 }
1113               counter += len3;
1114               move = RIGHT;
1115             }
1116           break;
1117         case TYPE_SEQUENCE_OF:
1118         case TYPE_SET_OF:
1119           if (move != UP)
1120             {
1121               _asn1_ltostr (counter, (char *) temp);
1122               tlen = _asn1_strlen (temp);
1123
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)
1131                 {
1132                   p = p->right;
1133                   move = RIGHT;
1134                   continue;
1135                 }
1136               else
1137                 p = _asn1_find_up (p);
1138               move = UP;
1139             }
1140           if (move == UP)
1141             {
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))
1146                 {
1147                   _asn1_ordering_set_of (der + len2, max_len - len2, p);
1148                 }
1149               asn1_length_der (counter - len2, temp, &len3);
1150               max_len -= len3;
1151               if (max_len >= 0)
1152                 {
1153                   memmove (der + len2 + len3, der + len2, counter - len2);
1154                   memcpy (der + len2, temp, len3);
1155                 }
1156               counter += len3;
1157               move = RIGHT;
1158             }
1159           break;
1160         case TYPE_ANY:
1161           if (p->value == NULL)
1162             {
1163               _asn1_error_description_value_not_found (p, ErrorDescription);
1164               err = ASN1_VALUE_NOT_FOUND;
1165               goto error;
1166             }
1167           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1168           if (len2 < 0)
1169             {
1170               err = ASN1_DER_ERROR;
1171               goto error;
1172             }
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;
1182         }
1183
1184       if ((move != DOWN) && (counter != counter_old))
1185         {
1186           err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
1187           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1188             goto error;
1189         }
1190
1191       if (p == node && move != DOWN)
1192         break;
1193
1194       if (move == DOWN)
1195         {
1196           if (p->down)
1197             p = p->down;
1198           else
1199             move = RIGHT;
1200         }
1201       if (move == RIGHT)
1202         {
1203           if (p->right)
1204             p = p->right;
1205           else
1206             move = UP;
1207         }
1208       if (move == UP)
1209         p = _asn1_find_up (p);
1210     }
1211
1212   *len = counter;
1213
1214   if (max_len < 0)
1215     {
1216       err = ASN1_MEM_ERROR;
1217       goto error;
1218     }
1219
1220   err = ASN1_SUCCESS;
1221
1222 error:
1223   asn1_delete_structure (&node);
1224   return err;
1225 }