the parameters field in an ASN.1 algorithmIdentifier is optional
[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 /*
352 * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
353 */
354 time_t
355 asn1totime(const chunk_t *utctime, asn1_t type)
356 {
357 struct tm t;
358 time_t tz_offset;
359 u_char *eot = NULL;
360
361 if ((eot = memchr(utctime->ptr, 'Z', utctime->len)) != NULL)
362 {
363 tz_offset = 0; /* Zulu time with a zero time zone offset */
364 }
365 else if ((eot = memchr(utctime->ptr, '+', utctime->len)) != NULL)
366 {
367 int tz_hour, tz_min;
368
369 sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min);
370 tz_offset = 3600*tz_hour + 60*tz_min; /* positive time zone offset */
371 }
372 else if ((eot = memchr(utctime->ptr, '-', utctime->len)) != NULL)
373 {
374 int tz_hour, tz_min;
375
376 sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min);
377 tz_offset = -3600*tz_hour - 60*tz_min; /* negative time zone offset */
378 }
379 else
380 {
381 return 0; /* error in time format */
382 }
383
384 {
385 const char* format = (type == ASN1_UTCTIME)? "%2d%2d%2d%2d%2d":
386 "%4d%2d%2d%2d%2d";
387
388 sscanf(utctime->ptr, format, &t.tm_year, &t.tm_mon, &t.tm_mday,
389 &t.tm_hour, &t.tm_min);
390 }
391
392 /* is there a seconds field? */
393 if ((eot - utctime->ptr) == ((type == ASN1_UTCTIME)?12:14))
394 {
395 sscanf(eot-2, "%2d", &t.tm_sec);
396 }
397 else
398 {
399 t.tm_sec = 0;
400 }
401
402 /* representation of year */
403 if (t.tm_year >= 1900)
404 {
405 t.tm_year -= 1900;
406 }
407 else if (t.tm_year >= 100)
408 {
409 return 0;
410 }
411 else if (t.tm_year < 50)
412 {
413 t.tm_year += 100;
414 }
415
416 /* representation of month 0..11*/
417 t.tm_mon--;
418
419 /* set daylight saving time to off */
420 t.tm_isdst = 0;
421
422 /* compensate timezone */
423
424 return mktime(&t) - timezone - tz_offset;
425 }
426
427 /*
428 * convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
429 */
430 chunk_t
431 timetoasn1(const time_t *time, asn1_t type)
432 {
433 int offset;
434 const char *format;
435 char buf[TIMETOA_BUF];
436 chunk_t formatted_time;
437 struct tm *t = gmtime(time);
438
439 if (type == ASN1_GENERALIZEDTIME)
440 {
441 format = "%04d%02d%02d%02d%02d%02dZ";
442 offset = 1900;
443 }
444 else /* ASN1_UTCTIME */
445 {
446 format = "%02d%02d%02d%02d%02d%02dZ";
447 offset = (t->tm_year < 100)? 0 : -100;
448 }
449 sprintf(buf, format, t->tm_year + offset, t->tm_mon + 1, t->tm_mday
450 , t->tm_hour, t->tm_min, t->tm_sec);
451 formatted_time.ptr = buf;
452 formatted_time.len = strlen(buf);
453 return asn1_simple_object(type, formatted_time);
454 }
455
456
457 /*
458 * Initializes the internal context of the ASN.1 parser
459 */
460 void
461 asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0,
462 bool implicit, u_int cond)
463 {
464 ctx->blobs[0] = blob;
465 ctx->level0 = level0;
466 ctx->implicit = implicit;
467 ctx->cond = cond;
468 memset(ctx->loopAddr, '\0', sizeof(ctx->loopAddr));
469 }
470
471 /*
472 * print the value of an ASN.1 simple object
473 */
474 static void
475 debug_asn1_simple_object(chunk_t object, asn1_t type, u_int cond)
476 {
477 int oid;
478
479 switch (type)
480 {
481 case ASN1_OID:
482 oid = known_oid(object);
483 if (oid != OID_UNKNOWN)
484 {
485 DBG(DBG_PARSING,
486 DBG_log(" '%s'",oid_names[oid].name);
487 )
488 return;
489 }
490 break;
491 case ASN1_UTF8STRING:
492 case ASN1_IA5STRING:
493 case ASN1_PRINTABLESTRING:
494 case ASN1_T61STRING:
495 case ASN1_VISIBLESTRING:
496 DBG(DBG_PARSING,
497 DBG_log(" '%.*s'", (int)object.len, object.ptr);
498 )
499 return;
500 case ASN1_UTCTIME:
501 case ASN1_GENERALIZEDTIME:
502 DBG(DBG_PARSING,
503 time_t time = asn1totime(&object, type);
504 DBG_log(" '%s'", timetoa(&time, TRUE));
505 )
506 return;
507 default:
508 break;
509 }
510 DBG(cond,
511 DBG_dump_chunk("", object);
512 )
513 }
514
515 /*
516 * Parses and extracts the next ASN.1 object
517 */
518 bool
519 extract_object(asn1Object_t const *objects,
520 u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx)
521 {
522 asn1Object_t obj = objects[*objectID];
523 chunk_t *blob;
524 chunk_t *blob1;
525 u_char *start_ptr;
526
527 *object = empty_chunk;
528
529 if (obj.flags & ASN1_END) /* end of loop or option found */
530 {
531 if (ctx->loopAddr[obj.level] && ctx->blobs[obj.level+1].len > 0)
532 {
533 *objectID = ctx->loopAddr[obj.level]; /* another iteration */
534 obj = objects[*objectID];
535 }
536 else
537 {
538 ctx->loopAddr[obj.level] = 0; /* exit loop or option*/
539 return TRUE;
540 }
541 }
542
543 *level = ctx->level0 + obj.level;
544 blob = ctx->blobs + obj.level;
545 blob1 = blob + 1;
546 start_ptr = blob->ptr;
547
548 /* handle ASN.1 defaults values */
549
550 if ((obj.flags & ASN1_DEF)
551 && (blob->len == 0 || *start_ptr != obj.type) )
552 {
553 /* field is missing */
554 DBG(DBG_PARSING,
555 DBG_log("L%d - %s:", *level, obj.name);
556 )
557 if (obj.type & ASN1_CONSTRUCTED)
558 {
559 (*objectID)++ ; /* skip context-specific tag */
560 }
561 return TRUE;
562 }
563
564 /* handle ASN.1 options */
565
566 if ((obj.flags & ASN1_OPT)
567 && (blob->len == 0 || *start_ptr != obj.type))
568 {
569 /* advance to end of missing option field */
570 do
571 (*objectID)++;
572 while (!((objects[*objectID].flags & ASN1_END)
573 && (objects[*objectID].level == obj.level)));
574 return TRUE;
575 }
576
577 /* an ASN.1 object must possess at least a tag and length field */
578
579 if (blob->len < 2)
580 {
581 DBG(DBG_PARSING,
582 DBG_log("L%d - %s: ASN.1 object smaller than 2 octets",
583 *level, obj.name);
584 )
585 return FALSE;
586 }
587
588 blob1->len = asn1_length(blob);
589
590 if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len)
591 {
592 DBG(DBG_PARSING,
593 DBG_log("L%d - %s: length of ASN.1 object invalid or too large",
594 *level, obj.name);
595 )
596 return FALSE;
597 }
598
599 blob1->ptr = blob->ptr;
600 blob->ptr += blob1->len;
601 blob->len -= blob1->len;
602
603 /* return raw ASN.1 object without prior type checking */
604
605 if (obj.flags & ASN1_RAW)
606 {
607 DBG(DBG_PARSING,
608 DBG_log("L%d - %s:", *level, obj.name);
609 )
610 object->ptr = start_ptr;
611 object->len = (size_t)(blob->ptr - start_ptr);
612 return TRUE;
613 }
614
615 if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0))
616 {
617 DBG(DBG_PARSING,
618 DBG_log("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
619 *level, obj.name, obj.type, *start_ptr);
620 DBG_dump("", start_ptr, (u_int)(blob->ptr - start_ptr));
621 )
622 return FALSE;
623 }
624
625 DBG(DBG_PARSING,
626 DBG_log("L%d - %s:", ctx->level0+obj.level, obj.name);
627 )
628
629 /* In case of "SEQUENCE OF" or "SET OF" start a loop */
630
631 if (obj.flags & ASN1_LOOP)
632 {
633 if (blob1->len > 0)
634 {
635 /* at least one item, start the loop */
636 ctx->loopAddr[obj.level] = *objectID + 1;
637 }
638 else
639 {
640 /* no items, advance directly to end of loop */
641 do
642 (*objectID)++;
643 while (!((objects[*objectID].flags & ASN1_END)
644 && (objects[*objectID].level == obj.level)));
645 return TRUE;
646 }
647 }
648
649 if (obj.flags & ASN1_OBJ)
650 {
651 object->ptr = start_ptr;
652 object->len = (size_t)(blob->ptr - start_ptr);
653 DBG(ctx->cond,
654 DBG_dump_chunk("", *object);
655 )
656 }
657 else if (obj.flags & ASN1_BODY)
658 {
659 *object = *blob1;
660 debug_asn1_simple_object(*object, obj.type, ctx->cond);
661 }
662 return TRUE;
663 }
664
665 /*
666 * parse an ASN.1 simple type
667 */
668 bool
669 parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level
670 , const char* name)
671 {
672 size_t len;
673
674 /* an ASN.1 object must possess at least a tag and length field */
675 if (object->len < 2)
676 {
677 DBG(DBG_PARSING,
678 DBG_log("L%d - %s: ASN.1 object smaller than 2 octets",
679 level, name);
680 )
681 return FALSE;
682 }
683
684 if (*object->ptr != type)
685 {
686 DBG(DBG_PARSING,
687 DBG_log("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
688 level, name, type, *object->ptr);
689 )
690 return FALSE;
691 }
692
693 len = asn1_length(object);
694
695 if (len == ASN1_INVALID_LENGTH || object->len < len)
696 {
697 DBG(DBG_PARSING,
698 DBG_log("L%d - %s: length of ASN.1 object invalid or too large",
699 level, name);
700 )
701 return FALSE;
702 }
703
704 DBG(DBG_PARSING,
705 DBG_log("L%d - %s:", level, name);
706 )
707 debug_asn1_simple_object(*object, type, DBG_RAW);
708 return TRUE;
709 }
710
711 /*
712 * extracts an algorithmIdentifier
713 */
714 int
715 parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
716 {
717 asn1_ctx_t ctx;
718 chunk_t object;
719 u_int level;
720 int alg = OID_UNKNOWN;
721 int objectID = 0;
722
723 asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
724
725 while (objectID < ALGORITHM_ID_ROOF)
726 {
727 if (!extract_object(algorithmIdentifierObjects, &objectID, &object, &level, &ctx))
728 return alg;
729
730 switch (objectID)
731 {
732 case ALGORITHM_ID_ALG:
733 alg = known_oid(object);
734 break;
735 case ALGORITHM_ID_PARAMETERS:
736 if (parameters != NULL)
737 *parameters = object;
738 break;
739 default:
740 break;
741 }
742 objectID++;
743 }
744 return alg;
745 }
746
747 /*
748 * tests if a blob contains a valid ASN.1 set or sequence
749 */
750 bool
751 is_asn1(chunk_t blob)
752 {
753 u_int len;
754 u_char tag = *blob.ptr;
755
756 if (tag != ASN1_SEQUENCE && tag != ASN1_SET)
757 {
758 DBG(DBG_PARSING,
759 DBG_log(" file content is not binary ASN.1");
760 )
761 return FALSE;
762 }
763
764 len = asn1_length(&blob);
765
766 /* exact match */
767 if (len == blob.len)
768 {
769 return TRUE;
770 }
771
772 /* some websites append a surplus newline character to the blob */
773 if (len + 1 == blob.len && *(blob.ptr + len) == '\n')
774 {
775 return TRUE;
776 }
777
778 DBG(DBG_PARSING,
779 DBG_log(" file size does not match ASN.1 coded length");
780 )
781 return FALSE;
782 }