2d402f72a4bb737712aa15aa2f4ee1aa3537b39a
[strongswan.git] / src / libstrongswan / asn1 / asn1.c
1 /*
2 * Copyright (C) 2006 Martin Will
3 * Copyright (C) 2000-2008 Andreas Steffen
4 *
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <time.h>
21 #include <pthread.h>
22
23 #include <utils.h>
24 #include <debug.h>
25
26 #include "oid.h"
27 #include "asn1.h"
28 #include "asn1_parser.h"
29
30 /**
31 * some common prefabricated ASN.1 constants
32 */
33 static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 };
34 static u_char ASN1_INTEGER_1_str[] = { 0x02, 0x01, 0x01 };
35 static u_char ASN1_INTEGER_2_str[] = { 0x02, 0x01, 0x02 };
36
37 const chunk_t ASN1_INTEGER_0 = chunk_from_buf(ASN1_INTEGER_0_str);
38 const chunk_t ASN1_INTEGER_1 = chunk_from_buf(ASN1_INTEGER_1_str);
39 const chunk_t ASN1_INTEGER_2 = chunk_from_buf(ASN1_INTEGER_2_str);
40
41 /*
42 * Defined in header.
43 */
44 chunk_t asn1_algorithmIdentifier(int oid)
45 {
46 chunk_t parameters;
47
48 /* some algorithmIdentifiers have a NULL parameters field and some do not */
49 switch (oid)
50 {
51 case OID_ECDSA_WITH_SHA1:
52 case OID_ECDSA_WITH_SHA224:
53 case OID_ECDSA_WITH_SHA256:
54 case OID_ECDSA_WITH_SHA384:
55 case OID_ECDSA_WITH_SHA512:
56 parameters = chunk_empty;
57 break;
58 default:
59 parameters = asn1_simple_object(ASN1_NULL, chunk_empty);
60 break;
61 }
62 return asn1_wrap(ASN1_SEQUENCE, "mm", asn1_build_known_oid(oid), parameters);
63 }
64
65 /*
66 * Defined in header.
67 */
68 int asn1_known_oid(chunk_t object)
69 {
70 int oid = 0;
71
72 while (object.len)
73 {
74 if (oid_names[oid].octet == *object.ptr)
75 {
76 if (--object.len == 0 || oid_names[oid].down == 0)
77 {
78 return oid; /* found terminal symbol */
79 }
80 else
81 {
82 object.ptr++; oid++; /* advance to next hex octet */
83 }
84 }
85 else
86 {
87 if (oid_names[oid].next)
88 {
89 oid = oid_names[oid].next;
90 }
91 else
92 {
93 return OID_UNKNOWN;
94 }
95 }
96 }
97 return -1;
98 }
99
100 /*
101 * Defined in header.
102 */
103 chunk_t asn1_build_known_oid(int n)
104 {
105 chunk_t oid;
106 int i;
107
108 if (n < 0 || n >= OID_MAX)
109 {
110 return chunk_empty;
111 }
112
113 i = oid_names[n].level + 1;
114 oid = chunk_alloc(2 + i);
115 oid.ptr[0] = ASN1_OID;
116 oid.ptr[1] = i;
117
118 do
119 {
120 if (oid_names[n].level >= i)
121 {
122 n--;
123 continue;
124 }
125 oid.ptr[--i + 2] = oid_names[n--].octet;
126 }
127 while (i > 0);
128
129 return oid;
130 }
131
132 /*
133 * Defined in header.
134 */
135 size_t asn1_length(chunk_t *blob)
136 {
137 u_char n;
138 size_t len;
139
140 if (blob->len < 2)
141 {
142 DBG2("insufficient number of octets to parse ASN.1 length");
143 return ASN1_INVALID_LENGTH;
144 }
145
146 /* read length field, skip tag and length */
147 n = blob->ptr[1];
148 *blob = chunk_skip(*blob, 2);
149
150 if ((n & 0x80) == 0)
151 { /* single length octet */
152 if (n > blob->len)
153 {
154 DBG2("length is larger than remaining blob size");
155 return ASN1_INVALID_LENGTH;
156 }
157 return n;
158 }
159
160 /* composite length, determine number of length octets */
161 n &= 0x7f;
162
163 if (n == 0 || n > blob->len)
164 {
165 DBG2("number of length octets invalid");
166 return ASN1_INVALID_LENGTH;
167 }
168
169 if (n > sizeof(len))
170 {
171 DBG2("number of length octets is larger than limit of %d octets",
172 (int)sizeof(len));
173 return ASN1_INVALID_LENGTH;
174 }
175
176 len = 0;
177
178 while (n-- > 0)
179 {
180 len = 256*len + *blob->ptr++;
181 blob->len--;
182 }
183 if (len > blob->len)
184 {
185 DBG2("length is larger than remaining blob size");
186 return ASN1_INVALID_LENGTH;
187 }
188 return len;
189 }
190
191 /*
192 * See header.
193 */
194 int asn1_unwrap(chunk_t *blob, chunk_t *inner)
195 {
196 chunk_t res;
197 u_char len;
198 int type;
199
200 if (blob->len < 2)
201 {
202 return ASN1_INVALID;
203 }
204 type = blob->ptr[0];
205 len = blob->ptr[1];
206 *blob = chunk_skip(*blob, 2);
207
208 if ((len & 0x80) == 0)
209 { /* single length octet */
210 res.len = len;
211 }
212 else
213 { /* composite length, determine number of length octets */
214 len &= 0x7f;
215 if (len == 0 || len > sizeof(res.len))
216 {
217 return ASN1_INVALID;
218 }
219 res.len = 0;
220 while (len-- > 0)
221 {
222 res.len = 256 * res.len + blob->ptr[0];
223 *blob = chunk_skip(*blob, 1);
224 }
225 }
226 if (res.len > blob->len)
227 {
228 return ASN1_INVALID;
229 }
230 res.ptr = blob->ptr;
231 *blob = chunk_skip(*blob, res.len);
232 /* updating inner not before we are finished allows a caller to pass
233 * blob = inner */
234 *inner = res;
235 return type;
236 }
237
238 #define TIME_MAX 0x7fffffff
239
240 static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
241 static const int tm_leap_1970 = 477;
242
243 /**
244 * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
245 */
246 time_t asn1_to_time(const chunk_t *utctime, asn1_t type)
247 {
248 int tm_year, tm_mon, tm_day, tm_days, tm_hour, tm_min, tm_sec;
249 int tm_leap_4, tm_leap_100, tm_leap_400, tm_leap;
250 int tz_hour, tz_min, tz_offset;
251 time_t tm_secs;
252 u_char *eot = NULL;
253
254 if ((eot = memchr(utctime->ptr, 'Z', utctime->len)) != NULL)
255 {
256 tz_offset = 0; /* Zulu time with a zero time zone offset */
257 }
258 else if ((eot = memchr(utctime->ptr, '+', utctime->len)) != NULL)
259 {
260 if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2)
261 {
262 return 0; /* error in positive timezone offset format */
263 }
264 tz_offset = 3600*tz_hour + 60*tz_min; /* positive time zone offset */
265 }
266 else if ((eot = memchr(utctime->ptr, '-', utctime->len)) != NULL)
267 {
268 if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2)
269 {
270 return 0; /* error in negative timezone offset format */
271 }
272 tz_offset = -3600*tz_hour - 60*tz_min; /* negative time zone offset */
273 }
274 else
275 {
276 return 0; /* error in time format */
277 }
278
279 /* parse ASN.1 time string */
280 {
281 const char* format = (type == ASN1_UTCTIME)? "%2d%2d%2d%2d%2d":
282 "%4d%2d%2d%2d%2d";
283
284 if (sscanf(utctime->ptr, format, &tm_year, &tm_mon, &tm_day,
285 &tm_hour, &tm_min) != 5)
286 {
287 return 0; /* error in [yy]yymmddhhmm time format */
288 }
289 }
290
291 /* is there a seconds field? */
292 if ((eot - utctime->ptr) == ((type == ASN1_UTCTIME)?12:14))
293 {
294 if (sscanf(eot-2, "%2d", &tm_sec) != 1)
295 {
296 return 0; /* error in ss seconds field format */
297 }
298 }
299 else
300 {
301 tm_sec = 0;
302 }
303
304 /* representation of two-digit years */
305 if (type == ASN1_UTCTIME)
306 {
307 tm_year += (tm_year < 50) ? 2000 : 1900;
308 }
309
310 /* prevent large 32 bit integer overflows */
311 if (sizeof(time_t) == 4 && tm_year > 2038)
312 {
313 return TIME_MAX;
314 }
315
316 /* representation of months as 0..11*/
317 if (tm_mon < 1 || tm_mon > 12)
318 {
319 return 0; /* error in month format */
320 }
321 tm_mon--;
322
323 /* representation of days as 0..30 */
324 tm_day--;
325
326 /* number of leap years between last year and 1970? */
327 tm_leap_4 = (tm_year - 1) / 4;
328 tm_leap_100 = tm_leap_4 / 25;
329 tm_leap_400 = tm_leap_100 / 4;
330 tm_leap = tm_leap_4 - tm_leap_100 + tm_leap_400 - tm_leap_1970;
331
332 /* if date later then February, is the current year a leap year? */
333 if (tm_mon > 1 && (tm_year % 4 == 0) &&
334 (tm_year % 100 != 0 || tm_year % 400 == 0))
335 {
336 tm_leap++;
337 }
338 tm_days = 365 * (tm_year - 1970) + days[tm_mon] + tm_day + tm_leap;
339 tm_secs = 60 * (60 * (24 * tm_days + tm_hour) + tm_min) + tm_sec - tz_offset;
340
341 /* has a 32 bit overflow occurred? */
342 return (tm_secs < 0) ? TIME_MAX : tm_secs;
343 }
344
345 /**
346 * Convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
347 */
348 chunk_t asn1_from_time(const time_t *time, asn1_t type)
349 {
350 int offset;
351 const char *format;
352 char buf[BUF_LEN];
353 chunk_t formatted_time;
354 struct tm t;
355
356 gmtime_r(time, &t);
357 if (type == ASN1_GENERALIZEDTIME)
358 {
359 format = "%04d%02d%02d%02d%02d%02dZ";
360 offset = 1900;
361 }
362 else /* ASN1_UTCTIME */
363 {
364 format = "%02d%02d%02d%02d%02d%02dZ";
365 offset = (t.tm_year < 100)? 0 : -100;
366 }
367 snprintf(buf, BUF_LEN, format, t.tm_year + offset,
368 t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
369 formatted_time.ptr = buf;
370 formatted_time.len = strlen(buf);
371 return asn1_simple_object(type, formatted_time);
372 }
373
374 /*
375 * Defined in header.
376 */
377 void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private)
378 {
379 int oid;
380
381 switch (type)
382 {
383 case ASN1_OID:
384 oid = asn1_known_oid(object);
385 if (oid != OID_UNKNOWN)
386 {
387 DBG2(" '%s'", oid_names[oid].name);
388 return;
389 }
390 break;
391 case ASN1_UTF8STRING:
392 case ASN1_IA5STRING:
393 case ASN1_PRINTABLESTRING:
394 case ASN1_T61STRING:
395 case ASN1_VISIBLESTRING:
396 DBG2(" '%.*s'", (int)object.len, object.ptr);
397 return;
398 case ASN1_UTCTIME:
399 case ASN1_GENERALIZEDTIME:
400 {
401 time_t time = asn1_to_time(&object, type);
402
403 DBG2(" '%T'", &time, TRUE);
404 }
405 return;
406 default:
407 break;
408 }
409 if (private)
410 {
411 DBG4("%B", &object);
412 }
413 else
414 {
415 DBG3("%B", &object);
416 }
417 }
418
419 /**
420 * parse an ASN.1 simple type
421 */
422 bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name)
423 {
424 size_t len;
425
426 /* an ASN.1 object must possess at least a tag and length field */
427 if (object->len < 2)
428 {
429 DBG2("L%d - %s: ASN.1 object smaller than 2 octets", level, name);
430 return FALSE;
431 }
432
433 if (*object->ptr != type)
434 {
435 DBG2("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
436 level, name, type, *object->ptr);
437 return FALSE;
438 }
439
440 len = asn1_length(object);
441
442 if (len == ASN1_INVALID_LENGTH || object->len < len)
443 {
444 DBG2("L%d - %s: length of ASN.1 object invalid or too large",
445 level, name);
446 return FALSE;
447 }
448
449 DBG2("L%d - %s:", level, name);
450 asn1_debug_simple_object(*object, type, FALSE);
451 return TRUE;
452 }
453
454 /**
455 * ASN.1 definition of an algorithmIdentifier
456 */
457 static const asn1Object_t algorithmIdentifierObjects[] = {
458 { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
459 { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */
460 { 1, "parameters", ASN1_EOC, ASN1_RAW|ASN1_OPT }, /* 2 */
461 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
462 { 0, "exit", ASN1_EOC, ASN1_EXIT }
463 };
464 #define ALGORITHM_ID_ALG 1
465 #define ALGORITHM_ID_PARAMETERS 2
466
467 /*
468 * Defined in header
469 */
470 int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
471 {
472 asn1_parser_t *parser;
473 chunk_t object;
474 int objectID;
475 int alg = OID_UNKNOWN;
476
477 parser = asn1_parser_create(algorithmIdentifierObjects, blob);
478 parser->set_top_level(parser, level0);
479
480 while (parser->iterate(parser, &objectID, &object))
481 {
482 switch (objectID)
483 {
484 case ALGORITHM_ID_ALG:
485 alg = asn1_known_oid(object);
486 break;
487 case ALGORITHM_ID_PARAMETERS:
488 if (parameters != NULL)
489 {
490 *parameters = object;
491 }
492 break;
493 default:
494 break;
495 }
496 }
497 parser->destroy(parser);
498 return alg;
499 }
500
501 /*
502 * tests if a blob contains a valid ASN.1 set or sequence
503 */
504 bool is_asn1(chunk_t blob)
505 {
506 u_int len;
507 u_char tag = *blob.ptr;
508
509 if (tag != ASN1_SEQUENCE && tag != ASN1_SET && tag != ASN1_OCTET_STRING)
510 {
511 DBG2(" file content is not binary ASN.1");
512 return FALSE;
513 }
514
515 len = asn1_length(&blob);
516
517 /* exact match */
518 if (len == blob.len)
519 {
520 return TRUE;
521 }
522
523 /* some websites append a surplus newline character to the blob */
524 if (len + 1 == blob.len && *(blob.ptr + len) == '\n')
525 {
526 return TRUE;
527 }
528
529 DBG2(" file size does not match ASN.1 coded length");
530 return FALSE;
531 }
532
533 /*
534 * Defined in header.
535 */
536 bool asn1_is_printablestring(chunk_t str)
537 {
538 const char printablestring_charset[] =
539 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";
540 u_int i;
541
542 for (i = 0; i < str.len; i++)
543 {
544 if (strchr(printablestring_charset, str.ptr[i]) == NULL)
545 return FALSE;
546 }
547 return TRUE;
548 }
549
550 /**
551 * codes ASN.1 lengths up to a size of 16'777'215 bytes
552 */
553 static void asn1_code_length(size_t length, chunk_t *code)
554 {
555 if (length < 128)
556 {
557 code->ptr[0] = length;
558 code->len = 1;
559 }
560 else if (length < 256)
561 {
562 code->ptr[0] = 0x81;
563 code->ptr[1] = (u_char) length;
564 code->len = 2;
565 }
566 else if (length < 65536)
567 {
568 code->ptr[0] = 0x82;
569 code->ptr[1] = length >> 8;
570 code->ptr[2] = length & 0x00ff;
571 code->len = 3;
572 }
573 else
574 {
575 code->ptr[0] = 0x83;
576 code->ptr[1] = length >> 16;
577 code->ptr[2] = (length >> 8) & 0x00ff;
578 code->ptr[3] = length & 0x0000ff;
579 code->len = 4;
580 }
581 }
582
583 /**
584 * build an empty asn.1 object with tag and length fields already filled in
585 */
586 u_char* asn1_build_object(chunk_t *object, asn1_t type, size_t datalen)
587 {
588 u_char length_buf[4];
589 chunk_t length = { length_buf, 0 };
590 u_char *pos;
591
592 /* code the asn.1 length field */
593 asn1_code_length(datalen, &length);
594
595 /* allocate memory for the asn.1 TLV object */
596 object->len = 1 + length.len + datalen;
597 object->ptr = malloc(object->len);
598
599 /* set position pointer at the start of the object */
600 pos = object->ptr;
601
602 /* copy the asn.1 tag field and advance the pointer */
603 *pos++ = type;
604
605 /* copy the asn.1 length field and advance the pointer */
606 memcpy(pos, length.ptr, length.len);
607 pos += length.len;
608
609 return pos;
610 }
611
612 /**
613 * Build a simple ASN.1 object
614 */
615 chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
616 {
617 chunk_t object;
618
619 u_char *pos = asn1_build_object(&object, tag, content.len);
620 memcpy(pos, content.ptr, content.len);
621 pos += content.len;
622
623 return object;
624 }
625
626 /**
627 * Build an ASN.1 BIT_STRING object
628 */
629 chunk_t asn1_bitstring(const char *mode, chunk_t content)
630 {
631 chunk_t object;
632 u_char *pos = asn1_build_object(&object, ASN1_BIT_STRING, 1 + content.len);
633
634 *pos++ = 0x00;
635 memcpy(pos, content.ptr, content.len);
636 if (*mode == 'm')
637 {
638 free(content.ptr);
639 }
640 return object;
641 }
642
643 /**
644 * Build an ASN.1 INTEGER object
645 */
646 chunk_t asn1_integer(const char *mode, chunk_t content)
647 {
648 chunk_t object;
649 size_t len;
650 u_char *pos;
651
652 if (content.len == 0 || (content.len == 1 && *content.ptr == 0x00))
653 {
654 /* a zero ASN.1 integer does not have a value field */
655 len = 0;
656 }
657 else
658 {
659 /* ASN.1 integers must be positive numbers in two's complement */
660 len = content.len + ((*content.ptr & 0x80) ? 1 : 0);
661 }
662 pos = asn1_build_object(&object, ASN1_INTEGER, len);
663 if (len > content.len)
664 {
665 *pos++ = 0x00;
666 }
667 if (len)
668 {
669 memcpy(pos, content.ptr, content.len);
670 }
671 if (*mode == 'm')
672 {
673 free(content.ptr);
674 }
675 return object;
676 }
677
678 /**
679 * Build an ASN.1 object from a variable number of individual chunks.
680 * Depending on the mode, chunks either are moved ('m') or copied ('c').
681 */
682 chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
683 {
684 chunk_t construct;
685 va_list chunks;
686 u_char *pos;
687 int i;
688 int count = strlen(mode);
689
690 /* sum up lengths of individual chunks */
691 va_start(chunks, mode);
692 construct.len = 0;
693 for (i = 0; i < count; i++)
694 {
695 chunk_t ch = va_arg(chunks, chunk_t);
696 construct.len += ch.len;
697 }
698 va_end(chunks);
699
700 /* allocate needed memory for construct */
701 pos = asn1_build_object(&construct, type, construct.len);
702
703 /* copy or move the chunks */
704 va_start(chunks, mode);
705 for (i = 0; i < count; i++)
706 {
707 chunk_t ch = va_arg(chunks, chunk_t);
708
709 memcpy(pos, ch.ptr, ch.len);
710 pos += ch.len;
711
712 switch (*mode++)
713 {
714 case 's':
715 chunk_clear(&ch);
716 break;
717 case 'm':
718 free(ch.ptr);
719 break;
720 default:
721 break;
722 }
723 }
724 va_end(chunks);
725
726 return construct;
727 }
728
729 /**
730 * ASN.1 definition of time
731 */
732 static const asn1Object_t timeObjects[] = {
733 { 0, "utcTime", ASN1_UTCTIME, ASN1_OPT|ASN1_BODY }, /* 0 */
734 { 0, "end opt", ASN1_EOC, ASN1_END }, /* 1 */
735 { 0, "generalizeTime", ASN1_GENERALIZEDTIME, ASN1_OPT|ASN1_BODY }, /* 2 */
736 { 0, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
737 { 0, "exit", ASN1_EOC, ASN1_EXIT }
738 };
739 #define TIME_UTC 0
740 #define TIME_GENERALIZED 2
741
742 /**
743 * extracts and converts a UTCTIME or GENERALIZEDTIME object
744 */
745 time_t asn1_parse_time(chunk_t blob, int level0)
746 {
747 asn1_parser_t *parser;
748 chunk_t object;
749 int objectID;
750 time_t utc_time = 0;
751
752 parser= asn1_parser_create(timeObjects, blob);
753 parser->set_top_level(parser, level0);
754
755 while (parser->iterate(parser, &objectID, &object))
756 {
757 if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
758 {
759 utc_time = asn1_to_time(&object, (objectID == TIME_UTC)
760 ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
761 }
762 }
763 parser->destroy(parser);
764 return utc_time;
765 }