Introduced ASN1_ETYPE_UTC_TIME and ASN1_ETYPE_GENERALIZED_TIME
[platform/upstream/libtasn1.git] / lib / 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_node 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  * @der: the encoding (may be %NULL).
65  * @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]).
66  *
67  * Creates the DER encoding of the provided length value.
68  * The @der buffer must have enough room for the output. The maximum
69  * length this function will encode is %ASN1_MAX_LENGTH_SIZE.
70  * 
71  * To know the size of the DER encoding use a %NULL value for @der.
72  **/
73 void
74 asn1_length_der (unsigned long int len, unsigned char *der, int *der_len)
75 {
76   int k;
77   unsigned char temp[ASN1_MAX_LENGTH_SIZE];
78 #if SIZEOF_UNSIGNED_LONG_INT > 8
79   len &= 0xFFFFFFFFFFFFFFFF;
80 #endif
81
82   if (len < 128)
83     {
84       /* short form */
85       if (der != NULL)
86         der[0] = (unsigned char) len;
87       *der_len = 1;
88     }
89   else
90     {
91       /* Long form */
92       k = 0;
93       while (len)
94         {
95           temp[k++] = len & 0xFF;
96           len = len >> 8;
97         }
98       *der_len = k + 1;
99       if (der != NULL)
100         {
101           der[0] = ((unsigned char) k & 0x7F) + 128;
102           while (k--)
103             der[*der_len - 1 - k] = temp[k];
104         }
105     }
106 }
107
108 /******************************************************/
109 /* Function : _asn1_tag_der                           */
110 /* Description: creates the DER coding for the CLASS  */
111 /* and TAG parameters.                                */
112 /* It is limited by the ASN1_MAX_TAG_SIZE variable    */
113 /* Parameters:                                        */
114 /*   class: value to convert.                         */
115 /*   tag_value: value to convert.                     */
116 /*   ans: string returned.                            */
117 /*   ans_len: number of meaningful bytes of ANS       */
118 /*            (ans[0]..ans[ans_len-1]).               */
119 /* Return:                                            */
120 /******************************************************/
121 static void
122 _asn1_tag_der (unsigned char class, unsigned int tag_value,
123                unsigned char *ans, int *ans_len)
124 {
125   int k;
126   unsigned char temp[ASN1_MAX_TAG_SIZE];
127
128   if (tag_value < 31)
129     {
130       /* short form */
131       ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
132       *ans_len = 1;
133     }
134   else
135     {
136       /* Long form */
137       ans[0] = (class & 0xE0) + 31;
138       k = 0;
139       while (tag_value != 0)
140         {
141           temp[k++] = tag_value & 0x7F;
142           tag_value >>= 7;
143           
144           if (k > ASN1_MAX_TAG_SIZE-1)
145             break; /* will not encode larger tags */
146         }
147       *ans_len = k + 1;
148       while (k--)
149         ans[*ans_len - 1 - k] = temp[k] + 128;
150       ans[*ans_len - 1] -= 128;
151     }
152 }
153
154 /**
155  * asn1_octet_der:
156  * @str: the input data.
157  * @str_len: STR length (str[0]..str[*str_len-1]).
158  * @der: encoded string returned.
159  * @der_len: number of meaningful bytes of DER (der[0]..der[der_len-1]).
160  *
161  * Creates a length-value DER encoding for the input data.
162  * The DER encoding of the input data will be placed in the @der variable.
163  *
164  * Note that the OCTET STRING tag is not included in the output.
165  *
166  * This function does not return any value because it is expected
167  * that @der_len will contain enough bytes to store the string
168  * plus the DER encoding. The DER encoding size can be obtained using
169  * asn1_length_der().
170  **/
171 void
172 asn1_octet_der (const unsigned char *str, int str_len,
173                 unsigned char *der, int *der_len)
174 {
175   int len_len;
176
177   if (der == NULL || str_len < 0)
178     return;
179
180   asn1_length_der (str_len, der, &len_len);
181   memcpy (der + len_len, str, str_len);
182   *der_len = str_len + len_len;
183 }
184
185
186 /**
187  * asn1_encode_simple_der:
188  * @etype: The type of the string to be encoded (ASN1_ETYPE_)
189  * @str: the string data.
190  * @str_len: the string length
191  * @tl: the encoded tag and length
192  * @tl_len: the bytes of the @tl field
193  *
194  * Creates the DER encoding for various simple ASN.1 types like strings etc.
195  * It stores the tag and length in @tl, which should have space for at least 
196  * %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl.
197  *
198  * The complete DER encoding should consist of the value in @tl appended
199  * with the provided @str.
200  *
201  * Returns: %ASN1_SUCCESS if successful or an error value. 
202  **/
203 int
204 asn1_encode_simple_der (unsigned int etype, const unsigned char *str, unsigned int str_len,
205                         unsigned char *tl, unsigned int *tl_len)
206 {
207   int tag_len, len_len;
208   unsigned tlen;
209   unsigned char der_tag[ASN1_MAX_TAG_SIZE];
210   unsigned char der_length[ASN1_MAX_LENGTH_SIZE];
211   unsigned char* p;
212
213   if (str == NULL)
214     return ASN1_VALUE_NOT_VALID;
215
216   if (ETYPE_OK(etype) == 0)
217     return ASN1_VALUE_NOT_VALID;
218
219   /* doesn't handle constructed classes */
220   if (ETYPE_CLASS(etype) != ASN1_CLASS_UNIVERSAL)
221     return ASN1_VALUE_NOT_VALID;
222
223   _asn1_tag_der (ETYPE_CLASS(etype), ETYPE_TAG(etype),
224                  der_tag, &tag_len);
225
226   asn1_length_der(str_len, der_length, &len_len);
227
228   if (tag_len <= 0 || len_len <= 0)
229     return ASN1_VALUE_NOT_VALID;
230   
231   tlen = tag_len + len_len;
232
233   if (*tl_len < tlen)
234     return ASN1_MEM_ERROR;
235
236   p = tl;
237   memcpy(p, der_tag, tag_len);
238   p+=tag_len;
239   memcpy(p, der_length, len_len);
240   
241   *tl_len = tlen;
242
243   return ASN1_SUCCESS;
244 }
245
246 /******************************************************/
247 /* Function : _asn1_time_der                          */
248 /* Description: creates the DER coding for a TIME     */
249 /* type (length included).                            */
250 /* Parameters:                                        */
251 /*   str: TIME null-terminated string.                */
252 /*   der: string returned.                            */
253 /*   der_len: number of meaningful bytes of DER       */
254 /*            (der[0]..der[ans_len-1]). Initially it  */
255 /*            if must store the lenght of DER.        */
256 /* Return:                                            */
257 /*   ASN1_MEM_ERROR when DER isn't big enough         */
258 /*   ASN1_SUCCESS otherwise                           */
259 /******************************************************/
260 static int
261 _asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
262 {
263   int len_len;
264   int max_len;
265   int str_len = _asn1_strlen (str);
266
267   max_len = *der_len;
268
269   asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len);
270
271   if ((len_len + str_len) <= max_len)
272     memcpy (der + len_len, str, str_len);
273   *der_len = len_len + str_len;
274
275   if ((*der_len) > max_len)
276     return ASN1_MEM_ERROR;
277
278   return ASN1_SUCCESS;
279 }
280
281
282 /*
283 void
284 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
285 {
286   int len_len,str_len;
287   char temp[20];
288
289   if(str==NULL) return;
290   str_len=asn1_get_length_der(der,*der_len,&len_len);
291   if (str_len<0) return;
292   memcpy(temp,der+len_len,str_len);
293   *der_len=str_len+len_len;
294   switch(str_len){
295   case 11:
296     temp[10]=0;
297     strcat(temp,"00+0000");
298     break;
299   case 13:
300     temp[12]=0;
301     strcat(temp,"+0000");
302     break;
303   case 15:
304     temp[15]=0;
305     memmove(temp+12,temp+10,6);
306     temp[10]=temp[11]='0';
307     break;
308   case 17:
309     temp[17]=0;
310     break;
311   default:
312     return;
313   }
314   strcpy(str,temp);
315 }
316 */
317
318 /******************************************************/
319 /* Function : _asn1_objectid_der                      */
320 /* Description: creates the DER coding for an         */
321 /* OBJECT IDENTIFIER  type (length included).         */
322 /* Parameters:                                        */
323 /*   str: OBJECT IDENTIFIER null-terminated string.   */
324 /*   der: string returned.                            */
325 /*   der_len: number of meaningful bytes of DER       */
326 /*            (der[0]..der[ans_len-1]). Initially it  */
327 /*            must store the length of DER.           */
328 /* Return:                                            */
329 /*   ASN1_MEM_ERROR when DER isn't big enough         */
330 /*   ASN1_SUCCESS otherwise                           */
331 /******************************************************/
332 static int
333 _asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
334 {
335   int len_len, counter, k, first, max_len;
336   char *temp, *n_end, *n_start;
337   unsigned char bit7;
338   unsigned long val, val1 = 0;
339   int str_len = _asn1_strlen (str);
340
341   max_len = *der_len;
342
343   temp = malloc (str_len + 2);
344   if (temp == NULL)
345     return ASN1_MEM_ALLOC_ERROR;
346
347   memcpy (temp, str, str_len);
348   temp[str_len] = '.';
349   temp[str_len + 1] = 0;
350
351   counter = 0;
352   n_start = temp;
353   while ((n_end = strchr (n_start, '.')))
354     {
355       *n_end = 0;
356       val = strtoul (n_start, NULL, 10);
357       counter++;
358
359       if (counter == 1)
360         val1 = val;
361       else if (counter == 2)
362         {
363           if (max_len > 0)
364             der[0] = 40 * val1 + val;
365           *der_len = 1;
366         }
367       else
368         {
369           first = 0;
370           for (k = 4; k >= 0; k--)
371             {
372               bit7 = (val >> (k * 7)) & 0x7F;
373               if (bit7 || first || !k)
374                 {
375                   if (k)
376                     bit7 |= 0x80;
377                   if (max_len > (*der_len))
378                     der[*der_len] = bit7;
379                   (*der_len)++;
380                   first = 1;
381                 }
382             }
383
384         }
385       n_start = n_end + 1;
386     }
387
388   asn1_length_der (*der_len, NULL, &len_len);
389   if (max_len >= (*der_len + len_len))
390     {
391       memmove (der + len_len, der, *der_len);
392       asn1_length_der (*der_len, der, &len_len);
393     }
394   *der_len += len_len;
395
396   free (temp);
397
398   if (max_len < (*der_len))
399     return ASN1_MEM_ERROR;
400
401   return ASN1_SUCCESS;
402 }
403
404
405 static const unsigned char bit_mask[] =
406   { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
407
408 /**
409  * asn1_bit_der:
410  * @str: BIT string.
411  * @bit_len: number of meaningful bits in STR.
412  * @der: string returned.
413  * @der_len: number of meaningful bytes of DER
414  *   (der[0]..der[ans_len-1]).
415  *
416  * Creates a length-value DER encoding for the input data
417  * as it would have been for a BIT STRING.
418  * The DER encoded data will be copied in @der.
419  *
420  * Note that the BIT STRING tag is not included in the output.
421  *
422  * This function does not return any value because it is expected
423  * that @der_len will contain enough bytes to store the string
424  * plus the DER encoding. The DER encoding size can be obtained using
425  * asn1_length_der().
426  **/
427 void
428 asn1_bit_der (const unsigned char *str, int bit_len,
429               unsigned char *der, int *der_len)
430 {
431   int len_len, len_byte, len_pad;
432
433   if (der == NULL)
434     return;
435
436   len_byte = bit_len >> 3;
437   len_pad = 8 - (bit_len & 7);
438   if (len_pad == 8)
439     len_pad = 0;
440   else
441     len_byte++;
442   asn1_length_der (len_byte + 1, der, &len_len);
443   der[len_len] = len_pad;
444   memcpy (der + len_len + 1, str, len_byte);
445   der[len_len + len_byte] &= bit_mask[len_pad];
446   *der_len = len_byte + len_len + 1;
447 }
448
449
450 /******************************************************/
451 /* Function : _asn1_complete_explicit_tag             */
452 /* Description: add the length coding to the EXPLICIT */
453 /* tags.                                              */
454 /* Parameters:                                        */
455 /*   node: pointer to the tree element.               */
456 /*   der: string with the DER coding of the whole tree*/
457 /*   counter: number of meaningful bytes of DER       */
458 /*            (der[0]..der[*counter-1]).              */
459 /*   max_len: size of der vector                      */
460 /* Return:                                            */
461 /*   ASN1_MEM_ERROR if der vector isn't big enough,   */
462 /*   otherwise ASN1_SUCCESS.                          */
463 /******************************************************/
464 static int
465 _asn1_complete_explicit_tag (asn1_node node, unsigned char *der,
466                              int *counter, int *max_len)
467 {
468   asn1_node p;
469   int is_tag_implicit, len2, len3;
470   unsigned char temp[SIZEOF_UNSIGNED_INT];
471
472   is_tag_implicit = 0;
473
474   if (node->type & CONST_TAG)
475     {
476       p = node->down;
477       /* When there are nested tags we must complete them reverse to
478          the order they were created. This is because completing a tag
479          modifies all data within it, including the incomplete tags
480          which store buffer positions -- simon@josefsson.org 2002-09-06
481        */
482       while (p->right)
483         p = p->right;
484       while (p && p != node->down->left)
485         {
486           if (type_field (p->type) == ASN1_ETYPE_TAG)
487             {
488               if (p->type & CONST_EXPLICIT)
489                 {
490                   len2 = strtol (p->name, NULL, 10);
491                   _asn1_set_name (p, NULL);
492                   asn1_length_der (*counter - len2, temp, &len3);
493                   if (len3 <= (*max_len))
494                     {
495                       memmove (der + len2 + len3, der + len2,
496                                *counter - len2);
497                       memcpy (der + len2, temp, len3);
498                     }
499                   *max_len -= len3;
500                   *counter += len3;
501                   is_tag_implicit = 0;
502                 }
503               else
504                 {               /* CONST_IMPLICIT */
505                   if (!is_tag_implicit)
506                     {
507                       is_tag_implicit = 1;
508                     }
509                 }
510             }
511           p = p->left;
512         }
513     }
514
515   if (*max_len < 0)
516     return ASN1_MEM_ERROR;
517
518   return ASN1_SUCCESS;
519 }
520
521 const tag_and_class_st _asn1_tags[] =
522 {
523   [ASN1_ETYPE_GENERALSTRING] = {ASN1_TAG_GENERALSTRING, ASN1_CLASS_UNIVERSAL, "type:GENERALSTRING"},
524   [ASN1_ETYPE_NUMERIC_STRING] = {ASN1_TAG_NUMERIC_STRING, ASN1_CLASS_UNIVERSAL, "type:NUMERIC_STR"},
525   [ASN1_ETYPE_IA5_STRING] =     {ASN1_TAG_IA5_STRING, ASN1_CLASS_UNIVERSAL, "type:IA5_STR"},
526   [ASN1_ETYPE_TELETEX_STRING] = {ASN1_TAG_TELETEX_STRING, ASN1_CLASS_UNIVERSAL, "type:TELETEX_STR"},
527   [ASN1_ETYPE_PRINTABLE_STRING] = {ASN1_TAG_PRINTABLE_STRING, ASN1_CLASS_UNIVERSAL, "type:PRINTABLE_STR"},
528   [ASN1_ETYPE_UNIVERSAL_STRING] = {ASN1_TAG_UNIVERSAL_STRING, ASN1_CLASS_UNIVERSAL, "type:UNIVERSAL_STR"},
529   [ASN1_ETYPE_BMP_STRING] =       {ASN1_TAG_BMP_STRING, ASN1_CLASS_UNIVERSAL, "type:BMP_STR"},
530   [ASN1_ETYPE_UTF8_STRING] =      {ASN1_TAG_UTF8_STRING, ASN1_CLASS_UNIVERSAL, "type:UTF8_STR"},
531   [ASN1_ETYPE_VISIBLE_STRING] =   {ASN1_TAG_VISIBLE_STRING, ASN1_CLASS_UNIVERSAL, "type:VISIBLE_STR"},
532   [ASN1_ETYPE_OCTET_STRING] =    {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, "type:OCT_STR"},
533   [ASN1_ETYPE_BIT_STRING] = {ASN1_TAG_BIT_STRING, ASN1_CLASS_UNIVERSAL, "type:BIT_STR"},
534   [ASN1_ETYPE_OBJECT_ID] =  {ASN1_TAG_OBJECT_ID, ASN1_CLASS_UNIVERSAL, "type:OBJ_STR"},
535   [ASN1_ETYPE_NULL] =       {ASN1_TAG_NULL, ASN1_CLASS_UNIVERSAL, "type:NULL"},
536   [ASN1_ETYPE_BOOLEAN] =    {ASN1_TAG_BOOLEAN, ASN1_CLASS_UNIVERSAL, "type:BOOLEAN"},
537   [ASN1_ETYPE_INTEGER] =    {ASN1_TAG_INTEGER, ASN1_CLASS_UNIVERSAL, "type:INTEGER"},
538   [ASN1_ETYPE_ENUMERATED] = {ASN1_TAG_ENUMERATED, ASN1_CLASS_UNIVERSAL, "type:ENUMERATED"},
539   [ASN1_ETYPE_SEQUENCE] =   {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SEQUENCE"},
540   [ASN1_ETYPE_SEQUENCE_OF] ={ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SEQ_OF"},
541   [ASN1_ETYPE_SET] =        {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SET"},
542   [ASN1_ETYPE_SET_OF] =     {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SET_OF"},
543   [ASN1_ETYPE_GENERALIZED_TIME] = {ASN1_TAG_GENERALIZEDTime, ASN1_CLASS_UNIVERSAL, "type:GENERALIZED_TIME"},
544   [ASN1_ETYPE_UTC_TIME] = {ASN1_TAG_UTCTime, ASN1_CLASS_UNIVERSAL, "type:UTC_TIME"},
545 };
546
547 unsigned int _asn1_tags_size = sizeof(_asn1_tags)/sizeof(_asn1_tags[0]);
548
549 /******************************************************/
550 /* Function : _asn1_insert_tag_der                    */
551 /* Description: creates the DER coding of tags of one */
552 /* NODE.                                              */
553 /* Parameters:                                        */
554 /*   node: pointer to the tree element.               */
555 /*   der: string returned                             */
556 /*   counter: number of meaningful bytes of DER       */
557 /*            (counter[0]..der[*counter-1]).          */
558 /*   max_len: size of der vector                      */
559 /* Return:                                            */
560 /*   ASN1_GENERIC_ERROR if the type is unknown,       */
561 /*   ASN1_MEM_ERROR if der vector isn't big enough,   */
562 /*   otherwise ASN1_SUCCESS.                          */
563 /******************************************************/
564 static int
565 _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
566                       int *max_len)
567 {
568   asn1_node p;
569   int tag_len, is_tag_implicit;
570   unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
571   unsigned long tag_implicit = 0;
572   unsigned char tag_der[MAX_TAG_LEN];
573
574   is_tag_implicit = 0;
575
576   if (node->type & CONST_TAG)
577     {
578       p = node->down;
579       while (p)
580         {
581           if (type_field (p->type) == ASN1_ETYPE_TAG)
582             {
583               if (p->type & CONST_APPLICATION)
584                 class = ASN1_CLASS_APPLICATION;
585               else if (p->type & CONST_UNIVERSAL)
586                 class = ASN1_CLASS_UNIVERSAL;
587               else if (p->type & CONST_PRIVATE)
588                 class = ASN1_CLASS_PRIVATE;
589               else
590                 class = ASN1_CLASS_CONTEXT_SPECIFIC;
591
592               if (p->type & CONST_EXPLICIT)
593                 {
594                   if (is_tag_implicit)
595                     _asn1_tag_der (class_implicit, tag_implicit, tag_der,
596                                    &tag_len);
597                   else
598                     _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
599                                    _asn1_strtoul (p->value, NULL, 10),
600                                    tag_der, &tag_len);
601
602                   *max_len -= tag_len;
603                   if (*max_len >= 0)
604                     memcpy (der + *counter, tag_der, tag_len);
605                   *counter += tag_len;
606
607                   _asn1_ltostr (*counter, (char *) temp);
608                   _asn1_set_name (p, (const char *) temp);
609
610                   is_tag_implicit = 0;
611                 }
612               else
613                 {               /* CONST_IMPLICIT */
614                   if (!is_tag_implicit)
615                     {
616                       if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
617                           (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) ||
618                           (type_field (node->type) == ASN1_ETYPE_SET) ||
619                           (type_field (node->type) == ASN1_ETYPE_SET_OF))
620                         class |= ASN1_CLASS_STRUCTURED;
621                       class_implicit = class;
622                       tag_implicit = _asn1_strtoul (p->value, NULL, 10);
623                       is_tag_implicit = 1;
624                     }
625                 }
626             }
627           p = p->right;
628         }
629     }
630
631   if (is_tag_implicit)
632     {
633       _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
634     }
635   else
636     {
637       unsigned type = type_field (node->type);
638       switch (type)
639         {
640         CASE_HANDLED_ETYPES:
641           _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag,
642                          tag_der, &tag_len);
643           break;
644         case ASN1_ETYPE_TAG:
645         case ASN1_ETYPE_CHOICE:
646         case ASN1_ETYPE_ANY:
647           tag_len = 0;
648           break;
649         default:
650           return ASN1_GENERIC_ERROR;
651         }
652     }
653
654   *max_len -= tag_len;
655   if (*max_len >= 0)
656     memcpy (der + *counter, tag_der, tag_len);
657   *counter += tag_len;
658
659   if (*max_len < 0)
660     return ASN1_MEM_ERROR;
661
662   return ASN1_SUCCESS;
663 }
664
665 /******************************************************/
666 /* Function : _asn1_ordering_set                      */
667 /* Description: puts the elements of a SET type in    */
668 /* the correct order according to DER rules.          */
669 /* Parameters:                                        */
670 /*   der: string with the DER coding.                 */
671 /*   node: pointer to the SET element.                */
672 /* Return:                                            */
673 /******************************************************/
674 static void
675 _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node)
676 {
677   struct vet
678   {
679     int end;
680     unsigned long value;
681     struct vet *next, *prev;
682   };
683
684   int counter, len, len2;
685   struct vet *first, *last, *p_vet, *p2_vet;
686   asn1_node p;
687   unsigned char class, *temp;
688   unsigned long tag;
689
690   counter = 0;
691
692   if (type_field (node->type) != ASN1_ETYPE_SET)
693     return;
694
695   p = node->down;
696   while ((type_field (p->type) == ASN1_ETYPE_TAG)
697          || (type_field (p->type) == ASN1_ETYPE_SIZE))
698     p = p->right;
699
700   if ((p == NULL) || (p->right == NULL))
701     return;
702
703   first = last = NULL;
704   while (p)
705     {
706       p_vet = malloc (sizeof (struct vet));
707       if (p_vet == NULL)
708         return;
709
710       p_vet->next = NULL;
711       p_vet->prev = last;
712       if (first == NULL)
713         first = p_vet;
714       else
715         last->next = p_vet;
716       last = p_vet;
717
718       /* tag value calculation */
719       if (asn1_get_tag_der
720           (der + counter, der_len - counter, &class, &len2,
721            &tag) != ASN1_SUCCESS)
722         return;
723       p_vet->value = (class << 24) | tag;
724       counter += len2;
725
726       /* extraction and length */
727       len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
728       if (len2 < 0)
729         return;
730       counter += len + len2;
731
732       p_vet->end = counter;
733       p = p->right;
734     }
735
736   p_vet = first;
737
738   while (p_vet)
739     {
740       p2_vet = p_vet->next;
741       counter = 0;
742       while (p2_vet)
743         {
744           if (p_vet->value > p2_vet->value)
745             {
746               /* change position */
747               temp = malloc (p_vet->end - counter);
748               if (temp == NULL)
749                 return;
750
751               memcpy (temp, der + counter, p_vet->end - counter);
752               memcpy (der + counter, der + p_vet->end,
753                       p2_vet->end - p_vet->end);
754               memcpy (der + counter + p2_vet->end - p_vet->end, temp,
755                       p_vet->end - counter);
756               free (temp);
757
758               tag = p_vet->value;
759               p_vet->value = p2_vet->value;
760               p2_vet->value = tag;
761
762               p_vet->end = counter + (p2_vet->end - p_vet->end);
763             }
764           counter = p_vet->end;
765
766           p2_vet = p2_vet->next;
767           p_vet = p_vet->next;
768         }
769
770       if (p_vet != first)
771         p_vet->prev->next = NULL;
772       else
773         first = NULL;
774       free (p_vet);
775       p_vet = first;
776     }
777 }
778
779 /******************************************************/
780 /* Function : _asn1_ordering_set_of                   */
781 /* Description: puts the elements of a SET OF type in */
782 /* the correct order according to DER rules.          */
783 /* Parameters:                                        */
784 /*   der: string with the DER coding.                 */
785 /*   node: pointer to the SET OF element.             */
786 /* Return:                                            */
787 /******************************************************/
788 static void
789 _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
790 {
791   struct vet
792   {
793     int end;
794     struct vet *next, *prev;
795   };
796
797   int counter, len, len2, change;
798   struct vet *first, *last, *p_vet, *p2_vet;
799   asn1_node p;
800   unsigned char *temp, class;
801   unsigned long k, max;
802
803   counter = 0;
804
805   if (type_field (node->type) != ASN1_ETYPE_SET_OF)
806     return;
807
808   p = node->down;
809   while ((type_field (p->type) == ASN1_ETYPE_TAG)
810          || (type_field (p->type) == ASN1_ETYPE_SIZE))
811     p = p->right;
812   p = p->right;
813
814   if ((p == NULL) || (p->right == NULL))
815     return;
816
817   first = last = NULL;
818   while (p)
819     {
820       p_vet = malloc (sizeof (struct vet));
821       if (p_vet == NULL)
822         return;
823
824       p_vet->next = NULL;
825       p_vet->prev = last;
826       if (first == NULL)
827         first = p_vet;
828       else
829         last->next = p_vet;
830       last = p_vet;
831
832       /* extraction of tag and length */
833       if (der_len - counter > 0)
834         {
835
836           if (asn1_get_tag_der
837               (der + counter, der_len - counter, &class, &len,
838                NULL) != ASN1_SUCCESS)
839             return;
840           counter += len;
841
842           len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
843           if (len2 < 0)
844             return;
845           counter += len + len2;
846         }
847
848       p_vet->end = counter;
849       p = p->right;
850     }
851
852   p_vet = first;
853
854   while (p_vet)
855     {
856       p2_vet = p_vet->next;
857       counter = 0;
858       while (p2_vet)
859         {
860           if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
861             max = p_vet->end - counter;
862           else
863             max = p2_vet->end - p_vet->end;
864
865           change = -1;
866           for (k = 0; k < max; k++)
867             if (der[counter + k] > der[p_vet->end + k])
868               {
869                 change = 1;
870                 break;
871               }
872             else if (der[counter + k] < der[p_vet->end + k])
873               {
874                 change = 0;
875                 break;
876               }
877
878           if ((change == -1)
879               && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
880             change = 1;
881
882           if (change == 1)
883             {
884               /* change position */
885               temp = malloc (p_vet->end - counter);
886               if (temp == NULL)
887                 return;
888
889               memcpy (temp, der + counter, (p_vet->end) - counter);
890               memcpy (der + counter, der + (p_vet->end),
891                       (p2_vet->end) - (p_vet->end));
892               memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
893                       (p_vet->end) - counter);
894               free (temp);
895
896               p_vet->end = counter + (p2_vet->end - p_vet->end);
897             }
898           counter = p_vet->end;
899
900           p2_vet = p2_vet->next;
901           p_vet = p_vet->next;
902         }
903
904       if (p_vet != first)
905         p_vet->prev->next = NULL;
906       else
907         first = NULL;
908       free (p_vet);
909       p_vet = first;
910     }
911 }
912
913 /**
914  * asn1_der_coding:
915  * @element: pointer to an ASN1 element
916  * @name: the name of the structure you want to encode (it must be
917  *   inside *POINTER).
918  * @ider: vector that will contain the DER encoding. DER must be a
919  *   pointer to memory cells already allocated.
920  * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
921  *   holds the sizeof of der vector.
922  * @errorDescription : return the error description or an empty
923  *   string if success.
924  *
925  * Creates the DER encoding for the NAME structure (inside *POINTER
926  * structure).
927  *
928  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
929  *   if @name is not a valid element, %ASN1_VALUE_NOT_FOUND if there
930  *   is an element without a value, %ASN1_MEM_ERROR if the @ider
931  *   vector isn't big enough and in this case @len will contain the
932  *   length needed.
933  **/
934 int
935 asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
936                  char *ErrorDescription)
937 {
938   asn1_node node, p, p2;
939   unsigned char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
940   int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
941   int err;
942   unsigned char *der = ider;
943
944   node = asn1_find_node (element, name);
945   if (node == NULL)
946     return ASN1_ELEMENT_NOT_FOUND;
947
948   /* Node is now a locally allocated variable.
949    * That is because in some point we modify the
950    * structure, and I don't know why! --nmav
951    */
952   node = _asn1_copy_structure3 (node);
953   if (node == NULL)
954     return ASN1_ELEMENT_NOT_FOUND;
955
956   max_len = *len;
957
958   counter = 0;
959   move = DOWN;
960   p = node;
961   while (1)
962     {
963
964       counter_old = counter;
965       max_len_old = max_len;
966       if (move != UP)
967         {
968           err = _asn1_insert_tag_der (p, der, &counter, &max_len);
969           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
970             goto error;
971         }
972       switch (type_field (p->type))
973         {
974         case ASN1_ETYPE_NULL:
975           max_len--;
976           if (max_len >= 0)
977             der[counter] = 0;
978           counter++;
979           move = RIGHT;
980           break;
981         case ASN1_ETYPE_BOOLEAN:
982           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
983             {
984               counter = counter_old;
985               max_len = max_len_old;
986             }
987           else
988             {
989               if (p->value == NULL)
990                 {
991                   _asn1_error_description_value_not_found (p,
992                                                            ErrorDescription);
993                   err = ASN1_VALUE_NOT_FOUND;
994                   goto error;
995                 }
996               max_len -= 2;
997               if (max_len >= 0)
998                 {
999                   der[counter++] = 1;
1000                   if (p->value[0] == 'F')
1001                     der[counter++] = 0;
1002                   else
1003                     der[counter++] = 0xFF;
1004                 }
1005               else
1006                 counter += 2;
1007             }
1008           move = RIGHT;
1009           break;
1010         case ASN1_ETYPE_INTEGER:
1011         case ASN1_ETYPE_ENUMERATED:
1012           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
1013             {
1014               counter = counter_old;
1015               max_len = max_len_old;
1016             }
1017           else
1018             {
1019               if (p->value == NULL)
1020                 {
1021                   _asn1_error_description_value_not_found (p,
1022                                                            ErrorDescription);
1023                   err = ASN1_VALUE_NOT_FOUND;
1024                   goto error;
1025                 }
1026               len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1027               if (len2 < 0)
1028                 {
1029                   err = ASN1_DER_ERROR;
1030                   goto error;
1031                 }
1032               max_len -= len2 + len3;
1033               if (max_len >= 0)
1034                 memcpy (der + counter, p->value, len3 + len2);
1035               counter += len3 + len2;
1036             }
1037           move = RIGHT;
1038           break;
1039         case ASN1_ETYPE_OBJECT_ID:
1040           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
1041             {
1042               counter = counter_old;
1043               max_len = max_len_old;
1044             }
1045           else
1046             {
1047               if (p->value == NULL)
1048                 {
1049                   _asn1_error_description_value_not_found (p,
1050                                                            ErrorDescription);
1051                   err = ASN1_VALUE_NOT_FOUND;
1052                   goto error;
1053                 }
1054               len2 = max_len;
1055               err = _asn1_objectid_der (p->value, der + counter, &len2);
1056               if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1057                 goto error;
1058
1059               max_len -= len2;
1060               counter += len2;
1061             }
1062           move = RIGHT;
1063           break;
1064         case ASN1_ETYPE_GENERALIZED_TIME:
1065         case ASN1_ETYPE_UTC_TIME:
1066           if (p->value == NULL)
1067             {
1068               _asn1_error_description_value_not_found (p, ErrorDescription);
1069               err = ASN1_VALUE_NOT_FOUND;
1070               goto error;
1071             }
1072           len2 = max_len;
1073           err = _asn1_time_der (p->value, der + counter, &len2);
1074           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1075             goto error;
1076
1077           max_len -= len2;
1078           counter += len2;
1079           move = RIGHT;
1080           break;
1081         case ASN1_ETYPE_OCTET_STRING:
1082         case ASN1_ETYPE_GENERALSTRING:
1083         case ASN1_ETYPE_NUMERIC_STRING:
1084         case ASN1_ETYPE_IA5_STRING:
1085         case ASN1_ETYPE_TELETEX_STRING:
1086         case ASN1_ETYPE_PRINTABLE_STRING:
1087         case ASN1_ETYPE_UNIVERSAL_STRING:
1088         case ASN1_ETYPE_BMP_STRING:
1089         case ASN1_ETYPE_UTF8_STRING:
1090         case ASN1_ETYPE_VISIBLE_STRING:
1091         case ASN1_ETYPE_BIT_STRING:
1092           if (p->value == NULL)
1093             {
1094               _asn1_error_description_value_not_found (p, ErrorDescription);
1095               err = ASN1_VALUE_NOT_FOUND;
1096               goto error;
1097             }
1098           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1099           if (len2 < 0)
1100             {
1101               err = ASN1_DER_ERROR;
1102               goto error;
1103             }
1104           max_len -= len2 + len3;
1105           if (max_len >= 0)
1106             memcpy (der + counter, p->value, len3 + len2);
1107           counter += len3 + len2;
1108           move = RIGHT;
1109           break;
1110         case ASN1_ETYPE_SEQUENCE:
1111         case ASN1_ETYPE_SET:
1112           if (move != UP)
1113             {
1114               _asn1_ltostr (counter, (char *) temp);
1115               tlen = _asn1_strlen (temp);
1116               if (tlen > 0)
1117                 _asn1_set_value (p, temp, tlen + 1);
1118               if (p->down == NULL)
1119                 {
1120                   move = UP;
1121                   continue;
1122                 }
1123               else
1124                 {
1125                   p2 = p->down;
1126                   while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG))
1127                     p2 = p2->right;
1128                   if (p2)
1129                     {
1130                       p = p2;
1131                       move = RIGHT;
1132                       continue;
1133                     }
1134                   move = UP;
1135                   continue;
1136                 }
1137             }
1138           else
1139             {                   /* move==UP */
1140               len2 = _asn1_strtol (p->value, NULL, 10);
1141               _asn1_set_value (p, NULL, 0);
1142               if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0))
1143                 _asn1_ordering_set (der + len2, max_len - len2, p);
1144               asn1_length_der (counter - len2, temp, &len3);
1145               max_len -= len3;
1146               if (max_len >= 0)
1147                 {
1148                   memmove (der + len2 + len3, der + len2, counter - len2);
1149                   memcpy (der + len2, temp, len3);
1150                 }
1151               counter += len3;
1152               move = RIGHT;
1153             }
1154           break;
1155         case ASN1_ETYPE_SEQUENCE_OF:
1156         case ASN1_ETYPE_SET_OF:
1157           if (move != UP)
1158             {
1159               _asn1_ltostr (counter, (char *) temp);
1160               tlen = _asn1_strlen (temp);
1161
1162               if (tlen > 0)
1163                 _asn1_set_value (p, temp, tlen + 1);
1164               p = p->down;
1165               while ((type_field (p->type) == ASN1_ETYPE_TAG)
1166                      || (type_field (p->type) == ASN1_ETYPE_SIZE))
1167                 p = p->right;
1168               if (p->right)
1169                 {
1170                   p = p->right;
1171                   move = RIGHT;
1172                   continue;
1173                 }
1174               else
1175                 p = _asn1_find_up (p);
1176               move = UP;
1177             }
1178           if (move == UP)
1179             {
1180               len2 = _asn1_strtol (p->value, NULL, 10);
1181               _asn1_set_value (p, NULL, 0);
1182               if ((type_field (p->type) == ASN1_ETYPE_SET_OF)
1183                   && (max_len - len2 > 0))
1184                 {
1185                   _asn1_ordering_set_of (der + len2, max_len - len2, p);
1186                 }
1187               asn1_length_der (counter - len2, temp, &len3);
1188               max_len -= len3;
1189               if (max_len >= 0)
1190                 {
1191                   memmove (der + len2 + len3, der + len2, counter - len2);
1192                   memcpy (der + len2, temp, len3);
1193                 }
1194               counter += len3;
1195               move = RIGHT;
1196             }
1197           break;
1198         case ASN1_ETYPE_ANY:
1199           if (p->value == NULL)
1200             {
1201               _asn1_error_description_value_not_found (p, ErrorDescription);
1202               err = ASN1_VALUE_NOT_FOUND;
1203               goto error;
1204             }
1205           len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1206           if (len2 < 0)
1207             {
1208               err = ASN1_DER_ERROR;
1209               goto error;
1210             }
1211           max_len -= len2;
1212           if (max_len >= 0)
1213             memcpy (der + counter, p->value + len3, len2);
1214           counter += len2;
1215           move = RIGHT;
1216           break;
1217         default:
1218           move = (move == UP) ? RIGHT : DOWN;
1219           break;
1220         }
1221
1222       if ((move != DOWN) && (counter != counter_old))
1223         {
1224           err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
1225           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1226             goto error;
1227         }
1228
1229       if (p == node && move != DOWN)
1230         break;
1231
1232       if (move == DOWN)
1233         {
1234           if (p->down)
1235             p = p->down;
1236           else
1237             move = RIGHT;
1238         }
1239       if (move == RIGHT)
1240         {
1241           if (p->right)
1242             p = p->right;
1243           else
1244             move = UP;
1245         }
1246       if (move == UP)
1247         p = _asn1_find_up (p);
1248     }
1249
1250   *len = counter;
1251
1252   if (max_len < 0)
1253     {
1254       err = ASN1_MEM_ERROR;
1255       goto error;
1256     }
1257
1258   err = ASN1_SUCCESS;
1259
1260 error:
1261   asn1_delete_structure (&node);
1262   return err;
1263 }