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