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