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