aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <JBottomley@Parallels.com>2012-12-10 09:41:13 +0000
committerJames Bottomley <JBottomley@Parallels.com>2012-12-12 00:23:50 +0000
commitda1aafb4a7c292cc1df9b00611ba7e4566524a6b (patch)
tree11889c68f6a34a970d6f466efb5a1397698f317c
parent4f431262cb5a84934dee1158624378d840c421e8 (diff)
downloadefitools-da1aafb4a7c292cc1df9b00611ba7e4566524a6b.tar.gz
asn1: Add parser files straight from strongswan-5.0.1
-rw-r--r--lib/asn1/asn1.c874
-rw-r--r--lib/asn1/asn1.h280
-rw-r--r--lib/asn1/asn1_parser.c289
-rw-r--r--lib/asn1/asn1_parser.h119
-rw-r--r--lib/asn1/oid.c390
-rw-r--r--lib/asn1/oid.h226
-rw-r--r--lib/asn1/oid.pl134
-rw-r--r--lib/asn1/oid.txt377
8 files changed, 2689 insertions, 0 deletions
diff --git a/lib/asn1/asn1.c b/lib/asn1/asn1.c
new file mode 100644
index 0000000..c9f6fce
--- /dev/null
+++ b/lib/asn1/asn1.c
@@ -0,0 +1,874 @@
+/*
+ * Copyright (C) 2006 Martin Will
+ * Copyright (C) 2000-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include <debug.h>
+
+#include "oid.h"
+#include "asn1.h"
+#include "asn1_parser.h"
+
+/**
+ * Commonly used ASN1 values.
+ */
+const chunk_t ASN1_INTEGER_0 = chunk_from_chars(0x02, 0x01, 0x00);
+const chunk_t ASN1_INTEGER_1 = chunk_from_chars(0x02, 0x01, 0x01);
+const chunk_t ASN1_INTEGER_2 = chunk_from_chars(0x02, 0x01, 0x02);
+
+/*
+ * Defined in header.
+ */
+chunk_t asn1_algorithmIdentifier(int oid)
+{
+ chunk_t parameters;
+
+ /* some algorithmIdentifiers have a NULL parameters field and some do not */
+ switch (oid)
+ {
+ case OID_ECDSA_WITH_SHA1:
+ case OID_ECDSA_WITH_SHA224:
+ case OID_ECDSA_WITH_SHA256:
+ case OID_ECDSA_WITH_SHA384:
+ case OID_ECDSA_WITH_SHA512:
+ parameters = chunk_empty;
+ break;
+ default:
+ parameters = asn1_simple_object(ASN1_NULL, chunk_empty);
+ break;
+ }
+ return asn1_wrap(ASN1_SEQUENCE, "mm", asn1_build_known_oid(oid), parameters);
+}
+
+/*
+ * Defined in header.
+ */
+int asn1_known_oid(chunk_t object)
+{
+ int oid = 0;
+
+ while (object.len)
+ {
+ if (oid_names[oid].octet == *object.ptr)
+ {
+ if (--object.len == 0 || oid_names[oid].down == 0)
+ {
+ return oid; /* found terminal symbol */
+ }
+ else
+ {
+ object.ptr++; oid++; /* advance to next hex octet */
+ }
+ }
+ else
+ {
+ if (oid_names[oid].next)
+ {
+ oid = oid_names[oid].next;
+ }
+ else
+ {
+ return OID_UNKNOWN;
+ }
+ }
+ }
+ return -1;
+}
+
+/*
+ * Defined in header.
+ */
+chunk_t asn1_build_known_oid(int n)
+{
+ chunk_t oid;
+ int i;
+
+ if (n < 0 || n >= OID_MAX)
+ {
+ return chunk_empty;
+ }
+
+ i = oid_names[n].level + 1;
+ oid = chunk_alloc(2 + i);
+ oid.ptr[0] = ASN1_OID;
+ oid.ptr[1] = i;
+
+ do
+ {
+ if (oid_names[n].level >= i)
+ {
+ n--;
+ continue;
+ }
+ oid.ptr[--i + 2] = oid_names[n--].octet;
+ }
+ while (i > 0);
+
+ return oid;
+}
+
+/*
+ * Defined in header.
+ */
+chunk_t asn1_oid_from_string(char *str)
+{
+ enumerator_t *enumerator;
+ u_char buf[64];
+ char *end;
+ int i = 0, pos = 0, shift;
+ u_int val, shifted_val, first = 0;
+
+ enumerator = enumerator_create_token(str, ".", "");
+ while (enumerator->enumerate(enumerator, &str))
+ {
+ val = strtoul(str, &end, 10);
+ if (end == str || pos > countof(buf))
+ {
+ pos = 0;
+ break;
+ }
+ switch (i++)
+ {
+ case 0:
+ first = val;
+ break;
+ case 1:
+ buf[pos++] = first * 40 + val;
+ break;
+ default:
+ shift = 28; /* sufficient to handle 32 bit node numbers */
+ while (shift)
+ {
+ shifted_val = val >> shift;
+ shift -= 7;
+ if (shifted_val) /* do not encode leading zeroes */
+ {
+ buf[pos++] = 0x80 | (shifted_val & 0x7F);
+ }
+ }
+ buf[pos++] = val & 0x7F;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return chunk_clone(chunk_create(buf, pos));
+}
+
+/*
+ * Defined in header.
+ */
+char *asn1_oid_to_string(chunk_t oid)
+{
+ char buf[64], *pos = buf;
+ int len;
+ u_int val;
+
+ if (!oid.len)
+ {
+ return NULL;
+ }
+ val = oid.ptr[0] / 40;
+ len = snprintf(buf, sizeof(buf), "%u.%u", val, oid.ptr[0] - val * 40);
+ oid = chunk_skip(oid, 1);
+ if (len < 0 || len >= sizeof(buf))
+ {
+ return NULL;
+ }
+ pos += len;
+ val = 0;
+
+ while (oid.len)
+ {
+ val = (val << 7) + (u_int)(oid.ptr[0] & 0x7f);
+
+ if (oid.ptr[0] < 128)
+ {
+ len = snprintf(pos, sizeof(buf) + buf - pos, ".%u", val);
+ if (len < 0 || len >= sizeof(buf) + buf - pos)
+ {
+ return NULL;
+ }
+ pos += len;
+ val = 0;
+ }
+ oid = chunk_skip(oid, 1);
+ }
+ return (val == 0) ? strdup(buf) : NULL;
+}
+
+/*
+ * Defined in header.
+ */
+size_t asn1_length(chunk_t *blob)
+{
+ u_char n;
+ size_t len;
+
+ if (blob->len < 2)
+ {
+ DBG2(DBG_ASN, "insufficient number of octets to parse ASN.1 length");
+ return ASN1_INVALID_LENGTH;
+ }
+
+ /* read length field, skip tag and length */
+ n = blob->ptr[1];
+ blob->ptr += 2;
+ blob->len -= 2;
+
+ if ((n & 0x80) == 0)
+ { /* single length octet */
+ if (n > blob->len)
+ {
+ DBG2(DBG_ASN, "length is larger than remaining blob size");
+ return ASN1_INVALID_LENGTH;
+ }
+ return n;
+ }
+
+ /* composite length, determine number of length octets */
+ n &= 0x7f;
+
+ if (n == 0 || n > blob->len)
+ {
+ DBG2(DBG_ASN, "number of length octets invalid");
+ return ASN1_INVALID_LENGTH;
+ }
+
+ if (n > sizeof(len))
+ {
+ DBG2(DBG_ASN, "number of length octets is larger than limit of"
+ " %d octets", (int)sizeof(len));
+ return ASN1_INVALID_LENGTH;
+ }
+
+ len = 0;
+
+ while (n-- > 0)
+ {
+ len = 256*len + *blob->ptr++;
+ blob->len--;
+ }
+ if (len > blob->len)
+ {
+ DBG2(DBG_ASN, "length is larger than remaining blob size");
+ return ASN1_INVALID_LENGTH;
+ }
+ return len;
+}
+
+/*
+ * See header.
+ */
+int asn1_unwrap(chunk_t *blob, chunk_t *inner)
+{
+ chunk_t res;
+ u_char len;
+ int type;
+
+ if (blob->len < 2)
+ {
+ return ASN1_INVALID;
+ }
+ type = blob->ptr[0];
+ len = blob->ptr[1];
+ *blob = chunk_skip(*blob, 2);
+
+ if ((len & 0x80) == 0)
+ { /* single length octet */
+ res.len = len;
+ }
+ else
+ { /* composite length, determine number of length octets */
+ len &= 0x7f;
+ if (len == 0 || len > sizeof(res.len))
+ {
+ return ASN1_INVALID;
+ }
+ res.len = 0;
+ while (len-- > 0)
+ {
+ res.len = 256 * res.len + blob->ptr[0];
+ *blob = chunk_skip(*blob, 1);
+ }
+ }
+ if (res.len > blob->len)
+ {
+ return ASN1_INVALID;
+ }
+ res.ptr = blob->ptr;
+ *blob = chunk_skip(*blob, res.len);
+ /* updating inner not before we are finished allows a caller to pass
+ * blob = inner */
+ *inner = res;
+ return type;
+}
+
+static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+static const int tm_leap_1970 = 477;
+
+/**
+ * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
+ */
+time_t asn1_to_time(const chunk_t *utctime, asn1_t type)
+{
+ int tm_year, tm_mon, tm_day, tm_hour, tm_min, tm_sec;
+ int tm_leap_4, tm_leap_100, tm_leap_400, tm_leap;
+ int tz_hour, tz_min, tz_offset;
+ time_t tm_days, tm_secs;
+ u_char *eot = NULL;
+
+ if ((eot = memchr(utctime->ptr, 'Z', utctime->len)) != NULL)
+ {
+ tz_offset = 0; /* Zulu time with a zero time zone offset */
+ }
+ else if ((eot = memchr(utctime->ptr, '+', utctime->len)) != NULL)
+ {
+ if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2)
+ {
+ return 0; /* error in positive timezone offset format */
+ }
+ tz_offset = 3600*tz_hour + 60*tz_min; /* positive time zone offset */
+ }
+ else if ((eot = memchr(utctime->ptr, '-', utctime->len)) != NULL)
+ {
+ if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2)
+ {
+ return 0; /* error in negative timezone offset format */
+ }
+ tz_offset = -3600*tz_hour - 60*tz_min; /* negative time zone offset */
+ }
+ else
+ {
+ return 0; /* error in time format */
+ }
+
+ /* parse ASN.1 time string */
+ {
+ const char* format = (type == ASN1_UTCTIME)? "%2d%2d%2d%2d%2d":
+ "%4d%2d%2d%2d%2d";
+
+ if (sscanf(utctime->ptr, format, &tm_year, &tm_mon, &tm_day,
+ &tm_hour, &tm_min) != 5)
+ {
+ return 0; /* error in [yy]yymmddhhmm time format */
+ }
+ }
+
+ /* is there a seconds field? */
+ if ((eot - utctime->ptr) == ((type == ASN1_UTCTIME)?12:14))
+ {
+ if (sscanf(eot-2, "%2d", &tm_sec) != 1)
+ {
+ return 0; /* error in ss seconds field format */
+ }
+ }
+ else
+ {
+ tm_sec = 0;
+ }
+
+ /* representation of two-digit years */
+ if (type == ASN1_UTCTIME)
+ {
+ tm_year += (tm_year < 50) ? 2000 : 1900;
+ }
+
+ /* prevent large 32 bit integer overflows */
+ if (sizeof(time_t) == 4 && tm_year > 2038)
+ {
+ return TIME_32_BIT_SIGNED_MAX;
+ }
+
+ /* representation of months as 0..11*/
+ if (tm_mon < 1 || tm_mon > 12)
+ {
+ return 0; /* error in month format */
+ }
+ tm_mon--;
+
+ /* representation of days as 0..30 */
+ tm_day--;
+
+ /* number of leap years between last year and 1970? */
+ tm_leap_4 = (tm_year - 1) / 4;
+ tm_leap_100 = tm_leap_4 / 25;
+ tm_leap_400 = tm_leap_100 / 4;
+ tm_leap = tm_leap_4 - tm_leap_100 + tm_leap_400 - tm_leap_1970;
+
+ /* if date later then February, is the current year a leap year? */
+ if (tm_mon > 1 && (tm_year % 4 == 0) &&
+ (tm_year % 100 != 0 || tm_year % 400 == 0))
+ {
+ tm_leap++;
+ }
+ tm_days = 365 * (tm_year - 1970) + days[tm_mon] + tm_day + tm_leap;
+ tm_secs = 60 * (60 * (24 * tm_days + tm_hour) + tm_min) + tm_sec - tz_offset;
+
+ /* has a 32 bit signed integer overflow occurred? */
+ return (tm_secs < 0) ? TIME_32_BIT_SIGNED_MAX : tm_secs;
+}
+
+/**
+ * Convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
+ */
+chunk_t asn1_from_time(const time_t *time, asn1_t type)
+{
+ int offset;
+ const char *format;
+ char buf[BUF_LEN];
+ chunk_t formatted_time;
+ struct tm t;
+
+ gmtime_r(time, &t);
+ /* RFC 5280 says that dates through the year 2049 MUST be encoded as UTCTIME
+ * and dates in 2050 or later MUST be encoded as GENERALIZEDTIME. We only
+ * enforce the latter to avoid overflows but allow callers to force the
+ * encoding to GENERALIZEDTIME */
+ type = (t.tm_year >= 150) ? ASN1_GENERALIZEDTIME : type;
+ if (type == ASN1_GENERALIZEDTIME)
+ {
+ format = "%04d%02d%02d%02d%02d%02dZ";
+ offset = 1900;
+ }
+ else /* ASN1_UTCTIME */
+ {
+ format = "%02d%02d%02d%02d%02d%02dZ";
+ offset = (t.tm_year < 100) ? 0 : -100;
+ }
+ snprintf(buf, BUF_LEN, format, t.tm_year + offset,
+ t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
+ formatted_time.ptr = buf;
+ formatted_time.len = strlen(buf);
+ return asn1_simple_object(type, formatted_time);
+}
+
+/*
+ * Defined in header.
+ */
+void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private)
+{
+ int oid;
+
+ switch (type)
+ {
+ case ASN1_OID:
+ oid = asn1_known_oid(object);
+ if (oid == OID_UNKNOWN)
+ {
+ char *oid_str = asn1_oid_to_string(object);
+
+ if (!oid_str)
+ {
+ break;
+ }
+ DBG2(DBG_ASN, " %s", oid_str);
+ free(oid_str);
+ }
+ else
+ {
+ DBG2(DBG_ASN, " '%s'", oid_names[oid].name);
+ }
+ return;
+ case ASN1_UTF8STRING:
+ case ASN1_IA5STRING:
+ case ASN1_PRINTABLESTRING:
+ case ASN1_T61STRING:
+ case ASN1_VISIBLESTRING:
+ DBG2(DBG_ASN, " '%.*s'", (int)object.len, object.ptr);
+ return;
+ case ASN1_UTCTIME:
+ case ASN1_GENERALIZEDTIME:
+ {
+ time_t time = asn1_to_time(&object, type);
+
+ DBG2(DBG_ASN, " '%T'", &time, TRUE);
+ }
+ return;
+ default:
+ break;
+ }
+ if (private)
+ {
+ DBG4(DBG_ASN, "%B", &object);
+ }
+ else
+ {
+ DBG3(DBG_ASN, "%B", &object);
+ }
+}
+
+/**
+ * parse an ASN.1 simple type
+ */
+bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name)
+{
+ size_t len;
+
+ /* an ASN.1 object must possess at least a tag and length field */
+ if (object->len < 2)
+ {
+ DBG2(DBG_ASN, "L%d - %s: ASN.1 object smaller than 2 octets", level,
+ name);
+ return FALSE;
+ }
+
+ if (*object->ptr != type)
+ {
+ DBG2(DBG_ASN, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
+ level, name, type, *object->ptr);
+ return FALSE;
+ }
+
+ len = asn1_length(object);
+
+ if (len == ASN1_INVALID_LENGTH || object->len < len)
+ {
+ DBG2(DBG_ASN, "L%d - %s: length of ASN.1 object invalid or too large",
+ level, name);
+ return FALSE;
+ }
+
+ DBG2(DBG_ASN, "L%d - %s:", level, name);
+ asn1_debug_simple_object(*object, type, FALSE);
+ return TRUE;
+}
+
+/**
+ * ASN.1 definition of an algorithmIdentifier
+ */
+static const asn1Object_t algorithmIdentifierObjects[] = {
+ { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */
+ { 1, "parameters", ASN1_OID, ASN1_RAW|ASN1_OPT }, /* 2 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 1, "parameters", ASN1_SEQUENCE, ASN1_RAW|ASN1_OPT }, /* 4 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 5 */
+ { 1, "parameters", ASN1_OCTET_STRING, ASN1_RAW|ASN1_OPT }, /* 6 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define ALGORITHM_ID_ALG 1
+#define ALGORITHM_ID_PARAMETERS_OID 2
+#define ALGORITHM_ID_PARAMETERS_SEQ 4
+#define ALGORITHM_ID_PARAMETERS_OCT 6
+
+/*
+ * Defined in header
+ */
+int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int alg = OID_UNKNOWN;
+
+ parser = asn1_parser_create(algorithmIdentifierObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case ALGORITHM_ID_ALG:
+ alg = asn1_known_oid(object);
+ break;
+ case ALGORITHM_ID_PARAMETERS_OID:
+ case ALGORITHM_ID_PARAMETERS_SEQ:
+ case ALGORITHM_ID_PARAMETERS_OCT:
+ if (parameters != NULL)
+ {
+ *parameters = object;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+ return alg;
+}
+
+/*
+ * tests if a blob contains a valid ASN.1 set or sequence
+ */
+bool is_asn1(chunk_t blob)
+{
+ u_int len;
+ u_char tag;
+
+ if (!blob.len || !blob.ptr)
+ {
+ return FALSE;
+ }
+
+ tag = *blob.ptr;
+ if (tag != ASN1_SEQUENCE && tag != ASN1_SET && tag != ASN1_OCTET_STRING)
+ {
+ DBG2(DBG_ASN, " file content is not binary ASN.1");
+ return FALSE;
+ }
+
+ len = asn1_length(&blob);
+
+ /* exact match */
+ if (len == blob.len)
+ {
+ return TRUE;
+ }
+
+ /* some websites append a surplus newline character to the blob */
+ if (len + 1 == blob.len && *(blob.ptr + len) == '\n')
+ {
+ return TRUE;
+ }
+
+ DBG2(DBG_ASN, " file size does not match ASN.1 coded length");
+ return FALSE;
+}
+
+/*
+ * Defined in header.
+ */
+bool asn1_is_printablestring(chunk_t str)
+{
+ const char printablestring_charset[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";
+ u_int i;
+
+ for (i = 0; i < str.len; i++)
+ {
+ if (strchr(printablestring_charset, str.ptr[i]) == NULL)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * codes ASN.1 lengths up to a size of 16'777'215 bytes
+ */
+static void asn1_code_length(size_t length, chunk_t *code)
+{
+ if (length < 128)
+ {
+ code->ptr[0] = length;
+ code->len = 1;
+ }
+ else if (length < 256)
+ {
+ code->ptr[0] = 0x81;
+ code->ptr[1] = (u_char) length;
+ code->len = 2;
+ }
+ else if (length < 65536)
+ {
+ code->ptr[0] = 0x82;
+ code->ptr[1] = length >> 8;
+ code->ptr[2] = length & 0x00ff;
+ code->len = 3;
+ }
+ else
+ {
+ code->ptr[0] = 0x83;
+ code->ptr[1] = length >> 16;
+ code->ptr[2] = (length >> 8) & 0x00ff;
+ code->ptr[3] = length & 0x0000ff;
+ code->len = 4;
+ }
+}
+
+/**
+ * build an empty asn.1 object with tag and length fields already filled in
+ */
+u_char* asn1_build_object(chunk_t *object, asn1_t type, size_t datalen)
+{
+ u_char length_buf[4];
+ chunk_t length = { length_buf, 0 };
+ u_char *pos;
+
+ /* code the asn.1 length field */
+ asn1_code_length(datalen, &length);
+
+ /* allocate memory for the asn.1 TLV object */
+ object->len = 1 + length.len + datalen;
+ object->ptr = malloc(object->len);
+
+ /* set position pointer at the start of the object */
+ pos = object->ptr;
+
+ /* copy the asn.1 tag field and advance the pointer */
+ *pos++ = type;
+
+ /* copy the asn.1 length field and advance the pointer */
+ memcpy(pos, length.ptr, length.len);
+ pos += length.len;
+
+ return pos;
+}
+
+/**
+ * Build a simple ASN.1 object
+ */
+chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
+{
+ chunk_t object;
+
+ u_char *pos = asn1_build_object(&object, tag, content.len);
+ memcpy(pos, content.ptr, content.len);
+ pos += content.len;
+
+ return object;
+}
+
+/**
+ * Build an ASN.1 BIT_STRING object
+ */
+chunk_t asn1_bitstring(const char *mode, chunk_t content)
+{
+ chunk_t object;
+ u_char *pos = asn1_build_object(&object, ASN1_BIT_STRING, 1 + content.len);
+
+ *pos++ = 0x00;
+ memcpy(pos, content.ptr, content.len);
+ if (*mode == 'm')
+ {
+ free(content.ptr);
+ }
+ return object;
+}
+
+/**
+ * Build an ASN.1 INTEGER object
+ */
+chunk_t asn1_integer(const char *mode, chunk_t content)
+{
+ chunk_t object;
+ size_t len;
+ u_char *pos;
+
+ if (content.len == 0)
+ { /* make sure 0 is encoded properly */
+ content = chunk_from_chars(0x00);
+ }
+
+ /* ASN.1 integers must be positive numbers in two's complement */
+ len = content.len + ((*content.ptr & 0x80) ? 1 : 0);
+ pos = asn1_build_object(&object, ASN1_INTEGER, len);
+ if (len > content.len)
+ {
+ *pos++ = 0x00;
+ }
+ if (len)
+ {
+ memcpy(pos, content.ptr, content.len);
+ }
+ if (*mode == 'm')
+ {
+ free(content.ptr);
+ }
+ return object;
+}
+
+/**
+ * Build an ASN.1 object from a variable number of individual chunks.
+ * Depending on the mode, chunks either are moved ('m') or copied ('c').
+ */
+chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
+{
+ chunk_t construct;
+ va_list chunks;
+ u_char *pos;
+ int i;
+ int count = strlen(mode);
+
+ /* sum up lengths of individual chunks */
+ va_start(chunks, mode);
+ construct.len = 0;
+ for (i = 0; i < count; i++)
+ {
+ chunk_t ch = va_arg(chunks, chunk_t);
+ construct.len += ch.len;
+ }
+ va_end(chunks);
+
+ /* allocate needed memory for construct */
+ pos = asn1_build_object(&construct, type, construct.len);
+
+ /* copy or move the chunks */
+ va_start(chunks, mode);
+ for (i = 0; i < count; i++)
+ {
+ chunk_t ch = va_arg(chunks, chunk_t);
+
+ memcpy(pos, ch.ptr, ch.len);
+ pos += ch.len;
+
+ switch (*mode++)
+ {
+ case 's':
+ chunk_clear(&ch);
+ break;
+ case 'm':
+ free(ch.ptr);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end(chunks);
+
+ return construct;
+}
+
+/**
+ * ASN.1 definition of time
+ */
+static const asn1Object_t timeObjects[] = {
+ { 0, "utcTime", ASN1_UTCTIME, ASN1_OPT|ASN1_BODY }, /* 0 */
+ { 0, "end opt", ASN1_EOC, ASN1_END }, /* 1 */
+ { 0, "generalizeTime", ASN1_GENERALIZEDTIME, ASN1_OPT|ASN1_BODY }, /* 2 */
+ { 0, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define TIME_UTC 0
+#define TIME_GENERALIZED 2
+
+/**
+ * extracts and converts a UTCTIME or GENERALIZEDTIME object
+ */
+time_t asn1_parse_time(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ time_t utc_time = 0;
+
+ parser= asn1_parser_create(timeObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
+ {
+ utc_time = asn1_to_time(&object, (objectID == TIME_UTC)
+ ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
+ }
+ }
+ parser->destroy(parser);
+ return utc_time;
+}
diff --git a/lib/asn1/asn1.h b/lib/asn1/asn1.h
new file mode 100644
index 0000000..15ffff6
--- /dev/null
+++ b/lib/asn1/asn1.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2006 Martin Will
+ * Copyright (C) 2000-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup asn1i asn1
+ * @{ @ingroup asn1
+ */
+
+#ifndef ASN1_H_
+#define ASN1_H_
+
+#include <stdarg.h>
+
+#include <library.h>
+
+/**
+ * Definition of some primitive ASN1 types
+ */
+typedef enum {
+ ASN1_EOC = 0x00,
+ ASN1_BOOLEAN = 0x01,
+ ASN1_INTEGER = 0x02,
+ ASN1_BIT_STRING = 0x03,
+ ASN1_OCTET_STRING = 0x04,
+ ASN1_NULL = 0x05,
+ ASN1_OID = 0x06,
+ ASN1_ENUMERATED = 0x0A,
+ ASN1_UTF8STRING = 0x0C,
+ ASN1_NUMERICSTRING = 0x12,
+ ASN1_PRINTABLESTRING = 0x13,
+ ASN1_T61STRING = 0x14,
+ ASN1_VIDEOTEXSTRING = 0x15,
+ ASN1_IA5STRING = 0x16,
+ ASN1_UTCTIME = 0x17,
+ ASN1_GENERALIZEDTIME = 0x18,
+ ASN1_GRAPHICSTRING = 0x19,
+ ASN1_VISIBLESTRING = 0x1A,
+ ASN1_GENERALSTRING = 0x1B,
+ ASN1_UNIVERSALSTRING = 0x1C,
+ ASN1_BMPSTRING = 0x1E,
+
+ ASN1_CONSTRUCTED = 0x20,
+
+ ASN1_SEQUENCE = 0x30,
+ ASN1_SET = 0x31,
+
+ ASN1_CONTEXT_S_0 = 0x80,
+ ASN1_CONTEXT_S_1 = 0x81,
+ ASN1_CONTEXT_S_2 = 0x82,
+ ASN1_CONTEXT_S_3 = 0x83,
+ ASN1_CONTEXT_S_4 = 0x84,
+ ASN1_CONTEXT_S_5 = 0x85,
+ ASN1_CONTEXT_S_6 = 0x86,
+ ASN1_CONTEXT_S_7 = 0x87,
+ ASN1_CONTEXT_S_8 = 0x88,
+
+ ASN1_CONTEXT_C_0 = 0xA0,
+ ASN1_CONTEXT_C_1 = 0xA1,
+ ASN1_CONTEXT_C_2 = 0xA2,
+ ASN1_CONTEXT_C_3 = 0xA3,
+ ASN1_CONTEXT_C_4 = 0xA4,
+ ASN1_CONTEXT_C_5 = 0xA5,
+
+ ASN1_INVALID = 0x100,
+} asn1_t;
+
+#define ASN1_INVALID_LENGTH 0xffffffff
+
+/**
+ * Some common prefabricated ASN.1 constants
+ */
+extern const chunk_t ASN1_INTEGER_0;
+extern const chunk_t ASN1_INTEGER_1;
+extern const chunk_t ASN1_INTEGER_2;
+
+
+/** Some ASN.1 analysis functions */
+
+/**
+ * Build an algorithmIdentifier from a known OID.
+ *
+ * @param oid known OID index
+ * @return body of the corresponding OID, allocated
+ */
+chunk_t asn1_algorithmIdentifier(int oid);
+
+/**
+ * Converts an ASN.1 OID into a known OID index
+ *
+ * @param object body of an OID
+ * @return index into the oid_names[] table or OID_UNKNOWN
+ */
+int asn1_known_oid(chunk_t object);
+
+/**
+ * Converts a known OID index to an ASN.1 OID
+ *
+ * @param n index into the oid_names[] table
+ * @return allocated OID chunk, chunk_empty if index out of range
+ */
+chunk_t asn1_build_known_oid(int n);
+
+/**
+ * Convert human readable OID to ASN.1 DER encoding, without OID header.
+ *
+ * @param str OID string (e.g. 1.2.345.67.8)
+ * @return allocated ASN.1 encoded OID, chunk_empty on error
+ */
+chunk_t asn1_oid_from_string(char *str);
+
+/**
+ * Convert a DER encoded ASN.1 OID to a human readable string.
+ *
+ * @param oid DER encoded OID, without header
+ * @return human readable OID string, allocated, NULL on error
+ */
+char* asn1_oid_to_string(chunk_t oid);
+
+/**
+ * Returns the length of an ASN.1 object
+ * The blob pointer is advanced past the tag length fields
+ *
+ * @param blob pointer to an ASN.1 coded blob
+ * @return length of ASN.1 object
+ */
+size_t asn1_length(chunk_t *blob);
+
+/**
+ * Unwrap the inner content of an ASN.1 type/length wrapped object.
+ *
+ * @param blob blob to parse header from, moved behind parsed content
+ * @param content inner content
+ * @return parsed type, ASN1_INVALID if length parsing failed
+ */
+int asn1_unwrap(chunk_t *blob, chunk_t *content);
+
+/**
+ * Parses an ASN.1 algorithmIdentifier object
+ *
+ * @param blob ASN.1 coded blob
+ * @param level0 top-most level offset
+ * @param params returns optional [ASN.1 coded] parameters
+ * @return known OID index or OID_UNKNOWN
+ */
+int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *params);
+
+/**
+ * Parse the top-most level of an ASN.1 object
+ *
+ * @param object ASN.1 coded object
+ * @param type Expected ASN.1 type
+ * @param level0 top-most level offset
+ * @param name descriptive name of object
+ * @return TRUE if parsing successful
+ */
+bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level0,
+ const char* name);
+
+/**
+ * Print the value of an ASN.1 simple object
+ *
+ * @param object ASN.1 object to be printed
+ * @param type asn1_t type
+ * @param private ASN.1 data is confidential (use debug level 4)
+ */
+void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private);
+
+/**
+ * Converts an ASN.1 UTCTIME or GENERALIZEDTIME string to time_t
+ *
+ * @param utctime body of an ASN.1 coded time object
+ * @param type ASN1_UTCTIME or ASN1_GENERALIZEDTIME
+ * @return time_t in UTC
+ */
+time_t asn1_to_time(const chunk_t *utctime, asn1_t type);
+
+/**
+ * Converts time_t to an ASN.1 UTCTIME or GENERALIZEDTIME string
+ *
+ * @note The type is automatically changed to GENERALIZEDTIME if needed
+ *
+ * @param time time_t in UTC
+ * @param type ASN1_UTCTIME or ASN1_GENERALIZEDTIME
+ * @return body of an ASN.1 code time object
+ */
+chunk_t asn1_from_time(const time_t *time, asn1_t type);
+
+/**
+ * Parse an ASN.1 UTCTIME or GENERALIZEDTIME object
+ *
+ * @param blob ASN.1 coded time object
+ * @param level0 top-most level offset
+ * @return time_t in UTC
+ */
+time_t asn1_parse_time(chunk_t blob, int level0);
+
+/**
+ * Determines if a binary blob is ASN.1 coded
+ *
+ * @param blob blob to be tested
+ * @return TRUE if blob is ASN.1 coded (SEQUENCE or SET)
+ */
+bool is_asn1(chunk_t blob);
+
+/**
+ * Determines if a character string can be coded as PRINTABLESTRING
+ *
+ * @param str character string to be tested
+ * @return TRUE if no special characters are contained
+ */
+bool asn1_is_printablestring(chunk_t str);
+
+
+/** some ASN.1 synthesis functions */
+
+/**
+ * Build an empty ASN.1 object with tag and length fields already filled in
+ *
+ * @param object returned object - memory is allocated by function
+ * @param type ASN.1 type to be created
+ * @param datalen size of the body to be created
+ * @return points to the first position in the body
+ */
+u_char* asn1_build_object(chunk_t *object, asn1_t type, size_t datalen);
+
+/**
+ * Build a simple ASN.1 object
+ *
+ * @param tag ASN.1 type to be created
+ * @param content content of the ASN.1 object
+ * @return chunk containing the ASN.1 coded object
+ */
+chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
+
+/**
+ * Build an ASN.1 BITSTRING object
+ *
+ * @param mode 'c' for copy or 'm' for move
+ * @param content content of the BITSTRING
+ * @return chunk containing the ASN.1 coded BITSTRING
+ */
+chunk_t asn1_bitstring(const char *mode, chunk_t content);
+
+/**
+ * Build an ASN.1 INTEGER object
+ *
+ * @param mode 'c' for copy or 'm' for move
+ * @param content content of the INTEGER
+ * @return chunk containing the ASN.1 coded INTEGER
+ */
+chunk_t asn1_integer(const char *mode, chunk_t content);
+
+/**
+ * Build an ASN.1 object from a variable number of individual chunks
+ *
+ * The mode string specifies the number of chunks, and how to handle each of
+ * them with a single character: 'c' for copy (allocate new chunk), 'm' for move
+ * (free given chunk) or 's' for sensitive-copy (clear given chunk, then free).
+ *
+ * @param type ASN.1 type to be created
+ * @param mode for each list member: 'c', 'm' or 's'
+ * @return chunk containing the ASN.1 coded object
+ */
+chunk_t asn1_wrap(asn1_t type, const char *mode, ...);
+
+#endif /** ASN1_H_ @}*/
diff --git a/lib/asn1/asn1_parser.c b/lib/asn1/asn1_parser.c
new file mode 100644
index 0000000..40e11b3
--- /dev/null
+++ b/lib/asn1/asn1_parser.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2006 Martin Will
+ * Copyright (C) 2000-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include <debug.h>
+
+#include "asn1.h"
+#include "asn1_parser.h"
+
+#define ASN1_MAX_LEVEL 10
+
+typedef struct private_asn1_parser_t private_asn1_parser_t;
+
+/**
+ * Private data of an asn1_cxt_t object.
+ */
+struct private_asn1_parser_t {
+ /**
+ * Public interface.
+ */
+ asn1_parser_t public;
+
+ /**
+ * Syntax definition of ASN.1 object
+ */
+ asn1Object_t const *objects;
+
+ /**
+ * Current syntax definition line
+ */
+ int line;
+
+ /**
+ * Current stat of the parsing operation
+ */
+ bool success;
+
+ /**
+ * Declare object data as private - use debug level 4 to log it
+ */
+ bool private;
+
+ /**
+ * Top-most type is implicit - ignore it
+ */
+ bool implicit;
+
+ /**
+ * Top-most parsing level - defaults to 0
+ */
+ u_int level0;
+
+ /**
+ * Jump back address for loops for each level
+ */
+ int loopAddr[ASN1_MAX_LEVEL + 1];
+
+ /**
+ * Current parsing pointer for each level
+ */
+ chunk_t blobs[ASN1_MAX_LEVEL + 2];
+};
+
+METHOD(asn1_parser_t, iterate, bool,
+ private_asn1_parser_t *this, int *objectID, chunk_t *object)
+{
+ chunk_t *blob, *blob1;
+ u_char *start_ptr;
+ u_int level;
+ asn1Object_t obj;
+
+ *object = chunk_empty;
+
+ /* Advance to the next object syntax definition line */
+ obj = this->objects[++(this->line)];
+
+ /* Terminate if the end of the object syntax definition has been reached */
+ if (obj.flags & ASN1_EXIT)
+ {
+ return FALSE;
+ }
+
+ if (obj.flags & ASN1_END) /* end of loop or option found */
+ {
+ if (this->loopAddr[obj.level] && this->blobs[obj.level+1].len > 0)
+ {
+ this->line = this->loopAddr[obj.level]; /* another iteration */
+ obj = this->objects[this->line];
+ }
+ else
+ {
+ this->loopAddr[obj.level] = 0; /* exit loop or option*/
+ goto end;
+ }
+ }
+
+ level = this->level0 + obj.level;
+ blob = this->blobs + obj.level;
+ blob1 = blob + 1;
+ start_ptr = blob->ptr;
+
+ /* handle ASN.1 defaults values */
+ if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) )
+ {
+ /* field is missing */
+ DBG2(DBG_ASN, "L%d - %s:", level, obj.name);
+ if (obj.type & ASN1_CONSTRUCTED)
+ {
+ this->line++ ; /* skip context-specific tag */
+ }
+ goto end;
+ }
+
+ /* handle ASN.1 options */
+
+ if ((obj.flags & ASN1_OPT)
+ && (blob->len == 0 || *start_ptr != obj.type))
+ {
+ /* advance to end of missing option field */
+ do
+ {
+ this->line++;
+ }
+ while (!((this->objects[this->line].flags & ASN1_END) &&
+ (this->objects[this->line].level == obj.level)));
+ goto end;
+ }
+
+ /* an ASN.1 object must possess at least a tag and length field */
+
+ if (blob->len < 2)
+ {
+ DBG1(DBG_ASN, "L%d - %s: ASN.1 object smaller than 2 octets",
+ level, obj.name);
+ this->success = FALSE;
+ goto end;
+ }
+
+ blob1->len = asn1_length(blob);
+
+ if (blob1->len == ASN1_INVALID_LENGTH)
+ {
+ DBG1(DBG_ASN, "L%d - %s: length of ASN.1 object invalid or too large",
+ level, obj.name);
+ this->success = FALSE;
+ }
+
+ blob1->ptr = blob->ptr;
+ blob->ptr += blob1->len;
+ blob->len -= blob1->len;
+
+ /* return raw ASN.1 object without prior type checking */
+
+ if (obj.flags & ASN1_RAW)
+ {
+ DBG2(DBG_ASN, "L%d - %s:", level, obj.name);
+ object->ptr = start_ptr;
+ object->len = (size_t)(blob->ptr - start_ptr);
+ goto end;
+ }
+
+ if (*start_ptr != obj.type && !(this->implicit && this->line == 0))
+ {
+ DBG2(DBG_ASN, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
+ level, obj.name, obj.type, *start_ptr);
+ DBG3(DBG_ASN, "%b", start_ptr, (u_int)(blob->ptr - start_ptr));
+ this->success = FALSE;
+ goto end;
+ }
+
+ DBG2(DBG_ASN, "L%d - %s:", level, obj.name);
+
+ /* In case of "SEQUENCE OF" or "SET OF" start a loop */
+ if (obj.flags & ASN1_LOOP)
+ {
+ if (blob1->len > 0)
+ {
+ /* at least one item, start the loop */
+ this->loopAddr[obj.level] = this->line + 1;
+ }
+ else
+ {
+ /* no items, advance directly to end of loop */
+ do
+ {
+ this->line++;
+ }
+ while (!((this->objects[this->line].flags & ASN1_END) &&
+ (this->objects[this->line].level == obj.level)));
+ goto end;
+ }
+ }
+
+ if (obj.flags & ASN1_OBJ)
+ {
+ object->ptr = start_ptr;
+ object->len = (size_t)(blob->ptr - start_ptr);
+ if (this->private)
+ {
+ DBG4(DBG_ASN, "%B", object);
+ }
+ else
+ {
+ DBG3(DBG_ASN, "%B", object);
+ }
+ }
+ else if (obj.flags & ASN1_BODY)
+ {
+ *object = *blob1;
+ asn1_debug_simple_object(*object, obj.type, this->private);
+ }
+
+end:
+ *objectID = this->line;
+ return this->success;
+}
+
+METHOD(asn1_parser_t, get_level, u_int,
+private_asn1_parser_t *this)
+{
+ return this->level0 + this->objects[this->line].level;
+}
+
+METHOD(asn1_parser_t, set_top_level, void,
+ private_asn1_parser_t *this, u_int level0)
+{
+ this->level0 = level0;
+}
+
+METHOD(asn1_parser_t, set_flags, void,
+ private_asn1_parser_t *this, bool implicit, bool private)
+{
+ this->implicit = implicit;
+ this->private = private;
+}
+
+METHOD(asn1_parser_t, success, bool,
+ private_asn1_parser_t *this)
+{
+ return this->success;
+}
+
+METHOD(asn1_parser_t, destroy, void,
+ private_asn1_parser_t *this)
+{
+ free(this);
+}
+
+/**
+ * Defined in header.
+ */
+asn1_parser_t* asn1_parser_create(asn1Object_t const *objects, chunk_t blob)
+{
+ private_asn1_parser_t *this;
+
+ INIT(this,
+ .public = {
+ .iterate = _iterate,
+ .get_level = _get_level,
+ .set_top_level = _set_top_level,
+ .set_flags = _set_flags,
+ .success = _success,
+ .destroy = _destroy,
+ },
+ .objects = objects,
+ .blobs[0] = blob,
+ .line = -1,
+ .success = TRUE,
+ );
+
+ return &this->public;
+}
diff --git a/lib/asn1/asn1_parser.h b/lib/asn1/asn1_parser.h
new file mode 100644
index 0000000..0edc22c
--- /dev/null
+++ b/lib/asn1/asn1_parser.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2006 Martin Will
+ * Copyright (C) 2000-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup asn1_parser asn1_parser
+ * @{ @ingroup asn1
+ */
+
+#ifndef ASN1_PARSER_H_
+#define ASN1_PARSER_H_
+
+#include <stdarg.h>
+
+#include <library.h>
+
+#include "asn1.h"
+
+/**
+ * Definition of ASN.1 flags
+ */
+#define ASN1_NONE 0x00
+#define ASN1_DEF 0x01
+#define ASN1_OPT 0x02
+#define ASN1_LOOP 0x04
+#define ASN1_END 0x08
+#define ASN1_OBJ 0x10
+#define ASN1_BODY 0x20
+#define ASN1_RAW 0x40
+#define ASN1_EXIT 0x80
+
+typedef struct asn1Object_t asn1Object_t;
+
+/**
+ * Syntax definition of an ASN.1 object
+ */
+struct asn1Object_t{
+ u_int level;
+ const u_char *name;
+ asn1_t type;
+ u_char flags;
+};
+
+typedef struct asn1_parser_t asn1_parser_t;
+
+/**
+ * Public interface of an ASN.1 parser
+ */
+struct asn1_parser_t {
+
+ /**
+ * Parse the next ASN.1 object in the hierarchy and return it
+ *
+ * @param objectID current line in the object syntax definition
+ * @param object current object
+ * @return - FALSE if end of object syntax definition was reached
+ * or a parsing error occurred
+ * - TRUE otherwise
+ */
+ bool (*iterate)(asn1_parser_t *this, int *objectID, chunk_t *object);
+
+ /**
+ * Get the current parsing level
+ *
+ * @return current level
+ */
+ u_int (*get_level)(asn1_parser_t *this);
+
+ /**
+ * Set the top-most level
+ *
+ * @param level top-most level
+ */
+ void (*set_top_level)(asn1_parser_t *this, u_int level0);
+
+ /**
+ * Set implicit and private flags
+ *
+ * @param implicit top-most type of object is implicit
+ * @param private object data is private (use debug level 4)
+ */
+ void (*set_flags)(asn1_parser_t *this, bool implicit, bool private);
+
+ /**
+ * Show final parsing status
+ *
+ * @return TRUE if parsing was successful, FALSE otherwise
+ */
+ bool (*success)(asn1_parser_t *this);
+
+ /**
+ * Destroy the ASN.1 parser
+ */
+ void (*destroy)(asn1_parser_t *this);
+};
+
+/**
+ * Create an ASN.1 parser
+ *
+ * @param objects syntax definition of the ASN.1 object to be parsed
+ * @param blob ASN.1 coded binary blob
+ * @return ASN.1 context
+ */
+asn1_parser_t* asn1_parser_create(asn1Object_t const *objects, chunk_t blob);
+
+#endif /** ASN1_PARSER_H_ @}*/
diff --git a/lib/asn1/oid.c b/lib/asn1/oid.c
new file mode 100644
index 0000000..b212996
--- /dev/null
+++ b/lib/asn1/oid.c
@@ -0,0 +1,390 @@
+/* List of some useful object identifiers (OIDs)
+ * Copyright (C) 2003-2008 Andreas Steffen, Hochschule fuer Technik Rapperswil
+ *
+ * This file has been automatically generated by the script oid.pl
+ * Do not edit manually!
+ */
+
+#include <stdlib.h>
+
+#include "oid.h"
+
+const oid_t oid_names[] = {
+ {0x02, 7, 1, 0, "ITU-T Administration" }, /* 0 */
+ { 0x82, 0, 1, 1, "" }, /* 1 */
+ { 0x06, 0, 1, 2, "Germany ITU-T member" }, /* 2 */
+ { 0x01, 0, 1, 3, "Deutsche Telekom AG" }, /* 3 */
+ { 0x0A, 0, 1, 4, "" }, /* 4 */
+ { 0x07, 0, 1, 5, "" }, /* 5 */
+ { 0x14, 0, 0, 6, "ND" }, /* 6 */
+ {0x09, 18, 1, 0, "data" }, /* 7 */
+ { 0x92, 0, 1, 1, "" }, /* 8 */
+ { 0x26, 0, 1, 2, "" }, /* 9 */
+ { 0x89, 0, 1, 3, "" }, /* 10 */
+ { 0x93, 0, 1, 4, "" }, /* 11 */
+ { 0xF2, 0, 1, 5, "" }, /* 12 */
+ { 0x2C, 0, 1, 6, "" }, /* 13 */
+ { 0x64, 0, 1, 7, "pilot" }, /* 14 */
+ { 0x01, 0, 1, 8, "pilotAttributeType" }, /* 15 */
+ { 0x01, 17, 0, 9, "UID" }, /* 16 */
+ { 0x19, 0, 0, 9, "DC" }, /* 17 */
+ {0x55, 65, 1, 0, "X.500" }, /* 18 */
+ { 0x04, 37, 1, 1, "X.509" }, /* 19 */
+ { 0x03, 21, 0, 2, "CN" }, /* 20 */
+ { 0x04, 22, 0, 2, "S" }, /* 21 */
+ { 0x05, 23, 0, 2, "SN" }, /* 22 */
+ { 0x06, 24, 0, 2, "C" }, /* 23 */
+ { 0x07, 25, 0, 2, "L" }, /* 24 */
+ { 0x08, 26, 0, 2, "ST" }, /* 25 */
+ { 0x0A, 27, 0, 2, "O" }, /* 26 */
+ { 0x0B, 28, 0, 2, "OU" }, /* 27 */
+ { 0x0C, 29, 0, 2, "T" }, /* 28 */
+ { 0x0D, 30, 0, 2, "D" }, /* 29 */
+ { 0x24, 31, 0, 2, "userCertificate" }, /* 30 */
+ { 0x29, 32, 0, 2, "N" }, /* 31 */
+ { 0x2A, 33, 0, 2, "G" }, /* 32 */
+ { 0x2B, 34, 0, 2, "I" }, /* 33 */
+ { 0x2D, 35, 0, 2, "ID" }, /* 34 */
+ { 0x2E, 36, 0, 2, "dnQualifier" }, /* 35 */
+ { 0x48, 0, 0, 2, "role" }, /* 36 */
+ { 0x1D, 0, 1, 1, "id-ce" }, /* 37 */
+ { 0x09, 39, 0, 2, "subjectDirectoryAttrs" }, /* 38 */
+ { 0x0E, 40, 0, 2, "subjectKeyIdentifier" }, /* 39 */
+ { 0x0F, 41, 0, 2, "keyUsage" }, /* 40 */
+ { 0x10, 42, 0, 2, "privateKeyUsagePeriod" }, /* 41 */
+ { 0x11, 43, 0, 2, "subjectAltName" }, /* 42 */
+ { 0x12, 44, 0, 2, "issuerAltName" }, /* 43 */
+ { 0x13, 45, 0, 2, "basicConstraints" }, /* 44 */
+ { 0x14, 46, 0, 2, "crlNumber" }, /* 45 */
+ { 0x15, 47, 0, 2, "reasonCode" }, /* 46 */
+ { 0x17, 48, 0, 2, "holdInstructionCode" }, /* 47 */
+ { 0x18, 49, 0, 2, "invalidityDate" }, /* 48 */
+ { 0x1B, 50, 0, 2, "deltaCrlIndicator" }, /* 49 */
+ { 0x1C, 51, 0, 2, "issuingDistributionPoint" }, /* 50 */
+ { 0x1D, 52, 0, 2, "certificateIssuer" }, /* 51 */
+ { 0x1E, 53, 0, 2, "nameConstraints" }, /* 52 */
+ { 0x1F, 54, 0, 2, "crlDistributionPoints" }, /* 53 */
+ { 0x20, 56, 1, 2, "certificatePolicies" }, /* 54 */
+ { 0x00, 0, 0, 3, "anyPolicy" }, /* 55 */
+ { 0x21, 57, 0, 2, "policyMappings" }, /* 56 */
+ { 0x23, 58, 0, 2, "authorityKeyIdentifier" }, /* 57 */
+ { 0x24, 59, 0, 2, "policyConstraints" }, /* 58 */
+ { 0x25, 61, 1, 2, "extendedKeyUsage" }, /* 59 */
+ { 0x00, 0, 0, 3, "anyExtendedKeyUsage" }, /* 60 */
+ { 0x2E, 62, 0, 2, "freshestCRL" }, /* 61 */
+ { 0x36, 63, 0, 2, "inhibitAnyPolicy" }, /* 62 */
+ { 0x37, 64, 0, 2, "targetInformation" }, /* 63 */
+ { 0x38, 0, 0, 2, "noRevAvail" }, /* 64 */
+ {0x2A, 169, 1, 0, "" }, /* 65 */
+ { 0x83, 78, 1, 1, "" }, /* 66 */
+ { 0x08, 0, 1, 2, "jp" }, /* 67 */
+ { 0x8C, 0, 1, 3, "" }, /* 68 */
+ { 0x9A, 0, 1, 4, "" }, /* 69 */
+ { 0x4B, 0, 1, 5, "" }, /* 70 */
+ { 0x3D, 0, 1, 6, "" }, /* 71 */
+ { 0x01, 0, 1, 7, "security" }, /* 72 */
+ { 0x01, 0, 1, 8, "algorithm" }, /* 73 */
+ { 0x01, 0, 1, 9, "symm-encryption-alg" }, /* 74 */
+ { 0x02, 76, 0, 10, "camellia128-cbc" }, /* 75 */
+ { 0x03, 77, 0, 10, "camellia192-cbc" }, /* 76 */
+ { 0x04, 0, 0, 10, "camellia256-cbc" }, /* 77 */
+ { 0x86, 0, 1, 1, "" }, /* 78 */
+ { 0x48, 0, 1, 2, "us" }, /* 79 */
+ { 0x86, 128, 1, 3, "" }, /* 80 */
+ { 0xF6, 86, 1, 4, "" }, /* 81 */
+ { 0x7D, 0, 1, 5, "NortelNetworks" }, /* 82 */
+ { 0x07, 0, 1, 6, "Entrust" }, /* 83 */
+ { 0x41, 0, 1, 7, "nsn-ce" }, /* 84 */
+ { 0x00, 0, 0, 8, "entrustVersInfo" }, /* 85 */
+ { 0xF7, 0, 1, 4, "" }, /* 86 */
+ { 0x0D, 0, 1, 5, "RSADSI" }, /* 87 */
+ { 0x01, 123, 1, 6, "PKCS" }, /* 88 */
+ { 0x01, 100, 1, 7, "PKCS-1" }, /* 89 */
+ { 0x01, 91, 0, 8, "rsaEncryption" }, /* 90 */
+ { 0x02, 92, 0, 8, "md2WithRSAEncryption" }, /* 91 */
+ { 0x04, 93, 0, 8, "md5WithRSAEncryption" }, /* 92 */
+ { 0x05, 94, 0, 8, "sha-1WithRSAEncryption" }, /* 93 */
+ { 0x07, 95, 0, 8, "id-RSAES-OAEP" }, /* 94 */
+ { 0x09, 96, 0, 8, "id-pSpecified" }, /* 95 */
+ { 0x0B, 97, 0, 8, "sha256WithRSAEncryption" }, /* 96 */
+ { 0x0C, 98, 0, 8, "sha384WithRSAEncryption" }, /* 97 */
+ { 0x0D, 99, 0, 8, "sha512WithRSAEncryption" }, /* 98 */
+ { 0x0E, 0, 0, 8, "sha224WithRSAEncryption" }, /* 99 */
+ { 0x05, 105, 1, 7, "PKCS-5" }, /* 100 */
+ { 0x03, 102, 0, 8, "pbeWithMD5AndDES-CBC" }, /* 101 */
+ { 0x0A, 103, 0, 8, "pbeWithSHA1AndDES-CBC" }, /* 102 */
+ { 0x0C, 104, 0, 8, "id-PBKDF2" }, /* 103 */
+ { 0x0D, 0, 0, 8, "id-PBES2" }, /* 104 */
+ { 0x07, 112, 1, 7, "PKCS-7" }, /* 105 */
+ { 0x01, 107, 0, 8, "data" }, /* 106 */
+ { 0x02, 108, 0, 8, "signedData" }, /* 107 */
+ { 0x03, 109, 0, 8, "envelopedData" }, /* 108 */
+ { 0x04, 110, 0, 8, "signedAndEnvelopedData" }, /* 109 */
+ { 0x05, 111, 0, 8, "digestedData" }, /* 110 */
+ { 0x06, 0, 0, 8, "encryptedData" }, /* 111 */
+ { 0x09, 0, 1, 7, "PKCS-9" }, /* 112 */
+ { 0x01, 114, 0, 8, "E" }, /* 113 */
+ { 0x02, 115, 0, 8, "unstructuredName" }, /* 114 */
+ { 0x03, 116, 0, 8, "contentType" }, /* 115 */
+ { 0x04, 117, 0, 8, "messageDigest" }, /* 116 */
+ { 0x05, 118, 0, 8, "signingTime" }, /* 117 */
+ { 0x06, 119, 0, 8, "counterSignature" }, /* 118 */
+ { 0x07, 120, 0, 8, "challengePassword" }, /* 119 */
+ { 0x08, 121, 0, 8, "unstructuredAddress" }, /* 120 */
+ { 0x0E, 122, 0, 8, "extensionRequest" }, /* 121 */
+ { 0x0F, 0, 0, 8, "S/MIME Capabilities" }, /* 122 */
+ { 0x02, 126, 1, 6, "digestAlgorithm" }, /* 123 */
+ { 0x02, 125, 0, 7, "md2" }, /* 124 */
+ { 0x05, 0, 0, 7, "md5" }, /* 125 */
+ { 0x03, 0, 1, 6, "encryptionAlgorithm" }, /* 126 */
+ { 0x07, 0, 0, 7, "3des-ede-cbc" }, /* 127 */
+ { 0xCE, 0, 1, 3, "" }, /* 128 */
+ { 0x3D, 0, 1, 4, "ansi-X9-62" }, /* 129 */
+ { 0x02, 132, 1, 5, "id-publicKeyType" }, /* 130 */
+ { 0x01, 0, 0, 6, "id-ecPublicKey" }, /* 131 */
+ { 0x03, 162, 1, 5, "ellipticCurve" }, /* 132 */
+ { 0x00, 154, 1, 6, "c-TwoCurve" }, /* 133 */
+ { 0x01, 135, 0, 7, "c2pnb163v1" }, /* 134 */
+ { 0x02, 136, 0, 7, "c2pnb163v2" }, /* 135 */
+ { 0x03, 137, 0, 7, "c2pnb163v3" }, /* 136 */
+ { 0x04, 138, 0, 7, "c2pnb176w1" }, /* 137 */
+ { 0x05, 139, 0, 7, "c2tnb191v1" }, /* 138 */
+ { 0x06, 140, 0, 7, "c2tnb191v2" }, /* 139 */
+ { 0x07, 141, 0, 7, "c2tnb191v3" }, /* 140 */
+ { 0x08, 142, 0, 7, "c2onb191v4" }, /* 141 */
+ { 0x09, 143, 0, 7, "c2onb191v5" }, /* 142 */
+ { 0x0A, 144, 0, 7, "c2pnb208w1" }, /* 143 */
+ { 0x0B, 145, 0, 7, "c2tnb239v1" }, /* 144 */
+ { 0x0C, 146, 0, 7, "c2tnb239v2" }, /* 145 */
+ { 0x0D, 147, 0, 7, "c2tnb239v3" }, /* 146 */
+ { 0x0E, 148, 0, 7, "c2onb239v4" }, /* 147 */
+ { 0x0F, 149, 0, 7, "c2onb239v5" }, /* 148 */
+ { 0x10, 150, 0, 7, "c2pnb272w1" }, /* 149 */
+ { 0x11, 151, 0, 7, "c2pnb304w1" }, /* 150 */
+ { 0x12, 152, 0, 7, "c2tnb359v1" }, /* 151 */
+ { 0x13, 153, 0, 7, "c2pnb368w1" }, /* 152 */
+ { 0x14, 0, 0, 7, "c2tnb431r1" }, /* 153 */
+ { 0x01, 0, 1, 6, "primeCurve" }, /* 154 */
+ { 0x01, 156, 0, 7, "prime192v1" }, /* 155 */
+ { 0x02, 157, 0, 7, "prime192v2" }, /* 156 */
+ { 0x03, 158, 0, 7, "prime192v3" }, /* 157 */
+ { 0x04, 159, 0, 7, "prime239v1" }, /* 158 */
+ { 0x05, 160, 0, 7, "prime239v2" }, /* 159 */
+ { 0x06, 161, 0, 7, "prime239v3" }, /* 160 */
+ { 0x07, 0, 0, 7, "prime256v1" }, /* 161 */
+ { 0x04, 0, 1, 5, "id-ecSigType" }, /* 162 */
+ { 0x01, 164, 0, 6, "ecdsa-with-SHA1" }, /* 163 */
+ { 0x03, 0, 1, 6, "ecdsa-with-Specified" }, /* 164 */
+ { 0x01, 166, 0, 7, "ecdsa-with-SHA224" }, /* 165 */
+ { 0x02, 167, 0, 7, "ecdsa-with-SHA256" }, /* 166 */
+ { 0x03, 168, 0, 7, "ecdsa-with-SHA384" }, /* 167 */
+ { 0x04, 0, 0, 7, "ecdsa-with-SHA512" }, /* 168 */
+ {0x2B, 323, 1, 0, "" }, /* 169 */
+ { 0x06, 237, 1, 1, "dod" }, /* 170 */
+ { 0x01, 0, 1, 2, "internet" }, /* 171 */
+ { 0x04, 194, 1, 3, "private" }, /* 172 */
+ { 0x01, 0, 1, 4, "enterprise" }, /* 173 */
+ { 0x82, 187, 1, 5, "" }, /* 174 */
+ { 0x37, 184, 1, 6, "Microsoft" }, /* 175 */
+ { 0x0A, 180, 1, 7, "" }, /* 176 */
+ { 0x03, 0, 1, 8, "" }, /* 177 */
+ { 0x03, 179, 0, 9, "msSGC" }, /* 178 */
+ { 0x04, 0, 0, 9, "msEncryptingFileSystem" }, /* 179 */
+ { 0x14, 0, 1, 7, "msEnrollmentInfrastructure"}, /* 180 */
+ { 0x02, 0, 1, 8, "msCertificateTypeExtension"}, /* 181 */
+ { 0x02, 183, 0, 9, "msSmartcardLogon" }, /* 182 */
+ { 0x03, 0, 0, 9, "msUPN" }, /* 183 */
+ { 0xA0, 0, 1, 6, "" }, /* 184 */
+ { 0x2A, 0, 1, 7, "ITA" }, /* 185 */
+ { 0x01, 0, 0, 8, "strongSwan" }, /* 186 */
+ { 0x89, 0, 1, 5, "" }, /* 187 */
+ { 0x31, 0, 1, 6, "" }, /* 188 */
+ { 0x01, 0, 1, 7, "" }, /* 189 */
+ { 0x01, 0, 1, 8, "" }, /* 190 */
+ { 0x02, 0, 1, 9, "" }, /* 191 */
+ { 0x02, 0, 1, 10, "" }, /* 192 */
+ { 0x4B, 0, 0, 11, "TCGID" }, /* 193 */
+ { 0x05, 0, 1, 3, "security" }, /* 194 */
+ { 0x05, 0, 1, 4, "mechanisms" }, /* 195 */
+ { 0x07, 234, 1, 5, "id-pkix" }, /* 196 */
+ { 0x01, 201, 1, 6, "id-pe" }, /* 197 */
+ { 0x01, 199, 0, 7, "authorityInfoAccess" }, /* 198 */
+ { 0x03, 200, 0, 7, "qcStatements" }, /* 199 */
+ { 0x07, 0, 0, 7, "ipAddrBlocks" }, /* 200 */
+ { 0x02, 204, 1, 6, "id-qt" }, /* 201 */
+ { 0x01, 203, 0, 7, "cps" }, /* 202 */
+ { 0x02, 0, 0, 7, "unotice" }, /* 203 */
+ { 0x03, 214, 1, 6, "id-kp" }, /* 204 */
+ { 0x01, 206, 0, 7, "serverAuth" }, /* 205 */
+ { 0x02, 207, 0, 7, "clientAuth" }, /* 206 */
+ { 0x03, 208, 0, 7, "codeSigning" }, /* 207 */
+ { 0x04, 209, 0, 7, "emailProtection" }, /* 208 */
+ { 0x05, 210, 0, 7, "ipsecEndSystem" }, /* 209 */
+ { 0x06, 211, 0, 7, "ipsecTunnel" }, /* 210 */
+ { 0x07, 212, 0, 7, "ipsecUser" }, /* 211 */
+ { 0x08, 213, 0, 7, "timeStamping" }, /* 212 */
+ { 0x09, 0, 0, 7, "ocspSigning" }, /* 213 */
+ { 0x08, 216, 1, 6, "id-otherNames" }, /* 214 */
+ { 0x05, 0, 0, 7, "xmppAddr" }, /* 215 */
+ { 0x0A, 221, 1, 6, "id-aca" }, /* 216 */
+ { 0x01, 218, 0, 7, "authenticationInfo" }, /* 217 */
+ { 0x02, 219, 0, 7, "accessIdentity" }, /* 218 */
+ { 0x03, 220, 0, 7, "chargingIdentity" }, /* 219 */
+ { 0x04, 0, 0, 7, "group" }, /* 220 */
+ { 0x0B, 222, 0, 6, "subjectInfoAccess" }, /* 221 */
+ { 0x30, 0, 1, 6, "id-ad" }, /* 222 */
+ { 0x01, 231, 1, 7, "ocsp" }, /* 223 */
+ { 0x01, 225, 0, 8, "basic" }, /* 224 */
+ { 0x02, 226, 0, 8, "nonce" }, /* 225 */
+ { 0x03, 227, 0, 8, "crl" }, /* 226 */
+ { 0x04, 228, 0, 8, "response" }, /* 227 */
+ { 0x05, 229, 0, 8, "noCheck" }, /* 228 */
+ { 0x06, 230, 0, 8, "archiveCutoff" }, /* 229 */
+ { 0x07, 0, 0, 8, "serviceLocator" }, /* 230 */
+ { 0x02, 232, 0, 7, "caIssuers" }, /* 231 */
+ { 0x03, 233, 0, 7, "timeStamping" }, /* 232 */
+ { 0x05, 0, 0, 7, "caRepository" }, /* 233 */
+ { 0x08, 0, 1, 5, "ipsec" }, /* 234 */
+ { 0x02, 0, 1, 6, "certificate" }, /* 235 */
+ { 0x02, 0, 0, 7, "iKEIntermediate" }, /* 236 */
+ { 0x0E, 243, 1, 1, "oiw" }, /* 237 */
+ { 0x03, 0, 1, 2, "secsig" }, /* 238 */
+ { 0x02, 0, 1, 3, "algorithms" }, /* 239 */
+ { 0x07, 241, 0, 4, "des-cbc" }, /* 240 */
+ { 0x1A, 242, 0, 4, "sha-1" }, /* 241 */
+ { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 242 */
+ { 0x24, 289, 1, 1, "TeleTrusT" }, /* 243 */
+ { 0x03, 0, 1, 2, "algorithm" }, /* 244 */
+ { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 245 */
+ { 0x01, 250, 1, 4, "rsaSignature" }, /* 246 */
+ { 0x02, 248, 0, 5, "rsaSigWithripemd160" }, /* 247 */
+ { 0x03, 249, 0, 5, "rsaSigWithripemd128" }, /* 248 */
+ { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 249 */
+ { 0x02, 0, 1, 4, "ecSign" }, /* 250 */
+ { 0x01, 252, 0, 5, "ecSignWithsha1" }, /* 251 */
+ { 0x02, 253, 0, 5, "ecSignWithripemd160" }, /* 252 */
+ { 0x03, 254, 0, 5, "ecSignWithmd2" }, /* 253 */
+ { 0x04, 255, 0, 5, "ecSignWithmd5" }, /* 254 */
+ { 0x05, 272, 1, 5, "ttt-ecg" }, /* 255 */
+ { 0x01, 260, 1, 6, "fieldType" }, /* 256 */
+ { 0x01, 0, 1, 7, "characteristictwoField" }, /* 257 */
+ { 0x01, 0, 1, 8, "basisType" }, /* 258 */
+ { 0x01, 0, 0, 9, "ipBasis" }, /* 259 */
+ { 0x02, 262, 1, 6, "keyType" }, /* 260 */
+ { 0x01, 0, 0, 7, "ecgPublicKey" }, /* 261 */
+ { 0x03, 263, 0, 6, "curve" }, /* 262 */
+ { 0x04, 270, 1, 6, "signatures" }, /* 263 */
+ { 0x01, 265, 0, 7, "ecgdsa-with-RIPEMD160" }, /* 264 */
+ { 0x02, 266, 0, 7, "ecgdsa-with-SHA1" }, /* 265 */
+ { 0x03, 267, 0, 7, "ecgdsa-with-SHA224" }, /* 266 */
+ { 0x04, 268, 0, 7, "ecgdsa-with-SHA256" }, /* 267 */
+ { 0x05, 269, 0, 7, "ecgdsa-with-SHA384" }, /* 268 */
+ { 0x06, 0, 0, 7, "ecgdsa-with-SHA512" }, /* 269 */
+ { 0x05, 0, 1, 6, "module" }, /* 270 */
+ { 0x01, 0, 0, 7, "1" }, /* 271 */
+ { 0x08, 0, 1, 5, "ecStdCurvesAndGeneration" }, /* 272 */
+ { 0x01, 0, 1, 6, "ellipticCurve" }, /* 273 */
+ { 0x01, 0, 1, 7, "versionOne" }, /* 274 */
+ { 0x01, 276, 0, 8, "brainpoolP160r1" }, /* 275 */
+ { 0x02, 277, 0, 8, "brainpoolP160t1" }, /* 276 */
+ { 0x03, 278, 0, 8, "brainpoolP192r1" }, /* 277 */
+ { 0x04, 279, 0, 8, "brainpoolP192t1" }, /* 278 */
+ { 0x05, 280, 0, 8, "brainpoolP224r1" }, /* 279 */
+ { 0x06, 281, 0, 8, "brainpoolP224t1" }, /* 280 */
+ { 0x07, 282, 0, 8, "brainpoolP256r1" }, /* 281 */
+ { 0x08, 283, 0, 8, "brainpoolP256t1" }, /* 282 */
+ { 0x09, 284, 0, 8, "brainpoolP320r1" }, /* 283 */
+ { 0x0A, 285, 0, 8, "brainpoolP320t1" }, /* 284 */
+ { 0x0B, 286, 0, 8, "brainpoolP384r1" }, /* 285 */
+ { 0x0C, 287, 0, 8, "brainpoolP384t1" }, /* 286 */
+ { 0x0D, 288, 0, 8, "brainpoolP512r1" }, /* 287 */
+ { 0x0E, 0, 0, 8, "brainpoolP512t1" }, /* 288 */
+ { 0x81, 0, 1, 1, "" }, /* 289 */
+ { 0x04, 0, 1, 2, "Certicom" }, /* 290 */
+ { 0x00, 0, 1, 3, "curve" }, /* 291 */
+ { 0x01, 293, 0, 4, "sect163k1" }, /* 292 */
+ { 0x02, 294, 0, 4, "sect163r1" }, /* 293 */
+ { 0x03, 295, 0, 4, "sect239k1" }, /* 294 */
+ { 0x04, 296, 0, 4, "sect113r1" }, /* 295 */
+ { 0x05, 297, 0, 4, "sect113r2" }, /* 296 */
+ { 0x06, 298, 0, 4, "secp112r1" }, /* 297 */
+ { 0x07, 299, 0, 4, "secp112r2" }, /* 298 */
+ { 0x08, 300, 0, 4, "secp160r1" }, /* 299 */
+ { 0x09, 301, 0, 4, "secp160k1" }, /* 300 */
+ { 0x0A, 302, 0, 4, "secp256k1" }, /* 301 */
+ { 0x0F, 303, 0, 4, "sect163r2" }, /* 302 */
+ { 0x10, 304, 0, 4, "sect283k1" }, /* 303 */
+ { 0x11, 305, 0, 4, "sect283r1" }, /* 304 */
+ { 0x16, 306, 0, 4, "sect131r1" }, /* 305 */
+ { 0x17, 307, 0, 4, "sect131r2" }, /* 306 */
+ { 0x18, 308, 0, 4, "sect193r1" }, /* 307 */
+ { 0x19, 309, 0, 4, "sect193r2" }, /* 308 */
+ { 0x1A, 310, 0, 4, "sect233k1" }, /* 309 */
+ { 0x1B, 311, 0, 4, "sect233r1" }, /* 310 */
+ { 0x1C, 312, 0, 4, "secp128r1" }, /* 311 */
+ { 0x1D, 313, 0, 4, "secp128r2" }, /* 312 */
+ { 0x1E, 314, 0, 4, "secp160r2" }, /* 313 */
+ { 0x1F, 315, 0, 4, "secp192k1" }, /* 314 */
+ { 0x20, 316, 0, 4, "secp224k1" }, /* 315 */
+ { 0x21, 317, 0, 4, "secp224r1" }, /* 316 */
+ { 0x22, 318, 0, 4, "secp384r1" }, /* 317 */
+ { 0x23, 319, 0, 4, "secp521r1" }, /* 318 */
+ { 0x24, 320, 0, 4, "sect409k1" }, /* 319 */
+ { 0x25, 321, 0, 4, "sect409r1" }, /* 320 */
+ { 0x26, 322, 0, 4, "sect571k1" }, /* 321 */
+ { 0x27, 0, 0, 4, "sect571r1" }, /* 322 */
+ {0x60, 369, 1, 0, "" }, /* 323 */
+ { 0x86, 0, 1, 1, "" }, /* 324 */
+ { 0x48, 0, 1, 2, "" }, /* 325 */
+ { 0x01, 0, 1, 3, "organization" }, /* 326 */
+ { 0x65, 345, 1, 4, "gov" }, /* 327 */
+ { 0x03, 0, 1, 5, "csor" }, /* 328 */
+ { 0x04, 0, 1, 6, "nistalgorithm" }, /* 329 */
+ { 0x01, 340, 1, 7, "aes" }, /* 330 */
+ { 0x02, 332, 0, 8, "id-aes128-CBC" }, /* 331 */
+ { 0x06, 333, 0, 8, "id-aes128-GCM" }, /* 332 */
+ { 0x07, 334, 0, 8, "id-aes128-CCM" }, /* 333 */
+ { 0x16, 335, 0, 8, "id-aes192-CBC" }, /* 334 */
+ { 0x1A, 336, 0, 8, "id-aes192-GCM" }, /* 335 */
+ { 0x1B, 337, 0, 8, "id-aes192-CCM" }, /* 336 */
+ { 0x2A, 338, 0, 8, "id-aes256-CBC" }, /* 337 */
+ { 0x2E, 339, 0, 8, "id-aes256-GCM" }, /* 338 */
+ { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 339 */
+ { 0x02, 0, 1, 7, "hashalgs" }, /* 340 */
+ { 0x01, 342, 0, 8, "id-SHA-256" }, /* 341 */
+ { 0x02, 343, 0, 8, "id-SHA-384" }, /* 342 */
+ { 0x03, 344, 0, 8, "id-SHA-512" }, /* 343 */
+ { 0x04, 0, 0, 8, "id-SHA-224" }, /* 344 */
+ { 0x86, 0, 1, 4, "" }, /* 345 */
+ { 0xf8, 0, 1, 5, "" }, /* 346 */
+ { 0x42, 359, 1, 6, "netscape" }, /* 347 */
+ { 0x01, 354, 1, 7, "" }, /* 348 */
+ { 0x01, 350, 0, 8, "nsCertType" }, /* 349 */
+ { 0x03, 351, 0, 8, "nsRevocationUrl" }, /* 350 */
+ { 0x04, 352, 0, 8, "nsCaRevocationUrl" }, /* 351 */
+ { 0x08, 353, 0, 8, "nsCaPolicyUrl" }, /* 352 */
+ { 0x0d, 0, 0, 8, "nsComment" }, /* 353 */
+ { 0x03, 357, 1, 7, "directory" }, /* 354 */
+ { 0x01, 0, 1, 8, "" }, /* 355 */
+ { 0x03, 0, 0, 9, "employeeNumber" }, /* 356 */
+ { 0x04, 0, 1, 7, "policy" }, /* 357 */
+ { 0x01, 0, 0, 8, "nsSGC" }, /* 358 */
+ { 0x45, 0, 1, 6, "verisign" }, /* 359 */
+ { 0x01, 0, 1, 7, "pki" }, /* 360 */
+ { 0x09, 0, 1, 8, "attributes" }, /* 361 */
+ { 0x02, 363, 0, 9, "messageType" }, /* 362 */
+ { 0x03, 364, 0, 9, "pkiStatus" }, /* 363 */
+ { 0x04, 365, 0, 9, "failInfo" }, /* 364 */
+ { 0x05, 366, 0, 9, "senderNonce" }, /* 365 */
+ { 0x06, 367, 0, 9, "recipientNonce" }, /* 366 */
+ { 0x07, 368, 0, 9, "transID" }, /* 367 */
+ { 0x08, 0, 0, 9, "extensionReq" }, /* 368 */
+ {0x67, 0, 1, 0, "" }, /* 369 */
+ { 0x81, 0, 1, 1, "" }, /* 370 */
+ { 0x05, 0, 1, 2, "" }, /* 371 */
+ { 0x02, 0, 1, 3, "tcg-attribute" }, /* 372 */
+ { 0x01, 374, 0, 4, "tcg-at-tpmManufacturer" }, /* 373 */
+ { 0x02, 375, 0, 4, "tcg-at-tpmModel" }, /* 374 */
+ { 0x03, 376, 0, 4, "tcg-at-tpmVersion" }, /* 375 */
+ { 0x0F, 0, 0, 4, "tcg-at-tpmIdLabel" } /* 376 */
+};
diff --git a/lib/asn1/oid.h b/lib/asn1/oid.h
new file mode 100644
index 0000000..5e30a36
--- /dev/null
+++ b/lib/asn1/oid.h
@@ -0,0 +1,226 @@
+/* Object identifiers (OIDs) used by strongSwan
+ * Copyright (C) 2003-2008 Andreas Steffen, Hochschule fuer Technik Rapperswil
+ *
+ * This file has been automatically generated by the script oid.pl
+ * Do not edit manually!
+ */
+
+#include <sys/types.h>
+
+#ifndef OID_H_
+#define OID_H_
+
+typedef struct {
+ u_char octet;
+ u_int next;
+ u_int down;
+ u_int level;
+ const u_char *name;
+} oid_t;
+
+extern const oid_t oid_names[];
+
+#define OID_UNKNOWN -1
+#define OID_NAME_DISTINGUISHER 6
+#define OID_PILOT_USERID 16
+#define OID_PILOT_DOMAIN_COMPONENT 17
+#define OID_COMMON_NAME 20
+#define OID_SURNAME 21
+#define OID_SERIAL_NUMBER 22
+#define OID_COUNTRY 23
+#define OID_LOCALITY 24
+#define OID_STATE_OR_PROVINCE 25
+#define OID_ORGANIZATION 26
+#define OID_ORGANIZATION_UNIT 27
+#define OID_TITLE 28
+#define OID_DESCRIPTION 29
+#define OID_USER_CERTIFICATE 30
+#define OID_NAME 31
+#define OID_GIVEN_NAME 32
+#define OID_INITIALS 33
+#define OID_UNIQUE_IDENTIFIER 34
+#define OID_DN_QUALIFIER 35
+#define OID_ROLE 36
+#define OID_SUBJECT_KEY_ID 39
+#define OID_KEY_USAGE 40
+#define OID_SUBJECT_ALT_NAME 42
+#define OID_BASIC_CONSTRAINTS 44
+#define OID_CRL_NUMBER 45
+#define OID_CRL_REASON_CODE 46
+#define OID_DELTA_CRL_INDICATOR 49
+#define OID_NAME_CONSTRAINTS 52
+#define OID_CRL_DISTRIBUTION_POINTS 53
+#define OID_CERTIFICATE_POLICIES 54
+#define OID_ANY_POLICY 55
+#define OID_POLICY_MAPPINGS 56
+#define OID_AUTHORITY_KEY_ID 57
+#define OID_POLICY_CONSTRAINTS 58
+#define OID_EXTENDED_KEY_USAGE 59
+#define OID_FRESHEST_CRL 61
+#define OID_INHIBIT_ANY_POLICY 62
+#define OID_TARGET_INFORMATION 63
+#define OID_NO_REV_AVAIL 64
+#define OID_CAMELLIA128_CBC 75
+#define OID_CAMELLIA192_CBC 76
+#define OID_CAMELLIA256_CBC 77
+#define OID_RSA_ENCRYPTION 90
+#define OID_MD2_WITH_RSA 91
+#define OID_MD5_WITH_RSA 92
+#define OID_SHA1_WITH_RSA 93
+#define OID_RSAES_OAEP 94
+#define OID_SHA256_WITH_RSA 96
+#define OID_SHA384_WITH_RSA 97
+#define OID_SHA512_WITH_RSA 98
+#define OID_SHA224_WITH_RSA 99
+#define OID_PBE_MD5_DES_CBC 101
+#define OID_PBE_SHA1_DES_CBC 102
+#define OID_PBKDF2 103
+#define OID_PBES2 104
+#define OID_PKCS7_DATA 106
+#define OID_PKCS7_SIGNED_DATA 107
+#define OID_PKCS7_ENVELOPED_DATA 108
+#define OID_PKCS7_SIGNED_ENVELOPED_DATA 109
+#define OID_PKCS7_DIGESTED_DATA 110
+#define OID_PKCS7_ENCRYPTED_DATA 111
+#define OID_EMAIL_ADDRESS 113
+#define OID_UNSTRUCTURED_NAME 114
+#define OID_PKCS9_CONTENT_TYPE 115
+#define OID_PKCS9_MESSAGE_DIGEST 116
+#define OID_PKCS9_SIGNING_TIME 117
+#define OID_CHALLENGE_PASSWORD 119
+#define OID_UNSTRUCTURED_ADDRESS 120
+#define OID_EXTENSION_REQUEST 121
+#define OID_MD2 124
+#define OID_MD5 125
+#define OID_3DES_EDE_CBC 127
+#define OID_EC_PUBLICKEY 131
+#define OID_C2PNB163V1 134
+#define OID_C2PNB163V2 135
+#define OID_C2PNB163V3 136
+#define OID_C2PNB176W1 137
+#define OID_C2PNB191V1 138
+#define OID_C2PNB191V2 139
+#define OID_C2PNB191V3 140
+#define OID_C2PNB191V4 141
+#define OID_C2PNB191V5 142
+#define OID_C2PNB208W1 143
+#define OID_C2PNB239V1 144
+#define OID_C2PNB239V2 145
+#define OID_C2PNB239V3 146
+#define OID_C2PNB239V4 147
+#define OID_C2PNB239V5 148
+#define OID_C2PNB272W1 149
+#define OID_C2PNB304W1 150
+#define OID_C2PNB359V1 151
+#define OID_C2PNB368W1 152
+#define OID_C2PNB431R1 153
+#define OID_PRIME192V1 155
+#define OID_PRIME192V2 156
+#define OID_PRIME192V3 157
+#define OID_PRIME239V1 158
+#define OID_PRIME239V2 159
+#define OID_PRIME239V3 160
+#define OID_PRIME256V1 161
+#define OID_ECDSA_WITH_SHA1 163
+#define OID_ECDSA_WITH_SHA224 165
+#define OID_ECDSA_WITH_SHA256 166
+#define OID_ECDSA_WITH_SHA384 167
+#define OID_ECDSA_WITH_SHA512 168
+#define OID_USER_PRINCIPAL_NAME 183
+#define OID_STRONGSWAN 186
+#define OID_TCGID 193
+#define OID_AUTHORITY_INFO_ACCESS 198
+#define OID_IP_ADDR_BLOCKS 200
+#define OID_POLICY_QUALIFIER_CPS 202
+#define OID_POLICY_QUALIFIER_UNOTICE 203
+#define OID_SERVER_AUTH 205
+#define OID_CLIENT_AUTH 206
+#define OID_OCSP_SIGNING 213
+#define OID_XMPP_ADDR 215
+#define OID_AUTHENTICATION_INFO 217
+#define OID_ACCESS_IDENTITY 218
+#define OID_CHARGING_IDENTITY 219
+#define OID_GROUP 220
+#define OID_OCSP 223
+#define OID_BASIC 224
+#define OID_NONCE 225
+#define OID_CRL 226
+#define OID_RESPONSE 227
+#define OID_NO_CHECK 228
+#define OID_ARCHIVE_CUTOFF 229
+#define OID_SERVICE_LOCATOR 230
+#define OID_CA_ISSUERS 231
+#define OID_IKE_INTERMEDIATE 236
+#define OID_DES_CBC 240
+#define OID_SHA1 241
+#define OID_SHA1_WITH_RSA_OIW 242
+#define OID_ECGDSA_PUBKEY 261
+#define OID_ECGDSA_SIG_WITH_RIPEMD160 264
+#define OID_ECGDSA_SIG_WITH_SHA1 265
+#define OID_ECGDSA_SIG_WITH_SHA224 266
+#define OID_ECGDSA_SIG_WITH_SHA256 267
+#define OID_ECGDSA_SIG_WITH_SHA384 268
+#define OID_ECGDSA_SIG_WITH_SHA512 269
+#define OID_SECT163K1 292
+#define OID_SECT163R1 293
+#define OID_SECT239K1 294
+#define OID_SECT113R1 295
+#define OID_SECT113R2 296
+#define OID_SECT112R1 297
+#define OID_SECT112R2 298
+#define OID_SECT160R1 299
+#define OID_SECT160K1 300
+#define OID_SECT256K1 301
+#define OID_SECT163R2 302
+#define OID_SECT283K1 303
+#define OID_SECT283R1 304
+#define OID_SECT131R1 305
+#define OID_SECT131R2 306
+#define OID_SECT193R1 307
+#define OID_SECT193R2 308
+#define OID_SECT233K1 309
+#define OID_SECT233R1 310
+#define OID_SECT128R1 311
+#define OID_SECT128R2 312
+#define OID_SECT160R2 313
+#define OID_SECT192K1 314
+#define OID_SECT224K1 315
+#define OID_SECT224R1 316
+#define OID_SECT384R1 317
+#define OID_SECT521R1 318
+#define OID_SECT409K1 319
+#define OID_SECT409R1 320
+#define OID_SECT571K1 321
+#define OID_SECT571R1 322
+#define OID_AES128_CBC 331
+#define OID_AES128_GCM 332
+#define OID_AES128_CCM 333
+#define OID_AES192_CBC 334
+#define OID_AES192_GCM 335
+#define OID_AES192_CCM 336
+#define OID_AES256_CBC 337
+#define OID_AES256_GCM 338
+#define OID_AES256_CCM 339
+#define OID_SHA256 341
+#define OID_SHA384 342
+#define OID_SHA512 343
+#define OID_SHA224 344
+#define OID_NS_REVOCATION_URL 350
+#define OID_NS_CA_REVOCATION_URL 351
+#define OID_NS_CA_POLICY_URL 352
+#define OID_NS_COMMENT 353
+#define OID_EMPLOYEE_NUMBER 356
+#define OID_PKI_MESSAGE_TYPE 362
+#define OID_PKI_STATUS 363
+#define OID_PKI_FAIL_INFO 364
+#define OID_PKI_SENDER_NONCE 365
+#define OID_PKI_RECIPIENT_NONCE 366
+#define OID_PKI_TRANS_ID 367
+#define OID_TPM_MANUFACTURER 373
+#define OID_TPM_MODEL 374
+#define OID_TPM_VERSION 375
+#define OID_TPM_ID_LABEL 376
+
+#define OID_MAX 377
+
+#endif /* OID_H_ */
diff --git a/lib/asn1/oid.pl b/lib/asn1/oid.pl
new file mode 100644
index 0000000..ed26feb
--- /dev/null
+++ b/lib/asn1/oid.pl
@@ -0,0 +1,134 @@
+#!/usr/bin/perl
+# Generates oid.h and oid.c out of oid.txt
+#
+# Copyright (C) 2003-2008 Andreas Steffen
+# Hochschule fuer Technik Rapperswil
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+$copyright="Copyright (C) 2003-2008 Andreas Steffen, Hochschule fuer Technik Rapperswil";
+$automatic="This file has been automatically generated by the script oid.pl";
+$warning="Do not edit manually!";
+
+print "oid.pl generating oid.h and oid.c\n";
+
+# Generate oid.h
+
+open(OID_H, ">oid.h")
+ or die "could not open 'oid.h': $!";
+
+print OID_H "/* Object identifiers (OIDs) used by strongSwan\n",
+ " * ", $copyright, "\n",
+ " * \n",
+ " * ", $automatic, "\n",
+ " * ", $warning, "\n",
+ " */\n\n",
+ "#include <sys/types.h>\n\n",
+ "#ifndef OID_H_\n",
+ "#define OID_H_\n\n",
+ "typedef struct {\n",
+ " u_char octet;\n",
+ " u_int next;\n",
+ " u_int down;\n",
+ " u_int level;\n",
+ " const u_char *name;\n",
+ "} oid_t;\n",
+ "\n",
+ "extern const oid_t oid_names[];\n",
+ "\n",
+ "#define OID_UNKNOWN -1\n";
+
+# parse oid.txt
+
+open(SRC, "<oid.txt")
+ or die "could not open 'oid.txt': $!";
+
+$counter = 0;
+$max_name = 0;
+$max_order = 0;
+
+while ($line = <SRC>)
+{
+ $line =~ m/( *?)(0x\w{2})\s+(".*?")[ \t]*?([\w_]*?)\Z/;
+
+ @order[$counter] = length($1);
+ @octet[$counter] = $2;
+ @name[$counter] = $3;
+
+ if (length($1) > $max_order)
+ {
+ $max_order = length($1);
+ }
+ if (length($3) > $max_name)
+ {
+ $max_name = length($3);
+ }
+ if (length($4) > 0)
+ {
+ printf OID_H "#define %s%s%d\n", $4, "\t" x ((39-length($4))/4), $counter;
+ }
+ $counter++;
+}
+
+printf OID_H "\n#define OID_MAX%s%d\n", "\t" x 8, $counter;
+
+print OID_H "\n#endif /* OID_H_ */\n";
+
+close SRC;
+close OID_H;
+
+# Generate oid.c
+
+open(OID_C, ">oid.c")
+ or die "could not open 'oid.c': $!";
+
+print OID_C "/* List of some useful object identifiers (OIDs)\n",
+ " * ", $copyright, "\n",
+ " * \n",
+ " * ", $automatic, "\n",
+ " * ", $warning, "\n",
+ " */\n",
+ "\n",
+ "#include <stdlib.h>\n",
+ "\n",
+ "#include \"oid.h\"\n",
+ "\n",
+ "const oid_t oid_names[] = {\n";
+
+for ($c = 0; $c < $counter; $c++)
+{
+ $next = 0;
+
+ for ($d = $c+1; $d < $counter && @order[$d] >= @order[$c]; $d++)
+ {
+ if (@order[$d] == @order[$c])
+ {
+ @next[$c] = $d;
+ last;
+ }
+ }
+
+ printf OID_C " {%s%s,%s%3d, %d, %2d, %s%s}%s /* %3d */\n"
+ ,' ' x @order[$c]
+ , @octet[$c]
+ , ' ' x (1 + $max_order - @order[$c])
+ , @next[$c]
+ , @order[$c+1] > @order[$c]
+ , @order[$c] / 2
+ , @name[$c]
+ , ' ' x ($max_name - length(@name[$c]))
+ , $c != $counter-1 ? "," : " "
+ , $c;
+}
+
+print OID_C "};\n" ;
+close OID_C;
diff --git a/lib/asn1/oid.txt b/lib/asn1/oid.txt
new file mode 100644
index 0000000..51a29eb
--- /dev/null
+++ b/lib/asn1/oid.txt
@@ -0,0 +1,377 @@
+0x02 "ITU-T Administration"
+ 0x82 ""
+ 0x06 "Germany ITU-T member"
+ 0x01 "Deutsche Telekom AG"
+ 0x0A ""
+ 0x07 ""
+ 0x14 "ND" OID_NAME_DISTINGUISHER
+0x09 "data"
+ 0x92 ""
+ 0x26 ""
+ 0x89 ""
+ 0x93 ""
+ 0xF2 ""
+ 0x2C ""
+ 0x64 "pilot"
+ 0x01 "pilotAttributeType"
+ 0x01 "UID" OID_PILOT_USERID
+ 0x19 "DC" OID_PILOT_DOMAIN_COMPONENT
+0x55 "X.500"
+ 0x04 "X.509"
+ 0x03 "CN" OID_COMMON_NAME
+ 0x04 "S" OID_SURNAME
+ 0x05 "SN" OID_SERIAL_NUMBER
+ 0x06 "C" OID_COUNTRY
+ 0x07 "L" OID_LOCALITY
+ 0x08 "ST" OID_STATE_OR_PROVINCE
+ 0x0A "O" OID_ORGANIZATION
+ 0x0B "OU" OID_ORGANIZATION_UNIT
+ 0x0C "T" OID_TITLE
+ 0x0D "D" OID_DESCRIPTION
+ 0x24 "userCertificate" OID_USER_CERTIFICATE
+ 0x29 "N" OID_NAME
+ 0x2A "G" OID_GIVEN_NAME
+ 0x2B "I" OID_INITIALS
+ 0x2D "ID" OID_UNIQUE_IDENTIFIER
+ 0x2E "dnQualifier" OID_DN_QUALIFIER
+ 0x48 "role" OID_ROLE
+ 0x1D "id-ce"
+ 0x09 "subjectDirectoryAttrs"
+ 0x0E "subjectKeyIdentifier" OID_SUBJECT_KEY_ID
+ 0x0F "keyUsage" OID_KEY_USAGE
+ 0x10 "privateKeyUsagePeriod"
+ 0x11 "subjectAltName" OID_SUBJECT_ALT_NAME
+ 0x12 "issuerAltName"
+ 0x13 "basicConstraints" OID_BASIC_CONSTRAINTS
+ 0x14 "crlNumber" OID_CRL_NUMBER
+ 0x15 "reasonCode" OID_CRL_REASON_CODE
+ 0x17 "holdInstructionCode"
+ 0x18 "invalidityDate"
+ 0x1B "deltaCrlIndicator" OID_DELTA_CRL_INDICATOR
+ 0x1C "issuingDistributionPoint"
+ 0x1D "certificateIssuer"
+ 0x1E "nameConstraints" OID_NAME_CONSTRAINTS
+ 0x1F "crlDistributionPoints" OID_CRL_DISTRIBUTION_POINTS
+ 0x20 "certificatePolicies" OID_CERTIFICATE_POLICIES
+ 0x00 "anyPolicy" OID_ANY_POLICY
+ 0x21 "policyMappings" OID_POLICY_MAPPINGS
+ 0x23 "authorityKeyIdentifier" OID_AUTHORITY_KEY_ID
+ 0x24 "policyConstraints" OID_POLICY_CONSTRAINTS
+ 0x25 "extendedKeyUsage" OID_EXTENDED_KEY_USAGE
+ 0x00 "anyExtendedKeyUsage"
+ 0x2E "freshestCRL" OID_FRESHEST_CRL
+ 0x36 "inhibitAnyPolicy" OID_INHIBIT_ANY_POLICY
+ 0x37 "targetInformation" OID_TARGET_INFORMATION
+ 0x38 "noRevAvail" OID_NO_REV_AVAIL
+0x2A ""
+ 0x83 ""
+ 0x08 "jp"
+ 0x8C ""
+ 0x9A ""
+ 0x4B ""
+ 0x3D ""
+ 0x01 "security"
+ 0x01 "algorithm"
+ 0x01 "symm-encryption-alg"
+ 0x02 "camellia128-cbc" OID_CAMELLIA128_CBC
+ 0x03 "camellia192-cbc" OID_CAMELLIA192_CBC
+ 0x04 "camellia256-cbc" OID_CAMELLIA256_CBC
+ 0x86 ""
+ 0x48 "us"
+ 0x86 ""
+ 0xF6 ""
+ 0x7D "NortelNetworks"
+ 0x07 "Entrust"
+ 0x41 "nsn-ce"
+ 0x00 "entrustVersInfo"
+ 0xF7 ""
+ 0x0D "RSADSI"
+ 0x01 "PKCS"
+ 0x01 "PKCS-1"
+ 0x01 "rsaEncryption" OID_RSA_ENCRYPTION
+ 0x02 "md2WithRSAEncryption" OID_MD2_WITH_RSA
+ 0x04 "md5WithRSAEncryption" OID_MD5_WITH_RSA
+ 0x05 "sha-1WithRSAEncryption" OID_SHA1_WITH_RSA
+ 0x07 "id-RSAES-OAEP" OID_RSAES_OAEP
+ 0x09 "id-pSpecified"
+ 0x0B "sha256WithRSAEncryption" OID_SHA256_WITH_RSA
+ 0x0C "sha384WithRSAEncryption" OID_SHA384_WITH_RSA
+ 0x0D "sha512WithRSAEncryption" OID_SHA512_WITH_RSA
+ 0x0E "sha224WithRSAEncryption" OID_SHA224_WITH_RSA
+ 0x05 "PKCS-5"
+ 0x03 "pbeWithMD5AndDES-CBC" OID_PBE_MD5_DES_CBC
+ 0x0A "pbeWithSHA1AndDES-CBC" OID_PBE_SHA1_DES_CBC
+ 0x0C "id-PBKDF2" OID_PBKDF2
+ 0x0D "id-PBES2" OID_PBES2
+ 0x07 "PKCS-7"
+ 0x01 "data" OID_PKCS7_DATA
+ 0x02 "signedData" OID_PKCS7_SIGNED_DATA
+ 0x03 "envelopedData" OID_PKCS7_ENVELOPED_DATA
+ 0x04 "signedAndEnvelopedData" OID_PKCS7_SIGNED_ENVELOPED_DATA
+ 0x05 "digestedData" OID_PKCS7_DIGESTED_DATA
+ 0x06 "encryptedData" OID_PKCS7_ENCRYPTED_DATA
+ 0x09 "PKCS-9"
+ 0x01 "E" OID_EMAIL_ADDRESS
+ 0x02 "unstructuredName" OID_UNSTRUCTURED_NAME
+ 0x03 "contentType" OID_PKCS9_CONTENT_TYPE
+ 0x04 "messageDigest" OID_PKCS9_MESSAGE_DIGEST
+ 0x05 "signingTime" OID_PKCS9_SIGNING_TIME
+ 0x06 "counterSignature"
+ 0x07 "challengePassword" OID_CHALLENGE_PASSWORD
+ 0x08 "unstructuredAddress" OID_UNSTRUCTURED_ADDRESS
+ 0x0E "extensionRequest" OID_EXTENSION_REQUEST
+ 0x0F "S/MIME Capabilities"
+ 0x02 "digestAlgorithm"
+ 0x02 "md2" OID_MD2
+ 0x05 "md5" OID_MD5
+ 0x03 "encryptionAlgorithm"
+ 0x07 "3des-ede-cbc" OID_3DES_EDE_CBC
+ 0xCE ""
+ 0x3D "ansi-X9-62"
+ 0x02 "id-publicKeyType"
+ 0x01 "id-ecPublicKey" OID_EC_PUBLICKEY
+ 0x03 "ellipticCurve"
+ 0x00 "c-TwoCurve"
+ 0x01 "c2pnb163v1" OID_C2PNB163V1
+ 0x02 "c2pnb163v2" OID_C2PNB163V2
+ 0x03 "c2pnb163v3" OID_C2PNB163V3
+ 0x04 "c2pnb176w1" OID_C2PNB176W1
+ 0x05 "c2tnb191v1" OID_C2PNB191V1
+ 0x06 "c2tnb191v2" OID_C2PNB191V2
+ 0x07 "c2tnb191v3" OID_C2PNB191V3
+ 0x08 "c2onb191v4" OID_C2PNB191V4
+ 0x09 "c2onb191v5" OID_C2PNB191V5
+ 0x0A "c2pnb208w1" OID_C2PNB208W1
+ 0x0B "c2tnb239v1" OID_C2PNB239V1
+ 0x0C "c2tnb239v2" OID_C2PNB239V2
+ 0x0D "c2tnb239v3" OID_C2PNB239V3
+ 0x0E "c2onb239v4" OID_C2PNB239V4
+ 0x0F "c2onb239v5" OID_C2PNB239V5
+ 0x10 "c2pnb272w1" OID_C2PNB272W1
+ 0x11 "c2pnb304w1" OID_C2PNB304W1
+ 0x12 "c2tnb359v1" OID_C2PNB359V1
+ 0x13 "c2pnb368w1" OID_C2PNB368W1
+ 0x14 "c2tnb431r1" OID_C2PNB431R1
+ 0x01 "primeCurve"
+ 0x01 "prime192v1" OID_PRIME192V1
+ 0x02 "prime192v2" OID_PRIME192V2
+ 0x03 "prime192v3" OID_PRIME192V3
+ 0x04 "prime239v1" OID_PRIME239V1
+ 0x05 "prime239v2" OID_PRIME239V2
+ 0x06 "prime239v3" OID_PRIME239V3
+ 0x07 "prime256v1" OID_PRIME256V1
+ 0x04 "id-ecSigType"
+ 0x01 "ecdsa-with-SHA1" OID_ECDSA_WITH_SHA1
+ 0x03 "ecdsa-with-Specified"
+ 0x01 "ecdsa-with-SHA224" OID_ECDSA_WITH_SHA224
+ 0x02 "ecdsa-with-SHA256" OID_ECDSA_WITH_SHA256
+ 0x03 "ecdsa-with-SHA384" OID_ECDSA_WITH_SHA384
+ 0x04 "ecdsa-with-SHA512" OID_ECDSA_WITH_SHA512
+0x2B ""
+ 0x06 "dod"
+ 0x01 "internet"
+ 0x04 "private"
+ 0x01 "enterprise"
+ 0x82 ""
+ 0x37 "Microsoft"
+ 0x0A ""
+ 0x03 ""
+ 0x03 "msSGC"
+ 0x04 "msEncryptingFileSystem"
+ 0x14 "msEnrollmentInfrastructure"
+ 0x02 "msCertificateTypeExtension"
+ 0x02 "msSmartcardLogon"
+ 0x03 "msUPN" OID_USER_PRINCIPAL_NAME
+ 0xA0 ""
+ 0x2A "ITA"
+ 0x01 "strongSwan" OID_STRONGSWAN
+ 0x89 ""
+ 0x31 ""
+ 0x01 ""
+ 0x01 ""
+ 0x02 ""
+ 0x02 ""
+ 0x4B "TCGID" OID_TCGID
+ 0x05 "security"
+ 0x05 "mechanisms"
+ 0x07 "id-pkix"
+ 0x01 "id-pe"
+ 0x01 "authorityInfoAccess" OID_AUTHORITY_INFO_ACCESS
+ 0x03 "qcStatements"
+ 0x07 "ipAddrBlocks" OID_IP_ADDR_BLOCKS
+ 0x02 "id-qt"
+ 0x01 "cps" OID_POLICY_QUALIFIER_CPS
+ 0x02 "unotice" OID_POLICY_QUALIFIER_UNOTICE
+ 0x03 "id-kp"
+ 0x01 "serverAuth" OID_SERVER_AUTH
+ 0x02 "clientAuth" OID_CLIENT_AUTH
+ 0x03 "codeSigning"
+ 0x04 "emailProtection"
+ 0x05 "ipsecEndSystem"
+ 0x06 "ipsecTunnel"
+ 0x07 "ipsecUser"
+ 0x08 "timeStamping"
+ 0x09 "ocspSigning" OID_OCSP_SIGNING
+ 0x08 "id-otherNames"
+ 0x05 "xmppAddr" OID_XMPP_ADDR
+ 0x0A "id-aca"
+ 0x01 "authenticationInfo" OID_AUTHENTICATION_INFO
+ 0x02 "accessIdentity" OID_ACCESS_IDENTITY
+ 0x03 "chargingIdentity" OID_CHARGING_IDENTITY
+ 0x04 "group" OID_GROUP
+ 0x0B "subjectInfoAccess"
+ 0x30 "id-ad"
+ 0x01 "ocsp" OID_OCSP
+ 0x01 "basic" OID_BASIC
+ 0x02 "nonce" OID_NONCE
+ 0x03 "crl" OID_CRL
+ 0x04 "response" OID_RESPONSE
+ 0x05 "noCheck" OID_NO_CHECK
+ 0x06 "archiveCutoff" OID_ARCHIVE_CUTOFF
+ 0x07 "serviceLocator" OID_SERVICE_LOCATOR
+ 0x02 "caIssuers" OID_CA_ISSUERS
+ 0x03 "timeStamping"
+ 0x05 "caRepository"
+ 0x08 "ipsec"
+ 0x02 "certificate"
+ 0x02 "iKEIntermediate" OID_IKE_INTERMEDIATE
+ 0x0E "oiw"
+ 0x03 "secsig"
+ 0x02 "algorithms"
+ 0x07 "des-cbc" OID_DES_CBC
+ 0x1A "sha-1" OID_SHA1
+ 0x1D "sha-1WithRSASignature" OID_SHA1_WITH_RSA_OIW
+ 0x24 "TeleTrusT"
+ 0x03 "algorithm"
+ 0x03 "signatureAlgorithm"
+ 0x01 "rsaSignature"
+ 0x02 "rsaSigWithripemd160"
+ 0x03 "rsaSigWithripemd128"
+ 0x04 "rsaSigWithripemd256"
+ 0x02 "ecSign"
+ 0x01 "ecSignWithsha1"
+ 0x02 "ecSignWithripemd160"
+ 0x03 "ecSignWithmd2"
+ 0x04 "ecSignWithmd5"
+ 0x05 "ttt-ecg"
+ 0x01 "fieldType"
+ 0x01 "characteristictwoField"
+ 0x01 "basisType"
+ 0x01 "ipBasis"
+ 0x02 "keyType"
+ 0x01 "ecgPublicKey" OID_ECGDSA_PUBKEY
+ 0x03 "curve"
+ 0x04 "signatures"
+ 0x01 "ecgdsa-with-RIPEMD160" OID_ECGDSA_SIG_WITH_RIPEMD160
+ 0x02 "ecgdsa-with-SHA1" OID_ECGDSA_SIG_WITH_SHA1
+ 0x03 "ecgdsa-with-SHA224" OID_ECGDSA_SIG_WITH_SHA224
+ 0x04 "ecgdsa-with-SHA256" OID_ECGDSA_SIG_WITH_SHA256
+ 0x05 "ecgdsa-with-SHA384" OID_ECGDSA_SIG_WITH_SHA384
+ 0x06 "ecgdsa-with-SHA512" OID_ECGDSA_SIG_WITH_SHA512
+ 0x05 "module"
+ 0x01 "1"
+ 0x08 "ecStdCurvesAndGeneration"
+ 0x01 "ellipticCurve"
+ 0x01 "versionOne"
+ 0x01 "brainpoolP160r1"
+ 0x02 "brainpoolP160t1"
+ 0x03 "brainpoolP192r1"
+ 0x04 "brainpoolP192t1"
+ 0x05 "brainpoolP224r1"
+ 0x06 "brainpoolP224t1"
+ 0x07 "brainpoolP256r1"
+ 0x08 "brainpoolP256t1"
+ 0x09 "brainpoolP320r1"
+ 0x0A "brainpoolP320t1"
+ 0x0B "brainpoolP384r1"
+ 0x0C "brainpoolP384t1"
+ 0x0D "brainpoolP512r1"
+ 0x0E "brainpoolP512t1"
+ 0x81 ""
+ 0x04 "Certicom"
+ 0x00 "curve"
+ 0x01 "sect163k1" OID_SECT163K1
+ 0x02 "sect163r1" OID_SECT163R1
+ 0x03 "sect239k1" OID_SECT239K1
+ 0x04 "sect113r1" OID_SECT113R1
+ 0x05 "sect113r2" OID_SECT113R2
+ 0x06 "secp112r1" OID_SECT112R1
+ 0x07 "secp112r2" OID_SECT112R2
+ 0x08 "secp160r1" OID_SECT160R1
+ 0x09 "secp160k1" OID_SECT160K1
+ 0x0A "secp256k1" OID_SECT256K1
+ 0x0F "sect163r2" OID_SECT163R2
+ 0x10 "sect283k1" OID_SECT283K1
+ 0x11 "sect283r1" OID_SECT283R1
+ 0x16 "sect131r1" OID_SECT131R1
+ 0x17 "sect131r2" OID_SECT131R2
+ 0x18 "sect193r1" OID_SECT193R1
+ 0x19 "sect193r2" OID_SECT193R2
+ 0x1A "sect233k1" OID_SECT233K1
+ 0x1B "sect233r1" OID_SECT233R1
+ 0x1C "secp128r1" OID_SECT128R1
+ 0x1D "secp128r2" OID_SECT128R2
+ 0x1E "secp160r2" OID_SECT160R2
+ 0x1F "secp192k1" OID_SECT192K1
+ 0x20 "secp224k1" OID_SECT224K1
+ 0x21 "secp224r1" OID_SECT224R1
+ 0x22 "secp384r1" OID_SECT384R1
+ 0x23 "secp521r1" OID_SECT521R1
+ 0x24 "sect409k1" OID_SECT409K1
+ 0x25 "sect409r1" OID_SECT409R1
+ 0x26 "sect571k1" OID_SECT571K1
+ 0x27 "sect571r1" OID_SECT571R1
+0x60 ""
+ 0x86 ""
+ 0x48 ""
+ 0x01 "organization"
+ 0x65 "gov"
+ 0x03 "csor"
+ 0x04 "nistalgorithm"
+ 0x01 "aes"
+ 0x02 "id-aes128-CBC" OID_AES128_CBC
+ 0x06 "id-aes128-GCM" OID_AES128_GCM
+ 0x07 "id-aes128-CCM" OID_AES128_CCM
+ 0x16 "id-aes192-CBC" OID_AES192_CBC
+ 0x1A "id-aes192-GCM" OID_AES192_GCM
+ 0x1B "id-aes192-CCM" OID_AES192_CCM
+ 0x2A "id-aes256-CBC" OID_AES256_CBC
+ 0x2E "id-aes256-GCM" OID_AES256_GCM
+ 0x2F "id-aes256-CCM" OID_AES256_CCM
+ 0x02 "hashalgs"
+ 0x01 "id-SHA-256" OID_SHA256
+ 0x02 "id-SHA-384" OID_SHA384
+ 0x03 "id-SHA-512" OID_SHA512
+ 0x04 "id-SHA-224" OID_SHA224
+ 0x86 ""
+ 0xf8 ""
+ 0x42 "netscape"
+ 0x01 ""
+ 0x01 "nsCertType"
+ 0x03 "nsRevocationUrl" OID_NS_REVOCATION_URL
+ 0x04 "nsCaRevocationUrl" OID_NS_CA_REVOCATION_URL
+ 0x08 "nsCaPolicyUrl" OID_NS_CA_POLICY_URL
+ 0x0d "nsComment" OID_NS_COMMENT
+ 0x03 "directory"
+ 0x01 ""
+ 0x03 "employeeNumber" OID_EMPLOYEE_NUMBER
+ 0x04 "policy"
+ 0x01 "nsSGC"
+ 0x45 "verisign"
+ 0x01 "pki"
+ 0x09 "attributes"
+ 0x02 "messageType" OID_PKI_MESSAGE_TYPE
+ 0x03 "pkiStatus" OID_PKI_STATUS
+ 0x04 "failInfo" OID_PKI_FAIL_INFO
+ 0x05 "senderNonce" OID_PKI_SENDER_NONCE
+ 0x06 "recipientNonce" OID_PKI_RECIPIENT_NONCE
+ 0x07 "transID" OID_PKI_TRANS_ID
+ 0x08 "extensionReq"
+0x67 ""
+ 0x81 ""
+ 0x05 ""
+ 0x02 "tcg-attribute"
+ 0x01 "tcg-at-tpmManufacturer" OID_TPM_MANUFACTURER
+ 0x02 "tcg-at-tpmModel" OID_TPM_MODEL
+ 0x03 "tcg-at-tpmVersion" OID_TPM_VERSION
+ 0x0F "tcg-at-tpmIdLabel" OID_TPM_ID_LABEL