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