- using asn1 pluto stuff now
authorMartin Willi <martin@strongswan.org>
Tue, 18 Apr 2006 07:22:20 +0000 (07:22 -0000)
committerMartin Willi <martin@strongswan.org>
Tue, 18 Apr 2006 07:22:20 +0000 (07:22 -0000)
25 files changed:
Source/lib/asn1-pluto/Makefile.asn1 [deleted file]
Source/lib/asn1-pluto/asn1-pluto.c [deleted file]
Source/lib/asn1-pluto/asn1-pluto.h [deleted file]
Source/lib/asn1-pluto/oid.c [deleted file]
Source/lib/asn1-pluto/oid.h [deleted file]
Source/lib/asn1-pluto/oid.pl [deleted file]
Source/lib/asn1-pluto/oid.txt [deleted file]
Source/lib/asn1-pluto/pem.c [deleted file]
Source/lib/asn1-pluto/pem.h [deleted file]
Source/lib/asn1-pluto/ttodata.c [deleted file]
Source/lib/asn1-pluto/ttodata.h [deleted file]
Source/lib/asn1/Makefile.asn1 [new file with mode: 0644]
Source/lib/asn1/asn1-pluto.c [new file with mode: 0644]
Source/lib/asn1/asn1-pluto.h [new file with mode: 0644]
Source/lib/asn1/oid.c [new file with mode: 0644]
Source/lib/asn1/oid.h [new file with mode: 0644]
Source/lib/asn1/oid.pl [new file with mode: 0644]
Source/lib/asn1/oid.txt [new file with mode: 0644]
Source/lib/asn1/pem.c [new file with mode: 0755]
Source/lib/asn1/pem.h [new file with mode: 0755]
Source/lib/asn1/ttodata.c [new file with mode: 0644]
Source/lib/asn1/ttodata.h [new file with mode: 0644]
Source/lib/crypto/certificate.h
Source/lib/utils/identification.h
Source/lib/utils/leak_detective.c

diff --git a/Source/lib/asn1-pluto/Makefile.asn1 b/Source/lib/asn1-pluto/Makefile.asn1
deleted file mode 100644 (file)
index 44726ff..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2006 Martin Willi
-# 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.
-#
-
-ASN1_DIR= $(LIB_DIR)asn1-pluto/
-
-
-LIB_OBJS+= $(BUILD_DIR)oid.o
-$(BUILD_DIR)oid.o :                                                    $(ASN1_DIR)oid.c $(ASN1_DIR)oid.h
-                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
-LIB_OBJS+= $(BUILD_DIR)asn1-pluto.o
-$(BUILD_DIR)asn1-pluto.o :                                     $(ASN1_DIR)asn1-pluto.c $(ASN1_DIR)asn1-pluto.h
-                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
-LIB_OBJS+= $(BUILD_DIR)pem.o
-$(BUILD_DIR)pem.o :                                                    $(ASN1_DIR)pem.c $(ASN1_DIR)pem.h
-                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
-LIB_OBJS+= $(BUILD_DIR)ttodata.o
-$(BUILD_DIR)ttodata.o :                                                $(ASN1_DIR)ttodata.c $(ASN1_DIR)ttodata.h
-                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
\ No newline at end of file
diff --git a/Source/lib/asn1-pluto/asn1-pluto.c b/Source/lib/asn1-pluto/asn1-pluto.c
deleted file mode 100644 (file)
index 01deb5c..0000000
+++ /dev/null
@@ -1,739 +0,0 @@
-/* Simple ASN.1 parser
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- * Copyright (C) 2006 Martin Will, 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 <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "asn1-pluto.h"
-#include "oid.h"
-
-#include <utils/logger_manager.h>
-
-static logger_t *logger;
-
-/* Names of the months */
-static const char* months[] = {
-       "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-/* some common prefabricated ASN.1 constants */
-static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 };
-static u_char ASN1_INTEGER_1_str[] = { 0x02, 0x01, 0x01 };
-static u_char ASN1_INTEGER_2_str[] = { 0x02, 0x01, 0x02 };
-
-const chunk_t ASN1_INTEGER_0 = chunk_from_buf(ASN1_INTEGER_0_str);
-const chunk_t ASN1_INTEGER_1 = chunk_from_buf(ASN1_INTEGER_1_str);
-const chunk_t ASN1_INTEGER_2 = chunk_from_buf(ASN1_INTEGER_2_str);
-
-/* some popular algorithmIdentifiers */
-
-static u_char ASN1_md5_id_str[] = {
-       0x30, 0x0C,
-       0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05,
-       0x05, 0x00
-};
-
-static u_char ASN1_sha1_id_str[] = {
-       0x30, 0x09,
-       0x06, 0x05, 0x2B, 0x0E,0x03, 0x02, 0x1A,
-       0x05, 0x00
-};
-
-static u_char ASN1_md5WithRSA_id_str[] = {
-       0x30, 0x0D,
-       0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04,
-       0x05, 0x00
-};
-
-static u_char ASN1_sha1WithRSA_id_str[] = {
-       0x30, 0x0D,
-       0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05,
-       0x05, 0x00
-};
-
-static u_char ASN1_rsaEncryption_id_str[] = {
-       0x30, 0x0D,
-       0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
-       0x05, 0x00
-};
-
-const chunk_t ASN1_md5_id = chunk_from_buf(ASN1_md5_id_str);
-const chunk_t ASN1_sha1_id = chunk_from_buf(ASN1_sha1_id_str);
-const chunk_t ASN1_rsaEncryption_id = chunk_from_buf(ASN1_rsaEncryption_id_str);
-const chunk_t ASN1_md5WithRSA_id = chunk_from_buf(ASN1_md5WithRSA_id_str);
-const chunk_t ASN1_sha1WithRSA_id = chunk_from_buf(ASN1_sha1WithRSA_id_str);
-
-/* ASN.1 definiton 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_EOC,               ASN1_RAW  }  /* 2 */
-};
-
-#define ALGORITHM_ID_ALG               1
-#define ALGORITHM_ID_PARAMETERS        2
-#define ALGORITHM_ID_ROOF              3
-
-/*
- * return the ASN.1 encoded algorithm identifier
- */
-chunk_t asn1_algorithmIdentifier(int oid)
-{
-       switch (oid)
-       {
-               case OID_RSA_ENCRYPTION:
-                       return ASN1_rsaEncryption_id;
-               case OID_MD5_WITH_RSA:
-                       return ASN1_md5WithRSA_id;
-               case OID_SHA1_WITH_RSA:
-                       return ASN1_sha1WithRSA_id;
-               case OID_MD5:
-                       return ASN1_md5_id;
-               case OID_SHA1:
-                       return ASN1_sha1_id;
-               default:
-                       return CHUNK_INITIALIZER;
-       }
-}
-
-/*
- * If the oid is listed in the oid_names table then the corresponding
- * position in the oid_names table is returned otherwise -1 is returned
- */
-int 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;
-}
-
-/*
- * Decodes the length in bytes of an ASN.1 object
- */
-u_int asn1_length(chunk_t *blob)
-{
-       u_char n;
-       size_t len;
-       
-       /* advance from tag field on to length field */
-       blob->ptr++;
-       blob->len--;
-       
-       /* read first octet of length field */
-       n = *blob->ptr++;
-       blob->len--;
-       
-       if ((n & 0x80) == 0) 
-       {/* single length octet */
-               return n;
-       }
-       
-       /* composite length, determine number of length octets */
-       n &= 0x7f;
-       
-       if (n > blob->len)
-       {
-               logger->log(logger, ERROR|LEVEL1, "number of length octets is larger than ASN.1 object");
-               return ASN1_INVALID_LENGTH;
-       }
-       
-       if (n > sizeof(len))
-       {
-               logger->log(logger, ERROR|LEVEL1, "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--;
-       }
-       return len;
-}
-
-/*
- * determines if a character string is of type ASN.1 printableString
- */
-bool 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;
-}
-
-/*
- * Display a date either in local or UTC time
- * TODO: Does not seem to be thread save
- */
-char* timetoa(const time_t *time, bool utc)
-{
-       static char buf[30];
-
-       if (*time == 0)
-               sprintf(buf, "--- -- --:--:--%s----", (utc)?" UTC ":" ");
-       else
-       {
-               struct tm *t = (utc)? gmtime(time) : localtime(time);
-               sprintf(buf, "%s %02d %02d:%02d:%02d%s%04d",
-                               months[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
-                               (utc)?" UTC ":" ", t->tm_year + 1900);
-       }
-       return buf;
-}
-
-/*
- * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
- */
-time_t asn1totime(const chunk_t *utctime, asn1_t type)
-{
-       struct tm t;
-       time_t tz_offset;
-       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)
-       {
-               int tz_hour, tz_min;
-       
-               sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min);
-               tz_offset = 3600*tz_hour + 60*tz_min;  /* positive time zone offset */
-       }
-       else if ((eot = memchr(utctime->ptr, '-', utctime->len)) != NULL)
-       {
-               int tz_hour, tz_min;
-       
-               sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min);
-               tz_offset = -3600*tz_hour - 60*tz_min;  /* negative time zone offset */
-       }
-       else
-       {
-               return 0; /* error in time format */
-       }
-       
-       {
-       const char* format = (type == ASN1_UTCTIME)? "%2d%2d%2d%2d%2d":
-                       "%4d%2d%2d%2d%2d";
-       
-       sscanf(utctime->ptr, format, &t.tm_year, &t.tm_mon, &t.tm_mday,
-                  &t.tm_hour, &t.tm_min);
-       }
-       
-       /* is there a seconds field? */
-       if ((eot - utctime->ptr) == ((type == ASN1_UTCTIME)?12:14))
-       {
-               sscanf(eot-2, "%2d", &t.tm_sec);
-       }
-       else
-       {
-               t.tm_sec = 0;
-       }
-       
-       /* representation of year */
-       if (t.tm_year >= 1900)
-       {
-               t.tm_year -= 1900;
-       }
-       else if (t.tm_year >= 100)
-       {
-               return 0;
-       }
-       else if (t.tm_year < 50)
-       {
-               t.tm_year += 100;
-       }
-       
-       /* representation of month 0..11*/
-       t.tm_mon--;
-       
-       /* set daylight saving time to off */
-       t.tm_isdst = 0;
-       
-       /* compensate timezone */
-       
-       return mktime(&t) - timezone - tz_offset;
-}
-
-/*
- * Initializes the internal context of the ASN.1 parser
- */
-void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit)
-{
-       logger = logger_manager->get_logger(logger_manager, ASN1);
-       ctx->blobs[0] = blob;
-       ctx->level0   = level0;
-       ctx->implicit = implicit;
-       memset(ctx->loopAddr, '\0', sizeof(ctx->loopAddr));
-}
-
-/*
- * print the value of an ASN.1 simple object
- */
-static void debug_asn1_simple_object(chunk_t object, asn1_t type)
-{
-       int oid;
-       time_t time;
-       
-       switch (type)
-       {
-               case ASN1_OID:
-                       oid = known_oid(object);
-                       if (oid != OID_UNKNOWN)
-                       {
-                               logger->log(logger, CONTROL|LEVEL1, "  '%s'", oid_names[oid].name);
-                               return;
-                       }
-                       break;
-               case ASN1_UTF8STRING:
-               case ASN1_IA5STRING:
-               case ASN1_PRINTABLESTRING:
-               case ASN1_T61STRING:
-               case ASN1_VISIBLESTRING:
-                       logger->log(logger, CONTROL|LEVEL1, "  '%.*s'", (int)object.len, object.ptr);
-                       return;
-               case ASN1_UTCTIME:
-               case ASN1_GENERALIZEDTIME:
-                       time = asn1totime(&object, type);
-                       logger->log(logger, CONTROL|LEVEL1, "  '%s'", timetoa(&time, TRUE));
-                       return;
-               default:
-                       break;
-       }
-       logger->log_chunk(logger, RAW|LEVEL1, "", object);
-}
-
-/*
- * Parses and extracts the next ASN.1 object
- */
-bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx)
-{
-       asn1Object_t obj = objects[*objectID];
-       chunk_t *blob;
-       chunk_t *blob1;
-       u_char *start_ptr;
-       
-       *object = CHUNK_INITIALIZER;
-       
-       if (obj.flags & ASN1_END)  /* end of loop or option found */
-       {
-               if (ctx->loopAddr[obj.level] && ctx->blobs[obj.level+1].len > 0)
-               {
-                       *objectID = ctx->loopAddr[obj.level]; /* another iteration */
-                       obj = objects[*objectID];
-               }
-               else
-               {
-                       ctx->loopAddr[obj.level] = 0;         /* exit loop or option*/
-                       return TRUE;
-               }
-       }
-       
-       *level = ctx->level0 + obj.level;
-       blob = ctx->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 */
-               logger->log(logger, CONTROL|LEVEL1, "L%d - %s:", *level, obj.name);
-               if (obj.type & ASN1_CONSTRUCTED)
-               {
-                       (*objectID)++ ;  /* skip context-specific tag */
-               }
-               return TRUE;
-       }
-       
-       /* handle ASN.1 options */
-       
-       if ((obj.flags & ASN1_OPT)
-                       && (blob->len == 0 || *start_ptr != obj.type))
-       {
-               /* advance to end of missing option field */
-               do
-                       (*objectID)++;
-               while (!((objects[*objectID].flags & ASN1_END)
-                                               && (objects[*objectID].level == obj.level)));
-               return TRUE;
-       }
-               
-       /* an ASN.1 object must possess at least a tag and length field */
-       
-       if (blob->len < 2)
-       {
-               logger->log(logger, ERROR|LEVEL1, "L%d - %s:  ASN.1 object smaller than 2 octets", 
-                                       *level, obj.name);
-               return FALSE;
-       }
-       
-       blob1->len = asn1_length(blob);
-       
-       if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len)
-       {
-               logger->log(logger, ERROR|LEVEL1, "L%d - %s:  length of ASN.1 object invalid or too large", 
-                                       *level, obj.name);
-               return 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)
-       {
-               logger->log(logger, CONTROL|LEVEL1, "L%d - %s:", *level, obj.name);
-               object->ptr = start_ptr;
-               object->len = (size_t)(blob->ptr - start_ptr);
-               return TRUE;
-       }
-
-       if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0))
-       {
-               logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
-                                       *level, obj.name, obj.type, *start_ptr);
-               logger->log_bytes(logger, RAW|LEVEL1, "", start_ptr, (u_int)(blob->ptr - start_ptr));
-               return FALSE;
-       }
-       
-       logger->log(logger, CONTROL|LEVEL1, "L%d - %s:", ctx->level0+obj.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 */
-                       ctx->loopAddr[obj.level] = *objectID + 1;
-               }
-               else
-               {
-                       /* no items, advance directly to end of loop */
-                       do
-                               (*objectID)++;
-                       while (!((objects[*objectID].flags & ASN1_END)
-                                                          && (objects[*objectID].level == obj.level)));
-                       return TRUE;
-               }
-       }
-
-       if (obj.flags & ASN1_OBJ)
-       {
-               object->ptr = start_ptr;
-               object->len = (size_t)(blob->ptr - start_ptr);
-               logger->log_chunk(logger, RAW|LEVEL1, "", *object);
-       }
-       else if (obj.flags & ASN1_BODY)
-       {
-               *object = *blob1;
-               debug_asn1_simple_object(*object, obj.type);
-       }
-       return TRUE;
-}
-
-/*
- * parse an ASN.1 simple type
- */
-bool parse_asn1_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)
-       {
-               logger->log(logger, ERROR|LEVEL1, "L%d - %s:  ASN.1 object smaller than 2 octets", 
-                                       level, name);
-               return FALSE;
-       }
-       
-       if (*object->ptr != type)
-       {
-               logger->log(logger, ERROR|LEVEL1, "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)
-       {
-               logger->log(logger, ERROR|LEVEL1, "L%d - %s:  length of ASN.1 object invalid or too large",
-                                       level, name);
-               return FALSE;
-       }
-       
-       logger->log(logger, CONTROL|LEVEL1, "L%d - %s:", level, name);
-       debug_asn1_simple_object(*object, type);
-       return TRUE;
-}
-
-/*
- * extracts an algorithmIdentifier
- */
-int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int alg = OID_UNKNOWN;
-       int objectID = 0;
-       
-       asn1_init(&ctx, blob, level0, FALSE);
-       
-       while (objectID < ALGORITHM_ID_ROOF)
-       {
-               if (!extract_object(algorithmIdentifierObjects, &objectID, &object, &level, &ctx))
-                       return OID_UNKNOWN;
-               
-               switch (objectID)
-               {
-                       case ALGORITHM_ID_ALG:
-                               alg = known_oid(object);
-                               break;
-                       case ALGORITHM_ID_PARAMETERS:
-                               if (parameters != NULL)
-                                       *parameters = object;
-                               break;
-                       default:
-                               break;
-               }
-               objectID++;
-       }
-       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 = *blob.ptr;
-       
-       if (tag != ASN1_SEQUENCE && tag != ASN1_SET)
-       {
-               logger->log(logger, ERROR|LEVEL2, "  file content is not binary ASN.1");
-               return FALSE;
-       }
-       len = asn1_length(&blob);
-       if (len != blob.len)
-       {
-               logger->log(logger, ERROR|LEVEL2, "  file size does not match ASN.1 coded length");
-               return FALSE;
-       }
-       return TRUE;
-}
-
-/*
- * codes ASN.1 lengths up to a size of 16'777'215 bytes
- */
-void code_asn1_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* build_asn1_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 */
-       code_asn1_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 = build_asn1_object(&object, tag, content.len);
-       memcpy(pos, content.ptr, content.len); 
-       pos += content.len;
-       
-       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 = build_asn1_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);
-               
-               switch (*mode++)
-               {
-                       case 'm':
-                               memcpy(pos, ch.ptr, ch.len); 
-                               pos += ch.len;
-                               free(ch.ptr);
-                               break;
-                       case 'c':
-                       default:
-                               memcpy(pos, ch.ptr, ch.len); 
-                               pos += ch.len;
-               }
-       }
-       va_end(chunks);
-       
-       return construct;
-}
-
-/*
- * convert a MP integer into a DER coded ASN.1 object
- */
-chunk_t asn1_integer_from_mpz(const mpz_t value)
-{
-       size_t bits = mpz_sizeinbase(value, 2);  /* size in bits */
-       chunk_t n;
-       n.len = 1 + bits / 8;  /* size in bytes */      
-       n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
-       
-       return asn1_wrap(ASN1_INTEGER, "m", n);
-}
-
-/*
- *  convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
- */
-chunk_t timetoasn1(const time_t *time, asn1_t type)
-{
-       int offset;
-       const char *format;
-       char buf[TIMETOA_BUF];
-       chunk_t formatted_time;
-       struct tm *t = gmtime(time);
-       
-       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;
-       }
-       sprintf(buf, 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);
-}
diff --git a/Source/lib/asn1-pluto/asn1-pluto.h b/Source/lib/asn1-pluto/asn1-pluto.h
deleted file mode 100644 (file)
index 3edaa32..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Simple ASN.1 parser
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- * Copyright (C) 2006 Martin Will, 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.
- */
-
-#ifndef _ASN1_H
-#define _ASN1_H
-
-#include <stdarg.h>
-#include <gmp.h>
-
-#include <types.h>
-
-
-/* Defines 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_t;
-
-/* Definition of ASN1 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_INVALID_LENGTH    0xffffffff
-
-/* definition of an ASN.1 object */
-
-typedef struct {
-    u_int   level;
-    const u_char  *name;
-    asn1_t  type;
-    u_char  flags;
-} asn1Object_t;
-
-#define ASN1_MAX_LEVEL 10
-
-typedef struct {
-    bool  implicit;
-    u_int level0;
-    u_int loopAddr[ASN1_MAX_LEVEL+1];
-    chunk_t  blobs[ASN1_MAX_LEVEL+2];
-} asn1_ctx_t;
-
-/* 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 popular algorithmIdentifiers */
-extern const chunk_t ASN1_md5_id;
-extern const chunk_t ASN1_sha1_id;
-extern const chunk_t ASN1_rsaEncryption_id;
-extern const chunk_t ASN1_md5WithRSA_id;
-extern const chunk_t ASN1_sha1WithRSA_id;
-
-#define TIMETOA_BUF 30
-
-extern chunk_t asn1_algorithmIdentifier(int oid);
-extern int known_oid(chunk_t object);
-extern u_int asn1_length(chunk_t *blob);
-extern bool is_printablestring(chunk_t str);
-extern time_t asn1totime(const chunk_t *utctime, asn1_t type);
-extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit);
-extern bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx);
-extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name);
-extern int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters);
-extern bool is_asn1(chunk_t blob);
-
-extern void code_asn1_length(size_t length, chunk_t *code);
-extern u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen);
-extern chunk_t asn1_integer_from_mpz(const mpz_t value);
-extern chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
-extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...);
-extern chunk_t timetoasn1(const time_t *time, asn1_t type);
-
-#endif /* _ASN1_H */
diff --git a/Source/lib/asn1-pluto/oid.c b/Source/lib/asn1-pluto/oid.c
deleted file mode 100644 (file)
index 7b0135d..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/* List of some useful object identifiers (OIDs)
- * Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- * 
- * 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, "ITU-T Administration"   },  /*   0 */
-  {  0x82,                     0, 1, ""                       },  /*   1 */
-  {    0x06,                   0, 1, "Germany ITU-T member"   },  /*   2 */
-  {      0x01,                 0, 1, "Deutsche Telekom AG"    },  /*   3 */
-  {        0x0A,               0, 1, ""                       },  /*   4 */
-  {          0x07,             0, 1, ""                       },  /*   5 */
-  {            0x14,           0, 0, "ND"                     },  /*   6 */
-  {0x09,                      18, 1, "data"                   },  /*   7 */
-  {  0x92,                     0, 1, ""                       },  /*   8 */
-  {    0x26,                   0, 1, ""                       },  /*   9 */
-  {      0x89,                 0, 1, ""                       },  /*  10 */
-  {        0x93,               0, 1, ""                       },  /*  11 */
-  {          0xF2,             0, 1, ""                       },  /*  12 */
-  {            0x2C,           0, 1, ""                       },  /*  13 */
-  {              0x64,         0, 1, "pilot"                  },  /*  14 */
-  {                0x01,       0, 1, "pilotAttributeType"     },  /*  15 */
-  {                  0x01,    17, 0, "UID"                    },  /*  16 */
-  {                  0x19,     0, 0, "DC"                     },  /*  17 */
-  {0x55,                      51, 1, "X.500"                  },  /*  18 */
-  {  0x04,                    36, 1, "X.509"                  },  /*  19 */
-  {    0x03,                  21, 0, "CN"                     },  /*  20 */
-  {    0x04,                  22, 0, "S"                      },  /*  21 */
-  {    0x05,                  23, 0, "SN"                     },  /*  22 */
-  {    0x06,                  24, 0, "C"                      },  /*  23 */
-  {    0x07,                  25, 0, "L"                      },  /*  24 */
-  {    0x08,                  26, 0, "ST"                     },  /*  25 */
-  {    0x0A,                  27, 0, "O"                      },  /*  26 */
-  {    0x0B,                  28, 0, "OU"                     },  /*  27 */
-  {    0x0C,                  29, 0, "T"                      },  /*  28 */
-  {    0x0D,                  30, 0, "D"                      },  /*  29 */
-  {    0x24,                  31, 0, "userCertificate"        },  /*  30 */
-  {    0x29,                  32, 0, "N"                      },  /*  31 */
-  {    0x2A,                  33, 0, "G"                      },  /*  32 */
-  {    0x2B,                  34, 0, "I"                      },  /*  33 */
-  {    0x2D,                  35, 0, "ID"                     },  /*  34 */
-  {    0x48,                   0, 0, "role"                   },  /*  35 */
-  {  0x1D,                     0, 1, "id-ce"                  },  /*  36 */
-  {    0x09,                  38, 0, "subjectDirectoryAttrs"  },  /*  37 */
-  {    0x0E,                  39, 0, "subjectKeyIdentifier"   },  /*  38 */
-  {    0x0F,                  40, 0, "keyUsage"               },  /*  39 */
-  {    0x10,                  41, 0, "privateKeyUsagePeriod"  },  /*  40 */
-  {    0x11,                  42, 0, "subjectAltName"         },  /*  41 */
-  {    0x12,                  43, 0, "issuerAltName"          },  /*  42 */
-  {    0x13,                  44, 0, "basicConstraints"       },  /*  43 */
-  {    0x15,                  45, 0, "reasonCode"             },  /*  44 */
-  {    0x1F,                  46, 0, "crlDistributionPoints"  },  /*  45 */
-  {    0x20,                  47, 0, "certificatePolicies"    },  /*  46 */
-  {    0x23,                  48, 0, "authorityKeyIdentifier" },  /*  47 */
-  {    0x25,                  49, 0, "extendedKeyUsage"       },  /*  48 */
-  {    0x37,                  50, 0, "targetInformation"      },  /*  49 */
-  {    0x38,                   0, 0, "noRevAvail"             },  /*  50 */
-  {0x2A,                      88, 1, ""                       },  /*  51 */
-  {  0x86,                     0, 1, ""                       },  /*  52 */
-  {    0x48,                   0, 1, ""                       },  /*  53 */
-  {      0x86,                 0, 1, ""                       },  /*  54 */
-  {        0xF7,               0, 1, ""                       },  /*  55 */
-  {          0x0D,             0, 1, "RSADSI"                 },  /*  56 */
-  {            0x01,          83, 1, "PKCS"                   },  /*  57 */
-  {              0x01,        66, 1, "PKCS-1"                 },  /*  58 */
-  {                0x01,      60, 0, "rsaEncryption"          },  /*  59 */
-  {                0x02,      61, 0, "md2WithRSAEncryption"   },  /*  60 */
-  {                0x04,      62, 0, "md5WithRSAEncryption"   },  /*  61 */
-  {                0x05,      63, 0, "sha-1WithRSAEncryption" },  /*  62 */
-  {                0x0B,      64, 0, "sha256WithRSAEncryption"},  /*  63 */
-  {                0x0C,      65, 0, "sha384WithRSAEncryption"},  /*  64 */
-  {                0x0D,       0, 0, "sha512WithRSAEncryption"},  /*  65 */
-  {              0x07,        73, 1, "PKCS-7"                 },  /*  66 */
-  {                0x01,      68, 0, "data"                   },  /*  67 */
-  {                0x02,      69, 0, "signedData"             },  /*  68 */
-  {                0x03,      70, 0, "envelopedData"          },  /*  69 */
-  {                0x04,      71, 0, "signedAndEnvelopedData" },  /*  70 */
-  {                0x05,      72, 0, "digestedData"           },  /*  71 */
-  {                0x06,       0, 0, "encryptedData"          },  /*  72 */
-  {              0x09,         0, 1, "PKCS-9"                 },  /*  73 */
-  {                0x01,      75, 0, "E"                      },  /*  74 */
-  {                0x02,      76, 0, "unstructuredName"       },  /*  75 */
-  {                0x03,      77, 0, "contentType"            },  /*  76 */
-  {                0x04,      78, 0, "messageDigest"          },  /*  77 */
-  {                0x05,      79, 0, "signingTime"            },  /*  78 */
-  {                0x06,      80, 0, "counterSignature"       },  /*  79 */
-  {                0x07,      81, 0, "challengePassword"      },  /*  80 */
-  {                0x08,      82, 0, "unstructuredAddress"    },  /*  81 */
-  {                0x0E,       0, 0, "extensionRequest"       },  /*  82 */
-  {            0x02,          86, 1, "digestAlgorithm"        },  /*  83 */
-  {              0x02,        85, 0, "md2"                    },  /*  84 */
-  {              0x05,         0, 0, "md5"                    },  /*  85 */
-  {            0x03,           0, 1, "encryptionAlgorithm"    },  /*  86 */
-  {              0x07,         0, 0, "3des-ede-cbc"           },  /*  87 */
-  {0x2B,                     149, 1, ""                       },  /*  88 */
-  {  0x06,                   136, 1, "dod"                    },  /*  89 */
-  {    0x01,                   0, 1, "internet"               },  /*  90 */
-  {      0x04,               105, 1, "private"                },  /*  91 */
-  {        0x01,               0, 1, "enterprise"             },  /*  92 */
-  {          0x82,            98, 1, ""                       },  /*  93 */
-  {            0x37,           0, 1, "Microsoft"              },  /*  94 */
-  {              0x0A,         0, 1, ""                       },  /*  95 */
-  {                0x03,       0, 1, ""                       },  /*  96 */
-  {                  0x03,     0, 0, "msSGC"                  },  /*  97 */
-  {          0x89,             0, 1, ""                       },  /*  98 */
-  {            0x31,           0, 1, ""                       },  /*  99 */
-  {              0x01,         0, 1, ""                       },  /* 100 */
-  {                0x01,       0, 1, ""                       },  /* 101 */
-  {                  0x02,     0, 1, ""                       },  /* 102 */
-  {                    0x02, 104, 0, ""                       },  /* 103 */
-  {                    0x4B,   0, 0, "TCGID"                  },  /* 104 */
-  {      0x05,                 0, 1, "security"               },  /* 105 */
-  {        0x05,               0, 1, "mechanisms"             },  /* 106 */
-  {          0x07,             0, 1, "id-pkix"                },  /* 107 */
-  {            0x01,         110, 1, "id-pe"                  },  /* 108 */
-  {              0x01,         0, 0, "authorityInfoAccess"    },  /* 109 */
-  {            0x03,         120, 1, "id-kp"                  },  /* 110 */
-  {              0x01,       112, 0, "serverAuth"             },  /* 111 */
-  {              0x02,       113, 0, "clientAuth"             },  /* 112 */
-  {              0x03,       114, 0, "codeSigning"            },  /* 113 */
-  {              0x04,       115, 0, "emailProtection"        },  /* 114 */
-  {              0x05,       116, 0, "ipsecEndSystem"         },  /* 115 */
-  {              0x06,       117, 0, "ipsecTunnel"            },  /* 116 */
-  {              0x07,       118, 0, "ipsecUser"              },  /* 117 */
-  {              0x08,       119, 0, "timeStamping"           },  /* 118 */
-  {              0x09,         0, 0, "ocspSigning"            },  /* 119 */
-  {            0x08,         122, 1, "id-otherNames"          },  /* 120 */
-  {              0x05,         0, 0, "xmppAddr"               },  /* 121 */
-  {            0x0A,         127, 1, "id-aca"                 },  /* 122 */
-  {              0x01,       124, 0, "authenticationInfo"     },  /* 123 */
-  {              0x02,       125, 0, "accessIdentity"         },  /* 124 */
-  {              0x03,       126, 0, "chargingIdentity"       },  /* 125 */
-  {              0x04,         0, 0, "group"                  },  /* 126 */
-  {            0x30,           0, 1, "id-ad"                  },  /* 127 */
-  {              0x01,         0, 1, "ocsp"                   },  /* 128 */
-  {                0x01,     130, 0, "basic"                  },  /* 129 */
-  {                0x02,     131, 0, "nonce"                  },  /* 130 */
-  {                0x03,     132, 0, "crl"                    },  /* 131 */
-  {                0x04,     133, 0, "response"               },  /* 132 */
-  {                0x05,     134, 0, "noCheck"                },  /* 133 */
-  {                0x06,     135, 0, "archiveCutoff"          },  /* 134 */
-  {                0x07,       0, 0, "serviceLocator"         },  /* 135 */
-  {  0x0E,                   142, 1, "oiw"                    },  /* 136 */
-  {    0x03,                   0, 1, "secsig"                 },  /* 137 */
-  {      0x02,                 0, 1, "algorithms"             },  /* 138 */
-  {        0x07,             140, 0, "des-cbc"                },  /* 139 */
-  {        0x1A,             141, 0, "sha-1"                  },  /* 140 */
-  {        0x1D,               0, 0, "sha-1WithRSASignature"  },  /* 141 */
-  {  0x24,                     0, 1, "TeleTrusT"              },  /* 142 */
-  {    0x03,                   0, 1, "algorithm"              },  /* 143 */
-  {      0x03,                 0, 1, "signatureAlgorithm"     },  /* 144 */
-  {        0x01,               0, 1, "rsaSignature"           },  /* 145 */
-  {          0x02,           147, 0, "rsaSigWithripemd160"    },  /* 146 */
-  {          0x03,           148, 0, "rsaSigWithripemd128"    },  /* 147 */
-  {          0x04,             0, 0, "rsaSigWithripemd256"    },  /* 148 */
-  {0x60,                       0, 1, ""                       },  /* 149 */
-  {  0x86,                     0, 1, ""                       },  /* 150 */
-  {    0x48,                   0, 1, ""                       },  /* 151 */
-  {      0x01,                 0, 1, "organization"           },  /* 152 */
-  {        0x65,             160, 1, "gov"                    },  /* 153 */
-  {          0x03,             0, 1, "csor"                   },  /* 154 */
-  {            0x04,           0, 1, "nistalgorithm"          },  /* 155 */
-  {              0x02,         0, 1, "hashalgs"               },  /* 156 */
-  {                0x01,     158, 0, "id-SHA-256"             },  /* 157 */
-  {                0x02,     159, 0, "id-SHA-384"             },  /* 158 */
-  {                0x03,       0, 0, "id-SHA-512"             },  /* 159 */
-  {        0x86,               0, 1, ""                       },  /* 160 */
-  {          0xf8,             0, 1, ""                       },  /* 161 */
-  {            0x42,         171, 1, "netscape"               },  /* 162 */
-  {              0x01,       169, 1, ""                       },  /* 163 */
-  {                0x01,     165, 0, "nsCertType"             },  /* 164 */
-  {                0x03,     166, 0, "nsRevocationUrl"        },  /* 165 */
-  {                0x04,     167, 0, "nsCaRevocationUrl"      },  /* 166 */
-  {                0x08,     168, 0, "nsCaPolicyUrl"          },  /* 167 */
-  {                0x0d,       0, 0, "nsComment"              },  /* 168 */
-  {              0x04,         0, 1, "policy"                 },  /* 169 */
-  {                0x01,       0, 0, "nsSGC"                  },  /* 170 */
-  {            0x45,           0, 1, "verisign"               },  /* 171 */
-  {              0x01,         0, 1, "pki"                    },  /* 172 */
-  {                0x09,       0, 1, "attributes"             },  /* 173 */
-  {                  0x02,   175, 0, "messageType"            },  /* 174 */
-  {                  0x03,   176, 0, "pkiStatus"              },  /* 175 */
-  {                  0x04,   177, 0, "failInfo"               },  /* 176 */
-  {                  0x05,   178, 0, "senderNonce"            },  /* 177 */
-  {                  0x06,   179, 0, "recipientNonce"         },  /* 178 */
-  {                  0x07,   180, 0, "transID"                },  /* 179 */
-  {                  0x08,     0, 0, "extensionReq"           }   /* 180 */
-};
diff --git a/Source/lib/asn1-pluto/oid.h b/Source/lib/asn1-pluto/oid.h
deleted file mode 100644 (file)
index 4096af3..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Object identifiers (OIDs) used by FreeS/WAN
- * Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- * 
- * This file has been automatically generated by the script oid.pl
- * Do not edit manually!
- */
-
-typedef struct {
-    u_char octet;
-    u_int  next;
-    u_int  down;
-    const u_char *name;
-} oid_t;
-
-extern const oid_t oid_names[];
-
-#define OID_UNKNOWN                    -1
-#define OID_ROLE                       35
-#define OID_SUBJECT_KEY_ID             38
-#define OID_SUBJECT_ALT_NAME           41
-#define OID_BASIC_CONSTRAINTS          43
-#define OID_CRL_REASON_CODE            44
-#define OID_CRL_DISTRIBUTION_POINTS    45
-#define OID_AUTHORITY_KEY_ID           47
-#define OID_EXTENDED_KEY_USAGE         48
-#define OID_TARGET_INFORMATION         49
-#define OID_NO_REV_AVAIL               50
-#define OID_RSA_ENCRYPTION             59
-#define OID_MD2_WITH_RSA               60
-#define OID_MD5_WITH_RSA               61
-#define OID_SHA1_WITH_RSA              62
-#define OID_SHA256_WITH_RSA            63
-#define OID_SHA384_WITH_RSA            64
-#define OID_SHA512_WITH_RSA            65
-#define OID_PKCS7_DATA                 67
-#define OID_PKCS7_SIGNED_DATA          68
-#define OID_PKCS7_ENVELOPED_DATA       69
-#define OID_PKCS7_SIGNED_ENVELOPED_DATA        70
-#define OID_PKCS7_DIGESTED_DATA                71
-#define OID_PKCS7_ENCRYPTED_DATA       72
-#define OID_PKCS9_EMAIL                        74
-#define OID_PKCS9_CONTENT_TYPE         76
-#define OID_PKCS9_MESSAGE_DIGEST       77
-#define OID_PKCS9_SIGNING_TIME         78
-#define OID_MD2                                84
-#define OID_MD5                                85
-#define OID_3DES_EDE_CBC               87
-#define OID_AUTHORITY_INFO_ACCESS      109
-#define OID_OCSP_SIGNING               119
-#define OID_XMPP_ADDR                  121
-#define OID_AUTHENTICATION_INFO                123
-#define OID_ACCESS_IDENTITY            124
-#define OID_CHARGING_IDENTITY          125
-#define OID_GROUP                      126
-#define OID_OCSP                       128
-#define OID_BASIC                      129
-#define OID_NONCE                      130
-#define OID_CRL                                131
-#define OID_RESPONSE                   132
-#define OID_NO_CHECK                   133
-#define OID_ARCHIVE_CUTOFF             134
-#define OID_SERVICE_LOCATOR            135
-#define OID_DES_CBC                    139
-#define OID_SHA1                       140
-#define OID_SHA1_WITH_RSA_OIW          141
-#define OID_NS_REVOCATION_URL          165
-#define OID_NS_CA_REVOCATION_URL       166
-#define OID_NS_CA_POLICY_URL           167
-#define OID_NS_COMMENT                 168
-#define OID_PKI_MESSAGE_TYPE           174
-#define OID_PKI_STATUS                 175
-#define OID_PKI_FAIL_INFO              176
-#define OID_PKI_SENDER_NONCE           177
-#define OID_PKI_RECIPIENT_NONCE                178
-#define OID_PKI_TRANS_ID               179
diff --git a/Source/lib/asn1-pluto/oid.pl b/Source/lib/asn1-pluto/oid.pl
deleted file mode 100644 (file)
index 52ac8ea..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/perl
-# Generates oid.h and oid.c out of oid.txt
-# Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur
-#
-# 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-2004 Andreas Steffen, Zuercher Hochschule Winterthur";
-$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 FreeS/WAN\n",
-           " * ", $copyright, "\n",
-           " * \n",
-           " * ", $automatic, "\n",
-           " * ", $warning, "\n",
-           " */\n\n",
-           "typedef struct {\n",
-           "    u_char octet;\n",
-           "    u_int  next;\n",
-           "    u_int  down;\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))/8), $counter;
-    }
-    $counter++;
-}
-
-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, %s%s}%s  /* %3d */\n"
-       ,' '  x @order[$c]
-       , @octet[$c]
-       , ' ' x (1 + $max_order - @order[$c])
-       , @next[$c]
-       , @order[$c+1] > @order[$c]
-       , @name[$c]
-       , ' ' x ($max_name - length(@name[$c]))
-       , $c != $counter-1 ? "," : " "
-       , $c;
-}
-
-print OID_C "};\n" ;
-close OID_C;
diff --git a/Source/lib/asn1-pluto/oid.txt b/Source/lib/asn1-pluto/oid.txt
deleted file mode 100644 (file)
index ad05a12..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-0x02                         "ITU-T Administration"
-  0x82                       ""
-    0x06                     "Germany ITU-T member"
-      0x01                   "Deutsche Telekom AG"
-        0x0A                 ""
-          0x07               ""
-            0x14             "ND"
-0x09                         "data"
-  0x92                       ""
-    0x26                     ""
-      0x89                   ""
-        0x93                 ""
-          0xF2               ""
-            0x2C             ""
-              0x64           "pilot"
-                0x01         "pilotAttributeType"
-                  0x01       "UID"
-                  0x19       "DC"
-0x55                         "X.500"
-  0x04                       "X.509"
-    0x03                     "CN"
-    0x04                     "S"
-    0x05                     "SN"
-    0x06                     "C"
-    0x07                     "L"
-    0x08                     "ST"
-    0x0A                     "O"
-    0x0B                     "OU"
-    0x0C                     "T"
-    0x0D                     "D"
-    0x24                     "userCertificate"
-    0x29                     "N"
-    0x2A                     "G"
-    0x2B                     "I"
-    0x2D                     "ID"
-    0x48                     "role"                    OID_ROLE
-  0x1D                       "id-ce"
-    0x09                     "subjectDirectoryAttrs"
-    0x0E                     "subjectKeyIdentifier"    OID_SUBJECT_KEY_ID
-    0x0F                     "keyUsage"
-    0x10                     "privateKeyUsagePeriod"
-    0x11                     "subjectAltName"          OID_SUBJECT_ALT_NAME
-    0x12                     "issuerAltName"
-    0x13                     "basicConstraints"                OID_BASIC_CONSTRAINTS
-    0x15                     "reasonCode"              OID_CRL_REASON_CODE
-    0x1F                     "crlDistributionPoints"   OID_CRL_DISTRIBUTION_POINTS
-    0x20                     "certificatePolicies"
-    0x23                     "authorityKeyIdentifier"  OID_AUTHORITY_KEY_ID
-    0x25                     "extendedKeyUsage"                OID_EXTENDED_KEY_USAGE
-    0x37                     "targetInformation"       OID_TARGET_INFORMATION
-    0x38                     "noRevAvail"              OID_NO_REV_AVAIL
-0x2A                         ""
-  0x86                       ""
-    0x48                     ""
-      0x86                   ""
-        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
-                0x0B         "sha256WithRSAEncryption" OID_SHA256_WITH_RSA
-                0x0C         "sha384WithRSAEncryption" OID_SHA384_WITH_RSA
-                0x0D         "sha512WithRSAEncryption" OID_SHA512_WITH_RSA
-              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_PKCS9_EMAIL
-                0x02         "unstructuredName"
-                0x03         "contentType"             OID_PKCS9_CONTENT_TYPE
-                0x04         "messageDigest"           OID_PKCS9_MESSAGE_DIGEST
-                0x05         "signingTime"             OID_PKCS9_SIGNING_TIME
-                0x06         "counterSignature"
-                0x07         "challengePassword"
-                0x08         "unstructuredAddress"
-                0x0E         "extensionRequest"
-            0x02             "digestAlgorithm"
-              0x02           "md2"                     OID_MD2
-              0x05           "md5"                     OID_MD5
-            0x03             "encryptionAlgorithm"
-              0x07           "3des-ede-cbc"            OID_3DES_EDE_CBC
-0x2B                         ""
-  0x06                       "dod"
-    0x01                     "internet"
-      0x04                   "private"
-        0x01                 "enterprise"
-          0x82               ""
-            0x37             "Microsoft"
-              0x0A           ""
-                0x03         ""
-                  0x03       "msSGC"
-          0x89               ""
-            0x31             ""
-              0x01           ""
-                0x01         ""
-                  0x02       ""
-                    0x02     ""
-                    0x4B     "TCGID"
-      0x05                   "security"
-        0x05                 "mechanisms"
-          0x07               "id-pkix"
-            0x01             "id-pe"
-              0x01           "authorityInfoAccess"     OID_AUTHORITY_INFO_ACCESS
-            0x03             "id-kp"
-              0x01           "serverAuth"
-              0x02           "clientAuth"
-              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
-            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
-  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"
-0x60                         ""
-  0x86                       ""
-    0x48                     ""
-      0x01                   "organization"
-        0x65                 "gov"
-          0x03               "csor"
-            0x04             "nistalgorithm"
-              0x02           "hashalgs"
-                0x01         "id-SHA-256"
-                0x02         "id-SHA-384"
-                0x03         "id-SHA-512"
-        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
-              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"
diff --git a/Source/lib/asn1-pluto/pem.c b/Source/lib/asn1-pluto/pem.c
deleted file mode 100755 (executable)
index 24c71c6..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * 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 <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-
-#include "pem.h"
-#include "ttodata.h"
-
-#include <crypto/hashers/hasher.h>
-#include <crypto/crypters/crypter.h>
-
-
-/*
- * check the presence of a pattern in a character string
- */
-static bool present(const char* pattern, chunk_t* ch)
-{
-       u_int pattern_len = strlen(pattern);
-
-       if (ch->len >= pattern_len && strncmp(ch->ptr, pattern, pattern_len) == 0)
-       {
-               ch->ptr += pattern_len;
-               ch->len -= pattern_len;
-               return TRUE;
-       }
-       return FALSE;
-}
-
-/*
- * compare string with chunk
- */
-static bool match(const char *pattern, const chunk_t *ch)
-{
-       return ch->len == strlen(pattern) && strncmp(pattern, ch->ptr, ch->len) == 0;
-}
-
-/*
- * find a boundary of the form -----tag name-----
- */
-static bool find_boundary(const char* tag, chunk_t *line)
-{
-       chunk_t name = CHUNK_INITIALIZER;
-
-       if (!present("-----", line))
-               return FALSE;
-       if (!present(tag, line))
-               return FALSE;
-       if (*line->ptr != ' ')
-               return FALSE;
-       line->ptr++;  line->len--;
-       
-       /* extract name */
-       name.ptr = line->ptr;
-       while (line->len > 0)
-       {
-               if (present("-----", line))
-               {
-                       return TRUE;
-               }
-               line->ptr++;  line->len--;  name.len++;
-       }
-       return FALSE;
-}
-
-/*
- * eat whitespace
- */
-static void eat_whitespace(chunk_t *src)
-{
-       while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
-       {
-               src->ptr++;  src->len--;
-       }
-}
-
-/*
- * extracts a token ending with a given termination symbol
- */
-static bool extract_token(chunk_t *token, char termination, chunk_t *src)
-{
-       u_char *eot = memchr(src->ptr, termination, src->len);
-       
-       /* initialize empty token */
-       *token = CHUNK_INITIALIZER;
-       
-       if (eot == NULL) /* termination symbol not found */
-       {
-               return FALSE;
-       }
-       
-       /* extract token */
-       token->ptr = src->ptr;
-       token->len = (u_int)(eot - src->ptr);
-       
-       /* advance src pointer after termination symbol */
-       src->ptr = eot + 1;
-       src->len -= (token->len + 1);
-       
-       return TRUE;
-}
-
-/*
- * extracts a name: value pair from the PEM header
- */
-static bool extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
-{
-       /* extract name */
-       if (!extract_token(name,':', line))
-       {
-               return FALSE;
-       }
-       
-       eat_whitespace(line);
-       
-       /* extract value */
-       *value = *line;
-       return TRUE;
-}
-
-/*
- *  fetches a new line terminated by \n or \r\n
- */
-static bool fetchline(chunk_t *src, chunk_t *line)
-{
-       if (src->len == 0) /* end of src reached */
-               return FALSE;
-
-       if (extract_token(line, '\n', src))
-       {
-               if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
-                       line->len--;  /* remove optional \r */
-       }
-       else /*last line ends without newline */
-       {
-               *line = *src;
-               src->ptr += src->len;
-               src->len = 0;
-       }
-       return TRUE;
-}
-
-/*
- * decrypts a DES-EDE-CBC encrypted data block
- */
-static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase)
-{
-       hasher_t *hasher;
-       crypter_t *crypter;
-       chunk_t hash;
-       chunk_t decrypted;
-       chunk_t pass = {passphrase, strlen(passphrase)};
-       chunk_t key = {alloca(24), 24};
-       u_int8_t padding, *last_padding_pos, *first_padding_pos;
-       
-       /* build key from passphrase and IV */
-       hasher = hasher_create(HASH_MD5);
-       hash.len = hasher->get_block_size(hasher);
-       hash.ptr = alloca(hash.len);
-       hasher->get_hash(hasher, pass, NULL);
-       hasher->get_hash(hasher, *iv, hash.ptr);
-       
-       memcpy(key.ptr, hash.ptr, hash.len);
-       
-       hasher->get_hash(hasher, hash, NULL);
-       hasher->get_hash(hasher, pass, NULL);
-       hasher->get_hash(hasher, *iv, hash.ptr);
-       
-       memcpy(key.ptr + hash.len, hash.ptr, key.len - hash.len);
-       
-       hasher->destroy(hasher);
-       
-       /* decrypt blob */
-       crypter = crypter_create(ENCR_3DES, 0);
-       crypter->set_key(crypter, key);
-       crypter->decrypt(crypter, *blob, *iv, &decrypted);
-       memcpy(blob->ptr, decrypted.ptr, blob->len);
-       chunk_free(&decrypted);
-       
-       /* determine amount of padding */
-       last_padding_pos = blob->ptr + blob->len - 1;
-       padding = *last_padding_pos;
-       first_padding_pos = (padding > blob->len) ? blob->ptr : last_padding_pos - padding;
-
-       /* check the padding pattern */
-       while (--last_padding_pos > first_padding_pos)
-       {
-               if (*last_padding_pos != padding)
-                       return FALSE;
-       }
-       /* remove padding */
-       blob->len -= padding;
-       return TRUE;
-}
-
-/*  Converts a PEM encoded file into its binary form
- *
- *  RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
- *  RFC 934 Message Encapsulation, January 1985
- */
-status_t pemtobin(chunk_t *blob, char *pass)
-{
-       typedef enum {
-               PEM_PRE    = 0,
-               PEM_MSG    = 1,
-               PEM_HEADER = 2,
-               PEM_BODY   = 3,
-               PEM_POST   = 4,
-               PEM_ABORT  = 5
-       } state_t;
-
-       bool encrypted = FALSE;
-
-       state_t state  = PEM_PRE;
-
-       chunk_t src    = *blob;
-       chunk_t dst    = *blob;
-       chunk_t line   = CHUNK_INITIALIZER;
-       chunk_t iv     = CHUNK_INITIALIZER;
-
-       u_char iv_buf[16]; /* MD5 digest size */
-
-       /* zero size of converted blob */
-       dst.len = 0;
-
-       /* zero size of IV */
-       iv.ptr = iv_buf;
-       iv.len = 0;
-
-       while (fetchline(&src, &line))
-       {
-               if (state == PEM_PRE)
-               {
-                       if (find_boundary("BEGIN", &line))
-                       {
-                               state = PEM_MSG;
-                       }
-                       continue;
-               }
-               else
-               {
-                       if (find_boundary("END", &line))
-                       {
-                               state = PEM_POST;
-                               break;
-                       }
-                       if (state == PEM_MSG)
-                       {
-                               state = (memchr(line.ptr, ':', line.len) == NULL) ? PEM_BODY : PEM_HEADER;
-                       }
-                       if (state == PEM_HEADER)
-                       {
-                               chunk_t name  = CHUNK_INITIALIZER;
-                               chunk_t value = CHUNK_INITIALIZER;
-
-                               /* an empty line separates HEADER and BODY */
-                               if (line.len == 0)
-                               {
-                                       state = PEM_BODY;
-                                       continue;
-                               }
-
-                               /* we are looking for a name: value pair */
-                               if (!extract_parameter(&name, &value, &line))
-                                       continue;
-
-                               if (match("Proc-Type", &name) && *value.ptr == '4')
-                                       encrypted = TRUE;
-                               else if (match("DEK-Info", &name))
-                               {
-                                       const char *ugh = NULL;
-                                       size_t len = 0;
-                                       chunk_t dek;
-
-                                       if (!extract_token(&dek, ',', &value))
-                                               dek = value;
-
-                                       /* we support DES-EDE3-CBC encrypted files, only */
-                                       if (!match("DES-EDE3-CBC", &dek))
-                                               return NOT_SUPPORTED;
-
-                                       eat_whitespace(&value);
-                                       ugh = ttodata(value.ptr, value.len, 16, iv.ptr, 16, &len);
-                                       if (ugh)
-                                               return PARSE_ERROR;
-
-                                       iv.len = len;
-                               }
-                       }
-                       else /* state is PEM_BODY */
-                       {
-                               const char *ugh = NULL;
-                               size_t len = 0;
-                               chunk_t data;
-                               
-                               /* remove any trailing whitespace */
-                               if (!extract_token(&data ,' ', &line))
-                               {
-                                       data = line;
-                               }
-                               
-                               ugh = ttodata(data.ptr, data.len, 64, dst.ptr, blob->len - dst.len, &len);
-                               if (ugh)
-                               {
-                                       state = PEM_ABORT;
-                                       break;
-                               }
-                               else
-                               {
-                                       dst.ptr += len;
-                                       dst.len += len;
-                               }
-                       }
-               }
-       }
-       /* set length to size of binary blob */
-       blob->len = dst.len;
-
-       if (state != PEM_POST)
-               return PARSE_ERROR;
-
-       if (encrypted)
-               return pem_decrypt(blob, &iv, pass);
-       else
-               return SUCCESS;
-}
diff --git a/Source/lib/asn1-pluto/pem.h b/Source/lib/asn1-pluto/pem.h
deleted file mode 100755 (executable)
index a4332fd..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2006 Martin Willi
- * 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.
- */
-
-#ifndef PEM_H_
-#define PEM_H_
-
-#include <stdio.h>
-
-#include <types.h>
-
-status_t pemtobin(chunk_t *blob, char *pass);
-
-#endif /*PEM_H_*/
diff --git a/Source/lib/asn1-pluto/ttodata.c b/Source/lib/asn1-pluto/ttodata.c
deleted file mode 100644 (file)
index 5e81499..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * convert from text form of arbitrary data (e.g., keys) to binary
- * Copyright (C) 2000  Henry Spencer.
- * 
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library 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/lgpl.txt>.
- * 
- * This library 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 Library General Public
- * License for more details.
- */
-
-#include "ttodata.h"
-
-#include <string.h>
-#include <ctype.h>
-
-/* converters and misc */
-static int unhex(const char *, char *, size_t);
-static int unb64(const char *, char *, size_t);
-static int untext(const char *, char *, size_t);
-static const char *badch(const char *, int, char *, size_t);
-
-/* internal error codes for converters */
-#define        SHORT   (-2)            /* internal buffer too short */
-#define        BADPAD  (-3)            /* bad base64 padding */
-#define        BADCH0  (-4)            /* invalid character 0 */
-#define        BADCH1  (-5)            /* invalid character 1 */
-#define        BADCH2  (-6)            /* invalid character 2 */
-#define        BADCH3  (-7)            /* invalid character 3 */
-#define        BADOFF(code) (BADCH0-(code))
-
-/*
- - ttodatav - convert text to data, with verbose error reports
- * If some of this looks slightly odd, it's because it has changed
- * repeatedly (from the original atodata()) without a major rewrite.
- */
-const char *                   /* NULL on success, else literal or errp */
-ttodatav(src, srclen, base, dst, dstlen, lenp, errp, errlen, flags)
-const char *src;
-size_t srclen;                 /* 0 means apply strlen() */
-int base;                      /* 0 means figure it out */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-size_t *lenp;                  /* where to record length (NULL is nowhere) */
-char *errp;                    /* error buffer */
-size_t errlen;
-unsigned int flags;
-{
-       size_t ingroup; /* number of input bytes converted at once */
-       char buf[4];            /* output from conversion */
-       int nbytes;             /* size of output */
-       int (*decode)(const char *, char *, size_t);
-       char *stop;
-       int ndone;
-       int i;
-       int underscoreok;
-       int skipSpace = 0;
-
-       if (srclen == 0)
-               srclen = strlen(src);
-       if (dstlen == 0)
-               dst = buf;      /* point it somewhere valid */
-       stop = dst + dstlen;
-
-       if (base == 0) {
-               if (srclen < 2)
-                       return "input too short to be valid";
-               if (*src++ != '0')
-                       return "input does not begin with format prefix";
-               switch (*src++) {
-               case 'x':
-               case 'X':
-                       base = 16;
-                       break;
-               case 's':
-               case 'S':
-                       base = 64;
-                       break;
-               case 't':
-               case 'T':
-                       base = 256;
-                       break;
-               default:
-                       return "unknown format prefix";
-               }
-               srclen -= 2;
-       }
-       switch (base) {
-       case 16:
-               decode = unhex;
-               underscoreok = 1;
-               ingroup = 2;
-               break;
-       case 64:
-               decode = unb64;
-               underscoreok = 0;
-               ingroup = 4;
-               if(flags & TTODATAV_IGNORESPACE) {
-                       skipSpace = 1;
-               }
-               break;
-
-       case 256:
-               decode = untext;
-               ingroup = 1;
-               underscoreok = 0;
-               break;
-       default:
-               return "unknown base";
-       }
-
-       /* proceed */
-       ndone = 0;
-       while (srclen > 0) {
-               char stage[4];  /* staging area for group */
-               size_t sl = 0;
-
-               /* Grab ingroup characters into stage,
-                * squeezing out blanks if we are supposed to ignore them.
-                */
-               for (sl = 0; sl < ingroup; src++, srclen--) {
-                       if (srclen == 0)
-                               return "input ends in mid-byte, perhaps truncated";
-                       else if (!(skipSpace && (*src == ' ' || *src == '\t')))
-                               stage[sl++] = *src;
-               }
-               
-               nbytes = (*decode)(stage, buf, sizeof(buf));
-               switch (nbytes) {
-               case BADCH0:
-               case BADCH1:
-               case BADCH2:
-               case BADCH3:
-                       return badch(stage, nbytes, errp, errlen);
-               case SHORT:
-                       return "internal buffer too short (\"can't happen\")";
-               case BADPAD:
-                       return "bad (non-zero) padding at end of base64 input";
-               }
-               if (nbytes <= 0)
-                       return "unknown internal error";
-               for (i = 0; i < nbytes; i++) {
-                       if (dst < stop)
-                               *dst++ = buf[i];
-                       ndone++;
-               }
-               while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t')){
-                       src++;
-                       srclen--;
-               }
-               if (underscoreok && srclen > 1 && *src == '_') {
-                       /* srclen > 1 means not last character */
-                       src++;
-                       srclen--;
-               }
-       }
-
-       if (ndone == 0)
-               return "no data bytes specified by input";
-       if (lenp != NULL)
-               *lenp = ndone;
-       return NULL;
-}
-
-/*
- - ttodata - convert text to data
- */
-const char *                   /* NULL on success, else literal */
-ttodata(src, srclen, base, dst, dstlen, lenp)
-const char *src;
-size_t srclen;                 /* 0 means apply strlen() */
-int base;                      /* 0 means figure it out */
-char *dst;                     /* need not be valid if dstlen is 0 */
-size_t dstlen;
-size_t *lenp;                  /* where to record length (NULL is nowhere) */
-{
-       return ttodatav(src, srclen, base, dst, dstlen, lenp, (char *)NULL,
-                       (size_t)0, TTODATAV_SPACECOUNTS);
-}
-
-/*
- - atodata - convert ASCII to data
- * backward-compatibility interface
- */
-size_t                         /* 0 for failure, true length for success */
-atodata(src, srclen, dst, dstlen)
-const char *src;
-size_t srclen;
-char *dst;
-size_t dstlen;
-{
-       size_t len;
-       const char *err;
-
-       err = ttodata(src, srclen, 0, dst, dstlen, &len);
-       if (err != NULL)
-               return 0;
-       return len;
-}
-
-/*
- - atobytes - convert ASCII to data bytes
- * another backward-compatibility interface
- */
-const char *
-atobytes(src, srclen, dst, dstlen, lenp)
-const char *src;
-size_t srclen;
-char *dst;
-size_t dstlen;
-size_t *lenp;
-{
-       return ttodata(src, srclen, 0, dst, dstlen, lenp);
-}
-
-/*
- - unhex - convert two ASCII hex digits to byte
- */
-static int             /* number of result bytes, or error code */
-unhex(src, dst, dstlen)
-const char *src;       /* known to be full length */
-char *dst;
-size_t dstlen;         /* not large enough is a failure */
-{
-       char *p;
-       unsigned byte;
-       static char hex[] = "0123456789abcdef";
-
-       if (dstlen < 1)
-               return SHORT;
-       
-       p = strchr(hex, *src);
-       if (p == NULL)
-               p = strchr(hex, tolower(*src));
-       if (p == NULL)
-               return BADCH0;
-       byte = (p - hex) << 4;
-       src++;
-
-       p = strchr(hex, *src);
-       if (p == NULL)
-               p = strchr(hex, tolower(*src));
-       if (p == NULL)
-               return BADCH1;
-       byte |= (p - hex);
-
-       *dst = byte;
-       return 1;
-}
-
-/*
- - unb64 - convert four ASCII base64 digits to three bytes
- * Note that a base64 digit group is padded out with '=' if it represents
- * less than three bytes:  one byte is dd==, two is ddd=, three is dddd.
- */
-static int             /* number of result bytes, or error code */
-unb64(src, dst, dstlen)
-const char *src;       /* known to be full length */
-char *dst;
-size_t dstlen;
-{
-       char *p;
-       unsigned byte1;
-       unsigned byte2;
-       static char base64[] =
-       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-       if (dstlen < 3)
-               return SHORT;
-
-       p = strchr(base64, *src++);
-
-       if (p == NULL)
-               return BADCH0;
-       byte1 = (p - base64) << 2;      /* first six bits */
-
-       p = strchr(base64, *src++);
-       if (p == NULL) {
-               return BADCH1;
-       }
-
-       byte2 = p - base64;             /* next six:  two plus four */
-       *dst++ = byte1 | (byte2 >> 4);
-       byte1 = (byte2 & 0xf) << 4;
-
-       p = strchr(base64, *src++);
-       if (p == NULL) {
-               if (*(src-1) == '=' && *src == '=') {
-                       if (byte1 != 0)         /* bad padding */
-                               return BADPAD;
-                       return 1;
-               }
-               return BADCH2;
-       }
-
-       byte2 = p - base64;             /* next six:  four plus two */
-       *dst++ = byte1 | (byte2 >> 2);
-       byte1 = (byte2 & 0x3) << 6;
-
-       p = strchr(base64, *src++);
-       if (p == NULL) {
-               if (*(src-1) == '=') {
-                       if (byte1 != 0)         /* bad padding */
-                               return BADPAD;
-                       return 2;
-               }
-               return BADCH3;
-       }
-       byte2 = p - base64;             /* last six */
-       *dst++ = byte1 | byte2;
-
-       return 3;
-}
-
-/*
- - untext - convert one ASCII character to byte
- */
-static int             /* number of result bytes, or error code */
-untext(src, dst, dstlen)
-const char *src;       /* known to be full length */
-char *dst;
-size_t dstlen;         /* not large enough is a failure */
-{
-       if (dstlen < 1)
-               return SHORT;
-
-       *dst = *src;
-       return 1;
-}
-
-/*
- - badch - produce a nice complaint about an unknown character
- *
- * If the compiler complains that the array bigenough[] has a negative
- * size, that means the TTODATAV_BUF constant has been set too small.
- */
-static const char *            /* literal or errp */
-badch(src, errcode, errp, errlen)
-const char *src;
-int errcode;
-char *errp;                    /* might be NULL */
-size_t errlen;
-{
-       static const char pre[] = "unknown character (`";
-       static const char suf[] = "') in input";
-       char buf[5];
-#      define  REQD    (sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf))
-       struct sizecheck {
-               char bigenough[TTODATAV_BUF - REQD];    /* see above */
-       };
-       char ch;
-
-       if (errp == NULL || errlen < REQD)
-               return "unknown character in input";
-       strcpy(errp, pre);
-       ch = *(src + BADOFF(errcode));
-       if (isprint(ch)) {
-               buf[0] = ch;
-               buf[1] = '\0';
-       } else {
-               buf[0] = '\\';
-               buf[1] = ((ch & 0700) >> 6) + '0';
-               buf[2] = ((ch & 0070) >> 3) + '0';
-               buf[3] = ((ch & 0007) >> 0) + '0';
-               buf[4] = '\0';
-       }
-       strcat(errp, buf);
-       strcat(errp, suf);
-       return (const char *)errp;
-}
diff --git a/Source/lib/asn1-pluto/ttodata.h b/Source/lib/asn1-pluto/ttodata.h
deleted file mode 100644 (file)
index d57244e..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * convert from text form of arbitrary data (e.g., keys) to binary
- * Copyright (C) 2000  Henry Spencer.
- * 
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library 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/lgpl.txt>.
- * 
- * This library 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 Library General Public
- * License for more details.
- */
-
-#ifndef TTODATA_H_
-#define TTODATA_H_
-
-#include <types.h>
-
-#define        TTODATAV_BUF    40      /* ttodatav's largest non-literal message */
-#define TTODATAV_IGNORESPACE  (1<<1)  /* ignore spaces in base64 encodings*/
-#define TTODATAV_SPACECOUNTS  0       /* do not ignore spaces in base64   */
-
-typedef const char *err_t;     /* error message, or NULL for success */
-
-err_t ttodata(const char *src, size_t srclen, int base, char *buf, size_t buflen, size_t *needed);
-
-
-#endif /* TTODATA_H_ */
diff --git a/Source/lib/asn1/Makefile.asn1 b/Source/lib/asn1/Makefile.asn1
new file mode 100644 (file)
index 0000000..44726ff
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (C) 2006 Martin Willi
+# 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.
+#
+
+ASN1_DIR= $(LIB_DIR)asn1-pluto/
+
+
+LIB_OBJS+= $(BUILD_DIR)oid.o
+$(BUILD_DIR)oid.o :                                                    $(ASN1_DIR)oid.c $(ASN1_DIR)oid.h
+                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
+LIB_OBJS+= $(BUILD_DIR)asn1-pluto.o
+$(BUILD_DIR)asn1-pluto.o :                                     $(ASN1_DIR)asn1-pluto.c $(ASN1_DIR)asn1-pluto.h
+                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
+LIB_OBJS+= $(BUILD_DIR)pem.o
+$(BUILD_DIR)pem.o :                                                    $(ASN1_DIR)pem.c $(ASN1_DIR)pem.h
+                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
+LIB_OBJS+= $(BUILD_DIR)ttodata.o
+$(BUILD_DIR)ttodata.o :                                                $(ASN1_DIR)ttodata.c $(ASN1_DIR)ttodata.h
+                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
\ No newline at end of file
diff --git a/Source/lib/asn1/asn1-pluto.c b/Source/lib/asn1/asn1-pluto.c
new file mode 100644 (file)
index 0000000..01deb5c
--- /dev/null
@@ -0,0 +1,739 @@
+/* Simple ASN.1 parser
+ * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2006 Martin Will, 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 <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "asn1-pluto.h"
+#include "oid.h"
+
+#include <utils/logger_manager.h>
+
+static logger_t *logger;
+
+/* Names of the months */
+static const char* months[] = {
+       "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+/* some common prefabricated ASN.1 constants */
+static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 };
+static u_char ASN1_INTEGER_1_str[] = { 0x02, 0x01, 0x01 };
+static u_char ASN1_INTEGER_2_str[] = { 0x02, 0x01, 0x02 };
+
+const chunk_t ASN1_INTEGER_0 = chunk_from_buf(ASN1_INTEGER_0_str);
+const chunk_t ASN1_INTEGER_1 = chunk_from_buf(ASN1_INTEGER_1_str);
+const chunk_t ASN1_INTEGER_2 = chunk_from_buf(ASN1_INTEGER_2_str);
+
+/* some popular algorithmIdentifiers */
+
+static u_char ASN1_md5_id_str[] = {
+       0x30, 0x0C,
+       0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05,
+       0x05, 0x00
+};
+
+static u_char ASN1_sha1_id_str[] = {
+       0x30, 0x09,
+       0x06, 0x05, 0x2B, 0x0E,0x03, 0x02, 0x1A,
+       0x05, 0x00
+};
+
+static u_char ASN1_md5WithRSA_id_str[] = {
+       0x30, 0x0D,
+       0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04,
+       0x05, 0x00
+};
+
+static u_char ASN1_sha1WithRSA_id_str[] = {
+       0x30, 0x0D,
+       0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05,
+       0x05, 0x00
+};
+
+static u_char ASN1_rsaEncryption_id_str[] = {
+       0x30, 0x0D,
+       0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
+       0x05, 0x00
+};
+
+const chunk_t ASN1_md5_id = chunk_from_buf(ASN1_md5_id_str);
+const chunk_t ASN1_sha1_id = chunk_from_buf(ASN1_sha1_id_str);
+const chunk_t ASN1_rsaEncryption_id = chunk_from_buf(ASN1_rsaEncryption_id_str);
+const chunk_t ASN1_md5WithRSA_id = chunk_from_buf(ASN1_md5WithRSA_id_str);
+const chunk_t ASN1_sha1WithRSA_id = chunk_from_buf(ASN1_sha1WithRSA_id_str);
+
+/* ASN.1 definiton 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_EOC,               ASN1_RAW  }  /* 2 */
+};
+
+#define ALGORITHM_ID_ALG               1
+#define ALGORITHM_ID_PARAMETERS        2
+#define ALGORITHM_ID_ROOF              3
+
+/*
+ * return the ASN.1 encoded algorithm identifier
+ */
+chunk_t asn1_algorithmIdentifier(int oid)
+{
+       switch (oid)
+       {
+               case OID_RSA_ENCRYPTION:
+                       return ASN1_rsaEncryption_id;
+               case OID_MD5_WITH_RSA:
+                       return ASN1_md5WithRSA_id;
+               case OID_SHA1_WITH_RSA:
+                       return ASN1_sha1WithRSA_id;
+               case OID_MD5:
+                       return ASN1_md5_id;
+               case OID_SHA1:
+                       return ASN1_sha1_id;
+               default:
+                       return CHUNK_INITIALIZER;
+       }
+}
+
+/*
+ * If the oid is listed in the oid_names table then the corresponding
+ * position in the oid_names table is returned otherwise -1 is returned
+ */
+int 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;
+}
+
+/*
+ * Decodes the length in bytes of an ASN.1 object
+ */
+u_int asn1_length(chunk_t *blob)
+{
+       u_char n;
+       size_t len;
+       
+       /* advance from tag field on to length field */
+       blob->ptr++;
+       blob->len--;
+       
+       /* read first octet of length field */
+       n = *blob->ptr++;
+       blob->len--;
+       
+       if ((n & 0x80) == 0) 
+       {/* single length octet */
+               return n;
+       }
+       
+       /* composite length, determine number of length octets */
+       n &= 0x7f;
+       
+       if (n > blob->len)
+       {
+               logger->log(logger, ERROR|LEVEL1, "number of length octets is larger than ASN.1 object");
+               return ASN1_INVALID_LENGTH;
+       }
+       
+       if (n > sizeof(len))
+       {
+               logger->log(logger, ERROR|LEVEL1, "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--;
+       }
+       return len;
+}
+
+/*
+ * determines if a character string is of type ASN.1 printableString
+ */
+bool 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;
+}
+
+/*
+ * Display a date either in local or UTC time
+ * TODO: Does not seem to be thread save
+ */
+char* timetoa(const time_t *time, bool utc)
+{
+       static char buf[30];
+
+       if (*time == 0)
+               sprintf(buf, "--- -- --:--:--%s----", (utc)?" UTC ":" ");
+       else
+       {
+               struct tm *t = (utc)? gmtime(time) : localtime(time);
+               sprintf(buf, "%s %02d %02d:%02d:%02d%s%04d",
+                               months[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
+                               (utc)?" UTC ":" ", t->tm_year + 1900);
+       }
+       return buf;
+}
+
+/*
+ * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
+ */
+time_t asn1totime(const chunk_t *utctime, asn1_t type)
+{
+       struct tm t;
+       time_t tz_offset;
+       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)
+       {
+               int tz_hour, tz_min;
+       
+               sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min);
+               tz_offset = 3600*tz_hour + 60*tz_min;  /* positive time zone offset */
+       }
+       else if ((eot = memchr(utctime->ptr, '-', utctime->len)) != NULL)
+       {
+               int tz_hour, tz_min;
+       
+               sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min);
+               tz_offset = -3600*tz_hour - 60*tz_min;  /* negative time zone offset */
+       }
+       else
+       {
+               return 0; /* error in time format */
+       }
+       
+       {
+       const char* format = (type == ASN1_UTCTIME)? "%2d%2d%2d%2d%2d":
+                       "%4d%2d%2d%2d%2d";
+       
+       sscanf(utctime->ptr, format, &t.tm_year, &t.tm_mon, &t.tm_mday,
+                  &t.tm_hour, &t.tm_min);
+       }
+       
+       /* is there a seconds field? */
+       if ((eot - utctime->ptr) == ((type == ASN1_UTCTIME)?12:14))
+       {
+               sscanf(eot-2, "%2d", &t.tm_sec);
+       }
+       else
+       {
+               t.tm_sec = 0;
+       }
+       
+       /* representation of year */
+       if (t.tm_year >= 1900)
+       {
+               t.tm_year -= 1900;
+       }
+       else if (t.tm_year >= 100)
+       {
+               return 0;
+       }
+       else if (t.tm_year < 50)
+       {
+               t.tm_year += 100;
+       }
+       
+       /* representation of month 0..11*/
+       t.tm_mon--;
+       
+       /* set daylight saving time to off */
+       t.tm_isdst = 0;
+       
+       /* compensate timezone */
+       
+       return mktime(&t) - timezone - tz_offset;
+}
+
+/*
+ * Initializes the internal context of the ASN.1 parser
+ */
+void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit)
+{
+       logger = logger_manager->get_logger(logger_manager, ASN1);
+       ctx->blobs[0] = blob;
+       ctx->level0   = level0;
+       ctx->implicit = implicit;
+       memset(ctx->loopAddr, '\0', sizeof(ctx->loopAddr));
+}
+
+/*
+ * print the value of an ASN.1 simple object
+ */
+static void debug_asn1_simple_object(chunk_t object, asn1_t type)
+{
+       int oid;
+       time_t time;
+       
+       switch (type)
+       {
+               case ASN1_OID:
+                       oid = known_oid(object);
+                       if (oid != OID_UNKNOWN)
+                       {
+                               logger->log(logger, CONTROL|LEVEL1, "  '%s'", oid_names[oid].name);
+                               return;
+                       }
+                       break;
+               case ASN1_UTF8STRING:
+               case ASN1_IA5STRING:
+               case ASN1_PRINTABLESTRING:
+               case ASN1_T61STRING:
+               case ASN1_VISIBLESTRING:
+                       logger->log(logger, CONTROL|LEVEL1, "  '%.*s'", (int)object.len, object.ptr);
+                       return;
+               case ASN1_UTCTIME:
+               case ASN1_GENERALIZEDTIME:
+                       time = asn1totime(&object, type);
+                       logger->log(logger, CONTROL|LEVEL1, "  '%s'", timetoa(&time, TRUE));
+                       return;
+               default:
+                       break;
+       }
+       logger->log_chunk(logger, RAW|LEVEL1, "", object);
+}
+
+/*
+ * Parses and extracts the next ASN.1 object
+ */
+bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx)
+{
+       asn1Object_t obj = objects[*objectID];
+       chunk_t *blob;
+       chunk_t *blob1;
+       u_char *start_ptr;
+       
+       *object = CHUNK_INITIALIZER;
+       
+       if (obj.flags & ASN1_END)  /* end of loop or option found */
+       {
+               if (ctx->loopAddr[obj.level] && ctx->blobs[obj.level+1].len > 0)
+               {
+                       *objectID = ctx->loopAddr[obj.level]; /* another iteration */
+                       obj = objects[*objectID];
+               }
+               else
+               {
+                       ctx->loopAddr[obj.level] = 0;         /* exit loop or option*/
+                       return TRUE;
+               }
+       }
+       
+       *level = ctx->level0 + obj.level;
+       blob = ctx->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 */
+               logger->log(logger, CONTROL|LEVEL1, "L%d - %s:", *level, obj.name);
+               if (obj.type & ASN1_CONSTRUCTED)
+               {
+                       (*objectID)++ ;  /* skip context-specific tag */
+               }
+               return TRUE;
+       }
+       
+       /* handle ASN.1 options */
+       
+       if ((obj.flags & ASN1_OPT)
+                       && (blob->len == 0 || *start_ptr != obj.type))
+       {
+               /* advance to end of missing option field */
+               do
+                       (*objectID)++;
+               while (!((objects[*objectID].flags & ASN1_END)
+                                               && (objects[*objectID].level == obj.level)));
+               return TRUE;
+       }
+               
+       /* an ASN.1 object must possess at least a tag and length field */
+       
+       if (blob->len < 2)
+       {
+               logger->log(logger, ERROR|LEVEL1, "L%d - %s:  ASN.1 object smaller than 2 octets", 
+                                       *level, obj.name);
+               return FALSE;
+       }
+       
+       blob1->len = asn1_length(blob);
+       
+       if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len)
+       {
+               logger->log(logger, ERROR|LEVEL1, "L%d - %s:  length of ASN.1 object invalid or too large", 
+                                       *level, obj.name);
+               return 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)
+       {
+               logger->log(logger, CONTROL|LEVEL1, "L%d - %s:", *level, obj.name);
+               object->ptr = start_ptr;
+               object->len = (size_t)(blob->ptr - start_ptr);
+               return TRUE;
+       }
+
+       if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0))
+       {
+               logger->log(logger, ERROR|LEVEL1, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
+                                       *level, obj.name, obj.type, *start_ptr);
+               logger->log_bytes(logger, RAW|LEVEL1, "", start_ptr, (u_int)(blob->ptr - start_ptr));
+               return FALSE;
+       }
+       
+       logger->log(logger, CONTROL|LEVEL1, "L%d - %s:", ctx->level0+obj.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 */
+                       ctx->loopAddr[obj.level] = *objectID + 1;
+               }
+               else
+               {
+                       /* no items, advance directly to end of loop */
+                       do
+                               (*objectID)++;
+                       while (!((objects[*objectID].flags & ASN1_END)
+                                                          && (objects[*objectID].level == obj.level)));
+                       return TRUE;
+               }
+       }
+
+       if (obj.flags & ASN1_OBJ)
+       {
+               object->ptr = start_ptr;
+               object->len = (size_t)(blob->ptr - start_ptr);
+               logger->log_chunk(logger, RAW|LEVEL1, "", *object);
+       }
+       else if (obj.flags & ASN1_BODY)
+       {
+               *object = *blob1;
+               debug_asn1_simple_object(*object, obj.type);
+       }
+       return TRUE;
+}
+
+/*
+ * parse an ASN.1 simple type
+ */
+bool parse_asn1_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)
+       {
+               logger->log(logger, ERROR|LEVEL1, "L%d - %s:  ASN.1 object smaller than 2 octets", 
+                                       level, name);
+               return FALSE;
+       }
+       
+       if (*object->ptr != type)
+       {
+               logger->log(logger, ERROR|LEVEL1, "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)
+       {
+               logger->log(logger, ERROR|LEVEL1, "L%d - %s:  length of ASN.1 object invalid or too large",
+                                       level, name);
+               return FALSE;
+       }
+       
+       logger->log(logger, CONTROL|LEVEL1, "L%d - %s:", level, name);
+       debug_asn1_simple_object(*object, type);
+       return TRUE;
+}
+
+/*
+ * extracts an algorithmIdentifier
+ */
+int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       u_int level;
+       int alg = OID_UNKNOWN;
+       int objectID = 0;
+       
+       asn1_init(&ctx, blob, level0, FALSE);
+       
+       while (objectID < ALGORITHM_ID_ROOF)
+       {
+               if (!extract_object(algorithmIdentifierObjects, &objectID, &object, &level, &ctx))
+                       return OID_UNKNOWN;
+               
+               switch (objectID)
+               {
+                       case ALGORITHM_ID_ALG:
+                               alg = known_oid(object);
+                               break;
+                       case ALGORITHM_ID_PARAMETERS:
+                               if (parameters != NULL)
+                                       *parameters = object;
+                               break;
+                       default:
+                               break;
+               }
+               objectID++;
+       }
+       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 = *blob.ptr;
+       
+       if (tag != ASN1_SEQUENCE && tag != ASN1_SET)
+       {
+               logger->log(logger, ERROR|LEVEL2, "  file content is not binary ASN.1");
+               return FALSE;
+       }
+       len = asn1_length(&blob);
+       if (len != blob.len)
+       {
+               logger->log(logger, ERROR|LEVEL2, "  file size does not match ASN.1 coded length");
+               return FALSE;
+       }
+       return TRUE;
+}
+
+/*
+ * codes ASN.1 lengths up to a size of 16'777'215 bytes
+ */
+void code_asn1_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* build_asn1_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 */
+       code_asn1_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 = build_asn1_object(&object, tag, content.len);
+       memcpy(pos, content.ptr, content.len); 
+       pos += content.len;
+       
+       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 = build_asn1_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);
+               
+               switch (*mode++)
+               {
+                       case 'm':
+                               memcpy(pos, ch.ptr, ch.len); 
+                               pos += ch.len;
+                               free(ch.ptr);
+                               break;
+                       case 'c':
+                       default:
+                               memcpy(pos, ch.ptr, ch.len); 
+                               pos += ch.len;
+               }
+       }
+       va_end(chunks);
+       
+       return construct;
+}
+
+/*
+ * convert a MP integer into a DER coded ASN.1 object
+ */
+chunk_t asn1_integer_from_mpz(const mpz_t value)
+{
+       size_t bits = mpz_sizeinbase(value, 2);  /* size in bits */
+       chunk_t n;
+       n.len = 1 + bits / 8;  /* size in bytes */      
+       n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
+       
+       return asn1_wrap(ASN1_INTEGER, "m", n);
+}
+
+/*
+ *  convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
+ */
+chunk_t timetoasn1(const time_t *time, asn1_t type)
+{
+       int offset;
+       const char *format;
+       char buf[TIMETOA_BUF];
+       chunk_t formatted_time;
+       struct tm *t = gmtime(time);
+       
+       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;
+       }
+       sprintf(buf, 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);
+}
diff --git a/Source/lib/asn1/asn1-pluto.h b/Source/lib/asn1/asn1-pluto.h
new file mode 100644 (file)
index 0000000..3edaa32
--- /dev/null
@@ -0,0 +1,137 @@
+/* Simple ASN.1 parser
+ * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2006 Martin Will, 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.
+ */
+
+#ifndef _ASN1_H
+#define _ASN1_H
+
+#include <stdarg.h>
+#include <gmp.h>
+
+#include <types.h>
+
+
+/* Defines 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_t;
+
+/* Definition of ASN1 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_INVALID_LENGTH    0xffffffff
+
+/* definition of an ASN.1 object */
+
+typedef struct {
+    u_int   level;
+    const u_char  *name;
+    asn1_t  type;
+    u_char  flags;
+} asn1Object_t;
+
+#define ASN1_MAX_LEVEL 10
+
+typedef struct {
+    bool  implicit;
+    u_int level0;
+    u_int loopAddr[ASN1_MAX_LEVEL+1];
+    chunk_t  blobs[ASN1_MAX_LEVEL+2];
+} asn1_ctx_t;
+
+/* 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 popular algorithmIdentifiers */
+extern const chunk_t ASN1_md5_id;
+extern const chunk_t ASN1_sha1_id;
+extern const chunk_t ASN1_rsaEncryption_id;
+extern const chunk_t ASN1_md5WithRSA_id;
+extern const chunk_t ASN1_sha1WithRSA_id;
+
+#define TIMETOA_BUF 30
+
+extern chunk_t asn1_algorithmIdentifier(int oid);
+extern int known_oid(chunk_t object);
+extern u_int asn1_length(chunk_t *blob);
+extern bool is_printablestring(chunk_t str);
+extern time_t asn1totime(const chunk_t *utctime, asn1_t type);
+extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit);
+extern bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx);
+extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name);
+extern int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters);
+extern bool is_asn1(chunk_t blob);
+
+extern void code_asn1_length(size_t length, chunk_t *code);
+extern u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen);
+extern chunk_t asn1_integer_from_mpz(const mpz_t value);
+extern chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
+extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...);
+extern chunk_t timetoasn1(const time_t *time, asn1_t type);
+
+#endif /* _ASN1_H */
diff --git a/Source/lib/asn1/oid.c b/Source/lib/asn1/oid.c
new file mode 100644 (file)
index 0000000..7b0135d
--- /dev/null
@@ -0,0 +1,194 @@
+/* List of some useful object identifiers (OIDs)
+ * Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * 
+ * 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, "ITU-T Administration"   },  /*   0 */
+  {  0x82,                     0, 1, ""                       },  /*   1 */
+  {    0x06,                   0, 1, "Germany ITU-T member"   },  /*   2 */
+  {      0x01,                 0, 1, "Deutsche Telekom AG"    },  /*   3 */
+  {        0x0A,               0, 1, ""                       },  /*   4 */
+  {          0x07,             0, 1, ""                       },  /*   5 */
+  {            0x14,           0, 0, "ND"                     },  /*   6 */
+  {0x09,                      18, 1, "data"                   },  /*   7 */
+  {  0x92,                     0, 1, ""                       },  /*   8 */
+  {    0x26,                   0, 1, ""                       },  /*   9 */
+  {      0x89,                 0, 1, ""                       },  /*  10 */
+  {        0x93,               0, 1, ""                       },  /*  11 */
+  {          0xF2,             0, 1, ""                       },  /*  12 */
+  {            0x2C,           0, 1, ""                       },  /*  13 */
+  {              0x64,         0, 1, "pilot"                  },  /*  14 */
+  {                0x01,       0, 1, "pilotAttributeType"     },  /*  15 */
+  {                  0x01,    17, 0, "UID"                    },  /*  16 */
+  {                  0x19,     0, 0, "DC"                     },  /*  17 */
+  {0x55,                      51, 1, "X.500"                  },  /*  18 */
+  {  0x04,                    36, 1, "X.509"                  },  /*  19 */
+  {    0x03,                  21, 0, "CN"                     },  /*  20 */
+  {    0x04,                  22, 0, "S"                      },  /*  21 */
+  {    0x05,                  23, 0, "SN"                     },  /*  22 */
+  {    0x06,                  24, 0, "C"                      },  /*  23 */
+  {    0x07,                  25, 0, "L"                      },  /*  24 */
+  {    0x08,                  26, 0, "ST"                     },  /*  25 */
+  {    0x0A,                  27, 0, "O"                      },  /*  26 */
+  {    0x0B,                  28, 0, "OU"                     },  /*  27 */
+  {    0x0C,                  29, 0, "T"                      },  /*  28 */
+  {    0x0D,                  30, 0, "D"                      },  /*  29 */
+  {    0x24,                  31, 0, "userCertificate"        },  /*  30 */
+  {    0x29,                  32, 0, "N"                      },  /*  31 */
+  {    0x2A,                  33, 0, "G"                      },  /*  32 */
+  {    0x2B,                  34, 0, "I"                      },  /*  33 */
+  {    0x2D,                  35, 0, "ID"                     },  /*  34 */
+  {    0x48,                   0, 0, "role"                   },  /*  35 */
+  {  0x1D,                     0, 1, "id-ce"                  },  /*  36 */
+  {    0x09,                  38, 0, "subjectDirectoryAttrs"  },  /*  37 */
+  {    0x0E,                  39, 0, "subjectKeyIdentifier"   },  /*  38 */
+  {    0x0F,                  40, 0, "keyUsage"               },  /*  39 */
+  {    0x10,                  41, 0, "privateKeyUsagePeriod"  },  /*  40 */
+  {    0x11,                  42, 0, "subjectAltName"         },  /*  41 */
+  {    0x12,                  43, 0, "issuerAltName"          },  /*  42 */
+  {    0x13,                  44, 0, "basicConstraints"       },  /*  43 */
+  {    0x15,                  45, 0, "reasonCode"             },  /*  44 */
+  {    0x1F,                  46, 0, "crlDistributionPoints"  },  /*  45 */
+  {    0x20,                  47, 0, "certificatePolicies"    },  /*  46 */
+  {    0x23,                  48, 0, "authorityKeyIdentifier" },  /*  47 */
+  {    0x25,                  49, 0, "extendedKeyUsage"       },  /*  48 */
+  {    0x37,                  50, 0, "targetInformation"      },  /*  49 */
+  {    0x38,                   0, 0, "noRevAvail"             },  /*  50 */
+  {0x2A,                      88, 1, ""                       },  /*  51 */
+  {  0x86,                     0, 1, ""                       },  /*  52 */
+  {    0x48,                   0, 1, ""                       },  /*  53 */
+  {      0x86,                 0, 1, ""                       },  /*  54 */
+  {        0xF7,               0, 1, ""                       },  /*  55 */
+  {          0x0D,             0, 1, "RSADSI"                 },  /*  56 */
+  {            0x01,          83, 1, "PKCS"                   },  /*  57 */
+  {              0x01,        66, 1, "PKCS-1"                 },  /*  58 */
+  {                0x01,      60, 0, "rsaEncryption"          },  /*  59 */
+  {                0x02,      61, 0, "md2WithRSAEncryption"   },  /*  60 */
+  {                0x04,      62, 0, "md5WithRSAEncryption"   },  /*  61 */
+  {                0x05,      63, 0, "sha-1WithRSAEncryption" },  /*  62 */
+  {                0x0B,      64, 0, "sha256WithRSAEncryption"},  /*  63 */
+  {                0x0C,      65, 0, "sha384WithRSAEncryption"},  /*  64 */
+  {                0x0D,       0, 0, "sha512WithRSAEncryption"},  /*  65 */
+  {              0x07,        73, 1, "PKCS-7"                 },  /*  66 */
+  {                0x01,      68, 0, "data"                   },  /*  67 */
+  {                0x02,      69, 0, "signedData"             },  /*  68 */
+  {                0x03,      70, 0, "envelopedData"          },  /*  69 */
+  {                0x04,      71, 0, "signedAndEnvelopedData" },  /*  70 */
+  {                0x05,      72, 0, "digestedData"           },  /*  71 */
+  {                0x06,       0, 0, "encryptedData"          },  /*  72 */
+  {              0x09,         0, 1, "PKCS-9"                 },  /*  73 */
+  {                0x01,      75, 0, "E"                      },  /*  74 */
+  {                0x02,      76, 0, "unstructuredName"       },  /*  75 */
+  {                0x03,      77, 0, "contentType"            },  /*  76 */
+  {                0x04,      78, 0, "messageDigest"          },  /*  77 */
+  {                0x05,      79, 0, "signingTime"            },  /*  78 */
+  {                0x06,      80, 0, "counterSignature"       },  /*  79 */
+  {                0x07,      81, 0, "challengePassword"      },  /*  80 */
+  {                0x08,      82, 0, "unstructuredAddress"    },  /*  81 */
+  {                0x0E,       0, 0, "extensionRequest"       },  /*  82 */
+  {            0x02,          86, 1, "digestAlgorithm"        },  /*  83 */
+  {              0x02,        85, 0, "md2"                    },  /*  84 */
+  {              0x05,         0, 0, "md5"                    },  /*  85 */
+  {            0x03,           0, 1, "encryptionAlgorithm"    },  /*  86 */
+  {              0x07,         0, 0, "3des-ede-cbc"           },  /*  87 */
+  {0x2B,                     149, 1, ""                       },  /*  88 */
+  {  0x06,                   136, 1, "dod"                    },  /*  89 */
+  {    0x01,                   0, 1, "internet"               },  /*  90 */
+  {      0x04,               105, 1, "private"                },  /*  91 */
+  {        0x01,               0, 1, "enterprise"             },  /*  92 */
+  {          0x82,            98, 1, ""                       },  /*  93 */
+  {            0x37,           0, 1, "Microsoft"              },  /*  94 */
+  {              0x0A,         0, 1, ""                       },  /*  95 */
+  {                0x03,       0, 1, ""                       },  /*  96 */
+  {                  0x03,     0, 0, "msSGC"                  },  /*  97 */
+  {          0x89,             0, 1, ""                       },  /*  98 */
+  {            0x31,           0, 1, ""                       },  /*  99 */
+  {              0x01,         0, 1, ""                       },  /* 100 */
+  {                0x01,       0, 1, ""                       },  /* 101 */
+  {                  0x02,     0, 1, ""                       },  /* 102 */
+  {                    0x02, 104, 0, ""                       },  /* 103 */
+  {                    0x4B,   0, 0, "TCGID"                  },  /* 104 */
+  {      0x05,                 0, 1, "security"               },  /* 105 */
+  {        0x05,               0, 1, "mechanisms"             },  /* 106 */
+  {          0x07,             0, 1, "id-pkix"                },  /* 107 */
+  {            0x01,         110, 1, "id-pe"                  },  /* 108 */
+  {              0x01,         0, 0, "authorityInfoAccess"    },  /* 109 */
+  {            0x03,         120, 1, "id-kp"                  },  /* 110 */
+  {              0x01,       112, 0, "serverAuth"             },  /* 111 */
+  {              0x02,       113, 0, "clientAuth"             },  /* 112 */
+  {              0x03,       114, 0, "codeSigning"            },  /* 113 */
+  {              0x04,       115, 0, "emailProtection"        },  /* 114 */
+  {              0x05,       116, 0, "ipsecEndSystem"         },  /* 115 */
+  {              0x06,       117, 0, "ipsecTunnel"            },  /* 116 */
+  {              0x07,       118, 0, "ipsecUser"              },  /* 117 */
+  {              0x08,       119, 0, "timeStamping"           },  /* 118 */
+  {              0x09,         0, 0, "ocspSigning"            },  /* 119 */
+  {            0x08,         122, 1, "id-otherNames"          },  /* 120 */
+  {              0x05,         0, 0, "xmppAddr"               },  /* 121 */
+  {            0x0A,         127, 1, "id-aca"                 },  /* 122 */
+  {              0x01,       124, 0, "authenticationInfo"     },  /* 123 */
+  {              0x02,       125, 0, "accessIdentity"         },  /* 124 */
+  {              0x03,       126, 0, "chargingIdentity"       },  /* 125 */
+  {              0x04,         0, 0, "group"                  },  /* 126 */
+  {            0x30,           0, 1, "id-ad"                  },  /* 127 */
+  {              0x01,         0, 1, "ocsp"                   },  /* 128 */
+  {                0x01,     130, 0, "basic"                  },  /* 129 */
+  {                0x02,     131, 0, "nonce"                  },  /* 130 */
+  {                0x03,     132, 0, "crl"                    },  /* 131 */
+  {                0x04,     133, 0, "response"               },  /* 132 */
+  {                0x05,     134, 0, "noCheck"                },  /* 133 */
+  {                0x06,     135, 0, "archiveCutoff"          },  /* 134 */
+  {                0x07,       0, 0, "serviceLocator"         },  /* 135 */
+  {  0x0E,                   142, 1, "oiw"                    },  /* 136 */
+  {    0x03,                   0, 1, "secsig"                 },  /* 137 */
+  {      0x02,                 0, 1, "algorithms"             },  /* 138 */
+  {        0x07,             140, 0, "des-cbc"                },  /* 139 */
+  {        0x1A,             141, 0, "sha-1"                  },  /* 140 */
+  {        0x1D,               0, 0, "sha-1WithRSASignature"  },  /* 141 */
+  {  0x24,                     0, 1, "TeleTrusT"              },  /* 142 */
+  {    0x03,                   0, 1, "algorithm"              },  /* 143 */
+  {      0x03,                 0, 1, "signatureAlgorithm"     },  /* 144 */
+  {        0x01,               0, 1, "rsaSignature"           },  /* 145 */
+  {          0x02,           147, 0, "rsaSigWithripemd160"    },  /* 146 */
+  {          0x03,           148, 0, "rsaSigWithripemd128"    },  /* 147 */
+  {          0x04,             0, 0, "rsaSigWithripemd256"    },  /* 148 */
+  {0x60,                       0, 1, ""                       },  /* 149 */
+  {  0x86,                     0, 1, ""                       },  /* 150 */
+  {    0x48,                   0, 1, ""                       },  /* 151 */
+  {      0x01,                 0, 1, "organization"           },  /* 152 */
+  {        0x65,             160, 1, "gov"                    },  /* 153 */
+  {          0x03,             0, 1, "csor"                   },  /* 154 */
+  {            0x04,           0, 1, "nistalgorithm"          },  /* 155 */
+  {              0x02,         0, 1, "hashalgs"               },  /* 156 */
+  {                0x01,     158, 0, "id-SHA-256"             },  /* 157 */
+  {                0x02,     159, 0, "id-SHA-384"             },  /* 158 */
+  {                0x03,       0, 0, "id-SHA-512"             },  /* 159 */
+  {        0x86,               0, 1, ""                       },  /* 160 */
+  {          0xf8,             0, 1, ""                       },  /* 161 */
+  {            0x42,         171, 1, "netscape"               },  /* 162 */
+  {              0x01,       169, 1, ""                       },  /* 163 */
+  {                0x01,     165, 0, "nsCertType"             },  /* 164 */
+  {                0x03,     166, 0, "nsRevocationUrl"        },  /* 165 */
+  {                0x04,     167, 0, "nsCaRevocationUrl"      },  /* 166 */
+  {                0x08,     168, 0, "nsCaPolicyUrl"          },  /* 167 */
+  {                0x0d,       0, 0, "nsComment"              },  /* 168 */
+  {              0x04,         0, 1, "policy"                 },  /* 169 */
+  {                0x01,       0, 0, "nsSGC"                  },  /* 170 */
+  {            0x45,           0, 1, "verisign"               },  /* 171 */
+  {              0x01,         0, 1, "pki"                    },  /* 172 */
+  {                0x09,       0, 1, "attributes"             },  /* 173 */
+  {                  0x02,   175, 0, "messageType"            },  /* 174 */
+  {                  0x03,   176, 0, "pkiStatus"              },  /* 175 */
+  {                  0x04,   177, 0, "failInfo"               },  /* 176 */
+  {                  0x05,   178, 0, "senderNonce"            },  /* 177 */
+  {                  0x06,   179, 0, "recipientNonce"         },  /* 178 */
+  {                  0x07,   180, 0, "transID"                },  /* 179 */
+  {                  0x08,     0, 0, "extensionReq"           }   /* 180 */
+};
diff --git a/Source/lib/asn1/oid.h b/Source/lib/asn1/oid.h
new file mode 100644 (file)
index 0000000..4096af3
--- /dev/null
@@ -0,0 +1,75 @@
+/* Object identifiers (OIDs) used by FreeS/WAN
+ * Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * 
+ * This file has been automatically generated by the script oid.pl
+ * Do not edit manually!
+ */
+
+typedef struct {
+    u_char octet;
+    u_int  next;
+    u_int  down;
+    const u_char *name;
+} oid_t;
+
+extern const oid_t oid_names[];
+
+#define OID_UNKNOWN                    -1
+#define OID_ROLE                       35
+#define OID_SUBJECT_KEY_ID             38
+#define OID_SUBJECT_ALT_NAME           41
+#define OID_BASIC_CONSTRAINTS          43
+#define OID_CRL_REASON_CODE            44
+#define OID_CRL_DISTRIBUTION_POINTS    45
+#define OID_AUTHORITY_KEY_ID           47
+#define OID_EXTENDED_KEY_USAGE         48
+#define OID_TARGET_INFORMATION         49
+#define OID_NO_REV_AVAIL               50
+#define OID_RSA_ENCRYPTION             59
+#define OID_MD2_WITH_RSA               60
+#define OID_MD5_WITH_RSA               61
+#define OID_SHA1_WITH_RSA              62
+#define OID_SHA256_WITH_RSA            63
+#define OID_SHA384_WITH_RSA            64
+#define OID_SHA512_WITH_RSA            65
+#define OID_PKCS7_DATA                 67
+#define OID_PKCS7_SIGNED_DATA          68
+#define OID_PKCS7_ENVELOPED_DATA       69
+#define OID_PKCS7_SIGNED_ENVELOPED_DATA        70
+#define OID_PKCS7_DIGESTED_DATA                71
+#define OID_PKCS7_ENCRYPTED_DATA       72
+#define OID_PKCS9_EMAIL                        74
+#define OID_PKCS9_CONTENT_TYPE         76
+#define OID_PKCS9_MESSAGE_DIGEST       77
+#define OID_PKCS9_SIGNING_TIME         78
+#define OID_MD2                                84
+#define OID_MD5                                85
+#define OID_3DES_EDE_CBC               87
+#define OID_AUTHORITY_INFO_ACCESS      109
+#define OID_OCSP_SIGNING               119
+#define OID_XMPP_ADDR                  121
+#define OID_AUTHENTICATION_INFO                123
+#define OID_ACCESS_IDENTITY            124
+#define OID_CHARGING_IDENTITY          125
+#define OID_GROUP                      126
+#define OID_OCSP                       128
+#define OID_BASIC                      129
+#define OID_NONCE                      130
+#define OID_CRL                                131
+#define OID_RESPONSE                   132
+#define OID_NO_CHECK                   133
+#define OID_ARCHIVE_CUTOFF             134
+#define OID_SERVICE_LOCATOR            135
+#define OID_DES_CBC                    139
+#define OID_SHA1                       140
+#define OID_SHA1_WITH_RSA_OIW          141
+#define OID_NS_REVOCATION_URL          165
+#define OID_NS_CA_REVOCATION_URL       166
+#define OID_NS_CA_POLICY_URL           167
+#define OID_NS_COMMENT                 168
+#define OID_PKI_MESSAGE_TYPE           174
+#define OID_PKI_STATUS                 175
+#define OID_PKI_FAIL_INFO              176
+#define OID_PKI_SENDER_NONCE           177
+#define OID_PKI_RECIPIENT_NONCE                178
+#define OID_PKI_TRANS_ID               179
diff --git a/Source/lib/asn1/oid.pl b/Source/lib/asn1/oid.pl
new file mode 100644 (file)
index 0000000..52ac8ea
--- /dev/null
@@ -0,0 +1,123 @@
+#!/usr/bin/perl
+# Generates oid.h and oid.c out of oid.txt
+# Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+#
+# 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-2004 Andreas Steffen, Zuercher Hochschule Winterthur";
+$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 FreeS/WAN\n",
+           " * ", $copyright, "\n",
+           " * \n",
+           " * ", $automatic, "\n",
+           " * ", $warning, "\n",
+           " */\n\n",
+           "typedef struct {\n",
+           "    u_char octet;\n",
+           "    u_int  next;\n",
+           "    u_int  down;\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))/8), $counter;
+    }
+    $counter++;
+}
+
+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, %s%s}%s  /* %3d */\n"
+       ,' '  x @order[$c]
+       , @octet[$c]
+       , ' ' x (1 + $max_order - @order[$c])
+       , @next[$c]
+       , @order[$c+1] > @order[$c]
+       , @name[$c]
+       , ' ' x ($max_name - length(@name[$c]))
+       , $c != $counter-1 ? "," : " "
+       , $c;
+}
+
+print OID_C "};\n" ;
+close OID_C;
diff --git a/Source/lib/asn1/oid.txt b/Source/lib/asn1/oid.txt
new file mode 100644 (file)
index 0000000..ad05a12
--- /dev/null
@@ -0,0 +1,181 @@
+0x02                         "ITU-T Administration"
+  0x82                       ""
+    0x06                     "Germany ITU-T member"
+      0x01                   "Deutsche Telekom AG"
+        0x0A                 ""
+          0x07               ""
+            0x14             "ND"
+0x09                         "data"
+  0x92                       ""
+    0x26                     ""
+      0x89                   ""
+        0x93                 ""
+          0xF2               ""
+            0x2C             ""
+              0x64           "pilot"
+                0x01         "pilotAttributeType"
+                  0x01       "UID"
+                  0x19       "DC"
+0x55                         "X.500"
+  0x04                       "X.509"
+    0x03                     "CN"
+    0x04                     "S"
+    0x05                     "SN"
+    0x06                     "C"
+    0x07                     "L"
+    0x08                     "ST"
+    0x0A                     "O"
+    0x0B                     "OU"
+    0x0C                     "T"
+    0x0D                     "D"
+    0x24                     "userCertificate"
+    0x29                     "N"
+    0x2A                     "G"
+    0x2B                     "I"
+    0x2D                     "ID"
+    0x48                     "role"                    OID_ROLE
+  0x1D                       "id-ce"
+    0x09                     "subjectDirectoryAttrs"
+    0x0E                     "subjectKeyIdentifier"    OID_SUBJECT_KEY_ID
+    0x0F                     "keyUsage"
+    0x10                     "privateKeyUsagePeriod"
+    0x11                     "subjectAltName"          OID_SUBJECT_ALT_NAME
+    0x12                     "issuerAltName"
+    0x13                     "basicConstraints"                OID_BASIC_CONSTRAINTS
+    0x15                     "reasonCode"              OID_CRL_REASON_CODE
+    0x1F                     "crlDistributionPoints"   OID_CRL_DISTRIBUTION_POINTS
+    0x20                     "certificatePolicies"
+    0x23                     "authorityKeyIdentifier"  OID_AUTHORITY_KEY_ID
+    0x25                     "extendedKeyUsage"                OID_EXTENDED_KEY_USAGE
+    0x37                     "targetInformation"       OID_TARGET_INFORMATION
+    0x38                     "noRevAvail"              OID_NO_REV_AVAIL
+0x2A                         ""
+  0x86                       ""
+    0x48                     ""
+      0x86                   ""
+        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
+                0x0B         "sha256WithRSAEncryption" OID_SHA256_WITH_RSA
+                0x0C         "sha384WithRSAEncryption" OID_SHA384_WITH_RSA
+                0x0D         "sha512WithRSAEncryption" OID_SHA512_WITH_RSA
+              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_PKCS9_EMAIL
+                0x02         "unstructuredName"
+                0x03         "contentType"             OID_PKCS9_CONTENT_TYPE
+                0x04         "messageDigest"           OID_PKCS9_MESSAGE_DIGEST
+                0x05         "signingTime"             OID_PKCS9_SIGNING_TIME
+                0x06         "counterSignature"
+                0x07         "challengePassword"
+                0x08         "unstructuredAddress"
+                0x0E         "extensionRequest"
+            0x02             "digestAlgorithm"
+              0x02           "md2"                     OID_MD2
+              0x05           "md5"                     OID_MD5
+            0x03             "encryptionAlgorithm"
+              0x07           "3des-ede-cbc"            OID_3DES_EDE_CBC
+0x2B                         ""
+  0x06                       "dod"
+    0x01                     "internet"
+      0x04                   "private"
+        0x01                 "enterprise"
+          0x82               ""
+            0x37             "Microsoft"
+              0x0A           ""
+                0x03         ""
+                  0x03       "msSGC"
+          0x89               ""
+            0x31             ""
+              0x01           ""
+                0x01         ""
+                  0x02       ""
+                    0x02     ""
+                    0x4B     "TCGID"
+      0x05                   "security"
+        0x05                 "mechanisms"
+          0x07               "id-pkix"
+            0x01             "id-pe"
+              0x01           "authorityInfoAccess"     OID_AUTHORITY_INFO_ACCESS
+            0x03             "id-kp"
+              0x01           "serverAuth"
+              0x02           "clientAuth"
+              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
+            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
+  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"
+0x60                         ""
+  0x86                       ""
+    0x48                     ""
+      0x01                   "organization"
+        0x65                 "gov"
+          0x03               "csor"
+            0x04             "nistalgorithm"
+              0x02           "hashalgs"
+                0x01         "id-SHA-256"
+                0x02         "id-SHA-384"
+                0x03         "id-SHA-512"
+        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
+              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"
diff --git a/Source/lib/asn1/pem.c b/Source/lib/asn1/pem.c
new file mode 100755 (executable)
index 0000000..24c71c6
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * 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 <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include "pem.h"
+#include "ttodata.h"
+
+#include <crypto/hashers/hasher.h>
+#include <crypto/crypters/crypter.h>
+
+
+/*
+ * check the presence of a pattern in a character string
+ */
+static bool present(const char* pattern, chunk_t* ch)
+{
+       u_int pattern_len = strlen(pattern);
+
+       if (ch->len >= pattern_len && strncmp(ch->ptr, pattern, pattern_len) == 0)
+       {
+               ch->ptr += pattern_len;
+               ch->len -= pattern_len;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/*
+ * compare string with chunk
+ */
+static bool match(const char *pattern, const chunk_t *ch)
+{
+       return ch->len == strlen(pattern) && strncmp(pattern, ch->ptr, ch->len) == 0;
+}
+
+/*
+ * find a boundary of the form -----tag name-----
+ */
+static bool find_boundary(const char* tag, chunk_t *line)
+{
+       chunk_t name = CHUNK_INITIALIZER;
+
+       if (!present("-----", line))
+               return FALSE;
+       if (!present(tag, line))
+               return FALSE;
+       if (*line->ptr != ' ')
+               return FALSE;
+       line->ptr++;  line->len--;
+       
+       /* extract name */
+       name.ptr = line->ptr;
+       while (line->len > 0)
+       {
+               if (present("-----", line))
+               {
+                       return TRUE;
+               }
+               line->ptr++;  line->len--;  name.len++;
+       }
+       return FALSE;
+}
+
+/*
+ * eat whitespace
+ */
+static void eat_whitespace(chunk_t *src)
+{
+       while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
+       {
+               src->ptr++;  src->len--;
+       }
+}
+
+/*
+ * extracts a token ending with a given termination symbol
+ */
+static bool extract_token(chunk_t *token, char termination, chunk_t *src)
+{
+       u_char *eot = memchr(src->ptr, termination, src->len);
+       
+       /* initialize empty token */
+       *token = CHUNK_INITIALIZER;
+       
+       if (eot == NULL) /* termination symbol not found */
+       {
+               return FALSE;
+       }
+       
+       /* extract token */
+       token->ptr = src->ptr;
+       token->len = (u_int)(eot - src->ptr);
+       
+       /* advance src pointer after termination symbol */
+       src->ptr = eot + 1;
+       src->len -= (token->len + 1);
+       
+       return TRUE;
+}
+
+/*
+ * extracts a name: value pair from the PEM header
+ */
+static bool extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
+{
+       /* extract name */
+       if (!extract_token(name,':', line))
+       {
+               return FALSE;
+       }
+       
+       eat_whitespace(line);
+       
+       /* extract value */
+       *value = *line;
+       return TRUE;
+}
+
+/*
+ *  fetches a new line terminated by \n or \r\n
+ */
+static bool fetchline(chunk_t *src, chunk_t *line)
+{
+       if (src->len == 0) /* end of src reached */
+               return FALSE;
+
+       if (extract_token(line, '\n', src))
+       {
+               if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
+                       line->len--;  /* remove optional \r */
+       }
+       else /*last line ends without newline */
+       {
+               *line = *src;
+               src->ptr += src->len;
+               src->len = 0;
+       }
+       return TRUE;
+}
+
+/*
+ * decrypts a DES-EDE-CBC encrypted data block
+ */
+static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase)
+{
+       hasher_t *hasher;
+       crypter_t *crypter;
+       chunk_t hash;
+       chunk_t decrypted;
+       chunk_t pass = {passphrase, strlen(passphrase)};
+       chunk_t key = {alloca(24), 24};
+       u_int8_t padding, *last_padding_pos, *first_padding_pos;
+       
+       /* build key from passphrase and IV */
+       hasher = hasher_create(HASH_MD5);
+       hash.len = hasher->get_block_size(hasher);
+       hash.ptr = alloca(hash.len);
+       hasher->get_hash(hasher, pass, NULL);
+       hasher->get_hash(hasher, *iv, hash.ptr);
+       
+       memcpy(key.ptr, hash.ptr, hash.len);
+       
+       hasher->get_hash(hasher, hash, NULL);
+       hasher->get_hash(hasher, pass, NULL);
+       hasher->get_hash(hasher, *iv, hash.ptr);
+       
+       memcpy(key.ptr + hash.len, hash.ptr, key.len - hash.len);
+       
+       hasher->destroy(hasher);
+       
+       /* decrypt blob */
+       crypter = crypter_create(ENCR_3DES, 0);
+       crypter->set_key(crypter, key);
+       crypter->decrypt(crypter, *blob, *iv, &decrypted);
+       memcpy(blob->ptr, decrypted.ptr, blob->len);
+       chunk_free(&decrypted);
+       
+       /* determine amount of padding */
+       last_padding_pos = blob->ptr + blob->len - 1;
+       padding = *last_padding_pos;
+       first_padding_pos = (padding > blob->len) ? blob->ptr : last_padding_pos - padding;
+
+       /* check the padding pattern */
+       while (--last_padding_pos > first_padding_pos)
+       {
+               if (*last_padding_pos != padding)
+                       return FALSE;
+       }
+       /* remove padding */
+       blob->len -= padding;
+       return TRUE;
+}
+
+/*  Converts a PEM encoded file into its binary form
+ *
+ *  RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
+ *  RFC 934 Message Encapsulation, January 1985
+ */
+status_t pemtobin(chunk_t *blob, char *pass)
+{
+       typedef enum {
+               PEM_PRE    = 0,
+               PEM_MSG    = 1,
+               PEM_HEADER = 2,
+               PEM_BODY   = 3,
+               PEM_POST   = 4,
+               PEM_ABORT  = 5
+       } state_t;
+
+       bool encrypted = FALSE;
+
+       state_t state  = PEM_PRE;
+
+       chunk_t src    = *blob;
+       chunk_t dst    = *blob;
+       chunk_t line   = CHUNK_INITIALIZER;
+       chunk_t iv     = CHUNK_INITIALIZER;
+
+       u_char iv_buf[16]; /* MD5 digest size */
+
+       /* zero size of converted blob */
+       dst.len = 0;
+
+       /* zero size of IV */
+       iv.ptr = iv_buf;
+       iv.len = 0;
+
+       while (fetchline(&src, &line))
+       {
+               if (state == PEM_PRE)
+               {
+                       if (find_boundary("BEGIN", &line))
+                       {
+                               state = PEM_MSG;
+                       }
+                       continue;
+               }
+               else
+               {
+                       if (find_boundary("END", &line))
+                       {
+                               state = PEM_POST;
+                               break;
+                       }
+                       if (state == PEM_MSG)
+                       {
+                               state = (memchr(line.ptr, ':', line.len) == NULL) ? PEM_BODY : PEM_HEADER;
+                       }
+                       if (state == PEM_HEADER)
+                       {
+                               chunk_t name  = CHUNK_INITIALIZER;
+                               chunk_t value = CHUNK_INITIALIZER;
+
+                               /* an empty line separates HEADER and BODY */
+                               if (line.len == 0)
+                               {
+                                       state = PEM_BODY;
+                                       continue;
+                               }
+
+                               /* we are looking for a name: value pair */
+                               if (!extract_parameter(&name, &value, &line))
+                                       continue;
+
+                               if (match("Proc-Type", &name) && *value.ptr == '4')
+                                       encrypted = TRUE;
+                               else if (match("DEK-Info", &name))
+                               {
+                                       const char *ugh = NULL;
+                                       size_t len = 0;
+                                       chunk_t dek;
+
+                                       if (!extract_token(&dek, ',', &value))
+                                               dek = value;
+
+                                       /* we support DES-EDE3-CBC encrypted files, only */
+                                       if (!match("DES-EDE3-CBC", &dek))
+                                               return NOT_SUPPORTED;
+
+                                       eat_whitespace(&value);
+                                       ugh = ttodata(value.ptr, value.len, 16, iv.ptr, 16, &len);
+                                       if (ugh)
+                                               return PARSE_ERROR;
+
+                                       iv.len = len;
+                               }
+                       }
+                       else /* state is PEM_BODY */
+                       {
+                               const char *ugh = NULL;
+                               size_t len = 0;
+                               chunk_t data;
+                               
+                               /* remove any trailing whitespace */
+                               if (!extract_token(&data ,' ', &line))
+                               {
+                                       data = line;
+                               }
+                               
+                               ugh = ttodata(data.ptr, data.len, 64, dst.ptr, blob->len - dst.len, &len);
+                               if (ugh)
+                               {
+                                       state = PEM_ABORT;
+                                       break;
+                               }
+                               else
+                               {
+                                       dst.ptr += len;
+                                       dst.len += len;
+                               }
+                       }
+               }
+       }
+       /* set length to size of binary blob */
+       blob->len = dst.len;
+
+       if (state != PEM_POST)
+               return PARSE_ERROR;
+
+       if (encrypted)
+               return pem_decrypt(blob, &iv, pass);
+       else
+               return SUCCESS;
+}
diff --git a/Source/lib/asn1/pem.h b/Source/lib/asn1/pem.h
new file mode 100755 (executable)
index 0000000..a4332fd
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 Martin Willi
+ * 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.
+ */
+
+#ifndef PEM_H_
+#define PEM_H_
+
+#include <stdio.h>
+
+#include <types.h>
+
+status_t pemtobin(chunk_t *blob, char *pass);
+
+#endif /*PEM_H_*/
diff --git a/Source/lib/asn1/ttodata.c b/Source/lib/asn1/ttodata.c
new file mode 100644 (file)
index 0000000..5e81499
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * convert from text form of arbitrary data (e.g., keys) to binary
+ * Copyright (C) 2000  Henry Spencer.
+ * 
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library 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/lgpl.txt>.
+ * 
+ * This library 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 Library General Public
+ * License for more details.
+ */
+
+#include "ttodata.h"
+
+#include <string.h>
+#include <ctype.h>
+
+/* converters and misc */
+static int unhex(const char *, char *, size_t);
+static int unb64(const char *, char *, size_t);
+static int untext(const char *, char *, size_t);
+static const char *badch(const char *, int, char *, size_t);
+
+/* internal error codes for converters */
+#define        SHORT   (-2)            /* internal buffer too short */
+#define        BADPAD  (-3)            /* bad base64 padding */
+#define        BADCH0  (-4)            /* invalid character 0 */
+#define        BADCH1  (-5)            /* invalid character 1 */
+#define        BADCH2  (-6)            /* invalid character 2 */
+#define        BADCH3  (-7)            /* invalid character 3 */
+#define        BADOFF(code) (BADCH0-(code))
+
+/*
+ - ttodatav - convert text to data, with verbose error reports
+ * If some of this looks slightly odd, it's because it has changed
+ * repeatedly (from the original atodata()) without a major rewrite.
+ */
+const char *                   /* NULL on success, else literal or errp */
+ttodatav(src, srclen, base, dst, dstlen, lenp, errp, errlen, flags)
+const char *src;
+size_t srclen;                 /* 0 means apply strlen() */
+int base;                      /* 0 means figure it out */
+char *dst;                     /* need not be valid if dstlen is 0 */
+size_t dstlen;
+size_t *lenp;                  /* where to record length (NULL is nowhere) */
+char *errp;                    /* error buffer */
+size_t errlen;
+unsigned int flags;
+{
+       size_t ingroup; /* number of input bytes converted at once */
+       char buf[4];            /* output from conversion */
+       int nbytes;             /* size of output */
+       int (*decode)(const char *, char *, size_t);
+       char *stop;
+       int ndone;
+       int i;
+       int underscoreok;
+       int skipSpace = 0;
+
+       if (srclen == 0)
+               srclen = strlen(src);
+       if (dstlen == 0)
+               dst = buf;      /* point it somewhere valid */
+       stop = dst + dstlen;
+
+       if (base == 0) {
+               if (srclen < 2)
+                       return "input too short to be valid";
+               if (*src++ != '0')
+                       return "input does not begin with format prefix";
+               switch (*src++) {
+               case 'x':
+               case 'X':
+                       base = 16;
+                       break;
+               case 's':
+               case 'S':
+                       base = 64;
+                       break;
+               case 't':
+               case 'T':
+                       base = 256;
+                       break;
+               default:
+                       return "unknown format prefix";
+               }
+               srclen -= 2;
+       }
+       switch (base) {
+       case 16:
+               decode = unhex;
+               underscoreok = 1;
+               ingroup = 2;
+               break;
+       case 64:
+               decode = unb64;
+               underscoreok = 0;
+               ingroup = 4;
+               if(flags & TTODATAV_IGNORESPACE) {
+                       skipSpace = 1;
+               }
+               break;
+
+       case 256:
+               decode = untext;
+               ingroup = 1;
+               underscoreok = 0;
+               break;
+       default:
+               return "unknown base";
+       }
+
+       /* proceed */
+       ndone = 0;
+       while (srclen > 0) {
+               char stage[4];  /* staging area for group */
+               size_t sl = 0;
+
+               /* Grab ingroup characters into stage,
+                * squeezing out blanks if we are supposed to ignore them.
+                */
+               for (sl = 0; sl < ingroup; src++, srclen--) {
+                       if (srclen == 0)
+                               return "input ends in mid-byte, perhaps truncated";
+                       else if (!(skipSpace && (*src == ' ' || *src == '\t')))
+                               stage[sl++] = *src;
+               }
+               
+               nbytes = (*decode)(stage, buf, sizeof(buf));
+               switch (nbytes) {
+               case BADCH0:
+               case BADCH1:
+               case BADCH2:
+               case BADCH3:
+                       return badch(stage, nbytes, errp, errlen);
+               case SHORT:
+                       return "internal buffer too short (\"can't happen\")";
+               case BADPAD:
+                       return "bad (non-zero) padding at end of base64 input";
+               }
+               if (nbytes <= 0)
+                       return "unknown internal error";
+               for (i = 0; i < nbytes; i++) {
+                       if (dst < stop)
+                               *dst++ = buf[i];
+                       ndone++;
+               }
+               while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t')){
+                       src++;
+                       srclen--;
+               }
+               if (underscoreok && srclen > 1 && *src == '_') {
+                       /* srclen > 1 means not last character */
+                       src++;
+                       srclen--;
+               }
+       }
+
+       if (ndone == 0)
+               return "no data bytes specified by input";
+       if (lenp != NULL)
+               *lenp = ndone;
+       return NULL;
+}
+
+/*
+ - ttodata - convert text to data
+ */
+const char *                   /* NULL on success, else literal */
+ttodata(src, srclen, base, dst, dstlen, lenp)
+const char *src;
+size_t srclen;                 /* 0 means apply strlen() */
+int base;                      /* 0 means figure it out */
+char *dst;                     /* need not be valid if dstlen is 0 */
+size_t dstlen;
+size_t *lenp;                  /* where to record length (NULL is nowhere) */
+{
+       return ttodatav(src, srclen, base, dst, dstlen, lenp, (char *)NULL,
+                       (size_t)0, TTODATAV_SPACECOUNTS);
+}
+
+/*
+ - atodata - convert ASCII to data
+ * backward-compatibility interface
+ */
+size_t                         /* 0 for failure, true length for success */
+atodata(src, srclen, dst, dstlen)
+const char *src;
+size_t srclen;
+char *dst;
+size_t dstlen;
+{
+       size_t len;
+       const char *err;
+
+       err = ttodata(src, srclen, 0, dst, dstlen, &len);
+       if (err != NULL)
+               return 0;
+       return len;
+}
+
+/*
+ - atobytes - convert ASCII to data bytes
+ * another backward-compatibility interface
+ */
+const char *
+atobytes(src, srclen, dst, dstlen, lenp)
+const char *src;
+size_t srclen;
+char *dst;
+size_t dstlen;
+size_t *lenp;
+{
+       return ttodata(src, srclen, 0, dst, dstlen, lenp);
+}
+
+/*
+ - unhex - convert two ASCII hex digits to byte
+ */
+static int             /* number of result bytes, or error code */
+unhex(src, dst, dstlen)
+const char *src;       /* known to be full length */
+char *dst;
+size_t dstlen;         /* not large enough is a failure */
+{
+       char *p;
+       unsigned byte;
+       static char hex[] = "0123456789abcdef";
+
+       if (dstlen < 1)
+               return SHORT;
+       
+       p = strchr(hex, *src);
+       if (p == NULL)
+               p = strchr(hex, tolower(*src));
+       if (p == NULL)
+               return BADCH0;
+       byte = (p - hex) << 4;
+       src++;
+
+       p = strchr(hex, *src);
+       if (p == NULL)
+               p = strchr(hex, tolower(*src));
+       if (p == NULL)
+               return BADCH1;
+       byte |= (p - hex);
+
+       *dst = byte;
+       return 1;
+}
+
+/*
+ - unb64 - convert four ASCII base64 digits to three bytes
+ * Note that a base64 digit group is padded out with '=' if it represents
+ * less than three bytes:  one byte is dd==, two is ddd=, three is dddd.
+ */
+static int             /* number of result bytes, or error code */
+unb64(src, dst, dstlen)
+const char *src;       /* known to be full length */
+char *dst;
+size_t dstlen;
+{
+       char *p;
+       unsigned byte1;
+       unsigned byte2;
+       static char base64[] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+       if (dstlen < 3)
+               return SHORT;
+
+       p = strchr(base64, *src++);
+
+       if (p == NULL)
+               return BADCH0;
+       byte1 = (p - base64) << 2;      /* first six bits */
+
+       p = strchr(base64, *src++);
+       if (p == NULL) {
+               return BADCH1;
+       }
+
+       byte2 = p - base64;             /* next six:  two plus four */
+       *dst++ = byte1 | (byte2 >> 4);
+       byte1 = (byte2 & 0xf) << 4;
+
+       p = strchr(base64, *src++);
+       if (p == NULL) {
+               if (*(src-1) == '=' && *src == '=') {
+                       if (byte1 != 0)         /* bad padding */
+                               return BADPAD;
+                       return 1;
+               }
+               return BADCH2;
+       }
+
+       byte2 = p - base64;             /* next six:  four plus two */
+       *dst++ = byte1 | (byte2 >> 2);
+       byte1 = (byte2 & 0x3) << 6;
+
+       p = strchr(base64, *src++);
+       if (p == NULL) {
+               if (*(src-1) == '=') {
+                       if (byte1 != 0)         /* bad padding */
+                               return BADPAD;
+                       return 2;
+               }
+               return BADCH3;
+       }
+       byte2 = p - base64;             /* last six */
+       *dst++ = byte1 | byte2;
+
+       return 3;
+}
+
+/*
+ - untext - convert one ASCII character to byte
+ */
+static int             /* number of result bytes, or error code */
+untext(src, dst, dstlen)
+const char *src;       /* known to be full length */
+char *dst;
+size_t dstlen;         /* not large enough is a failure */
+{
+       if (dstlen < 1)
+               return SHORT;
+
+       *dst = *src;
+       return 1;
+}
+
+/*
+ - badch - produce a nice complaint about an unknown character
+ *
+ * If the compiler complains that the array bigenough[] has a negative
+ * size, that means the TTODATAV_BUF constant has been set too small.
+ */
+static const char *            /* literal or errp */
+badch(src, errcode, errp, errlen)
+const char *src;
+int errcode;
+char *errp;                    /* might be NULL */
+size_t errlen;
+{
+       static const char pre[] = "unknown character (`";
+       static const char suf[] = "') in input";
+       char buf[5];
+#      define  REQD    (sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf))
+       struct sizecheck {
+               char bigenough[TTODATAV_BUF - REQD];    /* see above */
+       };
+       char ch;
+
+       if (errp == NULL || errlen < REQD)
+               return "unknown character in input";
+       strcpy(errp, pre);
+       ch = *(src + BADOFF(errcode));
+       if (isprint(ch)) {
+               buf[0] = ch;
+               buf[1] = '\0';
+       } else {
+               buf[0] = '\\';
+               buf[1] = ((ch & 0700) >> 6) + '0';
+               buf[2] = ((ch & 0070) >> 3) + '0';
+               buf[3] = ((ch & 0007) >> 0) + '0';
+               buf[4] = '\0';
+       }
+       strcat(errp, buf);
+       strcat(errp, suf);
+       return (const char *)errp;
+}
diff --git a/Source/lib/asn1/ttodata.h b/Source/lib/asn1/ttodata.h
new file mode 100644 (file)
index 0000000..d57244e
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * convert from text form of arbitrary data (e.g., keys) to binary
+ * Copyright (C) 2000  Henry Spencer.
+ * 
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library 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/lgpl.txt>.
+ * 
+ * This library 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 Library General Public
+ * License for more details.
+ */
+
+#ifndef TTODATA_H_
+#define TTODATA_H_
+
+#include <types.h>
+
+#define        TTODATAV_BUF    40      /* ttodatav's largest non-literal message */
+#define TTODATAV_IGNORESPACE  (1<<1)  /* ignore spaces in base64 encodings*/
+#define TTODATAV_SPACECOUNTS  0       /* do not ignore spaces in base64   */
+
+typedef const char *err_t;     /* error message, or NULL for success */
+
+err_t ttodata(const char *src, size_t srclen, int base, char *buf, size_t buflen, size_t *needed);
+
+
+#endif /* TTODATA_H_ */
index 2b5459e..8dc88e0 100755 (executable)
@@ -26,6 +26,8 @@
 #include <types.h>
 #include <definitions.h>
 #include <crypto/rsa/rsa_public_key.h>
+#include <utils/identification.h>
+#include <utils/iterator.h>
 
 
 typedef struct certificate_t certificate_t;
@@ -47,6 +49,14 @@ struct certificate_t {
         * @return                                      public_key
         */
        rsa_public_key_t *(*get_public_key) (certificate_t *this);
+
+       identification_t *(*get_issuer) (certificate_t *this);
+       identification_t *(*get_subject) (certificate_t *this);
+       iterator_t *(*create_subjectaltname_iter) (certificate_t *this);
+       iterator_t *(*create_issueraltname_iter) (certificate_t *this);
+       bool (*belongs_to) (certificate_t *this, identification_t *subject);
+       bool (*issued_by) (certificate_t *this, identification_t *issuer);
+       bool (*validate) (certificate_t *this, rsa_public_key_t *signer);
        
        /**
         * @brief Destroys the private key.
index b973da9..30796bd 100644 (file)
@@ -85,6 +85,21 @@ enum id_type_t {
 };
 
 /**
+ * Old pluto id format
+ * 
+ * @deprecated Do not use any more, only here for pluto.
+ */
+// struct id {
+//     /** ID_* value, pluto pendant to id_type_t */
+//     int kind;
+//     /** ID_IPV4_ADDR, ID_IPV6_ADDR */
+//     ip_address ip_addr;
+//     /** ID_FQDN, ID_USER_FQDN (with @) */
+//     /** ID_KEY_ID, ID_DER_ASN_DN       */
+//     chunk_t name;
+// };
+
+/**
  * String mappings for id_type_t.
  */
 extern mapping_t id_type_m[];
@@ -144,6 +159,17 @@ struct identification_t {
        char *(*get_string) (identification_t *this);
        
        /**
+        * @brief Get the id in the format used in pluto.
+        * 
+        * We do this in pluto style here, which means no memory
+        * is allocated.
+        * 
+        * @param this          the identification_t object
+        * @return                      string
+        */
+       // void (*get_pluto_id) (identification_t *this, struct id *pluto_id);
+       
+       /**
         * @brief Check if two identification_t objects are equal.
         * 
         * @param this          the identification_t object
@@ -195,7 +221,6 @@ struct identification_t {
  */
 identification_t * identification_create_from_string(id_type_t type, char *string);
 
-
 /**
  * @brief Creates an identification_t object from an encoded chunk.
  * 
@@ -207,5 +232,18 @@ identification_t * identification_create_from_string(id_type_t type, char *strin
  */
 identification_t * identification_create_from_encoding(id_type_t type, chunk_t encoded);
 
+/**
+ * @brief Creates an identification_t object from the old pluto id format.
+ * 
+ * Pluto uses struct id for identification stuff. Since we need to convert from
+ * this format to our identification_t, we need this special constructor.
+ * 
+ * @param id           old pluto format id
+ * @return                     identification_t object
+ * 
+ * @ingroup utils
+ */
+// identification_t * identification_create_from_pluto_id(struct id *pluto_id);
+
 
 #endif /* IDENTIFICATION_H_ */
index 67c123b..0d90820 100644 (file)
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <dlfcn.h>
+#include <unistd.h>
 
 #include "leak_detective.h"
 
 #include <types.h>
+#include <utils/logger_manager.h>
 
 #ifdef LEAK_DETECTIVE
 
  */
 #define MEMORY_HEADER_MAGIC 0xF1367ADF
 
+/**
+ * logger for the leak detective
+ */
+logger_t *logger;
 
 static void install_hooks(void);
 static void uninstall_hooks(void);
@@ -103,37 +109,39 @@ memory_header_t first_header = {
  */
 void *old_malloc_hook, *old_realloc_hook, *old_free_hook;
 
-
+/**
+ * Mutex to exclusivly uninstall hooks, access heap list
+ */
 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
+void (*__malloc_initialize_hook) (void) = install_hooks;
 
 /**
  * log stack frames queried by backtrace()
  * TODO: Dump symbols of static functions!!!
  */
-void log_stack_frames(void *stack_frames, int stack_frame_count)
+void log_stack_frames(void **stack_frames, int stack_frame_count)
 {
        char **strings;
        size_t i;
 
        strings = backtrace_symbols (stack_frames, stack_frame_count);
 
-       printf("  dumping %d stack frames.\n", stack_frame_count);
+       logger->log(logger, ERROR, "  dumping %d stack frame addresses.", stack_frame_count);
 
        for (i = 0; i < stack_frame_count; i++)
        {
-               printf ("    %s\n", strings[i]);
+               logger->log(logger, ERROR, "    %s", strings[i]);
        }
        free (strings);
 }
 
-void (*__malloc_initialize_hook) (void) = install_hooks;
-
 /**
  * Installs the malloc hooks, enables leak detection
  */
 void install_hooks()
 {
+       logger = logger_manager->get_logger(logger_manager, LEAK_DETECT);
        old_malloc_hook = __malloc_hook;
        old_realloc_hook = __realloc_hook;
        old_free_hook = __free_hook;
@@ -200,10 +208,10 @@ static void free_hook(void *ptr, const void *caller)
                pthread_mutex_unlock(&mutex);
                /* TODO: Since we get a lot of theses from the pthread lib, its deactivated for now... */
                return;
-               printf("freeing of invalid memory (%p)\n", ptr);
+               logger->log(logger, ERROR, "freeing of invalid memory (%p)", ptr);
                stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT);
                log_stack_frames(stack_frames, stack_frame_count);
-               kill(0, SIGSEGV);
+               kill(getpid(), SIGKILL);
                return;
        }
        /* remove magic from hdr */
@@ -239,10 +247,10 @@ static void *realloc_hook(void *old, size_t bytes, const void *caller)
        }
        if (hdr->magic != MEMORY_HEADER_MAGIC)
        {
-               printf("reallocation of invalid memory (%p)\n", old);
+               logger->log(logger, ERROR, "reallocation of invalid memory (%p)", old);
                stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT);
                log_stack_frames(stack_frames, stack_frame_count);
-               kill(0, SIGSEGV);
+               kill(getpid(), SIGKILL);
                return NULL;
        }
        
@@ -264,20 +272,20 @@ void __attribute__ ((destructor)) report_leaks()
        
        for (hdr = first_header.next; hdr != NULL; hdr = hdr->next)
        {
-               printf("Leak (%d bytes at %p)\n", hdr->bytes, hdr + 1);
+               logger->log(logger, ERROR, "Leak (%d bytes at %p)", hdr->bytes, hdr + 1);
                log_stack_frames(hdr->stack_frames, hdr->stack_frame_count);
                leaks++;
        }
        switch (leaks)
        {
                case 0:
-                       printf("No leaks detected\n");
+                       logger->log(logger, CONTROL, "No leaks detected");
                        break;
                case 1:
-                       printf("One leak detected\n");
+                       logger->log(logger, ERROR, "One leak detected");
                        break;
                default:
-                       printf("%d leaks detected\n", leaks);
+                       logger->log(logger, ERROR, "%d leaks detected", leaks);
                        break;
        }
 }
@@ -304,13 +312,18 @@ char *inet_ntoa(struct in_addr in)
        handle = dlopen("libc.so.6", RTLD_LAZY);
        if (handle == NULL)
        {
-               kill(0, SIGSEGV);
+               install_hooks();
+               pthread_mutex_unlock(&mutex);
+               kill(getpid(), SIGSEGV);
        }
        _inet_ntoa = dlsym(handle, "inet_ntoa");
        
        if (_inet_ntoa == NULL)
        {
-               kill(0, SIGSEGV);
+               dlclose(handle);
+               install_hooks();
+               pthread_mutex_unlock(&mutex);
+               kill(getpid(), SIGSEGV);
        }
        result = _inet_ntoa(in);
        dlclose(handle);
@@ -336,13 +349,18 @@ int pthread_create(pthread_t *__restrict __threadp, __const pthread_attr_t *__re
        handle = dlopen("libpthread.so.0", RTLD_LAZY);
        if (handle == NULL)
        {
-               kill(0, SIGSEGV);
+               install_hooks();
+               pthread_mutex_unlock(&mutex);
+               kill(getpid(), SIGSEGV);
        }
        _pthread_create = dlsym(handle, "pthread_create");
        
        if (_pthread_create == NULL)
        {
-               kill(0, SIGSEGV);
+               dlclose(handle);
+               install_hooks();
+               pthread_mutex_unlock(&mutex);
+               kill(getpid(), SIGSEGV);
        }
        result = _pthread_create(__threadp, __attr, __start_routine, __arg);
        dlclose(handle);
@@ -364,13 +382,18 @@ time_t mktime(struct tm *tm)
        handle = dlopen("libc.so.6", RTLD_LAZY);
        if (handle == NULL)
        {
-               kill(0, SIGSEGV);
+               install_hooks();
+               pthread_mutex_unlock(&mutex);
+               kill(getpid(), SIGSEGV);
        }
        _mktime = dlsym(handle, "mktime");
 
        if (_mktime == NULL)
        {
-               kill(0, SIGSEGV);
+               dlclose(handle);
+               install_hooks();
+               pthread_mutex_unlock(&mutex);
+               kill(getpid(), SIGSEGV);
        }
        result = _mktime(tm);
        dlclose(handle);