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