scepclient and pluto use asn1 from libstrongswan
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 20 Apr 2009 20:53:38 +0000 (20:53 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 20 Apr 2009 20:53:38 +0000 (20:53 -0000)
38 files changed:
src/charon/Makefile.am
src/charon/plugins/nm/Makefile.am
src/charon/plugins/sql/Makefile.am
src/charon/plugins/stroke/Makefile.am
src/charon/plugins/updown/Makefile.am
src/dumm/Makefile.am
src/libstrongswan/Makefile.am
src/libstrongswan/asn1/asn1.c
src/libstrongswan/asn1/asn1.h
src/libstrongswan/asn1/asn1_parser.c
src/libstrongswan/asn1/asn1_parser.h
src/libstrongswan/chunk.c
src/libstrongswan/plugins/x509/Makefile.am
src/openac/Makefile.am
src/pluto/Makefile.am
src/pluto/ac.c
src/pluto/asn1.c [deleted file]
src/pluto/asn1.h [deleted file]
src/pluto/certs.c
src/pluto/certs.h
src/pluto/connections.c
src/pluto/crl.c
src/pluto/defs.c
src/pluto/defs.h
src/pluto/fetch.c
src/pluto/ipsec_doi.c
src/pluto/mp_defs.c
src/pluto/mp_defs.h
src/pluto/ocsp.c
src/pluto/pkcs1.c
src/pluto/pkcs7.c
src/pluto/x509.c
src/pluto/x509.h
src/scepclient/Makefile.am
src/scepclient/pkcs10.c
src/scepclient/rsakey.c
src/scepclient/scep.c
src/scepclient/scepclient.c

index 13c8710..037f819 100644 (file)
@@ -105,7 +105,8 @@ AM_CFLAGS = -rdynamic \
   -DIPSEC_PIDDIR=\"${piddir}\" \
   -DIPSEC_PLUGINDIR=\"${plugindir}\" \
   -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
-  -DRESOLV_CONF=\"${resolv_conf}\"
+  -DRESOLV_CONF=\"${resolv_conf}\" \
+  -Wformat=0
 charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lm -ldl
 
 EXTRA_DIST = config/proposal_keywords.txt
index 9c8c64f..ffd38e8 100644 (file)
@@ -1,7 +1,7 @@
 
 INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon ${nm_CFLAGS}
 
-AM_CFLAGS = -rdynamic
+AM_CFLAGS = -rdynamic -Wformat=0
 
 plugin_LTLIBRARIES = libstrongswan-nm.la
 libstrongswan_nm_la_SOURCES = \
index ea39ce0..1e96944 100644 (file)
@@ -4,7 +4,8 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
 AM_CFLAGS = -rdynamic \
   -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
   -DIPSEC_PLUGINDIR=\"${plugindir}\" \
-  -DPLUGINS=\""${libstrongswan_plugins}\""
+  -DPLUGINS=\""${libstrongswan_plugins}\"" \
+  -Wformat=0
 
 plugin_LTLIBRARIES = libstrongswan-sql.la
 libstrongswan_sql_la_SOURCES = sql_plugin.h sql_plugin.c \
index 7a34110..a8ab074 100644 (file)
@@ -1,7 +1,10 @@
 
 INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke
 
-AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
+AM_CFLAGS = \
+-rdynamic -Wformat=0 \
+-DIPSEC_CONFDIR=\"${confdir}\" \
+-DIPSEC_PIDDIR=\"${piddir}\"
 
 plugin_LTLIBRARIES = libstrongswan-stroke.la
 
index de60d9f..21bb733 100644 (file)
@@ -1,7 +1,7 @@
 
 INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
 
-AM_CFLAGS = -rdynamic
+AM_CFLAGS = -rdynamic -Wformat=0
 
 plugin_LTLIBRARIES = libstrongswan-updown.la
 libstrongswan_updown_la_SOURCES = \
index 029290f..7307676 100644 (file)
@@ -16,4 +16,6 @@ irdumm_LDADD = libdumm.la -lruby1.8
 
 INCLUDES = -I$(top_srcdir)/src/libstrongswan ${gtk_CFLAGS} \
   -I/usr/lib/ruby/1.8/i486-linux/
-AM_CFLAGS = -D_FILE_OFFSET_BITS=64
+AM_CFLAGS = \
+-D_FILE_OFFSET_BITS=64 \
+-Wformat=0
index f18549e..c8c94ac 100644 (file)
@@ -63,6 +63,8 @@ enum.c enum.h \
 printf_hook.c printf_hook.h \
 settings.c settings.h \
 utils.c utils.h \
+asn1/asn1.c asn1/asn1.h \
+asn1/asn1_parser.c asn1/asn1_parser.h \
 asn1/oid.c asn1/oid.h \
 utils/enumerator.c utils/enumerator.h \
 utils/lexparser.c utils/lexparser.h \
@@ -70,8 +72,10 @@ utils/linked_list.c utils/linked_list.h \
 utils/optionsfrom.c utils/optionsfrom.h
 
 INCLUDES = -I$(top_srcdir)/src/libstrongswan
-AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \
-                       -DIPSEC_PLUGINDIR=\"${plugindir}\"
+AM_CFLAGS = \
+-DIPSEC_DIR=\"${ipsecdir}\" \
+-DIPSEC_PLUGINDIR=\"${plugindir}\" \
+-Wformat=0
 
 if USE_LEAK_DETECTIVE
   AM_CFLAGS += -DLEAK_DETECTIVE
index fa614ef..de8c5ea 100644 (file)
@@ -21,7 +21,7 @@
 #include <string.h>
 #include <time.h>
 
-#include <library.h>
+#include <utils.h>
 #include <debug.h>
 
 #include "oid.h"
index cc0010a..e29ffa8 100644 (file)
@@ -27,7 +27,8 @@
 
 #include <stdarg.h>
 
-#include <library.h>
+#include <utils.h>
+#include <chunk.h>
 
 /**
  * Definition of some primitive ASN1 types
index 68c5e73..e6ca599 100644 (file)
@@ -21,7 +21,7 @@
 #include <string.h>
 #include <time.h>
 
-#include <library.h>
+#include <utils.h>
 #include <debug.h>
 
 #include "asn1.h"
index f0e2112..6ac74ad 100644 (file)
@@ -27,7 +27,9 @@
 
 #include <stdarg.h>
 
-#include <library.h>
+#include <utils.h>
+#include <chunk.h>
+#include <asn1/asn1.h>
 
 /**
  * Definition of ASN.1 flags
index 24ac5e8..d165300 100644 (file)
@@ -225,13 +225,13 @@ bool chunk_write(chunk_t chunk, char *path, char *label, mode_t mask, bool force
        {
                if (fwrite(chunk.ptr, sizeof(u_char), chunk.len, fd) == chunk.len)
                {
-                       DBG1("  written to %s file '%s' (%d bytes)",
+                       DBG1("  written %s file '%s' (%d bytes)",
                                 label, path, chunk.len);
                        good = TRUE;
                }
                else
                {
-                       DBG1("  writing to %s file '%s' failed: %s",
+                       DBG1("  writing %s file '%s' failed: %s",
                                 label, path, strerror(errno));
                }
                fclose(fd);
index 3f9f85c..a4f3990 100644 (file)
@@ -1,7 +1,7 @@
 
 INCLUDES = -I$(top_srcdir)/src/libstrongswan
 
-AM_CFLAGS = -rdynamic
+AM_CFLAGS = -rdynamic -Wformat=0
 
 plugin_LTLIBRARIES = libstrongswan-x509.la
 
index 0054867..cc9b72e 100644 (file)
@@ -7,6 +7,7 @@ AM_CFLAGS = \
   -DIPSEC_CONFDIR=\"${confdir}\" \
   -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
   -DIPSEC_PLUGINDIR=\"${plugindir}\" \
-  -DPLUGINS=\""${libstrongswan_plugins}\""
+  -DPLUGINS=\""${libstrongswan_plugins}\"" \
+  -Wformat=0
 openac_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lgmp
 
index d6db237..78862ba 100644 (file)
@@ -7,7 +7,6 @@ ipsec_PROGRAMS = pluto _pluto_adns
 pluto_SOURCES = \
 ac.c ac.h \
 alg_info.c alg_info.h \
-asn1.c asn1.h \
 ca.c ca.h \
 certs.c certs.h \
 connections.c connections.h \
@@ -87,7 +86,8 @@ AM_CFLAGS = \
 -DSHARED_SECRETS_FILE=\"${confdir}/ipsec.secrets\" \
 -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
 -DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES \
--DPLUTO -DKLIPS -DDEBUG
+-DPLUTO -DKLIPS -DDEBUG \
+-Wformat=0
 
 pluto_LDADD = \
 $(LIBSTRONGSWANDIR)/libstrongswan-lite.la \
index d661557..302cc67 100644 (file)
 
 #include <freeswan.h>
 
-#include "constants.h"
-#include "defs.h"
-#include "asn1.h"
+#include <utils.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
 #include <asn1/oid.h>
+
 #include "ac.h"
 #include "x509.h"
 #include "crl.h"
 #include "whack.h"
 #include "fetch.h"
 
-/* chained list of X.509 attribute certificates */
-
+/**
+ * Chained list of X.509 attribute certificates
+ */
 static x509acert_t *x509acerts   = NULL;
 
-/* chained list of ietfAttributes */
-
+/**
+ * Chained list of ietfAttributes
+ */
 static ietfAttrList_t *ietfAttributes = NULL;
 
-/* ASN.1 definition of ietfAttrSyntax */
-
+/**
+ * ASN.1 definition of ietfAttrSyntax
+ */
 static const asn1Object_t ietfAttrSyntaxObjects[] =
 {
-  { 0, "ietfAttrSyntax",                ASN1_SEQUENCE,        ASN1_NONE }, /*  0 */
-  { 1,   "policyAuthority",             ASN1_CONTEXT_C_0,     ASN1_OPT |
-                                                                                                                         ASN1_BODY }, /*  1 */
-  { 1,   "end opt",                     ASN1_EOC,             ASN1_END  }, /*  2 */
-  { 1,   "values",                      ASN1_SEQUENCE,        ASN1_LOOP }, /*  3 */
-  { 2,     "octets",                    ASN1_OCTET_STRING,    ASN1_OPT |
-                                                                                                                         ASN1_BODY }, /*  4 */
-  { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  5 */
-  { 2,     "oid",                       ASN1_OID,             ASN1_OPT |
-                                                                                                                         ASN1_BODY }, /*  6 */
-  { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  7 */
-  { 2,     "string",                    ASN1_UTF8STRING,      ASN1_OPT |
-                                                                                                                         ASN1_BODY }, /*  8 */
-  { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  9 */
-  { 1,   "end loop",                    ASN1_EOC,             ASN1_END  }  /* 10 */
+       { 0, "ietfAttrSyntax",                ASN1_SEQUENCE,        ASN1_NONE }, /*  0 */
+       { 1,   "policyAuthority",             ASN1_CONTEXT_C_0,     ASN1_OPT |
+                                                                                                                               ASN1_BODY }, /*  1 */
+       { 1,   "end opt",                     ASN1_EOC,             ASN1_END  }, /*  2 */
+       { 1,   "values",                      ASN1_SEQUENCE,        ASN1_LOOP }, /*  3 */
+       { 2,     "octets",                    ASN1_OCTET_STRING,    ASN1_OPT |
+                                                                                                                               ASN1_BODY }, /*  4 */
+       { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  5 */
+       { 2,     "oid",                       ASN1_OID,             ASN1_OPT |
+                                                                                                                               ASN1_BODY }, /*  6 */
+       { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  7 */
+       { 2,     "string",                    ASN1_UTF8STRING,      ASN1_OPT |
+                                                                                                                               ASN1_BODY }, /*  8 */
+       { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  9 */
+       { 1,   "end loop",                    ASN1_EOC,             ASN1_END  }, /* 10 */
+       { 0, "exit",                          ASN1_EOC,             ASN1_EXIT }
 };
 
 #define IETF_ATTR_OCTETS         4
 #define IETF_ATTR_OID            6
 #define IETF_ATTR_STRING         8
-#define IETF_ATTR_ROOF          11
-
-/* ASN.1 definition of roleSyntax */
 
+/**
+ * ASN.1 definition of roleSyntax
+ */
 static const asn1Object_t roleSyntaxObjects[] =
 {
-  { 0, "roleSyntax",                    ASN1_SEQUENCE,        ASN1_NONE }, /*  0 */
-  { 1,   "roleAuthority",               ASN1_CONTEXT_C_0,     ASN1_OPT |
-                                                                                                                         ASN1_OBJ  }, /*  1 */
-  { 1,   "end opt",                     ASN1_EOC,             ASN1_END  }, /*  2 */
-  { 1,   "roleName",                    ASN1_CONTEXT_C_1,     ASN1_OBJ  }  /*  3 */
+       { 0, "roleSyntax",              ASN1_SEQUENCE,          ASN1_NONE }, /* 0 */
+       { 1,   "roleAuthority", ASN1_CONTEXT_C_0,       ASN1_OPT |
+                                                                                               ASN1_OBJ  }, /* 1 */
+       { 1,   "end opt",               ASN1_EOC,                       ASN1_END  }, /* 2 */
+       { 1,   "roleName",              ASN1_CONTEXT_C_1,       ASN1_OBJ  }, /* 3 */
+       { 0, "exit",                    ASN1_EOC,                       ASN1_EXIT }
 };
 
-#define ROLE_ROOF               4
-
-/* ASN.1 definition of an X509 attribute certificate */
-
+/**
+ * ASN.1 definition of an X509 attribute certificate
+ */
 static const asn1Object_t acObjects[] =
 {
-  { 0, "AttributeCertificate",          ASN1_SEQUENCE,        ASN1_OBJ  }, /*  0 */
-  { 1,   "AttributeCertificateInfo",    ASN1_SEQUENCE,        ASN1_OBJ  }, /*  1 */
-  { 2,     "version",                   ASN1_INTEGER,         ASN1_DEF |
-                                                                                                                         ASN1_BODY }, /*  2 */
-  { 2,     "holder",                    ASN1_SEQUENCE,        ASN1_NONE }, /*  3 */
-  { 3,       "baseCertificateID",       ASN1_CONTEXT_C_0,     ASN1_OPT  }, /*  4 */
-  { 4,         "issuer",                ASN1_SEQUENCE,        ASN1_OBJ  }, /*  5 */
-  { 4,         "serial",                ASN1_INTEGER,         ASN1_BODY }, /*  6 */
-  { 4,         "issuerUID",             ASN1_BIT_STRING,      ASN1_OPT |
-                                                                                                                         ASN1_BODY }, /*  7 */
-  { 4,         "end opt",               ASN1_EOC,             ASN1_END  }, /*  8 */
-  { 3,       "end opt",                 ASN1_EOC,             ASN1_END  }, /*  9 */
-  { 3,       "entityName",              ASN1_CONTEXT_C_1,     ASN1_OPT |
-                                                                                                                         ASN1_OBJ  }, /* 10 */
-  { 3,       "end opt",                 ASN1_EOC,             ASN1_END  }, /* 11 */
-  { 3,       "objectDigestInfo",        ASN1_CONTEXT_C_2,     ASN1_OPT  }, /* 12 */
-  { 4,         "digestedObjectType",    ASN1_ENUMERATED,      ASN1_BODY }, /* 13*/
-  { 4,         "otherObjectTypeID",     ASN1_OID,             ASN1_OPT |
-                                                                                                                         ASN1_BODY }, /* 14 */
-  { 4,         "end opt",               ASN1_EOC,             ASN1_END  }, /* 15*/
-  { 4,         "digestAlgorithm",       ASN1_EOC,             ASN1_RAW  }, /* 16 */
-  { 3,       "end opt",                 ASN1_EOC,             ASN1_END  }, /* 17 */
-  { 2,     "v2Form",                    ASN1_CONTEXT_C_0,     ASN1_NONE }, /* 18 */
-  { 3,       "issuerName",              ASN1_SEQUENCE,        ASN1_OPT |
-                                                                                                                         ASN1_OBJ  }, /* 19 */
-  { 3,       "end opt",                 ASN1_EOC,             ASN1_END  }, /* 20 */
-  { 3,       "baseCertificateID",       ASN1_CONTEXT_C_0,     ASN1_OPT  }, /* 21 */
-  { 4,         "issuerSerial",          ASN1_SEQUENCE,        ASN1_NONE }, /* 22 */
-  { 5,           "issuer",              ASN1_SEQUENCE,        ASN1_OBJ  }, /* 23 */
-  { 5,           "serial",              ASN1_INTEGER,         ASN1_BODY }, /* 24 */
-  { 5,           "issuerUID",           ASN1_BIT_STRING,      ASN1_OPT |
-                                                                                                                         ASN1_BODY }, /* 25 */
-  { 5,           "end opt",             ASN1_EOC,             ASN1_END  }, /* 26 */
-  { 3,       "end opt",                 ASN1_EOC,             ASN1_END  }, /* 27 */
-  { 3,       "objectDigestInfo",        ASN1_CONTEXT_C_1,     ASN1_OPT  }, /* 28 */
-  { 4,         "digestInfo",            ASN1_SEQUENCE,        ASN1_OBJ  }, /* 29 */
-  { 5,           "digestedObjectType",  ASN1_ENUMERATED,      ASN1_BODY }, /* 30 */
-  { 5,           "otherObjectTypeID",   ASN1_OID,             ASN1_OPT |
-                                                                                                                         ASN1_BODY }, /* 31 */
-  { 5,           "end opt",             ASN1_EOC,             ASN1_END  }, /* 32 */
-  { 5,           "digestAlgorithm",     ASN1_EOC,             ASN1_RAW  }, /* 33 */
-  { 3,       "end opt",                 ASN1_EOC,             ASN1_END  }, /* 34 */
-  { 2,     "signature",                 ASN1_EOC,             ASN1_RAW  }, /* 35 */
-  { 2,     "serialNumber",              ASN1_INTEGER,         ASN1_BODY }, /* 36 */
-  { 2,     "attrCertValidityPeriod",    ASN1_SEQUENCE,        ASN1_NONE }, /* 37 */
-  { 3,       "notBeforeTime",           ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
-  { 3,       "notAfterTime",            ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
-  { 2,     "attributes",                ASN1_SEQUENCE,        ASN1_LOOP }, /* 40 */
-  { 3,       "attribute",               ASN1_SEQUENCE,        ASN1_NONE }, /* 41 */
-  { 4,         "type",                  ASN1_OID,             ASN1_BODY }, /* 42 */
-  { 4,         "values",                ASN1_SET,             ASN1_LOOP }, /* 43 */
-  { 5,           "value",               ASN1_EOC,             ASN1_RAW  }, /* 44 */
-  { 4,         "end loop",              ASN1_EOC,             ASN1_END  }, /* 45 */
-  { 2,     "end loop",                  ASN1_EOC,             ASN1_END  }, /* 46 */
-  { 2,     "extensions",                ASN1_SEQUENCE,        ASN1_LOOP }, /* 47 */
-  { 3,       "extension",               ASN1_SEQUENCE,        ASN1_NONE }, /* 48 */
-  { 4,         "extnID",                ASN1_OID,             ASN1_BODY }, /* 49 */
-  { 4,         "critical",              ASN1_BOOLEAN,         ASN1_DEF |
-                                                                                                                         ASN1_BODY }, /* 50 */
-  { 4,         "extnValue",             ASN1_OCTET_STRING,    ASN1_BODY }, /* 51 */
-  { 2,     "end loop",                  ASN1_EOC,             ASN1_END  }, /* 52 */
-  { 1,   "signatureAlgorithm",          ASN1_EOC,             ASN1_RAW  }, /* 53 */
-  { 1,   "signatureValue",              ASN1_BIT_STRING,      ASN1_BODY }  /* 54 */
+       { 0, "AttributeCertificate",                    ASN1_SEQUENCE,            ASN1_OBJ  }, /*  0 */
+       { 1,   "AttributeCertificateInfo",              ASN1_SEQUENCE,            ASN1_OBJ  }, /*  1 */
+       { 2,       "version",                                   ASN1_INTEGER,             ASN1_DEF |
+                                                                                                                                 ASN1_BODY }, /*  2 */
+       { 2,       "holder",                                    ASN1_SEQUENCE,            ASN1_NONE }, /*  3 */
+       { 3,         "baseCertificateID",               ASN1_CONTEXT_C_0,         ASN1_OPT  }, /*  4 */
+       { 4,           "issuer",                                ASN1_SEQUENCE,            ASN1_OBJ  }, /*  5 */
+       { 4,           "serial",                                ASN1_INTEGER,             ASN1_BODY }, /*  6 */
+       { 4,         "issuerUID",                               ASN1_BIT_STRING,          ASN1_OPT |
+                                                                                                                                 ASN1_BODY }, /*  7 */
+       { 4,         "end opt",                                 ASN1_EOC,                         ASN1_END  }, /*  8 */
+       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /*  9 */
+       { 3,       "entityName",                                ASN1_CONTEXT_C_1,         ASN1_OPT |
+                                                                                                                                 ASN1_OBJ  }, /* 10 */
+       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 11 */
+       { 3,         "objectDigestInfo",                ASN1_CONTEXT_C_2,         ASN1_OPT  }, /* 12 */
+       { 4,           "digestedObjectType",    ASN1_ENUMERATED,          ASN1_BODY }, /* 13 */
+       { 4,           "otherObjectTypeID",             ASN1_OID,                         ASN1_OPT |
+                                                                                                                                 ASN1_BODY }, /* 14 */
+       { 4,         "end opt",                                 ASN1_EOC,                         ASN1_END  }, /* 15 */
+       { 4,         "digestAlgorithm",                 ASN1_EOC,                         ASN1_RAW  }, /* 16 */
+       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 17 */
+       { 2,       "v2Form",                                    ASN1_CONTEXT_C_0,         ASN1_NONE }, /* 18 */
+       { 3,         "issuerName",                              ASN1_SEQUENCE,            ASN1_OPT |
+                                                                                                                                 ASN1_OBJ  }, /* 19 */
+       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 20 */
+       { 3,         "baseCertificateID",               ASN1_CONTEXT_C_0,         ASN1_OPT  }, /* 21 */
+       { 4,           "issuerSerial",                  ASN1_SEQUENCE,            ASN1_NONE }, /* 22 */
+       { 5,             "issuer",                              ASN1_SEQUENCE,            ASN1_OBJ  }, /* 23 */
+       { 5,             "serial",                                      ASN1_INTEGER,             ASN1_BODY }, /* 24 */
+       { 5,           "issuerUID",                             ASN1_BIT_STRING,          ASN1_OPT |
+                                                                                                                                 ASN1_BODY }, /* 25 */
+       { 5,           "end opt",                               ASN1_EOC,                         ASN1_END  }, /* 26 */
+       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 27 */
+       { 3,       "objectDigestInfo",                  ASN1_CONTEXT_C_1,         ASN1_OPT  }, /* 28 */
+       { 4,           "digestInfo",                    ASN1_SEQUENCE,            ASN1_OBJ  }, /* 29 */
+       { 5,     "digestedObjectType",                  ASN1_ENUMERATED,          ASN1_BODY }, /* 30 */
+       { 5,             "otherObjectTypeID",           ASN1_OID,                         ASN1_OPT |
+                                                                                                                                 ASN1_BODY }, /* 31 */
+       { 5,           "end opt",                               ASN1_EOC,                         ASN1_END  }, /* 32 */
+       { 5,           "digestAlgorithm",               ASN1_EOC,                         ASN1_RAW  }, /* 33 */
+       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 34 */
+       { 2,       "signature",                                 ASN1_EOC,                         ASN1_RAW  }, /* 35 */
+       { 2,       "serialNumber",                              ASN1_INTEGER,             ASN1_BODY }, /* 36 */
+       { 2,       "attrCertValidityPeriod",    ASN1_SEQUENCE,            ASN1_NONE }, /* 37 */
+       { 3,         "notBeforeTime",                   ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
+       { 3,         "notAfterTime",                    ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
+       { 2,       "attributes",                                ASN1_SEQUENCE,            ASN1_LOOP }, /* 40 */
+       { 3,       "attribute",                                 ASN1_SEQUENCE,            ASN1_NONE }, /* 41 */
+       { 4,         "type",                                    ASN1_OID,                         ASN1_BODY }, /* 42 */
+       { 4,         "values",                                  ASN1_SET,                         ASN1_LOOP }, /* 43 */
+       { 5,           "value",                                 ASN1_EOC,                         ASN1_RAW  }, /* 44 */
+       { 4,           "end loop",                              ASN1_EOC,                         ASN1_END  }, /* 45 */
+       { 2,     "end loop",                                    ASN1_EOC,                         ASN1_END  }, /* 46 */
+       { 2,     "extensions",                                  ASN1_SEQUENCE,            ASN1_LOOP }, /* 47 */
+       { 3,       "extension",                                 ASN1_SEQUENCE,            ASN1_NONE }, /* 48 */
+       { 4,         "extnID",                                  ASN1_OID,                         ASN1_BODY }, /* 49 */
+       { 4,         "critical",                                ASN1_BOOLEAN,             ASN1_DEF |
+                                                                                                                                 ASN1_BODY }, /* 50 */
+       { 4,         "extnValue",                               ASN1_OCTET_STRING,        ASN1_BODY }, /* 51 */
+       { 2,     "end loop",                                    ASN1_EOC,                         ASN1_END  }, /* 52 */
+       { 1,   "signatureAlgorithm",                    ASN1_EOC,                         ASN1_RAW  }, /* 53 */
+       { 1,   "signatureValue",                                ASN1_BIT_STRING,          ASN1_BODY }, /* 54 */
+       { 0, "exit",                                                    ASN1_EOC,                         ASN1_EXIT }
 };
 
 #define AC_OBJ_CERTIFICATE               0
@@ -173,7 +179,6 @@ static const asn1Object_t acObjects[] =
 #define AC_OBJ_EXTN_VALUE               51
 #define AC_OBJ_ALGORITHM                53
 #define AC_OBJ_SIGNATURE                54
-#define AC_OBJ_ROOF                     55
 
 const x509acert_t empty_ac = {
          NULL     , /* *next */
@@ -208,11 +213,11 @@ const x509acert_t empty_ac = {
 };
 
 
-/*  compare two ietfAttributes, returns zero if a equals b
+/**
+ *  compare two ietfAttributes, returns zero if a equals b
  *  negative/positive if a is earlier/later in the alphabet than b
  */
-static int
-cmp_ietfAttr(ietfAttr_t *a,ietfAttr_t *b)
+static int cmp_ietfAttr(ietfAttr_t *a,ietfAttr_t *b)
 {
        int cmp_len, len, cmp_value;
 
@@ -227,11 +232,10 @@ cmp_ietfAttr(ietfAttr_t *a,ietfAttr_t *b)
        return (cmp_value == 0)? cmp_len : cmp_value;
 }
 
-/*
+/**
  *  add an ietfAttribute to the chained list
  */
-static ietfAttr_t*
-add_ietfAttr(ietfAttr_t *attr)
+static ietfAttr_t* add_ietfAttr(ietfAttr_t *attr)
 {
        ietfAttrList_t **listp = &ietfAttributes;
        ietfAttrList_t *list = *listp;
@@ -270,11 +274,10 @@ add_ietfAttr(ietfAttr_t *attr)
        }
 }
 
-/*
+/**
  * decodes a comma separated list of group attributes
  */
-void
-decode_groups(char *groups, ietfAttrList_t **listp)
+void decode_groups(char *groups, ietfAttrList_t **listp)
 {
        if (groups == NULL)
                return;
@@ -316,15 +319,13 @@ decode_groups(char *groups, ietfAttrList_t **listp)
        }
 }
 
-static bool
-same_attribute(const ietfAttr_t *a, const ietfAttr_t *b)
+static bool same_attribute(const ietfAttr_t *a, const ietfAttr_t *b)
 {
        return (a->kind == b->kind && a->value.len == b->value.len
                   && memeq(a->value.ptr, b->value.ptr, b->value.len));
 }
 
-bool
-group_membership(const ietfAttrList_t *peer_list
+bool group_membership(const ietfAttrList_t *peer_list
                           , const char *conn
                           , const ietfAttrList_t *conn_list)
 {
@@ -359,9 +360,7 @@ group_membership(const ietfAttrList_t *peer_list
        return FALSE;
 }
 
-
-void
-unshare_ietfAttrList(ietfAttrList_t **listp)
+void unshare_ietfAttrList(ietfAttrList_t **listp)
 {
        ietfAttrList_t *list = *listp;
 
@@ -378,26 +377,22 @@ unshare_ietfAttrList(ietfAttrList_t **listp)
        }
 }
 
-/*
- * parses ietfAttrSyntax
+/**
+ * Parses ietfAttrSyntax
  */
-static ietfAttrList_t*
-parse_ietfAttrSyntax(chunk_t blob, int level0)
+static ietfAttrList_t* parse_ietfAttrSyntax(chunk_t blob, int level0)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
 
        ietfAttrList_t *list = NULL;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+       parser = asn1_parser_create(ietfAttrSyntaxObjects, blob);
+       parser->set_top_level(parser, level0);
 
-       while (objectID < IETF_ATTR_ROOF)
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(ietfAttrSyntaxObjects, &objectID, &object, &level, &ctx))
-                        return NULL;
-
                switch (objectID)
                {
                case IETF_ATTR_OCTETS:
@@ -419,59 +414,52 @@ parse_ietfAttrSyntax(chunk_t blob, int level0)
                default:
                        break;
                }
-               objectID++;
        }
+       parser->destroy(parser);
        return list;
 }
-/*
- * parses roleSyntax
+
+/**
+ * Parses roleSyntax
  */
-static void
-parse_roleSyntax(chunk_t blob, int level0)
+static void parse_roleSyntax(chunk_t blob, int level0)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+       parser = asn1_parser_create(roleSyntaxObjects, blob);
+       parser->set_top_level(parser, level0);
 
-       while (objectID < ROLE_ROOF)
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx))
-                        return;
-
-               switch (objectID) {
-               default:
-                       break;
+               switch (objectID)
+               {
+                       default:
+                               break;
                }
-               objectID++;
        }
+       parser->destroy(parser);
 }
 
-/*
+/**
  *  Parses an X.509 attribute certificate
  */
-bool
-parse_ac(chunk_t blob, x509acert_t *ac)
+bool parse_ac(chunk_t blob, x509acert_t *ac)
 {
-       asn1_ctx_t ctx;
-       bool critical;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
        int type = OID_UNKNOWN;
        int extn_oid = OID_UNKNOWN;
+       bool success = FALSE;
+       bool critical;
 
-       asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
-
-       while (objectID < AC_OBJ_ROOF) {
-
-               if (!extract_object(acObjects, &objectID, &object, &level, &ctx))
-                        return FALSE;
+       parser = asn1_parser_create(acObjects, blob);
 
-               /* those objects which will parsed further need the next higher level */
-               level++;
+       while (parser->iterate(parser, &objectID, &object))
+       {
+               u_int level = parser->get_level(parser)+1;
 
                switch (objectID)
                {
@@ -490,7 +478,7 @@ parse_ac(chunk_t blob, x509acert_t *ac)
                        {
                                plog("v%d attribute certificates are not supported"
                                        , ac->version);
-                               return FALSE;
+                               goto end;
                        }
                        break;
                case AC_OBJ_HOLDER_ISSUER:
@@ -506,16 +494,16 @@ parse_ac(chunk_t blob, x509acert_t *ac)
                        ac->issuerName = get_directoryName(object, level, FALSE);
                        break;
                case AC_OBJ_SIG_ALG:
-                       ac->sigAlg = parse_algorithmIdentifier(object, level, NULL);
+                       ac->sigAlg = asn1_parse_algorithmIdentifier(object, level, NULL);
                        break;
                case AC_OBJ_SERIAL_NUMBER:
                        ac->serialNumber = object;
                        break;
                case AC_OBJ_NOT_BEFORE:
-                       ac->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME);
+                       ac->notBefore = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                        break;
                case AC_OBJ_NOT_AFTER:
-                       ac->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME);
+                       ac->notAfter = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                        break;
                case AC_OBJ_ATTRIBUTE_TYPE:
                        type = asn1_known_oid(object);
@@ -582,7 +570,7 @@ parse_ac(chunk_t blob, x509acert_t *ac)
                        }
                        break;
                case AC_OBJ_ALGORITHM:
-                       ac->algorithm = parse_algorithmIdentifier(object, level, NULL);
+                       ac->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
                        break;
                case AC_OBJ_SIGNATURE:
                        ac->signature = object;
@@ -591,17 +579,19 @@ parse_ac(chunk_t blob, x509acert_t *ac)
                default:
                        break;
                }
-               objectID++;
        }
+       success = parser->success(parser);
        time(&ac->installed);
-       return TRUE;
+
+end:
+       parser->destroy(parser);
+       return success;
 }
 
-/*
- *  release an ietfAttribute, free it if count reaches zero
+/**
+ *  Release an ietfAttribute, free it if count reaches zero
  */
-static void
-release_ietfAttr(ietfAttr_t* attr)
+static void release_ietfAttr(ietfAttr_t* attr)
 {
        if (--attr->count == 0)
        {
@@ -621,11 +611,10 @@ release_ietfAttr(ietfAttr_t* attr)
        }
 }
 
-/*
- *  free an ietfAttrList
+/**
+ *  Free an ietfAttrList
  */
-void
-free_ietfAttrList(ietfAttrList_t* list)
+void free_ietfAttrList(ietfAttrList_t* list)
 {
        while (list != NULL)
        {
@@ -637,11 +626,10 @@ free_ietfAttrList(ietfAttrList_t* list)
        }
 }
 
-/*
- *  free a X.509 attribute certificate
+/**
+ *  Free a X.509 attribute certificate
  */
-void
-free_acert(x509acert_t *ac)
+void free_acert(x509acert_t *ac)
 {
        if (ac != NULL)
        {
@@ -652,32 +640,29 @@ free_acert(x509acert_t *ac)
        }
 }
 
-/*
- *  free first X.509 attribute certificate in the chained list
+/**
+ *  Free first X.509 attribute certificate in the chained list
  */
-static void
-free_first_acert(void)
+static void free_first_acert(void)
 {
        x509acert_t *first = x509acerts;
        x509acerts = first->next;
        free_acert(first);
 }
 
-/*
+/**
  * Free all attribute certificates in the chained list
  */
-void
-free_acerts(void)
-{
+void free_acerts(void)
+{ 
        while (x509acerts != NULL)
                free_first_acert();
 }
 
-/*
- *  get a X.509 attribute certificate for a given holder
+/**
+ *  Get a X.509 attribute certificate for a given holder
  */
-x509acert_t*
-get_x509acert(chunk_t issuer, chunk_t serial)
+x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial)
 {
        x509acert_t *ac = x509acerts;
        x509acert_t *prev_ac = NULL;
@@ -702,11 +687,10 @@ get_x509acert(chunk_t issuer, chunk_t serial)
        return NULL;
 }
 
-/*
- *  add a X.509 attribute certificate to the chained list
+/**
+ *  Add a X.509 attribute certificate to the chained list
  */
-static void
-add_acert(x509acert_t *ac)
+static void add_acert(x509acert_t *ac)
 {
        x509acert_t *old_ac = get_x509acert(ac->holderIssuer, ac->holderSerial);
 
@@ -736,11 +720,11 @@ add_acert(x509acert_t *ac)
        x509acerts = ac;
 }
 
-/* verify the validity of an attribute certificate by
+/**
+ * Verify the validity of an attribute certificate by
  * checking the notBefore and notAfter dates
  */
-static err_t
-check_ac_validity(const x509acert_t *ac)
+static err_t check_ac_validity(const x509acert_t *ac)
 {
        time_t current_time;
 
@@ -759,11 +743,10 @@ check_ac_validity(const x509acert_t *ac)
                return NULL;
 }
 
-/*
+/**
  * verifies a X.509 attribute certificate
  */
-bool
-verify_x509acert(x509acert_t *ac, bool strict)
+bool verify_x509acert(x509acert_t *ac, bool strict)
 {
        u_char buf[BUF_LEN];
        x509cert_t *aacert;
@@ -815,11 +798,10 @@ verify_x509acert(x509acert_t *ac, bool strict)
        return verify_x509cert(aacert, strict, &valid_until);
 }
 
-/*
+/**
  * Loads X.509 attribute certificates
  */
-void
-load_acerts(void)
+void load_acerts(void)
 {
        u_char buf[BUF_LEN];
 
@@ -862,11 +844,10 @@ load_acerts(void)
        ignore_result(chdir(save_dir));
 }
 
-/*
+/**
  * lists group attributes separated by commas on a single line
  */
-void
-format_groups(const ietfAttrList_t *list, char *buf, int len)
+void format_groups(const ietfAttrList_t *list, char *buf, int len)
 {
        bool first_group = TRUE;
 
@@ -894,11 +875,10 @@ format_groups(const ietfAttrList_t *list, char *buf, int len)
        }
 }
 
-/*
+/**
  *  list all X.509 attribute certificates in the chained list
  */
-void
-list_acerts(bool utc)
+void list_acerts(bool utc)
 {
        x509acert_t *ac = x509acerts;
        time_t now;
@@ -967,11 +947,10 @@ list_acerts(bool utc)
        }
 }
 
-/*
+/**
  *  list all group attributes in alphabetical order
  */
-void
-list_groups(bool utc)
+void list_groups(bool utc)
 {
        ietfAttrList_t *list = ietfAttributes;
        
diff --git a/src/pluto/asn1.c b/src/pluto/asn1.c
deleted file mode 100644 (file)
index b760539..0000000
+++ /dev/null
@@ -1,825 +0,0 @@
-/* Simple ASN.1 parser
- * Copyright (C) 2000-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.
- *
- * RCSID $Id$
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "asn1.h"
-#include <asn1/oid.h>
-#include "log.h"
-
-/* 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 definition of an algorithmIdentifier */
-
-static const asn1Object_t algorithmIdentifierObjects[] = {
-  { 0, "algorithmIdentifier",   ASN1_SEQUENCE,  ASN1_NONE }, /* 0 */
-  { 1,   "algorithm",           ASN1_OID,       ASN1_BODY }, /* 1 */
-  { 1,   "parameters",          ASN1_EOC,       ASN1_OPT |
-                                                                                               ASN1_RAW  }, /* 2 */
-  { 1,   "end opt",             ASN1_EOC,       ASN1_END  }  /* 3 */
-};
-
-#define ALGORITHM_ID_ALG                1
-#define ALGORITHM_ID_PARAMETERS         2
-#define ALGORITHM_ID_ROOF               4
-
-/*
- * 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_empty;
-       }
-}
-
-/*  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
-asn1_known_oid(chunk_t object)
-{
-       int oid = 0;
-
-       while (object.len)
-       {
-               if (oid_names[oid].octet == *object.ptr)
-               {
-                       if (--object.len == 0 || oid_names[oid].down == 0)
-                       {
-                               return oid;          /* found terminal symbol */
-                       }
-                       else
-                       {
-                               object.ptr++; oid++; /* advance to next hex octet */
-                       }
-               }
-               else
-               {
-                       if (oid_names[oid].next)
-                       {
-                               oid = oid_names[oid].next;
-                       }
-                       else
-                       {
-                               return OID_UNKNOWN;
-                       }
-               }
-       }
-       return -1;
-}
-
-/*
- * Converts a known OID index to an ASN.1 OID
- */ 
-chunk_t
-asn1_build_known_oid(int n)
-{
-       chunk_t oid;
-       int i;
-               
-       if (n < 0 || n >= OID_MAX)
-       {
-               return chunk_empty;
-       }
-               
-       i = oid_names[n].level + 1;
-       oid.ptr = malloc(2 + i);
-       oid.len = i;
-       oid.ptr[0] = ASN1_OID;
-       oid.ptr[1] = i;
-
-       do
-       {
-               if (oid_names[n].level >= i)
-               {
-                       n--;
-                       continue;
-               }
-               oid.ptr[--i + 2] = oid_names[n--].octet;
-       }
-       while (i > 0);
-               
-       return oid;
-}
-
-/*
- *  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)
-       {
-               DBG(DBG_PARSING,
-                       DBG_log("number of length octets is larger than ASN.1 object")
-               )
-               return ASN1_INVALID_LENGTH;
-       }
-
-       if (n > sizeof(len))
-       {
-               DBG(DBG_PARSING,
-                       DBG_log("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;
-}
-
-/*
- * 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 */
-   chunkcpy(pos, length);
-
-   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);
-       chunkcpy(pos, content);
-
-       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':
-                       mv_chunk(&pos, ch);
-                       break;
-               case 'c':
-               default:
-                       chunkcpy(pos, ch);
-               }
-       }
-       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 */
-       size_t size = 1 + bits / BITS_PER_BYTE;  /* size in bytes */
-       chunk_t n = mpz_to_n(value, size);
-
-       return asn1_wrap(ASN1_INTEGER, "m", n);
-}
-
-/*
- *  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;
-}
-
-#define TIME_MAX        0x7fffffff
-
-/*
- *  Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
- */
-time_t
-asn1totime(const chunk_t *utctime, asn1_t type)
-{
-       struct tm t;
-       time_t tc, 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 */
-       }
-
-       /* parse ASN.1 time string */
-       {
-               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;
-
-       /* convert to time_t */
-       tc = mktime(&t);
-
-       /* if no conversion overflow occurred, compensate timezone */
-       return (tc == -1) ? TIME_MAX : (tc - timezone - tz_offset);
-}
-
-/*
- *  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[BUF_LEN];
-       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);
-}
-
-
-/*
- * Initializes the internal context of the ASN.1 parser
- */
-void
-asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0,
-               bool implicit, u_int cond)
-{
-       ctx->blobs[0] = blob;
-       ctx->level0   = level0;
-       ctx->implicit = implicit;
-       ctx->cond     = cond;
-       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, u_int cond)
-{
-       int oid;
-
-       switch (type)
-       {
-       case ASN1_OID:
-               oid = asn1_known_oid(object);
-               if (oid != OID_UNKNOWN)
-               {
-                       DBG(DBG_PARSING,
-                               DBG_log("  '%s'",oid_names[oid].name);
-                       )
-                       return;
-               }
-               break;
-       case ASN1_UTF8STRING:
-       case ASN1_IA5STRING:
-       case ASN1_PRINTABLESTRING:
-       case ASN1_T61STRING:
-       case ASN1_VISIBLESTRING:
-               DBG(DBG_PARSING,
-                       DBG_log("  '%.*s'", (int)object.len, object.ptr);
-               )
-               return;
-       case ASN1_UTCTIME:
-       case ASN1_GENERALIZEDTIME:
-               DBG(DBG_PARSING,
-                       time_t time = asn1totime(&object, type);
-                       DBG_log("  '%T'", &time, TRUE);
-               )
-               return;
-       default:
-                break;
-       }
-       DBG(cond,
-               DBG_dump_chunk("", 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_empty;
-
-       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 */
-               DBG(DBG_PARSING,
-                       DBG_log("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)
-       {
-               DBG(DBG_PARSING,
-                       DBG_log("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)
-       {
-               DBG(DBG_PARSING,
-                       DBG_log("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)
-       {
-               DBG(DBG_PARSING,
-                       DBG_log("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))
-       {
-               DBG(DBG_PARSING,
-                       DBG_log("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
-                               *level, obj.name, obj.type, *start_ptr);
-                       DBG_dump("", start_ptr, (u_int)(blob->ptr - start_ptr));
-               )
-               return FALSE;
-       }
-
-       DBG(DBG_PARSING,
-               DBG_log("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);
-               DBG(ctx->cond,
-                       DBG_dump_chunk("", *object);
-               )
-       }
-       else if (obj.flags & ASN1_BODY)
-       {
-               *object = *blob1;
-               debug_asn1_simple_object(*object, obj.type, ctx->cond);
-       }
-       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)
-       {
-               DBG(DBG_PARSING,
-                       DBG_log("L%d - %s:  ASN.1 object smaller than 2 octets",
-                                       level, name);
-               )
-               return FALSE;
-       }
-
-       if (*object->ptr != type)
-       {
-               DBG(DBG_PARSING,
-                       DBG_log("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)
-       {
-               DBG(DBG_PARSING,
-                       DBG_log("L%d - %s:  length of ASN.1 object invalid or too large",
-                                       level, name);
-               )
-               return FALSE;
-       }
-
-       DBG(DBG_PARSING,
-               DBG_log("L%d - %s:", level, name);
-       )
-       debug_asn1_simple_object(*object, type, DBG_RAW);
-       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, DBG_RAW);
-
-       while (objectID < ALGORITHM_ID_ROOF)
-       {
-               if (!extract_object(algorithmIdentifierObjects, &objectID, &object, &level, &ctx))
-                        return alg;
-
-               switch (objectID)
-               {
-               case ALGORITHM_ID_ALG:
-                       alg = asn1_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)
-       {
-               DBG(DBG_PARSING,
-                       DBG_log("  file content is not binary ASN.1");
-               )
-               return FALSE;
-       }
-
-       len = asn1_length(&blob);
-
-       /* exact match */
-       if (len == blob.len)
-       {
-               return TRUE;
-       }
-
-       /* some websites append a surplus newline character to the blob */
-       if (len + 1 == blob.len && *(blob.ptr + len) == '\n')
-       {
-               return TRUE;
-       }
-
-       DBG(DBG_PARSING,
-               DBG_log("  file size does not match ASN.1 coded length");
-       )
-       return FALSE;
-}
diff --git a/src/pluto/asn1.h b/src/pluto/asn1.h
deleted file mode 100644 (file)
index cbc923b..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Simple ASN.1 parser
- * Copyright (C) 2000-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.
- *
- * RCSID $Id$
- */
-
-#ifndef _ASN1_H
-#define _ASN1_H
-
-#include <stdarg.h>
-#include <gmp.h>
-
-#include "defs.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 cond;
-       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;
-
-extern chunk_t asn1_algorithmIdentifier(int oid);
-extern int asn1_known_oid(chunk_t object);
-extern chunk_t asn1_build_known_oid(int n);
-extern u_int asn1_length(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 bool is_printablestring(chunk_t str);
-extern time_t asn1totime(const chunk_t *utctime, asn1_t type);
-extern chunk_t timetoasn1(const time_t *time, asn1_t type);
-extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob
-       , u_int level0, bool implicit, u_int cond);
-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);
-
-#endif /* _ASN1_H */
-
index c9c270c..74ec363 100644 (file)
 #include <freeswan.h>
 #include <ipsec_policy.h>
 
+#include "asn1/asn1.h"
+
 #include "constants.h"
 #include "defs.h"
 #include "log.h"
-#include "asn1.h"
 #include "id.h"
 #include "x509.h"
 #include "pgp.h"
 #include "certs.h"
 #include "pkcs1.h"
 
-/*
+/**
  * used for initializatin of certs
  */
 const cert_t empty_cert = {CERT_NONE, {NULL}};
 
-/*
+/**
  * extracts the certificate to be sent to the peer
  */
-chunk_t
-get_mycert(cert_t cert)
+chunk_t get_mycert(cert_t cert)
 {
        switch (cert.type)
        {
@@ -57,9 +57,8 @@ get_mycert(cert_t cert)
 /* load a coded key or certificate file with autodetection
  * of binary DER or base64 PEM ASN.1 formats and armored PGP format
  */
-bool
-load_coded_file(const char *filename, prompt_pass_t *pass, const char *type
-, chunk_t *blob, bool *pgp)
+bool load_coded_file(char *filename, prompt_pass_t *pass, const char *type,
+                                        chunk_t *blob, bool *pgp)
 {
        err_t ugh = NULL;
 
@@ -121,18 +120,17 @@ load_coded_file(const char *filename, prompt_pass_t *pass, const char *type
        return FALSE;
 }
 
-/*
+/**
  *  Loads a PKCS#1 or PGP private RSA key file
  */
-err_t
-load_rsa_private_key(const char* filename, prompt_pass_t *pass
-, RSA_private_key_t *key)
+err_t load_rsa_private_key(char* filename, prompt_pass_t *pass,
+                                                  RSA_private_key_t *key)
 {
        err_t ugh = NULL;
        bool pgp = FALSE;
        chunk_t blob = chunk_empty;
 
-       const char *path = concatenate_paths(PRIVATE_KEY_PATH, filename);
+       char *path = concatenate_paths(PRIVATE_KEY_PATH, filename);
 
        if (load_coded_file(path, pass, "private key", &blob, &pgp))
        {
@@ -153,11 +151,11 @@ load_rsa_private_key(const char* filename, prompt_pass_t *pass
 
        return ugh;
 }
-/*
+
+/**
  *  Loads a X.509 or OpenPGP certificate
  */
-bool
-load_cert(const char *filename, const char *label, cert_t *cert)
+bool load_cert(char *filename, const char *label, cert_t *cert)
 {
        bool pgp = FALSE;
        chunk_t blob = chunk_empty;
@@ -206,42 +204,38 @@ load_cert(const char *filename, const char *label, cert_t *cert)
        return FALSE;
 }
 
-/*
+/**
  *  Loads a host certificate
  */
-bool
-load_host_cert(const char *filename, cert_t *cert)
+bool load_host_cert(char *filename, cert_t *cert)
 {
-       const char *path = concatenate_paths(HOST_CERT_PATH, filename);
+       char *path = concatenate_paths(HOST_CERT_PATH, filename);
 
        return load_cert(path, "host cert", cert);
 }
 
-/*
+/**
  *  Loads a CA certificate
  */
-bool
-load_ca_cert(const char *filename, cert_t *cert)
+bool load_ca_cert(char *filename, cert_t *cert)
 {
-       const char *path = concatenate_paths(CA_CERT_PATH, filename);
+       char *path = concatenate_paths(CA_CERT_PATH, filename);
 
        return load_cert(path, "CA cert", cert);
 }
 
-/*
+/**
  * establish equality of two certificates
  */
-bool
-same_cert(const cert_t *a, const cert_t *b)
+bool same_cert(const cert_t *a, const cert_t *b)
 {
        return a->type == b->type && a->u.x509 == b->u.x509;
 }
 
-/*  for each link pointing to the certif icate
 increase the count by one
+/**
* for each link pointing to the certificate increase the count by one
  */
-void
-share_cert(cert_t cert)
+void share_cert(cert_t cert)
 {
        switch (cert.type)
        {
index a370146..9c913a8 100644 (file)
@@ -61,15 +61,14 @@ extern const cert_t empty_cert;
  */
 extern bool no_cr_send;
 
-extern err_t load_rsa_private_key(const char* filename, prompt_pass_t *pass
+extern err_t load_rsa_private_key(char* filename, prompt_pass_t *pass
        , RSA_private_key_t *key);
 extern chunk_t get_mycert(cert_t cert);
-extern bool load_coded_file(const char *filename, prompt_pass_t *pass
+extern bool load_coded_file(char *filename, prompt_pass_t *pass
        , const char *type, chunk_t *blob, bool *pgp);
-extern bool load_cert(const char *filename, const char *label
-       , cert_t *cert);
-extern bool load_host_cert(const char *filename, cert_t *cert);
-extern bool load_ca_cert(const char *filename, cert_t *cert);
+extern bool load_cert(char *filename, const char *label, cert_t *cert);
+extern bool load_host_cert(char *filename, cert_t *cert);
+extern bool load_ca_cert(char *filename, cert_t *cert);
 extern bool same_cert(const cert_t *a, const cert_t *b);
 extern void share_cert(cert_t cert);
 extern void release_cert(cert_t cert);
index cbb48f6..1634630 100644 (file)
@@ -701,8 +701,7 @@ unshare_connection_strings(struct connection *c)
        alg_info_addref((struct alg_info *)c->alg_info_ike);
 }
 
-static void
-load_end_certificate(const char *filename, struct end *dst)
+static void load_end_certificate(char *filename, struct end *dst)
 {
        time_t valid_until;
        cert_t cert;
index d186aba..f419af0 100644 (file)
@@ -1,5 +1,7 @@
 /* Support of X.509 certificate revocation lists (CRLs)
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2000-2009 Andreas Steffen
+ *
+ * HSR 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
 #include <freeswan.h>
 #include <ipsec_policy.h>
 
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+
 #include "constants.h"
 #include "defs.h"
 #include "log.h"
-#include "asn1.h"
-#include <asn1/oid.h>
 #include "x509.h"
 #include "crl.h"
 #include "ca.h"
 
 static x509crl_t  *x509crls      = NULL;
 
-/* ASN.1 definition of an X.509 certificate list */
-
+/**
+  * ASN.1 definition of an X.509 certificate revocation list
+ */
 static const asn1Object_t crlObjects[] = {
-  { 0, "certificateList",               ASN1_SEQUENCE,     ASN1_OBJ  }, /*  0 */
-  { 1,   "tbsCertList",                 ASN1_SEQUENCE,     ASN1_OBJ  }, /*  1 */
-  { 2,     "version",                   ASN1_INTEGER,      ASN1_OPT |
+       { 0, "certificateList",                         ASN1_SEQUENCE,     ASN1_OBJ  }, /*  0 */
+       { 1,   "tbsCertList",                           ASN1_SEQUENCE,     ASN1_OBJ  }, /*  1 */
+       { 2,     "version",                                     ASN1_INTEGER,      ASN1_OPT |
                                                                                                                   ASN1_BODY }, /*  2 */
-  { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /*  3 */
-  { 2,     "signature",                 ASN1_EOC,          ASN1_RAW  }, /*  4 */
-  { 2,     "issuer",                    ASN1_SEQUENCE,     ASN1_OBJ  }, /*  5 */
-  { 2,     "thisUpdate",                ASN1_EOC,          ASN1_RAW  }, /*  6 */
-  { 2,     "nextUpdate",                ASN1_EOC,          ASN1_RAW  }, /*  7 */
-  { 2,     "revokedCertificates",       ASN1_SEQUENCE,     ASN1_OPT |
+       { 2,     "end opt",                                     ASN1_EOC,          ASN1_END  }, /*  3 */
+       { 2,     "signature",                           ASN1_EOC,          ASN1_RAW  }, /*  4 */        
+       { 2,     "issuer",                                      ASN1_SEQUENCE,     ASN1_OBJ  }, /*  5 */
+       { 2,     "thisUpdate",                          ASN1_EOC,          ASN1_RAW  }, /*  6 */
+       { 2,     "nextUpdate",                          ASN1_EOC,          ASN1_RAW  }, /*  7 */
+       { 2,     "revokedCertificates",         ASN1_SEQUENCE,     ASN1_OPT |
                                                                                                                   ASN1_LOOP }, /*  8 */
-  { 3,       "certList",                ASN1_SEQUENCE,     ASN1_NONE }, /*  9 */
-  { 4,         "userCertificate",       ASN1_INTEGER,      ASN1_BODY }, /* 10 */
-  { 4,         "revocationDate",        ASN1_EOC,          ASN1_RAW  }, /* 11 */
-  { 4,         "crlEntryExtensions",    ASN1_SEQUENCE,     ASN1_OPT |
-                                                                                                                  ASN1_LOOP }, /* 12 */
-  { 5,           "extension",           ASN1_SEQUENCE,     ASN1_NONE }, /* 13 */
-  { 6,             "extnID",            ASN1_OID,          ASN1_BODY }, /* 14 */
-  { 6,             "critical",          ASN1_BOOLEAN,      ASN1_DEF |
+       { 3,       "certList",                          ASN1_SEQUENCE,     ASN1_NONE }, /*  9 */
+       { 4,         "userCertificate",         ASN1_INTEGER,      ASN1_BODY }, /* 10 */
+       { 4,         "revocationDate",          ASN1_EOC,          ASN1_RAW  }, /* 11 */
+       { 4,         "crlEntryExtensions",  ASN1_SEQUENCE,     ASN1_OPT |
+                                                                                                                  ASN1_LOOP }, /* 12 */
+       { 5,           "extension",                     ASN1_SEQUENCE,     ASN1_NONE }, /* 13 */
+       { 6,             "extnID",                      ASN1_OID,          ASN1_BODY }, /* 14 */
+       { 6,             "critical",            ASN1_BOOLEAN,      ASN1_DEF |
                                                                                                                   ASN1_BODY }, /* 15 */
-  { 6,             "extnValue",         ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
-  { 4,         "end opt or loop",       ASN1_EOC,          ASN1_END  }, /* 17 */
-  { 2,     "end opt or loop",           ASN1_EOC,          ASN1_END  }, /* 18 */
-  { 2,     "optional extensions",       ASN1_CONTEXT_C_0,  ASN1_OPT  }, /* 19 */
-  { 3,       "crlExtensions",           ASN1_SEQUENCE,     ASN1_LOOP }, /* 20 */
-  { 4,         "extension",             ASN1_SEQUENCE,     ASN1_NONE }, /* 21 */
-  { 5,           "extnID",              ASN1_OID,          ASN1_BODY }, /* 22 */
-  { 5,           "critical",            ASN1_BOOLEAN,      ASN1_DEF |
+       { 6,             "extnValue",           ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
+       { 4,         "end opt or loop",         ASN1_EOC,          ASN1_END  }, /* 17 */
+       { 2,     "end opt or loop",                     ASN1_EOC,          ASN1_END  }, /* 18 */
+       { 2,     "optional extensions",         ASN1_CONTEXT_C_0,  ASN1_OPT  }, /* 19 */
+       { 3,       "crlExtensions",                     ASN1_SEQUENCE,     ASN1_LOOP }, /* 20 */
+       { 4,         "extension",                       ASN1_SEQUENCE,     ASN1_NONE }, /* 21 */
+       { 5,           "extnID",                        ASN1_OID,          ASN1_BODY }, /* 22 */
+       { 5,           "critical",                      ASN1_BOOLEAN,      ASN1_DEF |
                                                                                                                   ASN1_BODY }, /* 23 */
-  { 5,           "extnValue",           ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
-  { 3,       "end loop",                ASN1_EOC,          ASN1_END  }, /* 25 */
-  { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 26 */
-  { 1,   "signatureAlgorithm",          ASN1_EOC,          ASN1_RAW  }, /* 27 */
-  { 1,   "signatureValue",              ASN1_BIT_STRING,   ASN1_BODY }  /* 28 */
- };
-
-#define CRL_OBJ_CERTIFICATE_LIST                 0
-#define CRL_OBJ_TBS_CERT_LIST                    1
-#define CRL_OBJ_VERSION                          2
-#define CRL_OBJ_SIG_ALG                          4
-#define CRL_OBJ_ISSUER                           5
-#define CRL_OBJ_THIS_UPDATE                      6
-#define CRL_OBJ_NEXT_UPDATE                      7
-#define CRL_OBJ_USER_CERTIFICATE                10
-#define CRL_OBJ_REVOCATION_DATE                 11
-#define CRL_OBJ_CRL_ENTRY_EXTN_ID               14
-#define CRL_OBJ_CRL_ENTRY_CRITICAL              15
-#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE            16
-#define CRL_OBJ_EXTN_ID                         22
-#define CRL_OBJ_CRITICAL                        23
-#define CRL_OBJ_EXTN_VALUE                      24
-#define CRL_OBJ_ALGORITHM                       27
-#define CRL_OBJ_SIGNATURE                       28
-#define CRL_OBJ_ROOF                            29
+       { 5,           "extnValue",                     ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
+       { 3,       "end loop",                          ASN1_EOC,          ASN1_END  }, /* 25 */
+       { 2,     "end opt",                                     ASN1_EOC,          ASN1_END  }, /* 26 */
+       { 1,   "signatureAlgorithm",            ASN1_EOC,          ASN1_RAW  }, /* 27 */
+       { 1,   "signatureValue",                        ASN1_BIT_STRING,   ASN1_BODY }, /* 28 */
+       { 0, "exit",                                            ASN1_EOC,                  ASN1_EXIT }
+};
 
+#define CRL_OBJ_CERTIFICATE_LIST         0
+#define CRL_OBJ_TBS_CERT_LIST                   1
+#define CRL_OBJ_VERSION                                         2
+#define CRL_OBJ_SIG_ALG                                         4
+#define CRL_OBJ_ISSUER                                  5
+#define CRL_OBJ_THIS_UPDATE                             6
+#define CRL_OBJ_NEXT_UPDATE                             7
+#define CRL_OBJ_USER_CERTIFICATE               10
+#define CRL_OBJ_REVOCATION_DATE                        11
+#define CRL_OBJ_CRL_ENTRY_EXTN_ID              14
+#define CRL_OBJ_CRL_ENTRY_CRITICAL             15
+#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE   16
+#define CRL_OBJ_EXTN_ID                                        22
+#define CRL_OBJ_CRITICAL                               23
+#define CRL_OBJ_EXTN_VALUE                             24
+#define CRL_OBJ_ALGORITHM                              27
+#define CRL_OBJ_SIGNATURE                              28
 
 const x509crl_t empty_x509crl = {
          NULL        , /* *next */
@@ -126,11 +130,10 @@ const x509crl_t empty_x509crl = {
        { NULL, 0 }     /*   signature */
 };
 
-/*
- *  get the X.509 CRL with a given issuer
+/**
+ *  Get the X.509 CRL with a given issuer
  */
-static x509crl_t*
-get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
+static x509crl_t* get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
 {
        x509crl_t *crl = x509crls;
        x509crl_t *prev_crl = NULL;
@@ -156,11 +159,10 @@ get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
        return NULL;
 }
 
-/*
- *  free the dynamic memory used to store revoked certificates
+/**
+ *  Free the dynamic memory used to store revoked certificates
  */
-static void
-free_revoked_certs(revokedCert_t* revokedCerts)
+static void free_revoked_certs(revokedCert_t* revokedCerts)
 {
        while (revokedCerts != NULL)
        {
@@ -170,11 +172,10 @@ free_revoked_certs(revokedCert_t* revokedCerts)
        }
 }
 
-/*
- *  free the dynamic memory used to store CRLs
+/**
+ *  Free the dynamic memory used to store CRLs
  */
-void
-free_crl(x509crl_t *crl)
+void free_crl(x509crl_t *crl)
 {
        free_revoked_certs(crl->revokedCertificates);
        free_generalNames(crl->distributionPoints, TRUE);
@@ -182,8 +183,7 @@ free_crl(x509crl_t *crl)
        free(crl);
 }
 
-static void
-free_first_crl(void)
+static void free_first_crl(void)
 {
        x509crl_t *crl = x509crls;
 
@@ -191,8 +191,7 @@ free_first_crl(void)
        free_crl(crl);
 }
 
-void
-free_crls(void)
+void free_crls(void)
 {
        lock_crl_list("free_crls");
 
@@ -202,11 +201,10 @@ free_crls(void)
        unlock_crl_list("free_crls");
 }
 
-/*
+/**
  * Insert X.509 CRL into chained list
  */
-bool
-insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl)
+bool insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl)
 {
        x509crl_t *crl = malloc_thing(x509crl_t);
 
@@ -322,11 +320,10 @@ insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl)
        }
 }
 
-/*
+/**
  *  Loads CRLs
  */
-void
-load_crls(void)
+void load_crls(void)
 {
        struct dirent **filelist;
        u_char buf[BUF_LEN];
@@ -376,11 +373,10 @@ load_crls(void)
        ignore_result(chdir(save_dir));
 }
 
-/*
+/**
  * Parses a CRL revocation reason code
  */
-static crl_reason_t
-parse_crl_reasonCode(chunk_t object)
+static crl_reason_t parse_crl_reasonCode(chunk_t object)
 {
        crl_reason_t reason = REASON_UNSPECIFIED;
 
@@ -399,27 +395,22 @@ parse_crl_reasonCode(chunk_t object)
 /*
  *  Parses an X.509 CRL
  */
-bool
-parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
+bool parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
 {
        u_char buf[BUF_LEN];
-       asn1_ctx_t ctx;
-       bool critical;
+       asn1_parser_t *parser;
        chunk_t extnID;
        chunk_t userCertificate = chunk_empty;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
+       bool success = FALSE;
+       bool critical;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+       parser = asn1_parser_create(crlObjects, blob);
 
-       while (objectID < CRL_OBJ_ROOF)
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(crlObjects, &objectID, &object, &level, &ctx))
-                        return FALSE;
-
-               /* those objects which will parsed further need the next higher level */
-               level++;
+               u_int level = parser->get_level(parser)+1;
 
                switch (objectID) {
                case CRL_OBJ_CERTIFICATE_LIST:
@@ -435,7 +426,7 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
                        )
                        break;
                case CRL_OBJ_SIG_ALG:
-                       crl->sigAlg = parse_algorithmIdentifier(object, level, NULL);
+                       crl->sigAlg = asn1_parse_algorithmIdentifier(object, level, NULL);
                        break;
                case CRL_OBJ_ISSUER:
                        crl->issuer = object;
@@ -445,10 +436,10 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
                        )
                        break;
                case CRL_OBJ_THIS_UPDATE:
-                       crl->thisUpdate = parse_time(object, level);
+                       crl->thisUpdate = asn1_parse_time(object, level);
                        break;
                case CRL_OBJ_NEXT_UPDATE:
-                       crl->nextUpdate = parse_time(object, level);
+                       crl->nextUpdate = asn1_parse_time(object, level);
                        break;
                case CRL_OBJ_USER_CERTIFICATE:
                        userCertificate = object;
@@ -460,7 +451,7 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
 
                                revokedCert_t *revokedCert = malloc_thing(revokedCert_t);
                                revokedCert->userCertificate = userCertificate;
-                               revokedCert->revocationDate = parse_time(object, level);
+                               revokedCert->revocationDate = asn1_parse_time(object, level);
                                revokedCert->revocationReason = REASON_UNSPECIFIED;
                                revokedCert->next = crl->revokedCertificates;
                                crl->revokedCertificates = revokedCert;
@@ -494,14 +485,17 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
                                }
                                else if (extn_oid == OID_CRL_NUMBER)
                                {
-                                       if (!parse_asn1_simple_object(&object, ASN1_INTEGER, level, "crlNumber"))
-                                               return FALSE;
+                                       if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
+                                                                                                 level, "crlNumber"))
+                                       {
+                                               goto end;
+                                       }
                                        crl->crlNumber = object;
                                }
                        }
                        break;
                case CRL_OBJ_ALGORITHM:
-                       crl->algorithm = parse_algorithmIdentifier(object, level, NULL);
+                       crl->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
                        break;
                case CRL_OBJ_SIGNATURE:
                        crl->signature = object;
@@ -509,10 +503,13 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
                default:
                        break;
                }
-               objectID++;
        }
+       success = parser->success(parser);
        time(&crl->installed);
-       return TRUE;
+
+end:
+       parser->destroy(parser);
+       return success;
 }
 
 /*  Checks if the current certificate is revoked. It goes through the
index 84c269a..7b327e7 100644 (file)
@@ -68,8 +68,7 @@ temporary_cyclic_buffer(void)
 /* concatenates two sub paths into a string with a maximum size of BUF_LEN
  * use for temporary storage only
  */
-const char*
-concatenate_paths(const char *a, const char *b)
+char* concatenate_paths(char *a, char *b)
 {
        char *c;
 
index ac4f20e..160681b 100644 (file)
@@ -58,7 +58,7 @@ extern void *clone_bytes(const void *orig, size_t size);
        { memcpy(dst, chunk.ptr, chunk.len); dst += chunk.len;}
 
 extern char* temporary_cyclic_buffer(void);
-extern const char* concatenate_paths(const char *a, const char *b);
+extern char* concatenate_paths(char *a, char *b);
 
 /* move a chunk to a memory position and free it after insertion */
 extern void mv_chunk(u_char **pos, chunk_t content);
index e191f38..a8919e6 100644 (file)
 #include <ldap.h>
 #endif
 
+#include "asn1/asn1.h"
+
 #include "constants.h"
 #include "defs.h"
 #include "log.h"
 #include "id.h"
-#include "asn1.h"
 #include "pem.h"
 #include "x509.h"
 #include "ca.h"
index 2f3de9c..7e53e40 100644 (file)
@@ -58,7 +58,6 @@
 #include "whack.h"
 #include "fetch.h"
 #include "pkcs7.h"
-#include "asn1.h"
 
 #include "sha1.h"
 #include "md5.h"
index 201effc..ee9dd03 100644 (file)
@@ -16,6 +16,9 @@
 
 #include <freeswan.h>
 
+#include <utils.h>
+#include <asn1/asn1.h>
+
 #include "constants.h"
 #include "defs.h"
 #include "mp_defs.h"
@@ -68,3 +71,17 @@ n_to_mpz(MP_INT *mp, const u_char *nbytes, size_t nlen)
                mpz_add_ui(mp, mp, nbytes[i]);
        }
 }
+
+/*
+ * 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 */
+       size_t size = 1 + bits / BITS_PER_BYTE;  /* size in bytes */
+       chunk_t n = mpz_to_n(value, size);
+
+       return asn1_wrap(ASN1_INTEGER, "m", n);
+}
+
index 7b3b569..fa6d67f 100644 (file)
 
 #include <gmp.h>
 
-#include "defs.h"
+#include <utils.h>
 
 extern void n_to_mpz(MP_INT *mp, const u_char *nbytes, size_t nlen);
 extern chunk_t mpz_to_n(const MP_INT *mp, size_t bytes);
+extern chunk_t asn1_integer_from_mpz(const mpz_t value);
 
 /* var := mod(base ** exp, mod), ensuring var is mpz_inited */
 #define mpz_init_powm(flag, var, base, exp, mod) { \
index ef270cd..2516391 100644 (file)
 #include <freeswan.h>
 #include <ipsec_policy.h>
 
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+
 #include "constants.h"
 #include "defs.h"
 #include "log.h"
 #include "crl.h"
 #include "ca.h"
 #include "rnd.h"
-#include "asn1.h"
 #include "certs.h"
 #include "smartcard.h"
-#include <asn1/oid.h>
 #include "whack.h"
 #include "pkcs1.h"
 #include "keys.h"
@@ -160,131 +162,137 @@ static smartcard_t *ocsp_requestor_sc = NULL;
 
 static const struct RSA_private_key *ocsp_requestor_pri = NULL;
 
-/* asn.1 definitions for parsing */
-
+/**
+ * ASN.1 definition of ocspResponse
+ */
 static const asn1Object_t ocspResponseObjects[] = {
-  { 0, "OCSPResponse",                  ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
-  { 1,   "responseStatus",              ASN1_ENUMERATED,   ASN1_BODY }, /*  1 */
-  { 1,   "responseBytesContext",        ASN1_CONTEXT_C_0,  ASN1_OPT  }, /*  2 */
-  { 2,     "responseBytes",             ASN1_SEQUENCE,     ASN1_NONE }, /*  3 */
-  { 3,       "responseType",            ASN1_OID,          ASN1_BODY }, /*  4 */
-  { 3,       "response",                ASN1_OCTET_STRING, ASN1_BODY }, /*  5 */
-  { 1,   "end opt",                     ASN1_EOC,          ASN1_END  }  /*  6 */
+       { 0, "OCSPResponse",                    ASN1_SEQUENCE,          ASN1_NONE }, /* 0 */
+       { 1,   "responseStatus",                ASN1_ENUMERATED,        ASN1_BODY }, /* 1 */
+       { 1,   "responseBytesContext",  ASN1_CONTEXT_C_0,       ASN1_OPT  }, /* 2 */
+       { 2,     "responseBytes",               ASN1_SEQUENCE,          ASN1_NONE }, /* 3 */
+       { 3,       "responseType",              ASN1_OID,                       ASN1_BODY }, /* 4 */
+       { 3,       "response",                  ASN1_OCTET_STRING,      ASN1_BODY }, /* 5 */
+       { 1,   "end opt",                               ASN1_EOC,                       ASN1_END  }, /* 6 */
+       { 0, "exit",                                    ASN1_EOC,                       ASN1_EXIT }
 };
+#define OCSP_RESPONSE_STATUS   1
+#define OCSP_RESPONSE_TYPE             4
+#define OCSP_RESPONSE                  5
 
-#define OCSP_RESPONSE_STATUS    1
-#define OCSP_RESPONSE_TYPE      4
-#define OCSP_RESPONSE           5
-#define OCSP_RESPONSE_ROOF      7
-
+/**
+ * ASN.1 definition of basicResponse
+ */
 static const asn1Object_t basicResponseObjects[] = {
-  { 0, "BasicOCSPResponse",             ASN1_SEQUENCE,        ASN1_NONE }, /*  0 */
-  { 1,   "tbsResponseData",             ASN1_SEQUENCE,        ASN1_OBJ  }, /*  1 */
-  { 2,     "versionContext",            ASN1_CONTEXT_C_0,     ASN1_NONE |
-                                                                                                                         ASN1_DEF  }, /*  2 */
-  { 3,       "version",                 ASN1_INTEGER,         ASN1_BODY }, /*  3 */
-  { 2,     "responderIdContext",        ASN1_CONTEXT_C_1,     ASN1_OPT  }, /*  4 */
-  { 3,       "responderIdByName",       ASN1_SEQUENCE,        ASN1_OBJ  }, /*  5 */
-  { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  6 */
-  { 2,     "responderIdContext",        ASN1_CONTEXT_C_2,     ASN1_OPT  }, /*  7 */
-  { 3,       "responderIdByKey",        ASN1_OCTET_STRING,    ASN1_BODY }, /*  8 */
-  { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  9 */
-  { 2,     "producedAt",                ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
-  { 2,     "responses",                 ASN1_SEQUENCE,        ASN1_OBJ  }, /* 11 */
-  { 2,     "responseExtensionsContext", ASN1_CONTEXT_C_1,     ASN1_OPT  }, /* 12 */
-  { 3,       "responseExtensions",      ASN1_SEQUENCE,        ASN1_LOOP }, /* 13 */
-  { 4,         "extension",             ASN1_SEQUENCE,        ASN1_NONE }, /* 14 */
-  { 5,           "extnID",              ASN1_OID,             ASN1_BODY }, /* 15 */
-  { 5,           "critical",            ASN1_BOOLEAN,         ASN1_BODY |
-                                                                                                                         ASN1_DEF  }, /* 16 */
-  { 5,           "extnValue",           ASN1_OCTET_STRING,    ASN1_BODY }, /* 17 */
-  { 4,         "end loop",              ASN1_EOC,             ASN1_END  }, /* 18 */
-  { 2,     "end opt",                   ASN1_EOC,             ASN1_END  }, /* 19 */
-  { 1,   "signatureAlgorithm",          ASN1_EOC,             ASN1_RAW  }, /* 20 */
-  { 1,   "signature",                   ASN1_BIT_STRING,      ASN1_BODY }, /* 21 */
-  { 1,   "certsContext",                ASN1_CONTEXT_C_0,     ASN1_OPT  }, /* 22 */
-  { 2,     "certs",                     ASN1_SEQUENCE,        ASN1_LOOP }, /* 23 */
-  { 3,       "certificate",             ASN1_SEQUENCE,        ASN1_OBJ  }, /* 24 */
-  { 2,     "end loop",                  ASN1_EOC,             ASN1_END  }, /* 25 */
-  { 1,   "end opt",                     ASN1_EOC,             ASN1_END  }  /* 26 */
+       { 0, "BasicOCSPResponse",                               ASN1_SEQUENCE,                  ASN1_NONE }, /*  0 */
+       { 1,   "tbsResponseData",                               ASN1_SEQUENCE,                  ASN1_OBJ  }, /*  1 */
+       { 2,     "versionContext",                              ASN1_CONTEXT_C_0,               ASN1_NONE |
+                                                                                                                                       ASN1_DEF  }, /*  2 */
+       { 3,       "version",                                   ASN1_INTEGER,                   ASN1_BODY }, /*  3 */
+       { 2,     "responderIdContext",                  ASN1_CONTEXT_C_1,               ASN1_OPT  }, /*  4 */
+       { 3,       "responderIdByName",                 ASN1_SEQUENCE,                  ASN1_OBJ  }, /*  5 */
+       { 2,     "end choice",                                  ASN1_EOC,                               ASN1_END  }, /*  6 */
+       { 2,     "responderIdContext",                  ASN1_CONTEXT_C_2,               ASN1_OPT  }, /*  7 */
+       { 3,       "responderIdByKey",                  ASN1_OCTET_STRING,              ASN1_BODY }, /*  8 */
+       { 2,     "end choice",                                  ASN1_EOC,                               ASN1_END  }, /*  9 */
+       { 2,     "producedAt",                                  ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 10 */
+       { 2,     "responses",                                   ASN1_SEQUENCE,                  ASN1_OBJ  }, /* 11 */
+       { 2,     "responseExtensionsContext",   ASN1_CONTEXT_C_1,               ASN1_OPT  }, /* 12 */
+       { 3,       "responseExtensions",                ASN1_SEQUENCE,                  ASN1_LOOP }, /* 13 */
+       { 4,         "extension",                               ASN1_SEQUENCE,                  ASN1_NONE }, /* 14 */
+       { 5,           "extnID",                                ASN1_OID,                               ASN1_BODY }, /* 15 */
+       { 5,           "critical",                              ASN1_BOOLEAN,                   ASN1_BODY |
+                                                                                                                                       ASN1_DEF  }, /* 16 */
+       { 5,           "extnValue",                             ASN1_OCTET_STRING,              ASN1_BODY }, /* 17 */
+       { 4,         "end loop",                                ASN1_EOC,                               ASN1_END  }, /* 18 */
+       { 2,     "end opt",                                             ASN1_EOC,                               ASN1_END  }, /* 19 */
+       { 1,   "signatureAlgorithm",                    ASN1_EOC,                               ASN1_RAW  }, /* 20 */
+       { 1,   "signature",                                             ASN1_BIT_STRING,                ASN1_BODY }, /* 21 */
+       { 1,   "certsContext",                                  ASN1_CONTEXT_C_0,               ASN1_OPT  }, /* 22 */
+       { 2,     "certs",                                               ASN1_SEQUENCE,                  ASN1_LOOP }, /* 23 */
+       { 3,       "certificate",                               ASN1_SEQUENCE,                  ASN1_RAW  }, /* 24 */
+       { 2,     "end loop",                                    ASN1_EOC,                               ASN1_END  }, /* 25 */
+       { 1,   "end opt",                                               ASN1_EOC,                               ASN1_END  }, /* 26 */
+       { 0, "exit",                                                    ASN1_EOC,                               ASN1_EXIT }
 };
-
-#define BASIC_RESPONSE_TBS_DATA          1
-#define BASIC_RESPONSE_VERSION           3
-#define BASIC_RESPONSE_ID_BY_NAME        5
-#define BASIC_RESPONSE_ID_BY_KEY         8
-#define BASIC_RESPONSE_PRODUCED_AT      10
-#define BASIC_RESPONSE_RESPONSES        11
-#define BASIC_RESPONSE_EXT_ID           15
-#define BASIC_RESPONSE_CRITICAL         16
-#define BASIC_RESPONSE_EXT_VALUE        17
-#define BASIC_RESPONSE_ALGORITHM        20
-#define BASIC_RESPONSE_SIGNATURE        21
-#define BASIC_RESPONSE_CERTIFICATE      24
-#define BASIC_RESPONSE_ROOF             27
-
+#define BASIC_RESPONSE_TBS_DATA                 1
+#define BASIC_RESPONSE_VERSION          3
+#define BASIC_RESPONSE_ID_BY_NAME       5
+#define BASIC_RESPONSE_ID_BY_KEY        8
+#define BASIC_RESPONSE_PRODUCED_AT     10
+#define BASIC_RESPONSE_RESPONSES       11
+#define BASIC_RESPONSE_EXT_ID          15
+#define BASIC_RESPONSE_CRITICAL                16
+#define BASIC_RESPONSE_EXT_VALUE       17
+#define BASIC_RESPONSE_ALGORITHM       20
+#define BASIC_RESPONSE_SIGNATURE       21
+#define BASIC_RESPONSE_CERTIFICATE     24
+
+/**
+ * ASN.1 definition of responses
+ */
 static const asn1Object_t responsesObjects[] = {
-  { 0, "responses",                   ASN1_SEQUENCE,          ASN1_LOOP }, /*  0 */
-  { 1,   "singleResponse",            ASN1_EOC,               ASN1_RAW  }, /*  1 */
-  { 0, "end loop",                    ASN1_EOC,               ASN1_END  }  /*  2 */
+       { 0, "responses",                       ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
+       { 1,   "singleResponse",        ASN1_EOC,               ASN1_RAW  }, /* 1 */
+       { 0, "end loop",                        ASN1_EOC,               ASN1_END  }, /* 2 */
+       { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
 };
+#define RESPONSES_SINGLE_RESPONSE      1
 
-#define RESPONSES_SINGLE_RESPONSE        1
-#define RESPONSES_ROOF                   3
-
+/**
+ * ASN.1 definition of singleResponse
+ */
 static const asn1Object_t singleResponseObjects[] = {
-  { 0, "singleResponse",            ASN1_SEQUENCE,          ASN1_BODY }, /*  0 */
-  { 1,   "certID",                  ASN1_SEQUENCE,          ASN1_NONE }, /*  1 */
-  { 2,     "algorithm",             ASN1_EOC,               ASN1_RAW  }, /*  2 */
-  { 2,     "issuerNameHash",        ASN1_OCTET_STRING,      ASN1_BODY }, /*  3 */
-  { 2,     "issuerKeyHash",         ASN1_OCTET_STRING,      ASN1_BODY }, /*  4 */
-  { 2,     "serialNumber",          ASN1_INTEGER,           ASN1_BODY }, /*  5 */
-  { 1,   "certStatusGood",          ASN1_CONTEXT_S_0,       ASN1_OPT  }, /*  6 */
-  { 1,   "end opt",                 ASN1_EOC,               ASN1_END  }, /*  7 */
-  { 1,   "certStatusRevoked",       ASN1_CONTEXT_C_1,       ASN1_OPT  }, /*  8 */
-  { 2,     "revocationTime",        ASN1_GENERALIZEDTIME,   ASN1_BODY }, /*  9 */
-  { 2,     "revocationReason",      ASN1_CONTEXT_C_0,       ASN1_OPT  }, /* 10 */
-  { 3,       "crlReason",           ASN1_ENUMERATED,        ASN1_BODY }, /* 11 */
-  { 2,     "end opt",               ASN1_EOC,               ASN1_END  }, /* 12 */
-  { 1,   "end opt",                 ASN1_EOC,               ASN1_END  }, /* 13 */
-  { 1,   "certStatusUnknown",       ASN1_CONTEXT_S_2,       ASN1_OPT  }, /* 14 */
-  { 1,   "end opt",                 ASN1_EOC,               ASN1_END  }, /* 15 */
-  { 1,   "thisUpdate",              ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 16 */
-  { 1,   "nextUpdateContext",       ASN1_CONTEXT_C_0,       ASN1_OPT  }, /* 17 */
-  { 2,     "nextUpdate",            ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 18 */
-  { 1,   "end opt",                 ASN1_EOC,               ASN1_END  }, /* 19 */
-  { 1,   "singleExtensionsContext", ASN1_CONTEXT_C_1,       ASN1_OPT  }, /* 20 */
-  { 2,     "singleExtensions",      ASN1_SEQUENCE,          ASN1_LOOP }, /* 21 */
-  { 3,       "extension",           ASN1_SEQUENCE,          ASN1_NONE }, /* 22 */
-  { 4,         "extnID",            ASN1_OID,               ASN1_BODY }, /* 23 */
-  { 4,         "critical",          ASN1_BOOLEAN,           ASN1_BODY |
-                                                                                                                       ASN1_DEF  }, /* 24 */
-  { 4,         "extnValue",         ASN1_OCTET_STRING,      ASN1_BODY }, /* 25 */
-  { 2,     "end loop",              ASN1_EOC,               ASN1_END  }, /* 26 */
-  { 1,   "end opt",                 ASN1_EOC,               ASN1_END  }  /* 27 */
+       { 0, "singleResponse",                          ASN1_SEQUENCE,                  ASN1_BODY }, /*  0 */
+       { 1,   "certID",                                        ASN1_SEQUENCE,                  ASN1_NONE }, /*  1 */
+       { 2,     "algorithm",                           ASN1_EOC,                               ASN1_RAW  }, /*  2 */
+       { 2,     "issuerNameHash",                      ASN1_OCTET_STRING,              ASN1_BODY }, /*  3 */
+       { 2,     "issuerKeyHash",                       ASN1_OCTET_STRING,              ASN1_BODY }, /*  4 */
+       { 2,     "serialNumber",                        ASN1_INTEGER,                   ASN1_BODY }, /*  5 */
+       { 1,   "certStatusGood",                        ASN1_CONTEXT_S_0,               ASN1_OPT  }, /*  6 */
+       { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /*  7 */
+       { 1,   "certStatusRevoked",                     ASN1_CONTEXT_C_1,               ASN1_OPT  }, /*  8 */
+       { 2,     "revocationTime",                      ASN1_GENERALIZEDTIME,   ASN1_BODY }, /*  9 */
+       { 2,     "revocationReason",            ASN1_CONTEXT_C_0,               ASN1_OPT  }, /* 10 */
+       { 3,       "crlReason",                         ASN1_ENUMERATED,                ASN1_BODY }, /* 11 */
+       { 2,     "end opt",                                     ASN1_EOC,                               ASN1_END  }, /* 12 */
+       { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 13 */
+       { 1,   "certStatusUnknown",                     ASN1_CONTEXT_S_2,               ASN1_OPT  }, /* 14 */
+       { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 15 */
+       { 1,   "thisUpdate",                            ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 16 */
+       { 1,   "nextUpdateContext",                     ASN1_CONTEXT_C_0,               ASN1_OPT  }, /* 17 */
+       { 2,     "nextUpdate",                          ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 18 */
+       { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 19 */
+       { 1,   "singleExtensionsContext",       ASN1_CONTEXT_C_1,               ASN1_OPT  }, /* 20 */
+       { 2,     "singleExtensions",            ASN1_SEQUENCE,                  ASN1_LOOP }, /* 21 */
+       { 3,       "extension",                         ASN1_SEQUENCE,                  ASN1_NONE }, /* 22 */
+       { 4,         "extnID",                          ASN1_OID,                               ASN1_BODY }, /* 23 */
+       { 4,         "critical",                        ASN1_BOOLEAN,                   ASN1_BODY |
+                                                                                                                               ASN1_DEF  }, /* 24 */
+       { 4,         "extnValue",                       ASN1_OCTET_STRING,              ASN1_BODY }, /* 25 */
+       { 2,     "end loop",                            ASN1_EOC,                               ASN1_END  }, /* 26 */
+       { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 27 */
+       { 0, "exit",                                            ASN1_EOC,                               ASN1_EXIT }
 };
+#define SINGLE_RESPONSE_ALGORITHM                                       2
+#define SINGLE_RESPONSE_ISSUER_NAME_HASH                        3
+#define SINGLE_RESPONSE_ISSUER_KEY_HASH                                 4
+#define SINGLE_RESPONSE_SERIAL_NUMBER                           5
+#define SINGLE_RESPONSE_CERT_STATUS_GOOD                        6
+#define SINGLE_RESPONSE_CERT_STATUS_REVOKED                     8
+#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME     9
+#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON         11
+#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN                    14
+#define SINGLE_RESPONSE_THIS_UPDATE                                    16
+#define SINGLE_RESPONSE_NEXT_UPDATE                                    18
+#define SINGLE_RESPONSE_EXT_ID                                         23
+#define SINGLE_RESPONSE_CRITICAL                                       24
+#define SINGLE_RESPONSE_EXT_VALUE                                      25
 
-#define SINGLE_RESPONSE_ALGORITHM                        2
-#define SINGLE_RESPONSE_ISSUER_NAME_HASH                 3
-#define SINGLE_RESPONSE_ISSUER_KEY_HASH                  4
-#define SINGLE_RESPONSE_SERIAL_NUMBER                    5
-#define SINGLE_RESPONSE_CERT_STATUS_GOOD                 6
-#define SINGLE_RESPONSE_CERT_STATUS_REVOKED              8
-#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME      9
-#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON          11
-#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN             14
-#define SINGLE_RESPONSE_THIS_UPDATE                     16
-#define SINGLE_RESPONSE_NEXT_UPDATE                     18
-#define SINGLE_RESPONSE_EXT_ID                          23
-#define SINGLE_RESPONSE_CRITICAL                        24
-#define SINGLE_RESPONSE_EXT_VALUE                       25
-#define SINGLE_RESPONSE_ROOF                            28
-
-/* build an ocsp location from certificate information
+/*
+ * Build an ocsp location from certificate information
  * without unsharing its contents
  */
-static bool
-build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
+static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
 {
        static u_char digest[SHA1_DIGEST_SIZE];  /* temporary storage */
 
@@ -330,11 +338,10 @@ build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
        return TRUE;
 }
 
-/*
- * compare two ocsp locations for equality
+/**
+ * Compare two ocsp locations for equality
  */
-static bool
-same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
+static bool same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
 {
        return ((a->authKeyID.ptr != NULL)
                                ? same_keyid(a->authKeyID, b->authKeyID)
@@ -343,11 +350,10 @@ same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
                        && chunk_equals(a->uri, b->uri);
 }
 
-/*
- * find an existing ocsp location in a chained list
+/**
+ * Find an existing ocsp location in a chained list
  */
-ocsp_location_t*
-get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
+ocsp_location_t* get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
 {
 
        while (chain != NULL)
@@ -359,12 +365,14 @@ get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
        return NULL;
 }
 
-/* retrieves the status of a cert from the ocsp cache
+/**
+ * Retrieves the status of a cert from the ocsp cache
  * returns CERT_UNDEFINED if no status is found
  */
-static cert_status_t
-get_ocsp_status(const ocsp_location_t *loc, chunk_t serialNumber
-       ,time_t *nextUpdate, time_t *revocationTime, crl_reason_t *revocationReason)
+static cert_status_t get_ocsp_status(const ocsp_location_t *loc,
+                                                                        chunk_t serialNumber,
+                                                                        time_t *nextUpdate, time_t *revocationTime,
+                                                                        crl_reason_t *revocationReason)
 {
        ocsp_certinfo_t *certinfo, **certinfop;
        int cmp = -1;
@@ -399,12 +407,12 @@ get_ocsp_status(const ocsp_location_t *loc, chunk_t serialNumber
        return CERT_UNDEFINED;
 }
 
-/*
- * verify the ocsp status of a certificate
+/**
+ * Verify the ocsp status of a certificate
  */
-cert_status_t
-verify_by_ocsp(const x509cert_t *cert, time_t *until
-, time_t *revocationDate, crl_reason_t *revocationReason)
+cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until,
+                                                        time_t *revocationDate,
+                                                        crl_reason_t *revocationReason)
 {
        cert_status_t status;
        ocsp_location_t location;
@@ -434,11 +442,10 @@ verify_by_ocsp(const x509cert_t *cert, time_t *until
        return status;
 }
 
-/*
- * check if an ocsp status is about to expire
+/**
+ * Check if an ocsp status is about to expire
  */
-void
-check_ocsp(void)
+void check_ocsp(void)
 {
        ocsp_location_t *location;
 
@@ -485,21 +492,19 @@ check_ocsp(void)
        unlock_ocsp_cache("check_ocsp");
 }
 
-/*
+/**
  *  frees the allocated memory of a certinfo struct
  */
-static void
-free_certinfo(ocsp_certinfo_t *certinfo)
+static void free_certinfo(ocsp_certinfo_t *certinfo)
 {
        free(certinfo->serialNumber.ptr);
        free(certinfo);
 }
 
-/*
+/**
  * frees all certinfos in a chained list
  */
-static void
-free_certinfos(ocsp_certinfo_t *chain)
+static void free_certinfos(ocsp_certinfo_t *chain)
 {
        ocsp_certinfo_t *certinfo;
 
@@ -511,11 +516,10 @@ free_certinfos(ocsp_certinfo_t *chain)
        }
 }
 
-/*
- * frees the memory allocated to an ocsp location including all certinfos
+/**
+ * Frees the memory allocated to an ocsp location including all certinfos
  */
-static void
-free_ocsp_location(ocsp_location_t* location)
+static void free_ocsp_location(ocsp_location_t* location)
 {
        free(location->issuer.ptr);
        free(location->authNameID.ptr);
@@ -527,10 +531,9 @@ free_ocsp_location(ocsp_location_t* location)
 }
 
 /*
- * free a chained list of ocsp locations
+ * Free a chained list of ocsp locations
  */
-void
-free_ocsp_locations(ocsp_location_t **chain)
+void free_ocsp_locations(ocsp_location_t **chain)
 {
        while (*chain != NULL)
        {
@@ -540,33 +543,30 @@ free_ocsp_locations(ocsp_location_t **chain)
        }
 }
 
-/*
- * free the ocsp cache
+/**
+ * Free the ocsp cache
  */
-void
-free_ocsp_cache(void)
+void free_ocsp_cache(void)
 {
        lock_ocsp_cache("free_ocsp_cache");
        free_ocsp_locations(&ocsp_cache);
        unlock_ocsp_cache("free_ocsp_cache");
 }
 
-/*
- * frees the ocsp cache and global variables
+/**
+ * Frees the ocsp cache and global variables
  */
-void
-free_ocsp(void)
+void free_ocsp(void)
 {
        free(ocsp_default_uri.ptr);
        free_ocsp_cache();
 }
 
-/*
- * list a chained list of ocsp_locations
+/**
+ * List a chained list of ocsp_locations
  */
-void
-list_ocsp_locations(ocsp_location_t *location, bool requests, bool utc
-, bool strict)
+void list_ocsp_locations(ocsp_location_t *location, bool requests,
+                                                bool utc, bool strict)
 {
        bool first = TRUE;
 
@@ -644,19 +644,17 @@ list_ocsp_locations(ocsp_location_t *location, bool requests, bool utc
        }
 }
 
-/*
- * list the ocsp cache
+/**
+ * List the ocsp cache
  */
-void
-list_ocsp_cache(bool utc, bool strict)
+void list_ocsp_cache(bool utc, bool strict)
 {
        lock_ocsp_cache("list_ocsp_cache");
        list_ocsp_locations(ocsp_cache, FALSE, utc, strict);
        unlock_ocsp_cache("list_ocsp_cache");
 }
 
-static bool
-get_ocsp_requestor_cert(ocsp_location_t *location)
+static bool get_ocsp_requestor_cert(ocsp_location_t *location)
 {
        x509cert_t *cert = NULL;
 
@@ -718,9 +716,8 @@ get_ocsp_requestor_cert(ocsp_location_t *location)
        return FALSE;
 }
 
-static chunk_t
-generate_signature(chunk_t digest, smartcard_t *sc
-       , const RSA_private_key_t *pri)
+static chunk_t generate_signature(chunk_t digest, smartcard_t *sc,
+                                                                 const RSA_private_key_t *pri)
 {
        chunk_t sigdata;
        u_char *pos;
@@ -750,7 +747,7 @@ generate_signature(chunk_t digest, smartcard_t *sc
                                , (int)sc->slot, sc->id)
                )
 
-               pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
+               pos = asn1_build_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
                *pos++ = 0x00;
                scx_sign_hash(sc, digest.ptr, digest.len, pos, siglen);
                if (!pkcs11_keep_state)
@@ -760,20 +757,18 @@ generate_signature(chunk_t digest, smartcard_t *sc
        {
                /* RSA signature is done in software */
                siglen = pri->pub.k;
-               pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
+               pos = asn1_build_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
                *pos++ = 0x00;
                sign_hash(pri, digest.ptr, digest.len, pos, siglen);
        }
        return sigdata;
 }
 
-/*
- * build signature into ocsp request
- * gets built only if a request cert with
- * a corresponding private key is found
+/**
+ * build signature into ocsp request gets built only if a request cert
+ * with a corresponding private key is found
  */
-static chunk_t
-build_signature(chunk_t tbsRequest)
+static chunk_t build_signature(chunk_t tbsRequest)
 {
        chunk_t sigdata, certs;
        chunk_t digest_info;
@@ -788,7 +783,7 @@ build_signature(chunk_t tbsRequest)
         * an ASN.1 structure for encryption
         */
        digest_info = asn1_wrap(ASN1_SEQUENCE, "cm"
-               , ASN1_sha1_id
+               , asn1_algorithmIdentifier(OID_SHA1)
                , asn1_simple_object(ASN1_OCTET_STRING, digest_raw));
 
        /* generate the RSA signature */
@@ -811,21 +806,21 @@ build_signature(chunk_t tbsRequest)
        /* build signature comprising algorithm, signature and cert */
        return asn1_wrap(ASN1_CONTEXT_C_0, "m"
                                , asn1_wrap(ASN1_SEQUENCE, "cmm"
-                                       , ASN1_sha1WithRSA_id
+                                       , asn1_algorithmIdentifier(OID_SHA1_WITH_RSA)
                                        , sigdata
                                        , certs
                                  )
                   );
 }
 
-/* build request (into requestList)
+/**
+ * Build request (into requestList)
  * no singleRequestExtensions used
  */
-static chunk_t
-build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
+static chunk_t build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
 {
        chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm"
-                               , ASN1_sha1_id
+                               , asn1_algorithmIdentifier(OID_SHA1)
                                , asn1_simple_object(ASN1_OCTET_STRING, location->authNameID)
                                , asn1_simple_object(ASN1_OCTET_STRING, location->authKeyID)
                                , asn1_simple_object(ASN1_INTEGER, certinfo->serialNumber));
@@ -833,11 +828,10 @@ build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
        return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
 }
 
-/*
+/**
  * build requestList (into TBSRequest)
  */
-static chunk_t
-build_request_list(ocsp_location_t *location)
+static chunk_t build_request_list(ocsp_location_t *location)
 {
        chunk_t requestList;
        request_list_t *reqs = NULL;
@@ -862,8 +856,7 @@ build_request_list(ocsp_location_t *location)
                certinfo = certinfo->next;
        }
 
-       pos = build_asn1_object(&requestList, ASN1_SEQUENCE
-                       , datalen);
+       pos = asn1_build_object(&requestList, ASN1_SEQUENCE, datalen);
 
        /* copy all in chained list, free list afterwards */
        while (reqs != NULL)
@@ -878,22 +871,20 @@ build_request_list(ocsp_location_t *location)
        return requestList;
 }
 
-/*
- * build requestorName (into TBSRequest)
+/**
+ * Build requestorName (into TBSRequest)
  */
-static chunk_t
-build_requestor_name(void)
+static chunk_t build_requestor_name(void)
 {
        return asn1_wrap(ASN1_CONTEXT_C_1, "m"
                                , asn1_simple_object(ASN1_CONTEXT_C_4
                                        , ocsp_requestor_cert->subject));
 }
 
-/*
+/**
  * build nonce extension (into requestExtensions)
  */
-static chunk_t
-build_nonce_extension(ocsp_location_t *location)
+static chunk_t build_nonce_extension(ocsp_location_t *location)
 {
        /* generate a random nonce */
        location->nonce.ptr = malloc(NONCE_LENGTH),
@@ -905,11 +896,10 @@ build_nonce_extension(ocsp_location_t *location)
                                , asn1_simple_object(ASN1_OCTET_STRING, location->nonce));
 }
 
-/*
- * build requestExtensions (into TBSRequest)
+/**
+ * Build requestExtensions (into TBSRequest)
  */
-static chunk_t
-build_request_ext(ocsp_location_t *location)
+static chunk_t build_request_ext(ocsp_location_t *location)
 {
        return asn1_wrap(ASN1_CONTEXT_C_2, "m"
                                , asn1_wrap(ASN1_SEQUENCE, "mm"
@@ -922,11 +912,10 @@ build_request_ext(ocsp_location_t *location)
                        );
 }
 
-/*
- * build TBSRequest (into OCSPRequest)
+/**
+ * Build TBSRequest (into OCSPRequest)
  */
-static chunk_t
-build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
+static chunk_t build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
 {
        /* version is skipped since the default is ok */
        return asn1_wrap(ASN1_SEQUENCE, "mmm"
@@ -937,11 +926,11 @@ build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
                                , build_request_ext(location));
 }
 
-/* assembles an ocsp request to given location
+/**
+ * Assembles an ocsp request to given location
  * and sets nonce field in location to the sent nonce
  */
-chunk_t
-build_ocsp_request(ocsp_location_t *location)
+chunk_t build_ocsp_request(ocsp_location_t *location)
 {
        bool has_requestor_cert;
        chunk_t tbsRequest, signature;
@@ -977,11 +966,10 @@ build_ocsp_request(ocsp_location_t *location)
                                , signature);
 }
 
-/*
- * check if the OCSP response has a valid signature
+/**
+ * Check if the OCSP response has a valid signature
  */
-static bool
-valid_ocsp_response(response_t *res)
+static bool valid_ocsp_response(response_t *res)
 {
        int pathlen;
        x509cert_t *authcert;
@@ -1086,27 +1074,25 @@ valid_ocsp_response(response_t *res)
        return FALSE;
 }
 
-/*
- * parse a basic OCSP response
+/**
+ * Parse a basic OCSP response
  */
-static bool
-parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
+static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
 {
-       asn1_ctx_t ctx;
-       bool critical;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level, version;
+       u_int version;
        u_char buf[BUF_LEN];
-       int objectID = 0;
+       int objectID;
        int extn_oid = OID_UNKNOWN;
+       bool success = FALSE;
+       bool critical;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+       parser = asn1_parser_create(basicResponseObjects, blob);
+       parser->set_top_level(parser, level0);
 
-       while (objectID < BASIC_RESPONSE_ROOF)
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
-                       return FALSE;
-               
                switch (objectID)
                {
                case BASIC_RESPONSE_TBS_DATA:
@@ -1117,7 +1103,7 @@ parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
                        if (version != OCSP_BASIC_RESPONSE_VERSION)
                        {
                                plog("wrong ocsp basic response version (version= %i)",  version);
-                               return FALSE;
+                               goto end;
                        }
                        break;
                case BASIC_RESPONSE_ID_BY_NAME:
@@ -1131,7 +1117,7 @@ parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
                        res->responder_id_key = object;
                        break;
                case BASIC_RESPONSE_PRODUCED_AT:
-                       res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME);
+                       res->produced_at = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                        break;
                case BASIC_RESPONSE_RESPONSES:
                        res->responses = object;
@@ -1150,7 +1136,8 @@ parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
                                res->nonce = object;
                        break;
                case BASIC_RESPONSE_ALGORITHM:
-                       res->algorithm = parse_algorithmIdentifier(object, level+1, NULL);
+                       res->algorithm = asn1_parse_algorithmIdentifier(object,
+                                                               parser->get_level(parser)+1, NULL);
                        break;
                case BASIC_RESPONSE_SIGNATURE:
                        res->signature = object;
@@ -1162,7 +1149,7 @@ parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
 
                                *cert = empty_x509cert;
 
-                               if (parse_x509cert(blob, level+1, cert)
+                               if (parse_x509cert(blob, parser->get_level(parser)+1, cert)
                                && cert->isOcspSigner
                                && trust_authcert_candidate(cert, NULL))
                                {
@@ -1178,32 +1165,32 @@ parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
                        }
                        break;
                }
-               objectID++;
        }
-       return TRUE;
+       success = parser->success(parser);
+
+end:
+       parser->destroy(parser);
+       return success;
+
 }
 
 
-/*
- * parse an ocsp response and return the result as a response_t struct
+/**
+ * Parse an ocsp response and return the result as a response_t struct
  */
-static response_status
-parse_ocsp_response(chunk_t blob, response_t * res)
+static response_status parse_ocsp_response(chunk_t blob, response_t * res)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
        int ocspResponseType = OID_UNKNOWN;
+       bool success = FALSE;
        response_status rStatus = STATUS_INTERNALERROR;
 
-       asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
+       parser = asn1_parser_create(ocspResponseObjects, blob);
 
-       while (objectID < OCSP_RESPONSE_ROOF)
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
-                       return STATUS_INTERNALERROR;
-
                switch (objectID) {
                case OCSP_RESPONSE_STATUS:
                        rStatus = (response_status) *object.ptr;
@@ -1219,9 +1206,9 @@ parse_ocsp_response(chunk_t blob, response_t * res)
                        case STATUS_UNAUTHORIZED:
                                plog("ocsp response: server said '%s'"
                                        , response_status_names[rStatus]);
-                               return rStatus;
+                               goto end;
                        default:
-                               return STATUS_INTERNALERROR;
+                               goto end;
                        }
                        break;
                case OCSP_RESPONSE_TYPE:
@@ -1231,47 +1218,50 @@ parse_ocsp_response(chunk_t blob, response_t * res)
                        {
                                switch (ocspResponseType) {
                                case OID_BASIC:
-                                       if (!parse_basic_ocsp_response(object, level+1, res))
-                                               return STATUS_INTERNALERROR;
+                                       success = parse_basic_ocsp_response(object,
+                                                                       parser->get_level(parser)+1, res);
                                        break;
                                default:
                                        DBG(DBG_CONTROL,
                                                DBG_log("ocsp response is not of type BASIC");
                                                DBG_dump_chunk("ocsp response OID: ", object);
                                        )
-                                       return STATUS_INTERNALERROR;
+                                       goto end;
                                }
                        }
                        break;
                }
-               objectID++;
        }
+       success &= parser->success(parser);
+
+end:
+       parser->destroy(parser);
        return rStatus;
 }
 
-/*
- * parse a basic OCSP response
+/**
+ * Parse a basic OCSP response
  */
-static bool
-parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
+static bool parse_ocsp_single_response(chunk_t blob, int level0,
+                                                                          single_response_t *sres)
 {
-       u_int level, extn_oid;
-       asn1_ctx_t ctx;
-       bool critical;
+       asn1_parser_t *parser;
        chunk_t object;
-       int objectID = 0;
+       u_int extn_oid;
+       int objectID;
+       bool critical;
+       bool success = FALSE;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+       parser = asn1_parser_create(singleResponseObjects, blob);
+       parser->set_top_level(parser, level0);
 
-       while (objectID < SINGLE_RESPONSE_ROOF)
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
-                       return FALSE;
-
                switch (objectID)
                {
                case SINGLE_RESPONSE_ALGORITHM:
-                       sres->hash_algorithm = parse_algorithmIdentifier(object, level+1, NULL);
+                       sres->hash_algorithm = asn1_parse_algorithmIdentifier(object,
+                                                                               parser->get_level(parser)+1, NULL);
                        break;
                case SINGLE_RESPONSE_ISSUER_NAME_HASH:
                        sres->issuer_name_hash = object;
@@ -1289,7 +1279,7 @@ parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
                        sres->status = CERT_REVOKED;
                        break;
                case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
-                       sres->revocationTime = asn1totime(&object, ASN1_GENERALIZEDTIME);
+                       sres->revocationTime = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                        break;
                case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
                        sres->revocationReason = (object.len == 1)
@@ -1299,10 +1289,10 @@ parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
                        sres->status = CERT_UNKNOWN;
                        break;
                case SINGLE_RESPONSE_THIS_UPDATE:
-                       sres->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
+                       sres->thisUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                        break;
                case SINGLE_RESPONSE_NEXT_UPDATE:
-                       sres->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
+                       sres->nextUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                        break;
                case SINGLE_RESPONSE_EXT_ID:
                        extn_oid = asn1_known_oid(object);
@@ -1315,16 +1305,17 @@ parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
                case SINGLE_RESPONSE_EXT_VALUE:
                        break;
                }
-               objectID++;
        }
-       return TRUE;
+       success = parser->success(parser);
+       parser->destroy(parser);
+       return success;
 }
 
-/*
- * add an ocsp location to a chained list
+/**
+ * Add an ocsp location to a chained list
  */
-ocsp_location_t*
-add_ocsp_location(const ocsp_location_t *loc, ocsp_location_t **chain)
+ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc,
+                                                                  ocsp_location_t **chain)
 {
        ocsp_location_t *location = malloc_thing(ocsp_location_t);
 
@@ -1347,12 +1338,11 @@ add_ocsp_location(const ocsp_location_t *loc, ocsp_location_t **chain)
        return location;
 }
 
-/*
+/**
  * add a certinfo struct to a chained list
  */
-void
-add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chain
-       , bool request)
+void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info,
+                                 ocsp_location_t **chain, bool request)
 {
        ocsp_location_t *location;
        ocsp_certinfo_t *certinfo, **certinfop;
@@ -1362,7 +1352,9 @@ add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chai
 
        location = get_ocsp_location(loc, *chain);
        if (location == NULL)
+       {
                location = add_ocsp_location(loc, chain);
+       }
 
        /* traverse list of certinfos in increasing order */
        certinfop = &location->certinfo;
@@ -1404,8 +1396,9 @@ add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chai
                certinfo->status = CERT_UNDEFINED;
                
                if (cmp != 0)
+               {
                        certinfo->thisUpdate = now;
-
+               }
                certinfo->nextUpdate = UNDEFINED_TIME;
        }
        else
@@ -1424,11 +1417,11 @@ add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chai
        }
 }
 
-/*
- * process received ocsp single response and add it to ocsp cache
+/**
+ * Process received ocsp single response and add it to ocsp cache
  */
-static void
-process_single_response(ocsp_location_t *location, single_response_t *sres)
+static void process_single_response(ocsp_location_t *location,
+                                                                       single_response_t *sres)
 {
        ocsp_certinfo_t *certinfo, **certinfop;
        int cmp = -1;
@@ -1481,14 +1474,12 @@ process_single_response(ocsp_location_t *location, single_response_t *sres)
 
        /* free certinfo unlinked from ocsp fetch request list */
        free_certinfo(certinfo);
-
 }
 
-/*
- *  parse and verify ocsp response and update the ocsp cache
+/**
+ *  Parse and verify ocsp response and update the ocsp cache
  */
-void
-parse_ocsp(ocsp_location_t *location, chunk_t blob)
+void parse_ocsp(ocsp_location_t *location, chunk_t blob)
 {
        response_t res = empty_response;
 
@@ -1523,28 +1514,27 @@ parse_ocsp(ocsp_location_t *location, chunk_t blob)
 
        /* now parse the single responses one at a time */
        {
-               u_int level;
-               asn1_ctx_t ctx;
+               asn1_parser_t *parser;
                chunk_t object;
-               int objectID = 0;
+               int objectID;
 
-               asn1_init(&ctx, res.responses, 0, FALSE, DBG_RAW);
+               parser = asn1_parser_create(responsesObjects, res.responses);
 
-               while (objectID < RESPONSES_ROOF)
+               while (parser->iterate(parser, &objectID, &object))
                {
-                       if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
-                               return;
-                       
                        if (objectID == RESPONSES_SINGLE_RESPONSE)
                        {
                                single_response_t sres = empty_single_response;
 
-                               if (parse_ocsp_single_response(object, level+1, &sres))
+                               if (!parse_ocsp_single_response(object,
+                                                                               parser->get_level(parser)+1, &sres))
                                {
-                                       process_single_response(location, &sres);
+                                       goto end;
                                }
+                               process_single_response(location, &sres);
                        }
-                       objectID++;
                }
+end:
+               parser->destroy(parser);
        }
 }
index b7ef107..73fa7cc 100644 (file)
 #include <freeswan.h>
 #include <libsha2/sha2.h>
 
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+
 #include "constants.h"
 #include "defs.h"
 #include "mp_defs.h"
-#include "asn1.h"
-#include <asn1/oid.h>
 #include "log.h"
 #include "pkcs1.h"
 #include "md2.h"
@@ -48,40 +50,38 @@ const struct fld RSA_private_field[] =
        { "Coefficient",     offsetof(RSA_private_key_t, qInv) },
 };
 
-/* ASN.1 definition of a PKCS#1 RSA private key */
-
+/**
+ * ASN.1 definition of a PKCS#1 RSA private key
+ */
 static const asn1Object_t privkeyObjects[] = {
-  { 0, "RSAPrivateKey",                 ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
-  { 1,   "version",                     ASN1_INTEGER,      ASN1_BODY }, /*  1 */
-  { 1,   "modulus",                     ASN1_INTEGER,      ASN1_BODY }, /*  2 */
-  { 1,   "publicExponent",              ASN1_INTEGER,      ASN1_BODY }, /*  3 */
-  { 1,   "privateExponent",             ASN1_INTEGER,      ASN1_BODY }, /*  4 */
-  { 1,   "prime1",                      ASN1_INTEGER,      ASN1_BODY }, /*  5 */
-  { 1,   "prime2",                      ASN1_INTEGER,      ASN1_BODY }, /*  6 */
-  { 1,   "exponent1",                   ASN1_INTEGER,      ASN1_BODY }, /*  7 */
-  { 1,   "exponent2",                   ASN1_INTEGER,      ASN1_BODY }, /*  8 */
-  { 1,   "coefficient",                 ASN1_INTEGER,      ASN1_BODY }, /*  9 */
-  { 1,   "otherPrimeInfos",             ASN1_SEQUENCE,     ASN1_OPT |
-                                                                                                                  ASN1_LOOP }, /* 10 */
-  { 2,     "otherPrimeInfo",            ASN1_SEQUENCE,     ASN1_NONE }, /* 11 */
-  { 3,       "prime",                   ASN1_INTEGER,      ASN1_BODY }, /* 12 */
-  { 3,       "exponent",                ASN1_INTEGER,      ASN1_BODY }, /* 13 */
-  { 3,       "coefficient",             ASN1_INTEGER,      ASN1_BODY }, /* 14 */
-  { 1,   "end opt or loop",             ASN1_EOC,          ASN1_END  }  /* 15 */
+       { 0, "RSAPrivateKey",           ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
+       { 1,   "version",                       ASN1_INTEGER,      ASN1_BODY }, /*  1 */
+       { 1,   "modulus",                       ASN1_INTEGER,      ASN1_BODY }, /*  2 */
+       { 1,   "publicExponent",        ASN1_INTEGER,      ASN1_BODY }, /*  3 */
+       { 1,   "privateExponent",       ASN1_INTEGER,      ASN1_BODY }, /*  4 */
+       { 1,   "prime1",                        ASN1_INTEGER,      ASN1_BODY }, /*  5 */
+       { 1,   "prime2",                        ASN1_INTEGER,      ASN1_BODY }, /*  6 */
+       { 1,   "exponent1",                     ASN1_INTEGER,      ASN1_BODY }, /*  7 */
+       { 1,   "exponent2",                     ASN1_INTEGER,      ASN1_BODY }, /*  8 */
+       { 1,   "coefficient",           ASN1_INTEGER,      ASN1_BODY }, /*  9 */
+       { 1,   "otherPrimeInfos",       ASN1_SEQUENCE,     ASN1_OPT |
+                                                                                                  ASN1_LOOP }, /* 10 */
+       { 2,     "otherPrimeInfo",      ASN1_SEQUENCE,     ASN1_NONE }, /* 11 */
+       { 3,       "prime",                     ASN1_INTEGER,      ASN1_BODY }, /* 12 */
+       { 3,       "exponent",          ASN1_INTEGER,      ASN1_BODY }, /* 13 */
+       { 3,       "coefficient",       ASN1_INTEGER,      ASN1_BODY }, /* 14 */
+       { 1,   "end opt or loop",       ASN1_EOC,          ASN1_END  }, /* 15 */
+       { 0, "exit",                            ASN1_EOC,          ASN1_EXIT }
 };
+#define PKCS1_PRIV_KEY_VERSION          1
+#define PKCS1_PRIV_KEY_MODULUS          2
+#define PKCS1_PRIV_KEY_PUB_EXP          3
+#define PKCS1_PRIV_KEY_COEFF            9
 
-#define PKCS1_PRIV_KEY_VERSION           1
-#define PKCS1_PRIV_KEY_MODULUS           2
-#define PKCS1_PRIV_KEY_PUB_EXP           3
-#define PKCS1_PRIV_KEY_COEFF             9
-#define PKCS1_PRIV_KEY_ROOF             16
-
-
-/*
- * forms the FreeS/WAN keyid from the public exponent e and modulus n
+/**
+ * Forms the FreeS/WAN keyid from the public exponent e and modulus n
  */
-void
-form_keyid(chunk_t e, chunk_t n, char* keyid, unsigned *keysize)
+void form_keyid(chunk_t e, chunk_t n, char* keyid, unsigned *keysize)
 {
        /* eliminate leading zero bytes in modulus from ASN.1 coding */
        while (n.len > 1 && *n.ptr == 0x00)
@@ -97,11 +97,10 @@ form_keyid(chunk_t e, chunk_t n, char* keyid, unsigned *keysize)
        *keysize = n.len;
 }
 
-/*
- * initialize an RSA_public_key_t object
+/**
+ * Initialize an RSA_public_key_t object
  */
-void
-init_RSA_public_key(RSA_public_key_t *rsa, chunk_t e, chunk_t n)
+void init_RSA_public_key(RSA_public_key_t *rsa, chunk_t e, chunk_t n)
 {
        n_to_mpz(&rsa->e, e.ptr, e.len);
        n_to_mpz(&rsa->n, n.ptr, n.len);
@@ -110,8 +109,7 @@ init_RSA_public_key(RSA_public_key_t *rsa, chunk_t e, chunk_t n)
 }
 
 #ifdef DEBUG
-static void
-RSA_show_key_fields(RSA_private_key_t *k, int fieldcnt)
+static void RSA_show_key_fields(RSA_private_key_t *k, int fieldcnt)
 {
        const struct fld *p;
 
@@ -130,15 +128,15 @@ RSA_show_key_fields(RSA_private_key_t *k, int fieldcnt)
        }
 }
 
-/* debugging info that compromises security! */
-void
-RSA_show_private_key(RSA_private_key_t *k)
+/**
+ * debugging info that compromises security!
+ */
+void RSA_show_private_key(RSA_private_key_t *k)
 {
        RSA_show_key_fields(k, countof(RSA_private_field));
 }
 
-void
-RSA_show_public_key(RSA_public_key_t *k)
+void RSA_show_public_key(RSA_public_key_t *k)
 {
        /* Kludge: pretend that it is a private key, but only display the
         * first two fields (which are the public key).
@@ -148,8 +146,7 @@ RSA_show_public_key(RSA_public_key_t *k)
 }
 #endif
 
-err_t
-RSA_private_key_sanity(RSA_private_key_t *k)
+err_t RSA_private_key_sanity(RSA_private_key_t *k)
 {
        /* note that the *last* error found is reported */
        err_t ugh = NULL;
@@ -226,41 +223,36 @@ RSA_private_key_sanity(RSA_private_key_t *k)
        return ugh;
 }
 
-/*
+/**
  * Check the equality of two RSA public keys
  */
-bool
-same_RSA_public_key(const RSA_public_key_t *a, const RSA_public_key_t *b)
+bool same_RSA_public_key(const RSA_public_key_t *a, const RSA_public_key_t *b)
 {
        return a == b
        || (a->k == b->k && mpz_cmp(&a->n, &b->n) == 0 && mpz_cmp(&a->e, &b->e) == 0);
 }
 
-/*
+/**
  *  Parses a PKCS#1 private key
  */
-bool
-pkcs1_parse_private_key(chunk_t blob, RSA_private_key_t *key)
+bool pkcs1_parse_private_key(chunk_t blob, RSA_private_key_t *key)
 {
-       err_t ugh = NULL;
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object, modulus, exp;
-       u_int level;
-       int objectID = 0;
-
-       asn1_init(&ctx, blob, 0, FALSE, DBG_PRIVATE);
-
-       while (objectID < PKCS1_PRIV_KEY_ROOF) {
-
-               if (!extract_object(privkeyObjects, &objectID, &object, &level, &ctx))
-                        return FALSE;
+       int objectID;
+       bool success = FALSE;
 
+       parser = asn1_parser_create(privkeyObjects, blob);
+       parser->set_flags(parser, FALSE, TRUE);
+       
+       while (parser->iterate(parser, &objectID, &object))
+       {
                if (objectID == PKCS1_PRIV_KEY_VERSION)
                {
                        if (object.len > 0 && *object.ptr != 0)
                        {
                                plog("  wrong PKCS#1 private key version");
-                               return FALSE;
+                               goto end;
                        }
                }
                else if (objectID >= PKCS1_PRIV_KEY_MODULUS &&
@@ -276,18 +268,27 @@ pkcs1_parse_private_key(chunk_t blob, RSA_private_key_t *key)
                        else if (objectID == PKCS1_PRIV_KEY_PUB_EXP)
                                exp = object;
                }
-               objectID++;
        }
-       form_keyid(exp, modulus, key->pub.keyid, &key->pub.k);
-       ugh = RSA_private_key_sanity(key);
-       return (ugh == NULL);
+       success = parser->success(parser);
+
+end:
+       parser->destroy(parser);
+
+       if (success)
+       {
+               err_t ugh;
+
+               form_keyid(exp, modulus, key->pub.keyid, &key->pub.k);
+               ugh = RSA_private_key_sanity(key);
+               success = (ugh == NULL);
+       }
+       return success;
 }
 
-/*
- *  compute a digest over a binary blob
+/**
+ *  Compute a digest over a binary blob
  */
-bool
-compute_digest(chunk_t tbs, int alg, chunk_t *digest)
+bool compute_digest(chunk_t tbs, int alg, chunk_t *digest)
 {
        switch (alg)
        {
@@ -367,12 +368,11 @@ compute_digest(chunk_t tbs, int alg, chunk_t *digest)
        }
 }
 
-/*
- * compute an RSA signature with PKCS#1 padding
+/**
+ * Compute an RSA signature with PKCS#1 padding
  */
-void
-sign_hash(const RSA_private_key_t *k, const u_char *hash_val, size_t hash_len
-       , u_char *sig_val, size_t sig_len)
+void sign_hash(const RSA_private_key_t *k, const u_char *hash_val,
+                          size_t hash_len, u_char *sig_val, size_t sig_len)
 {
        chunk_t ch;
        mpz_t t1, t2;
@@ -423,11 +423,10 @@ sign_hash(const RSA_private_key_t *k, const u_char *hash_val, size_t hash_len
        mpz_clear(t2);
 }
 
-/*
- * encrypt data with an RSA public key after padding
+/**
+ * Encrypt data with an RSA public key after padding
  */
-chunk_t
-RSA_encrypt(const RSA_public_key_t *key, chunk_t in)
+chunk_t RSA_encrypt(const RSA_public_key_t *key, chunk_t in)
 {
        u_char padded[RSA_MAX_OCTETS];
        u_char *pos = padded;
@@ -485,11 +484,10 @@ RSA_encrypt(const RSA_public_key_t *key, chunk_t in)
        }
 }
 
-/*
- * decrypt data with an RSA private key and remove padding
+/**
+ * Decrypt data with an RSA private key and remove padding
  */
-bool
-RSA_decrypt(const RSA_private_key_t *key, chunk_t in, chunk_t *out)
+bool RSA_decrypt(const RSA_private_key_t *key, chunk_t in, chunk_t *out)
 {
        chunk_t padded, plaintext;
        u_char *pos;
@@ -551,12 +549,11 @@ RSA_decrypt(const RSA_private_key_t *key, chunk_t in, chunk_t *out)
        return TRUE;
 }
 
-/*
- * build signatureValue
+/**
+ * Build signatureValue
  */
-chunk_t
-pkcs1_build_signature(chunk_t tbs, int hash_alg, const RSA_private_key_t *key
-, bool bit_string)
+chunk_t pkcs1_build_signature(chunk_t tbs, int hash_alg,
+                                                         const RSA_private_key_t *key, bool bit_string)
 {
 
        size_t siglen = key->pub.k;
@@ -566,37 +563,27 @@ pkcs1_build_signature(chunk_t tbs, int hash_alg, const RSA_private_key_t *key
        chunk_t digestInfo, alg_id, signatureValue;
        u_char *pos;
 
-       switch (hash_alg)
+       if (!compute_digest(tbs, hash_alg, &digest))
        {
-       case OID_MD5:
-       case OID_MD5_WITH_RSA:
-               alg_id = ASN1_md5_id;
-               break;
-       case OID_SHA1:
-       case OID_SHA1_WITH_RSA:
-               alg_id = ASN1_sha1_id;
-               break;
-       default:
                return chunk_empty;
        }
-       compute_digest(tbs, hash_alg, &digest);
 
        /* according to PKCS#1 v2.1 digest must be packaged into
         * an ASN.1 structure for encryption
         */
        digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm"
-                                       , alg_id
+                                       , asn1_algorithmIdentifier(hash_alg)
                                        , asn1_simple_object(ASN1_OCTET_STRING, digest));
 
        /* generate the RSA signature */
        if (bit_string)
        {
-               pos = build_asn1_object(&signatureValue, ASN1_BIT_STRING, 1 + siglen);
+               pos = asn1_build_object(&signatureValue, ASN1_BIT_STRING, 1 + siglen);
                *pos++ = 0x00;
        }
        else
        {
-               pos = build_asn1_object(&signatureValue, ASN1_OCTET_STRING, siglen);
+               pos = asn1_build_object(&signatureValue, ASN1_OCTET_STRING, siglen);
        }
        sign_hash(key, digestInfo.ptr, digestInfo.len, pos, siglen);
        free(digestInfo.ptr);
@@ -604,11 +591,10 @@ pkcs1_build_signature(chunk_t tbs, int hash_alg, const RSA_private_key_t *key
        return signatureValue;
 }
 
-/*
- * build a DER-encoded PKCS#1 private key object
+/**
+ * Build a DER-encoded PKCS#1 private key object
  */
-chunk_t
-pkcs1_build_private_key(const RSA_private_key_t *key)
+chunk_t pkcs1_build_private_key(const RSA_private_key_t *key)
 {
        chunk_t pkcs1 = asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm"
                                                , ASN1_INTEGER_0
@@ -627,44 +613,41 @@ pkcs1_build_private_key(const RSA_private_key_t *key)
        return pkcs1;
 }
 
-/*
- * build a DER-encoded PKCS#1 public key object
+/**
+ * Build a DER-encoded PKCS#1 public key object
  */
-chunk_t
-pkcs1_build_public_key(const RSA_public_key_t *rsa)
+chunk_t pkcs1_build_public_key(const RSA_public_key_t *rsa)
 {
        return asn1_wrap(ASN1_SEQUENCE, "mm"
                                , asn1_integer_from_mpz(&rsa->n)
                                , asn1_integer_from_mpz(&rsa->e));
 }
 
-/*
- * build a DER-encoded publicKeyInfo object
+/**
+ * Build a DER-encoded publicKeyInfo object
  */
-chunk_t
-pkcs1_build_publicKeyInfo(const RSA_public_key_t *rsa)
+chunk_t pkcs1_build_publicKeyInfo(const RSA_public_key_t *rsa)
 {
        chunk_t publicKey;
        chunk_t rawKey = pkcs1_build_public_key(rsa);
+       u_char *pos;
 
-       u_char *pos = build_asn1_object(&publicKey, ASN1_BIT_STRING
-                                               , 1 + rawKey.len);
+       pos = asn1_build_object(&publicKey, ASN1_BIT_STRING, 1 + rawKey.len);
        *pos++ = 0x00;
        mv_chunk(&pos, rawKey);
 
        return asn1_wrap(ASN1_SEQUENCE, "cm"
-                               , ASN1_rsaEncryption_id
+                               , asn1_algorithmIdentifier(OID_RSA_ENCRYPTION)
                                , publicKey);   
 }
-void
-free_RSA_public_content(RSA_public_key_t *rsa)
+
+void free_RSA_public_content(RSA_public_key_t *rsa)
 {
        mpz_clear(&rsa->n);
        mpz_clear(&rsa->e);
 }
 
-void
-free_RSA_private_content(RSA_private_key_t *rsak)
+void free_RSA_private_content(RSA_private_key_t *rsak)
 {
        free_RSA_public_content(&rsak->pub);
        mpz_clear(&rsak->d);
@@ -674,4 +657,3 @@ free_RSA_private_content(RSA_private_key_t *rsak)
        mpz_clear(&rsak->dQ);
        mpz_clear(&rsak->qInv);
 }
-
index 8283a06..7fa2cb3 100644 (file)
 
 #include <freeswan.h>
 
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+
 #include "constants.h"
 #include "defs.h"
-#include "asn1.h"
-#include <asn1/oid.h>
 #include "log.h"
 #include "x509.h"
 #include "certs.h"
@@ -37,54 +39,55 @@ const contentInfo_t empty_contentInfo = {
        { NULL, 0 }   /* content */
 };
 
-/* ASN.1 definition of the PKCS#7 ContentInfo type */
-
+/**
+ * ASN.1 definition of the PKCS#7 ContentInfo type
+ */
 static const asn1Object_t contentInfoObjects[] = {
-  { 0, "contentInfo",                   ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
-  { 1,   "contentType",                 ASN1_OID,          ASN1_BODY }, /*  1 */
-  { 1,   "content",                     ASN1_CONTEXT_C_0,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /*  2 */
-  { 1,   "end opt",                     ASN1_EOC,          ASN1_END  }  /*  3 */
+       { 0, "contentInfo",                   ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
+       { 1,   "contentType",                 ASN1_OID,          ASN1_BODY }, /*  1 */
+       { 1,   "content",                     ASN1_CONTEXT_C_0,  ASN1_OPT |
+                                                                                                                        ASN1_BODY }, /*  2 */
+       { 1,   "end opt",                     ASN1_EOC,          ASN1_END  }, /*  3 */
+       { 0, "exit",                          ASN1_EOC,          ASN1_EXIT }
 };
-
 #define PKCS7_INFO_TYPE         1
 #define PKCS7_INFO_CONTENT      2
-#define PKCS7_INFO_ROOF         4
-
-/* ASN.1 definition of the PKCS#7 signedData type */
 
+/**
+ * ASN.1 definition of the PKCS#7 signedData type
+ */
 static const asn1Object_t signedDataObjects[] = {
-  { 0, "signedData",                      ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
-  { 1,   "version",                       ASN1_INTEGER,      ASN1_BODY }, /*  1 */
-  { 1,   "digestAlgorithms",              ASN1_SET,          ASN1_LOOP }, /*  2 */
-  { 2,     "algorithm",                   ASN1_EOC,          ASN1_RAW  }, /*  3 */
-  { 1,   "end loop",                      ASN1_EOC,          ASN1_END  }, /*  4 */
-  { 1,   "contentInfo",                   ASN1_EOC,          ASN1_RAW  }, /*  5 */
-  { 1,   "certificates",                  ASN1_CONTEXT_C_0,  ASN1_OPT |
-                                                                                                                        ASN1_LOOP }, /*  6 */
-  { 2,      "certificate",                ASN1_SEQUENCE,     ASN1_OBJ  }, /*  7 */
-  { 1,   "end opt or loop",               ASN1_EOC,          ASN1_END  }, /*  8 */
-  { 1,   "crls",                          ASN1_CONTEXT_C_1,  ASN1_OPT |
-                                                                                                                        ASN1_LOOP }, /*  9 */
-  { 2,      "crl",                        ASN1_SEQUENCE,     ASN1_OBJ  }, /* 10 */
-  { 1,   "end opt or loop",               ASN1_EOC,          ASN1_END  }, /* 11 */
-  { 1,   "signerInfos",                   ASN1_SET,          ASN1_LOOP }, /* 12 */
-  { 2,     "signerInfo",                  ASN1_SEQUENCE,     ASN1_NONE }, /* 13 */
-  { 3,       "version",                   ASN1_INTEGER,      ASN1_BODY }, /* 14 */
-  { 3,       "issuerAndSerialNumber",     ASN1_SEQUENCE,     ASN1_BODY }, /* 15 */
-  { 4,         "issuer",                  ASN1_SEQUENCE,     ASN1_OBJ  }, /* 16 */
-  { 4,         "serial",                  ASN1_INTEGER,      ASN1_BODY }, /* 17 */
-  { 3,       "digestAlgorithm",           ASN1_EOC,          ASN1_RAW  }, /* 18 */
-  { 3,       "authenticatedAttributes",   ASN1_CONTEXT_C_0,  ASN1_OPT |
-                                                                                                                        ASN1_OBJ  }, /* 19 */
-  { 3,       "end opt",                   ASN1_EOC,          ASN1_END  }, /* 20 */
-  { 3,       "digestEncryptionAlgorithm", ASN1_EOC,          ASN1_RAW  }, /* 21 */
-  { 3,       "encryptedDigest",           ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */
-  { 3,       "unauthenticatedAttributes", ASN1_CONTEXT_C_1,  ASN1_OPT  }, /* 23 */
-  { 3,       "end opt",                   ASN1_EOC,          ASN1_END  }, /* 24 */
-  { 1,   "end loop",                      ASN1_EOC,          ASN1_END  }  /* 25 */
+       { 0, "signedData",                      ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
+       { 1,   "version",                       ASN1_INTEGER,      ASN1_BODY }, /*  1 */
+       { 1,   "digestAlgorithms",              ASN1_SET,          ASN1_LOOP }, /*  2 */
+       { 2,     "algorithm",                   ASN1_EOC,          ASN1_RAW  }, /*  3 */
+       { 1,   "end loop",                      ASN1_EOC,          ASN1_END  }, /*  4 */
+       { 1,   "contentInfo",                   ASN1_EOC,          ASN1_RAW  }, /*  5 */
+       { 1,   "certificates",                  ASN1_CONTEXT_C_0,  ASN1_OPT |
+                                                                                                                          ASN1_LOOP }, /*  6 */
+       { 2,      "certificate",                ASN1_SEQUENCE,     ASN1_OBJ  }, /*  7 */
+       { 1,   "end opt or loop",               ASN1_EOC,          ASN1_END  }, /*  8 */
+       { 1,   "crls",                          ASN1_CONTEXT_C_1,  ASN1_OPT |
+                                                                                                                          ASN1_LOOP }, /*  9 */
+       { 2,      "crl",                        ASN1_SEQUENCE,     ASN1_OBJ  }, /* 10 */
+       { 1,   "end opt or loop",               ASN1_EOC,          ASN1_END  }, /* 11 */
+       { 1,   "signerInfos",                   ASN1_SET,          ASN1_LOOP }, /* 12 */
+       { 2,     "signerInfo",                  ASN1_SEQUENCE,     ASN1_NONE }, /* 13 */
+       { 3,       "version",                   ASN1_INTEGER,      ASN1_BODY }, /* 14 */
+       { 3,       "issuerAndSerialNumber",     ASN1_SEQUENCE,     ASN1_BODY }, /* 15 */
+       { 4,         "issuer",                  ASN1_SEQUENCE,     ASN1_OBJ  }, /* 16 */
+       { 4,         "serial",                  ASN1_INTEGER,      ASN1_BODY }, /* 17 */
+       { 3,       "digestAlgorithm",           ASN1_EOC,          ASN1_RAW  }, /* 18 */
+       { 3,       "authenticatedAttributes",   ASN1_CONTEXT_C_0,  ASN1_OPT |
+                                                                                                                          ASN1_OBJ  }, /* 19 */
+       { 3,       "end opt",                   ASN1_EOC,          ASN1_END  }, /* 20 */
+       { 3,       "digestEncryptionAlgorithm", ASN1_EOC,          ASN1_RAW  }, /* 21 */
+       { 3,       "encryptedDigest",           ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */
+       { 3,       "unauthenticatedAttributes", ASN1_CONTEXT_C_1,  ASN1_OPT  }, /* 23 */
+       { 3,       "end opt",                   ASN1_EOC,          ASN1_END  }, /* 24 */
+       { 1,   "end loop",                      ASN1_EOC,          ASN1_END  }, /* 25 */
+       { 0, "exit",                            ASN1_EOC,          ASN1_EXIT }
 };
-
 #define PKCS7_DIGEST_ALG                 3
 #define PKCS7_SIGNED_CONTENT_INFO        5
 #define PKCS7_SIGNED_CERT                7
@@ -95,28 +98,28 @@ static const asn1Object_t signedDataObjects[] = {
 #define PKCS7_AUTH_ATTRIBUTES           19
 #define PKCS7_DIGEST_ENC_ALGORITHM      21
 #define PKCS7_ENCRYPTED_DIGEST          22
-#define PKCS7_SIGNED_ROOF               26
-
-/* ASN.1 definition of the PKCS#7 envelopedData type */
 
+/**
+ * ASN.1 definition of the PKCS#7 envelopedData type
+ */
 static const asn1Object_t envelopedDataObjects[] = {
-  { 0, "envelopedData",                         ASN1_SEQUENCE,          ASN1_NONE }, /*  0 */
-  { 1,   "version",                             ASN1_INTEGER,           ASN1_BODY }, /*  1 */
-  { 1,   "recipientInfos",                      ASN1_SET,               ASN1_LOOP }, /*  2 */
-  { 2,     "recipientInfo",                     ASN1_SEQUENCE,          ASN1_BODY }, /*  3 */
-  { 3,       "version",                         ASN1_INTEGER,           ASN1_BODY }, /*  4 */
-  { 3,       "issuerAndSerialNumber",           ASN1_SEQUENCE,          ASN1_BODY }, /*  5 */
-  { 4,         "issuer",                        ASN1_SEQUENCE,          ASN1_OBJ  }, /*  6 */
-  { 4,         "serial",                        ASN1_INTEGER,           ASN1_BODY }, /*  7 */
-  { 3,       "encryptionAlgorithm",             ASN1_EOC,               ASN1_RAW  }, /*  8 */
-  { 3,       "encryptedKey",                    ASN1_OCTET_STRING,      ASN1_BODY }, /*  9 */
-  { 1,   "end loop",                            ASN1_EOC,               ASN1_END  }, /* 10 */
-  { 1,   "encryptedContentInfo",                ASN1_SEQUENCE,          ASN1_OBJ  }, /* 11 */
-  { 2,     "contentType",                       ASN1_OID,               ASN1_BODY }, /* 12 */
-  { 2,     "contentEncryptionAlgorithm",        ASN1_EOC,               ASN1_RAW  }, /* 13 */
-  { 2,     "encryptedContent",                  ASN1_CONTEXT_S_0,       ASN1_BODY }  /* 14 */
+       { 0, "envelopedData",                  ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
+       { 1,   "version",                      ASN1_INTEGER,      ASN1_BODY }, /*  1 */
+       { 1,   "recipientInfos",               ASN1_SET,          ASN1_LOOP }, /*  2 */
+       { 2,     "recipientInfo",              ASN1_SEQUENCE,     ASN1_BODY }, /*  3 */
+       { 3,       "version",                  ASN1_INTEGER,      ASN1_BODY }, /*  4 */
+       { 3,       "issuerAndSerialNumber",    ASN1_SEQUENCE,     ASN1_BODY }, /*  5 */
+       { 4,         "issuer",                 ASN1_SEQUENCE,     ASN1_OBJ  }, /*  6 */
+       { 4,         "serial",                 ASN1_INTEGER,      ASN1_BODY }, /*  7 */
+       { 3,       "encryptionAlgorithm",      ASN1_EOC,          ASN1_RAW  }, /*  8 */
+       { 3,       "encryptedKey",             ASN1_OCTET_STRING, ASN1_BODY }, /*  9 */
+       { 1,   "end loop",                     ASN1_EOC,          ASN1_END  }, /* 10 */
+       { 1,   "encryptedContentInfo",         ASN1_SEQUENCE,     ASN1_OBJ  }, /* 11 */
+       { 2,     "contentType",                ASN1_OID,          ASN1_BODY }, /* 12 */
+       { 2,     "contentEncryptionAlgorithm", ASN1_EOC,          ASN1_RAW  }, /* 13 */
+       { 2,     "encryptedContent",           ASN1_CONTEXT_S_0,  ASN1_BODY }, /* 14 */
+       { 0, "exit",                           ASN1_EOC,          ASN1_EXIT }
 };
-
 #define PKCS7_ENVELOPED_VERSION          1
 #define PKCS7_RECIPIENT_INFO_VERSION     4
 #define PKCS7_ISSUER                     6
@@ -128,7 +131,9 @@ static const asn1Object_t envelopedDataObjects[] = {
 #define PKCS7_ENCRYPTED_CONTENT         14
 #define PKCS7_ENVELOPED_ROOF            15
 
-/* PKCS7 contentInfo OIDs */
+/**
+ * PKCS7 contentInfo OIDs
+ */
 
 static u_char ASN1_pkcs7_data_oid_str[] = {
        0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01
@@ -167,7 +172,9 @@ static const chunk_t ASN1_pkcs7_digested_data_oid =
 static const chunk_t ASN1_pkcs7_encrypted_data_oid =
                                                chunk_from_buf(ASN1_pkcs7_encrypted_data_oid_str);
 
-/* 3DES and DES encryption OIDs */
+/**
+ * 3DES and DES encryption OIDs
+ */
 
 static u_char ASN1_3des_ede_cbc_oid_str[] = {
        0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07
@@ -182,7 +189,9 @@ static const chunk_t ASN1_3des_ede_cbc_oid =
 static const chunk_t ASN1_des_cbc_oid =
                                                chunk_from_buf(ASN1_des_cbc_oid_str);
 
-/* PKCS#7 attribute type OIDs */
+/**
+ * PKCS#7 attribute type OIDs
+ */
 
 static u_char ASN1_contentType_oid_str[] = {
        0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03
@@ -197,24 +206,21 @@ static const chunk_t ASN1_contentType_oid =
 static const chunk_t ASN1_messageDigest_oid =
                                                chunk_from_buf(ASN1_messageDigest_oid_str);
 
-/*
+/**
  * Parse PKCS#7 ContentInfo object
  */
-bool
-pkcs7_parse_contentInfo(chunk_t blob, u_int level0, contentInfo_t *cInfo)
+bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0, contentInfo_t *cInfo)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
+       bool success = FALSE;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+       parser = asn1_parser_create(contentInfoObjects, blob);
+       parser->set_top_level(parser, level0);
 
-       while (objectID < PKCS7_INFO_ROOF)
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(contentInfoObjects, &objectID, &object, &level, &ctx))
-                        return FALSE;
-
                if (objectID == PKCS7_INFO_TYPE)
                {
                        cInfo->type = asn1_known_oid(object);
@@ -222,57 +228,60 @@ pkcs7_parse_contentInfo(chunk_t blob, u_int level0, contentInfo_t *cInfo)
                        ||  cInfo->type > OID_PKCS7_ENCRYPTED_DATA)
                        {
                                plog("unknown pkcs7 content type");
-                               return FALSE;
+                               goto end;
                        }
                }
                else if (objectID == PKCS7_INFO_CONTENT)
                {
                        cInfo->content = object;
                }
-               objectID++;
        }
-       return TRUE;
+       success = parser->success(parser);
+
+end:
+       parser->destroy(parser);
+       return success;
 }
 
-/*
+/**
  * Parse a PKCS#7 signedData object
  */
-bool
-pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert
-, chunk_t *attributes, const x509cert_t *cacert)
+bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert,
+                                                       chunk_t *attributes, const x509cert_t *cacert)
 {
        u_char buf[BUF_LEN];
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
        int digest_alg = OID_UNKNOWN;
        int enc_alg    = OID_UNKNOWN;
        int signerInfos = 0;
-       int objectID = 0;
+       int objectID;
+       bool success = FALSE;
 
        contentInfo_t cInfo = empty_contentInfo;
        chunk_t encrypted_digest = chunk_empty;
 
        if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
+       {
                return FALSE;
-
+       }
        if (cInfo.type != OID_PKCS7_SIGNED_DATA)
        {
                plog("pkcs7 content type is not signedData");
                return FALSE;
        }
 
-       asn1_init(&ctx, cInfo.content, 2, FALSE, DBG_RAW);
+       parser = asn1_parser_create(signedDataObjects, blob);
+       parser->set_top_level(parser, 2);
 
-       while (objectID < PKCS7_SIGNED_ROOF)
-   {
-               if (!extract_object(signedDataObjects, &objectID, &object, &level, &ctx))
-                        return FALSE;
+       while (parser->iterate(parser, &objectID, &object))
+       {
+               u_int level = parser->get_level(parser);
 
                switch (objectID)
                {
                case PKCS7_DIGEST_ALG:
-                       digest_alg = parse_algorithmIdentifier(object, level, NULL);
+                       digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
                        break;
                case PKCS7_SIGNED_CONTENT_INFO:
                        if (data != NULL)
@@ -322,15 +331,20 @@ pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert
                        }
                        break;
                case PKCS7_DIGEST_ALGORITHM:
-                       digest_alg = parse_algorithmIdentifier(object, level, NULL);
+                       digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
                        break;
                case PKCS7_DIGEST_ENC_ALGORITHM:
-                       enc_alg = parse_algorithmIdentifier(object, level, NULL);
+                       enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
                        break;
                case PKCS7_ENCRYPTED_DIGEST:
                        encrypted_digest = object;
                }
-               objectID++;
+       }
+       success = parser->success(parser);
+       parser->destroy(parser);
+       if (!success)
+       {
+               return FALSE;
        }
 
        /* check the signature only if a cacert is available */
@@ -367,44 +381,45 @@ pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert
        return TRUE;
 }
 
-/*
+/**
  * Parse a PKCS#7 envelopedData object
  */
-bool
-pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
-, chunk_t serialNumber, const RSA_private_key_t *key)
+bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
+                                                          chunk_t serialNumber,
+                                                          const RSA_private_key_t *key)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
        chunk_t iv                = chunk_empty;
        chunk_t symmetric_key     = chunk_empty;
        chunk_t encrypted_content = chunk_empty;
 
        u_char buf[BUF_LEN];
-       u_int level;
        u_int total_keys = 3;
        int enc_alg         = OID_UNKNOWN;
        int content_enc_alg = OID_UNKNOWN;
-       int objectID = 0;
+       int objectID;
+       bool success = FALSE;
 
        contentInfo_t cInfo = empty_contentInfo;
        *data = chunk_empty;
 
        if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
-               goto failed;
-
+       {
+               goto end;
+       }
        if (cInfo.type != OID_PKCS7_ENVELOPED_DATA)
        {
                plog("pkcs7 content type is not envelopedData");
-               return FALSE;
+               goto end;
        }
 
-       asn1_init(&ctx, cInfo.content, 2, FALSE, DBG_RAW);
+       parser = asn1_parser_create(envelopedDataObjects, cInfo.content);
+       parser->set_top_level(parser, 2);
 
-       while (objectID < PKCS7_ENVELOPED_ROOF)
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(envelopedDataObjects, &objectID, &object, &level, &ctx))
-                        goto failed;
+               u_int level = parser->get_level(parser);
 
                switch (objectID)
                {
@@ -412,14 +427,14 @@ pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
                if (*object.ptr != 0)
                {
                        plog("envelopedData version is not 0");
-                       goto failed;
+                       goto end;
                }
                break;
                case PKCS7_RECIPIENT_INFO_VERSION:
                        if (*object.ptr != 0)
                        {
                                plog("recipient info version is not 0");
-                               goto failed;
+                               goto end;
                        }
                        break;
                case PKCS7_ISSUER:
@@ -432,22 +447,22 @@ pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
                        if (!chunk_equals(serialNumber, object))
                        {
                                plog("serial numbers do not match");
-                               goto failed;
+                               goto end;
                        }   
                        break;      
                case PKCS7_ENCRYPTION_ALG:
-                       enc_alg = parse_algorithmIdentifier(object, level, NULL);
+                       enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
                        if (enc_alg != OID_RSA_ENCRYPTION)
                        {
                                plog("only rsa encryption supported");
-                               goto failed;
+                               goto end;
                        } 
                        break;
                case PKCS7_ENCRYPTED_KEY:
                        if (!RSA_decrypt(key, object, &symmetric_key))
                        {
                                plog("symmetric key could not be decrypted with rsa");
-                               goto failed;
+                               goto end;
                        }
                        DBG(DBG_PRIVATE,
                                DBG_dump_chunk("symmetric key :", symmetric_key)
@@ -457,11 +472,11 @@ pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
                        if (asn1_known_oid(object) != OID_PKCS7_DATA)
                        {
                                 plog("encrypted content not of type pkcs7 data");
-                                goto failed;
+                                goto end;
                        }
                        break;
                case PKCS7_CONTENT_ENC_ALGORITHM:
-                       content_enc_alg = parse_algorithmIdentifier(object, level, &iv);
+                       content_enc_alg = asn1_parse_algorithmIdentifier(object, level, &iv);
 
                        switch (content_enc_alg)
                        {
@@ -473,29 +488,33 @@ pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
                                break;
                        default:
                                plog("Only DES and 3DES supported for symmetric encryption");
-                               goto failed;
+                               goto end;
                        }
                        if (symmetric_key.len != (total_keys * DES_CBC_BLOCK_SIZE))
                        {
                                plog("key length is not %d",(total_keys * DES_CBC_BLOCK_SIZE));
-                               goto failed;
+                               goto end;
                        }
-                       if (!parse_asn1_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
+                       if (!asn1_parse_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
                        {
                                plog("IV could not be parsed");
-                               goto failed;
+                               goto end;
                        }
                        if (iv.len != DES_CBC_BLOCK_SIZE)
                        {
                                plog("IV has wrong length");
-                               goto failed;
+                               goto end;
                        }
                        break;
                case PKCS7_ENCRYPTED_CONTENT:
                        encrypted_content = object;
                        break;
                }
-               objectID++;
+       }
+;
+       if (!parser->success(parser))
+       {
+               goto end;
        }
 
        /* decrypt the content */
@@ -512,7 +531,7 @@ pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
                        if (des_set_key(&des_key[i], key_s[i]))
                        {
                                plog("des key schedule failed");
-                               goto failed;
+                               goto end;
                        }
                }
 
@@ -546,7 +565,7 @@ pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
                if (padding > data->len)
                {
                        plog("padding greater than data length");
-                       goto failed;
+                       goto end;
                }
                data->len -= padding;
 
@@ -555,17 +574,19 @@ pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
                        if (*pos-- != pattern)
                        {
                                plog("wrong padding pattern");
-                               goto failed;
+                               goto end;
                        }
                }
        }
-       chunk_clear(&symmetric_key);
-       return TRUE;
+       success = TRUE;
 
-failed:
+end:
        chunk_clear(&symmetric_key);
-       free(data->ptr);
-       return FALSE;
+       if (!success)
+       {
+               free(data->ptr);
+       }
+       return success;
 }
 
 /**
@@ -573,8 +594,7 @@ failed:
  *
  * @return ASN.1 encoded contentType attribute
  */
-chunk_t
-pkcs7_contentType_attribute(void)
+chunk_t pkcs7_contentType_attribute(void)
 {
        return asn1_wrap(ASN1_SEQUENCE, "cm"
                                , ASN1_contentType_oid
@@ -590,8 +610,7 @@ pkcs7_contentType_attribute(void)
  * @return ASN.1 encoded messageDigest attribute
  * 
  */
-chunk_t
-pkcs7_messageDigest_attribute(chunk_t content, int digest_alg)
+chunk_t pkcs7_messageDigest_attribute(chunk_t content, int digest_alg)
 {
        u_char digest_buf[MAX_DIGEST_LEN];
        chunk_t digest = { digest_buf, MAX_DIGEST_LEN };
@@ -605,11 +624,11 @@ pkcs7_messageDigest_attribute(chunk_t content, int digest_alg)
                                  )
                   );
 }
-/*
+
+/**
  * build a DER-encoded contentInfo object
  */
-static chunk_t
-pkcs7_build_contentInfo(contentInfo_t *cInfo)
+static chunk_t pkcs7_build_contentInfo(contentInfo_t *cInfo)
 {
        chunk_t content_type;
 
@@ -648,23 +667,22 @@ pkcs7_build_contentInfo(contentInfo_t *cInfo)
                  );
 }
 
-/*
+/**
  * build issuerAndSerialNumber object
  */
-chunk_t
-pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert)
+chunk_t pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert)
 {
        return asn1_wrap(ASN1_SEQUENCE, "cm"
                                , cert->issuer
                                , asn1_simple_object(ASN1_INTEGER, cert->serialNumber));
 }
 
-/*
+/**
  * create a signed pkcs7 contentInfo object
  */
-chunk_t
-pkcs7_build_signedData(chunk_t data, chunk_t attributes, const x509cert_t *cert
-, int digest_alg, const RSA_private_key_t *key)
+chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes,
+                                                          const x509cert_t *cert, int digest_alg,
+                                                          const RSA_private_key_t *key)
 {
        contentInfo_t pkcs7Data, signedData;
        chunk_t authenticatedAttributes, encryptedDigest, signerInfo, cInfo;
@@ -690,7 +708,7 @@ pkcs7_build_signedData(chunk_t data, chunk_t attributes, const x509cert_t *cert
                                , pkcs7_build_issuerAndSerialNumber(cert)
                                , digestAlgorithm
                                , authenticatedAttributes
-                               , ASN1_rsaEncryption_id
+                               , asn1_algorithmIdentifier(OID_RSA_ENCRYPTION)
                                , encryptedDigest);
 
        pkcs7Data.type    = OID_PKCS7_DATA;
@@ -715,11 +733,10 @@ pkcs7_build_signedData(chunk_t data, chunk_t attributes, const x509cert_t *cert
        return cInfo;
 }
 
-/*
+/**
  * create a symmetrically encrypted pkcs7 contentInfo object
  */
-chunk_t
-pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int cipher)
+chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int cipher)
 {
        bool des_check_key_save;
        des_key_schedule ks[3];
@@ -833,7 +850,7 @@ pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int cipher)
                chunk_t recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmcm"
                                        , ASN1_INTEGER_0
                                        , pkcs7_build_issuerAndSerialNumber(cert)
-                                       , ASN1_rsaEncryption_id
+                                       , asn1_algorithmIdentifier(OID_RSA_ENCRYPTION)
                                        , encryptedKey);
 
                chunk_t cInfo;
index 5d308eb..7ef1636 100644 (file)
 #include <freeswan.h>
 #include <ipsec_policy.h>
 
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+
 #include "constants.h"
 #include "defs.h"
 #include "mp_defs.h"
 #include "log.h"
 #include "id.h"
-#include "asn1.h"
-#include <asn1/oid.h>
 #include "pkcs1.h"
 #include "x509.h"
 #include "crl.h"
 #include "ocsp.h"
 #include "sha1.h"
 
-/* chained lists of X.509 end certificates */
-
+/**
+ * Chained lists of X.509 end certificates
+ */
 static x509cert_t *x509certs     = NULL;
 
-/* ASN.1 definition of a basicConstraints extension */
-
+/**
+ * ASN.1 definition of a basicConstraints extension 
+ */
 static const asn1Object_t basicConstraintsObjects[] = {
-  { 0, "basicConstraints",              ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
-  { 1,   "CA",                          ASN1_BOOLEAN,      ASN1_DEF |
-                                                                                                                  ASN1_BODY }, /*  1 */
-  { 1,   "pathLenConstraint",           ASN1_INTEGER,      ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /*  2 */
-  { 1,   "end opt",                     ASN1_EOC,          ASN1_END  }  /*  3 */
-};
-
-#define BASIC_CONSTRAINTS_CA    1
-#define BASIC_CONSTRAINTS_ROOF  4
-
-/* ASN.1 definition of time */
-
-static const asn1Object_t timeObjects[] = {
-  { 0,   "utcTime",                     ASN1_UTCTIME,         ASN1_OPT |
-                                                                                                                         ASN1_BODY }, /*  0 */
-  { 0,   "end opt",                     ASN1_EOC,             ASN1_END  }, /*  1 */
-  { 0,   "generalizeTime",              ASN1_GENERALIZEDTIME, ASN1_OPT |
-                                                                                                                         ASN1_BODY }, /*  2 */
-  { 0,   "end opt",                     ASN1_EOC,             ASN1_END  }  /*  3 */
+       { 0, "basicConstraints",        ASN1_SEQUENCE, ASN1_NONE          }, /*  0 */
+       { 1,   "CA",                            ASN1_BOOLEAN,  ASN1_DEF|ASN1_BODY }, /*  1 */
+       { 1,   "pathLenConstraint",     ASN1_INTEGER,  ASN1_OPT|ASN1_BODY }, /*  2 */
+       { 1,   "end opt",                       ASN1_EOC,      ASN1_END           }, /*  3 */
+       { 0, "exit",                            ASN1_EOC,      ASN1_EXIT          }
 };
+#define BASIC_CONSTRAINTS_CA   1
 
-#define TIME_UTC                0
-#define TIME_GENERALIZED        2
-#define TIME_ROOF               4
-
-/* ASN.1 definition of a keyIdentifier */
-
-static const asn1Object_t keyIdentifierObjects[] = {
-  { 0,   "keyIdentifier",               ASN1_OCTET_STRING, ASN1_BODY }  /*  0 */
-};
-
-/* ASN.1 definition of a authorityKeyIdentifier extension */
-
-static const asn1Object_t authorityKeyIdentifierObjects[] = {
-  { 0,   "authorityKeyIdentifier",      ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
-  { 1,     "keyIdentifier",             ASN1_CONTEXT_S_0,  ASN1_OPT |
-                                                                                                                  ASN1_OBJ  }, /*  1 */
-  { 1,     "end opt",                   ASN1_EOC,          ASN1_END  }, /*  2 */
-  { 1,     "authorityCertIssuer",       ASN1_CONTEXT_C_1,  ASN1_OPT |
-                                                                                                                  ASN1_OBJ  }, /*  3 */
-  { 1,     "end opt",                   ASN1_EOC,          ASN1_END  }, /*  4 */
-  { 1,     "authorityCertSerialNumber", ASN1_CONTEXT_S_2,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /*  5 */
-  { 1,     "end opt",                   ASN1_EOC,          ASN1_END  }  /*  6 */
+/**
+ * ASN.1 definition of a authorityKeyIdentifier extension 
+ */
+static const asn1Object_t authKeyIdentifierObjects[] = {
+       { 0, "authorityKeyIdentifier",          ASN1_SEQUENCE,    ASN1_NONE          }, /* 0 */
+       { 1,   "keyIdentifier",                         ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_BODY }, /* 1 */
+       { 1,   "end opt",                                       ASN1_EOC,                 ASN1_END           }, /* 2 */
+       { 1,   "authorityCertIssuer",           ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ  }, /* 3 */
+       { 1,   "end opt",                                       ASN1_EOC,                 ASN1_END           }, /* 4 */
+       { 1,   "authorityCertSerialNumber",     ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
+       { 1,   "end opt",                                       ASN1_EOC,                 ASN1_END           }, /* 6 */
+       { 0, "exit",                                            ASN1_EOC,                 ASN1_EXIT          }
 };
+#define AUTH_KEY_ID_KEY_ID                     1
+#define AUTH_KEY_ID_CERT_ISSUER                3
+#define AUTH_KEY_ID_CERT_SERIAL                5
 
-#define AUTH_KEY_ID_KEY_ID              1
-#define AUTH_KEY_ID_CERT_ISSUER         3
-#define AUTH_KEY_ID_CERT_SERIAL         5
-#define AUTH_KEY_ID_ROOF                7
-
-/* ASN.1 definition of a authorityInfoAccess extension */
-
-static const asn1Object_t authorityInfoAccessObjects[] = {
-  { 0,   "authorityInfoAccess",         ASN1_SEQUENCE,     ASN1_LOOP }, /*  0 */
-  { 1,     "accessDescription",         ASN1_SEQUENCE,     ASN1_NONE }, /*  1 */
-  { 2,       "accessMethod",            ASN1_OID,          ASN1_BODY }, /*  2 */
-  { 2,       "accessLocation",          ASN1_EOC,          ASN1_RAW  }, /*  3 */
-  { 0,   "end loop",                    ASN1_EOC,          ASN1_END  }  /*  4 */
+/**
+ * ASN.1 definition of a authorityInfoAccess extension 
+ */
+static const asn1Object_t authInfoAccessObjects[] = {
+       { 0, "authorityInfoAccess",     ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
+       { 1,   "accessDescription",     ASN1_SEQUENCE,  ASN1_NONE }, /* 1 */
+       { 2,     "accessMethod",        ASN1_OID,               ASN1_BODY }, /* 2 */
+       { 2,     "accessLocation",      ASN1_EOC,               ASN1_RAW  }, /* 3 */
+       { 0, "end loop",                        ASN1_EOC,               ASN1_END  }, /* 4 */
+       { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
 };
+#define AUTH_INFO_ACCESS_METHOD                2
+#define AUTH_INFO_ACCESS_LOCATION      3
 
-#define AUTH_INFO_ACCESS_METHOD         2
-#define AUTH_INFO_ACCESS_LOCATION       3
-#define AUTH_INFO_ACCESS_ROOF           5
-
-/* ASN.1 definition of a extendedKeyUsage extension */
-
+/**
+ * ASN.1 definition of a extendedKeyUsage extension
+ */
 static const asn1Object_t extendedKeyUsageObjects[] = {
-  { 0, "extendedKeyUsage",              ASN1_SEQUENCE,     ASN1_LOOP }, /*  0 */
-  { 1,   "keyPurposeID",                ASN1_OID,          ASN1_BODY }, /*  1 */
-  { 0, "end loop",                      ASN1_EOC,          ASN1_END  }, /*  2 */
+       { 0, "extendedKeyUsage",        ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
+       { 1,   "keyPurposeID",          ASN1_OID,               ASN1_BODY }, /* 1 */
+       { 0, "end loop",                        ASN1_EOC,               ASN1_END  }, /* 2 */
+       { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
 };
+#define EXT_KEY_USAGE_PURPOSE_ID       1
 
-#define EXT_KEY_USAGE_PURPOSE_ID        1
-#define EXT_KEY_USAGE_ROOF              3
-
-/* ASN.1 definition of generalNames */
-
+/**
+ * ASN.1 definition of generalNames 
+ */
 static const asn1Object_t generalNamesObjects[] = {
-  { 0, "generalNames",                  ASN1_SEQUENCE,     ASN1_LOOP }, /*  0 */
-  { 1,   "generalName",                 ASN1_EOC,          ASN1_RAW  }, /*  1 */
-  { 0, "end loop",                      ASN1_EOC,          ASN1_END  }  /*  2 */
+       { 0, "generalNames",    ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
+       { 1,   "generalName",   ASN1_EOC,               ASN1_RAW  }, /* 1 */
+       { 0, "end loop",                ASN1_EOC,               ASN1_END  }, /* 2 */
+       { 0, "exit",                    ASN1_EOC,               ASN1_EXIT }
 };
+#define GENERAL_NAMES_GN       1
 
-#define GENERAL_NAMES_GN        1
-#define GENERAL_NAMES_ROOF      3
-
-/* ASN.1 definition of generalName */
-
+/**
+ * ASN.1 definition of generalName 
+ */
 static const asn1Object_t generalNameObjects[] = {
-  { 0,   "otherName",                   ASN1_CONTEXT_C_0,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /*  0 */
-  { 0,   "end choice",                  ASN1_EOC,          ASN1_END  }, /*  1 */
-  { 0,   "rfc822Name",                  ASN1_CONTEXT_S_1,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /*  2 */
-  { 0,   "end choice",                  ASN1_EOC,          ASN1_END  }, /*  3 */
-  { 0,   "dnsName",                     ASN1_CONTEXT_S_2,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /*  4 */
-  { 0,   "end choice",                  ASN1_EOC,          ASN1_END  }, /*  5 */
-  { 0,   "x400Address",                 ASN1_CONTEXT_S_3,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /*  6 */
-  { 0,   "end choice",                  ASN1_EOC,          ASN1_END  }, /*  7 */
-  { 0,   "directoryName",               ASN1_CONTEXT_C_4,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /*  8 */
-  { 0,   "end choice",                  ASN1_EOC,          ASN1_END  }, /*  9 */
-  { 0,   "ediPartyName",                ASN1_CONTEXT_C_5,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /* 10 */
-  { 0,   "end choice",                  ASN1_EOC,          ASN1_END  }, /* 11 */
-  { 0,   "uniformResourceIdentifier",   ASN1_CONTEXT_S_6,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /* 12 */
-  { 0,   "end choice",                  ASN1_EOC,          ASN1_END  }, /* 13 */
-  { 0,   "ipAddress",                   ASN1_CONTEXT_S_7,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /* 14 */
-  { 0,   "end choice",                  ASN1_EOC,          ASN1_END  }, /* 15 */
-  { 0,   "registeredID",                ASN1_CONTEXT_S_8,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /* 16 */
-  { 0,   "end choice",                  ASN1_EOC,          ASN1_END  }  /* 17 */
+       { 0, "otherName",               ASN1_CONTEXT_C_0,  ASN1_OPT|ASN1_BODY   }, /*  0 */
+       { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /*  1 */
+       { 0, "rfc822Name",              ASN1_CONTEXT_S_1,  ASN1_OPT|ASN1_BODY   }, /*  2 */
+       { 0, "end choice",              ASN1_EOC,          ASN1_END                     }, /*  3 */
+       { 0, "dnsName",                 ASN1_CONTEXT_S_2,  ASN1_OPT|ASN1_BODY   }, /*  4 */
+       { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /*  5 */
+       { 0, "x400Address",             ASN1_CONTEXT_S_3,  ASN1_OPT|ASN1_BODY   }, /*  6 */
+       { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /*  7 */
+       { 0, "directoryName",   ASN1_CONTEXT_C_4,  ASN1_OPT|ASN1_BODY   }, /*  8 */
+       { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /*  9 */
+       { 0, "ediPartyName",    ASN1_CONTEXT_C_5,  ASN1_OPT|ASN1_BODY   }, /* 10 */
+       { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /* 11 */
+       { 0, "URI",                             ASN1_CONTEXT_S_6,  ASN1_OPT|ASN1_BODY   }, /* 12 */
+       { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /* 13 */
+       { 0, "ipAddress",               ASN1_CONTEXT_S_7,  ASN1_OPT|ASN1_BODY   }, /* 14 */
+       { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /* 15 */
+       { 0, "registeredID",    ASN1_CONTEXT_S_8,  ASN1_OPT|ASN1_BODY   }, /* 16 */
+       { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /* 17 */
+       { 0, "exit",                    ASN1_EOC,          ASN1_EXIT                    }
 };
-
-#define GN_OBJ_OTHER_NAME        0
-#define GN_OBJ_RFC822_NAME       2
-#define GN_OBJ_DNS_NAME          4
-#define GN_OBJ_X400_ADDRESS      6
-#define GN_OBJ_DIRECTORY_NAME    8
-#define GN_OBJ_EDI_PARTY_NAME   10
-#define GN_OBJ_URI              12
-#define GN_OBJ_IP_ADDRESS       14
-#define GN_OBJ_REGISTERED_ID    16
-#define GN_OBJ_ROOF             18
-
-/* ASN.1 definition of otherName */
-
+#define GN_OBJ_OTHER_NAME               0
+#define GN_OBJ_RFC822_NAME              2
+#define GN_OBJ_DNS_NAME                         4
+#define GN_OBJ_X400_ADDRESS             6
+#define GN_OBJ_DIRECTORY_NAME   8
+#define GN_OBJ_EDI_PARTY_NAME  10
+#define GN_OBJ_URI                             12
+#define GN_OBJ_IP_ADDRESS              14
+#define GN_OBJ_REGISTERED_ID   16
+
+/**
+ * ASN.1 definition of otherName 
+ */
 static const asn1Object_t otherNameObjects[] = {
-  {0, "type-id",                        ASN1_OID,          ASN1_BODY }, /*  0 */
-  {0, "value",                          ASN1_CONTEXT_C_0,  ASN1_BODY }  /*  1 */
+       {0, "type-id",  ASN1_OID,                       ASN1_BODY       }, /* 0 */
+       {0, "value",    ASN1_CONTEXT_C_0,       ASN1_BODY       }, /* 1 */
+       {0, "exit",             ASN1_EOC,                       ASN1_EXIT       }
 };
+#define ON_OBJ_ID_TYPE         0
+#define ON_OBJ_VALUE           1
 
-#define ON_OBJ_ID_TYPE          0
-#define ON_OBJ_VALUE            1
-#define ON_OBJ_ROOF             2
-
-/* ASN.1 definition of crlDistributionPoints */
-
+/**
+ * ASN.1 definition of crlDistributionPoints
+ */
 static const asn1Object_t crlDistributionPointsObjects[] = {
-  { 0, "crlDistributionPoints",         ASN1_SEQUENCE,     ASN1_LOOP }, /*  0 */
-  { 1,   "DistributionPoint",           ASN1_SEQUENCE,     ASN1_NONE }, /*  1 */
-  { 2,     "distributionPoint",         ASN1_CONTEXT_C_0,  ASN1_OPT |
-                                                                                                                  ASN1_LOOP }, /*  2 */
-  { 3,       "fullName",                ASN1_CONTEXT_C_0,  ASN1_OPT |
-                                                                                                                  ASN1_OBJ  }, /*  3 */
-  { 3,       "end choice",              ASN1_EOC,          ASN1_END  }, /*  4 */
-  { 3,       "nameRelativeToCRLIssuer", ASN1_CONTEXT_C_1,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /*  5 */
-  { 3,       "end choice",              ASN1_EOC,          ASN1_END  }, /*  6 */
-  { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /*  7 */
-  { 2,     "reasons",                   ASN1_CONTEXT_C_1,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /*  8 */
-  { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /*  9 */
-  { 2,     "crlIssuer",                 ASN1_CONTEXT_C_2,  ASN1_OPT |
-                                                                                                                  ASN1_BODY }, /* 10 */
-  { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 11 */
-  { 0, "end loop",                      ASN1_EOC,          ASN1_END  }, /* 12 */
+       { 0, "crlDistributionPoints",   ASN1_SEQUENCE,          ASN1_LOOP                       }, /*  0 */
+       { 1,   "DistributionPoint",             ASN1_SEQUENCE,          ASN1_NONE                       }, /*  1 */
+       { 2,     "distributionPoint",   ASN1_CONTEXT_C_0,       ASN1_OPT|ASN1_LOOP      }, /*  2 */
+       { 3,       "fullName",                  ASN1_CONTEXT_C_0,       ASN1_OPT|ASN1_OBJ       }, /*  3 */
+       { 3,       "end choice",                ASN1_EOC,                       ASN1_END                        }, /*  4 */
+       { 3,       "nameRelToCRLIssuer",ASN1_CONTEXT_C_1,       ASN1_OPT|ASN1_BODY      }, /*  5 */
+       { 3,       "end choice",                ASN1_EOC,                       ASN1_END                        }, /*  6 */
+       { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /*  7 */
+       { 2,     "reasons",                             ASN1_CONTEXT_C_1,       ASN1_OPT|ASN1_BODY      }, /*  8 */
+       { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /*  9 */
+       { 2,     "crlIssuer",                   ASN1_CONTEXT_C_2,       ASN1_OPT|ASN1_BODY      }, /* 10 */
+       { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /* 11 */
+       { 0, "end loop",                                ASN1_EOC,                       ASN1_END                        }, /* 12 */
+       { 0, "exit",                                    ASN1_EOC,                       ASN1_EXIT                       }
 };
+#define CRL_DIST_POINTS_FULLNAME        3
 
-#define CRL_DIST_POINTS_FULLNAME         3
-#define CRL_DIST_POINTS_ROOF            13
-
-/* ASN.1 definition of an X.509v3 certificate */
+/**
+ * ASN.1 definition of RSApublicKey
+ */
+static const asn1Object_t pubkeyObjects[] = {
+       { 0, "RSAPublicKey",            ASN1_SEQUENCE,  ASN1_OBJ  }, /*  0 */
+       { 1,   "modulus",                       ASN1_INTEGER,   ASN1_BODY }, /*  1 */
+       { 1,   "publicExponent",        ASN1_INTEGER,   ASN1_BODY }, /*  2 */
+       { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
+};
+#define PUB_KEY_RSA_PUBLIC_KEY         0
+#define PUB_KEY_MODULUS                                1
+#define PUB_KEY_EXPONENT                       2
 
+/**
+ * ASN.1 definition of an X.509v3 x509_cert
+ */
 static const asn1Object_t certObjects[] = {
-  { 0, "certificate",                   ASN1_SEQUENCE,     ASN1_OBJ  }, /*  0 */
-  { 1,   "tbsCertificate",              ASN1_SEQUENCE,     ASN1_OBJ  }, /*  1 */
-  { 2,     "DEFAULT v1",                ASN1_CONTEXT_C_0,  ASN1_DEF  }, /*  2 */
-  { 3,       "version",                 ASN1_INTEGER,      ASN1_BODY }, /*  3 */
-  { 2,     "serialNumber",              ASN1_INTEGER,      ASN1_BODY }, /*  4 */
-  { 2,     "signature",                 ASN1_EOC,          ASN1_RAW  }, /*  5 */
-  { 2,     "issuer",                    ASN1_SEQUENCE,     ASN1_OBJ  }, /*  6 */
-  { 2,     "validity",                  ASN1_SEQUENCE,     ASN1_NONE }, /*  7 */
-  { 3,       "notBefore",               ASN1_EOC,          ASN1_RAW  }, /*  8 */
-  { 3,       "notAfter",                ASN1_EOC,          ASN1_RAW  }, /*  9 */
-  { 2,     "subject",                   ASN1_SEQUENCE,     ASN1_OBJ  }, /* 10 */
-  { 2,     "subjectPublicKeyInfo",      ASN1_SEQUENCE,     ASN1_NONE }, /* 11 */
-  { 3,       "algorithm",               ASN1_EOC,          ASN1_RAW  }, /* 12 */
-  { 3,       "subjectPublicKey",        ASN1_BIT_STRING,   ASN1_NONE }, /* 13 */
-  { 4,         "RSAPublicKey",          ASN1_SEQUENCE,     ASN1_OBJ  }, /* 14 */
-  { 5,           "modulus",             ASN1_INTEGER,      ASN1_BODY }, /* 15 */
-  { 5,           "publicExponent",      ASN1_INTEGER,      ASN1_BODY }, /* 16 */
-  { 2,     "issuerUniqueID",            ASN1_CONTEXT_C_1,  ASN1_OPT  }, /* 17 */
-  { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 18 */
-  { 2,     "subjectUniqueID",           ASN1_CONTEXT_C_2,  ASN1_OPT  }, /* 19 */
-  { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 20 */
-  { 2,     "optional extensions",       ASN1_CONTEXT_C_3,  ASN1_OPT  }, /* 21 */
-  { 3,       "extensions",              ASN1_SEQUENCE,     ASN1_LOOP }, /* 22 */
-  { 4,         "extension",             ASN1_SEQUENCE,     ASN1_NONE }, /* 23 */
-  { 5,           "extnID",              ASN1_OID,          ASN1_BODY }, /* 24 */
-  { 5,           "critical",            ASN1_BOOLEAN,      ASN1_DEF |
-                                                                                                                  ASN1_BODY }, /* 25 */
-  { 5,           "extnValue",           ASN1_OCTET_STRING, ASN1_BODY }, /* 26 */
-  { 3,       "end loop",                ASN1_EOC,          ASN1_END  }, /* 27 */
-  { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 28 */
-  { 1,   "signatureAlgorithm",          ASN1_EOC,          ASN1_RAW  }, /* 29 */
-  { 1,   "signatureValue",              ASN1_BIT_STRING,   ASN1_BODY }  /* 30 */
+       { 0, "certificate",                   ASN1_SEQUENCE,     ASN1_OBJ  }, /*  0 */
+       { 1,   "tbsCertificate",              ASN1_SEQUENCE,     ASN1_OBJ  }, /*  1 */
+       { 2,     "DEFAULT v1",                ASN1_CONTEXT_C_0,  ASN1_DEF  }, /*  2 */
+       { 3,       "version",                 ASN1_INTEGER,      ASN1_BODY }, /*  3 */
+       { 2,     "serialNumber",              ASN1_INTEGER,      ASN1_BODY }, /*  4 */
+       { 2,     "signature",                 ASN1_EOC,          ASN1_RAW  }, /*  5 */
+       { 2,     "issuer",                    ASN1_SEQUENCE,     ASN1_OBJ  }, /*  6 */
+       { 2,     "validity",                  ASN1_SEQUENCE,     ASN1_NONE }, /*  7 */
+       { 3,       "notBefore",               ASN1_EOC,          ASN1_RAW  }, /*  8 */
+       { 3,       "notAfter",                ASN1_EOC,          ASN1_RAW  }, /*  9 */
+       { 2,     "subject",                   ASN1_SEQUENCE,     ASN1_OBJ  }, /* 10 */
+       { 2,     "subjectPublicKeyInfo",      ASN1_SEQUENCE,     ASN1_NONE }, /* 11 */
+       { 3,       "algorithm",               ASN1_EOC,          ASN1_RAW  }, /* 12 */
+       { 3,       "subjectPublicKey",        ASN1_BIT_STRING,   ASN1_BODY }, /* 13 */
+       { 2,     "issuerUniqueID",            ASN1_CONTEXT_C_1,  ASN1_OPT  }, /* 14 */
+       { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 15 */
+       { 2,     "subjectUniqueID",           ASN1_CONTEXT_C_2,  ASN1_OPT  }, /* 16 */
+       { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 17 */
+       { 2,     "optional extensions",       ASN1_CONTEXT_C_3,  ASN1_OPT  }, /* 18 */
+       { 3,       "extensions",              ASN1_SEQUENCE,     ASN1_LOOP }, /* 19 */
+       { 4,         "extension",             ASN1_SEQUENCE,     ASN1_NONE }, /* 20 */
+       { 5,           "extnID",              ASN1_OID,          ASN1_BODY }, /* 21 */
+       { 5,           "critical",            ASN1_BOOLEAN,      ASN1_DEF |
+                                                                                                                        ASN1_BODY }, /* 22 */
+       { 5,           "extnValue",           ASN1_OCTET_STRING, ASN1_BODY }, /* 23 */
+       { 3,       "end loop",                ASN1_EOC,          ASN1_END  }, /* 24 */
+       { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 25 */
+       { 1,   "signatureAlgorithm",          ASN1_EOC,          ASN1_RAW  }, /* 26 */
+       { 1,   "signatureValue",              ASN1_BIT_STRING,   ASN1_BODY }, /* 27 */
+       { 0, "exit",                          ASN1_EOC,          ASN1_EXIT }
 };
-
 #define X509_OBJ_CERTIFICATE                     0
 #define X509_OBJ_TBS_CERTIFICATE                 1
 #define X509_OBJ_VERSION                         3
@@ -269,16 +243,11 @@ static const asn1Object_t certObjects[] = {
 #define X509_OBJ_SUBJECT                        10
 #define X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM   12
 #define X509_OBJ_SUBJECT_PUBLIC_KEY             13
-#define X509_OBJ_RSA_PUBLIC_KEY                 14
-#define X509_OBJ_MODULUS                        15
-#define X509_OBJ_PUBLIC_EXPONENT                16
-#define X509_OBJ_EXTN_ID                        24
-#define X509_OBJ_CRITICAL                       25
-#define X509_OBJ_EXTN_VALUE                     26
-#define X509_OBJ_ALGORITHM                      29
-#define X509_OBJ_SIGNATURE                      30
-#define X509_OBJ_ROOF                           31
-
+#define X509_OBJ_EXTN_ID                        21
+#define X509_OBJ_CRITICAL                       22
+#define X509_OBJ_EXTN_VALUE                     23
+#define X509_OBJ_ALGORITHM                      26
+#define X509_OBJ_SIGNATURE                      27
 
 const x509cert_t empty_x509cert = {
          NULL        , /* *next */
@@ -396,19 +365,17 @@ static u_char ASN1_subjectAltName_oid_str[] = {
 
 static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_subjectAltName_oid_str);
 
-static void
-update_chunk(chunk_t *ch, int n)
+static void update_chunk(chunk_t *ch, int n)
 {
        n = (n > -1 && n < (int)ch->len)? n : (int)ch->len-1;
        ch->ptr += n; ch->len -= n;
 }
 
 
-/*
+/**
  *  Pointer is set to the first RDN in a DN
  */
-static err_t
-init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
+static err_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
 {
        *rdn = chunk_empty;
        *attribute = chunk_empty;
@@ -434,12 +401,11 @@ init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
        return NULL;
 }
 
-/*
+/**
  *  Fetches the next RDN in a DN
  */
-static err_t
-get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value
-, asn1_t *type, bool *next)
+static err_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid,
+                                                 chunk_t *value, asn1_t *type, bool *next)
 {
        chunk_t body;
 
@@ -524,11 +490,10 @@ get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value
        return NULL;
 }
 
-/*
+/**
  *  Parses an ASN.1 distinguished name int its OID/value pairs
  */
-static err_t
-dn_parse(chunk_t dn, chunk_t *str)
+static err_t dn_parse(chunk_t dn, chunk_t *str)
 {
        chunk_t rdn, oid, attribute, value;
        asn1_t type;
@@ -580,11 +545,10 @@ dn_parse(chunk_t dn, chunk_t *str)
        return NULL;
 }
 
-/*
+/**
  *  Count the number of wildcard RDNs in a distinguished name
  */
-int
-dn_count_wildcards(chunk_t dn)
+int dn_count_wildcards(chunk_t dn)
 {
        chunk_t rdn, attribute, oid, value;
        asn1_t type;
@@ -614,11 +578,10 @@ dn_count_wildcards(chunk_t dn)
        return wildcards;
 }
 
-/*
+/**
  * Prints a binary string in hexadecimal form
  */
-void
-hex_str(chunk_t bin, chunk_t *str)
+void hex_str(chunk_t bin, chunk_t *str)
 {
        u_int i;
        update_chunk(str, snprintf(str->ptr,str->len,"0x"));
@@ -627,11 +590,10 @@ hex_str(chunk_t bin, chunk_t *str)
 }
 
 
-/*  Converts a binary DER-encoded ASN.1 distinguished name
+/** Converts a binary DER-encoded ASN.1 distinguished name
  *  into LDAP-style human-readable ASCII format
  */
-int
-dntoa(char *dst, size_t dstlen, chunk_t dn)
+int dntoa(char *dst, size_t dstlen, chunk_t dn)
 {
        err_t ugh = NULL;
        chunk_t str;
@@ -652,11 +614,10 @@ dntoa(char *dst, size_t dstlen, chunk_t dn)
        return (int)(dstlen - str.len);
 }
 
-/*
+/**
  * Same as dntoa but prints a special string for a null dn
  */
-int
-dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, const char* null_dn)
+int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, const char* null_dn)
 {
        if (dn.ptr == NULL)
        {
@@ -668,11 +629,45 @@ dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, const char* null_dn)
        }
 }
 
-/*  Converts an LDAP-style human-readable ASCII-encoded
+
+/**
+ * Codes ASN.1 lengths up to a size of 16'777'215 bytes
+ */
+static 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;
+    }
+}
+
+/**
+ *  Converts an LDAP-style human-readable ASCII-encoded
  *  ASN.1 distinguished name into binary DER-encoded format
  */
-err_t
-atodn(char *src, chunk_t *dn)
+err_t atodn(char *src, chunk_t *dn)
 {
   /* finite state machine for atodn */
 
@@ -796,7 +791,7 @@ atodn(char *src, chunk_t *dn)
                                chunkcpy(dn_ptr, x501rdns[pos].oid);
                                /* encode the ASN.1 character string type of the name */
                                *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
-                                       && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
+                                       && !asn1_is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
                                chunkcpy(dn_ptr, asn1_name_len);
                                chunkcpy(dn_ptr, name);
 
@@ -823,11 +818,10 @@ atodn(char *src, chunk_t *dn)
        return ugh;
 }
 
-/*  compare two distinguished names by
- *  comparing the individual RDNs
+/**
+ * compare two distinguished names by comparing the individual RDNs
  */
-bool
-same_dn(chunk_t a, chunk_t b)
+bool same_dn(chunk_t a, chunk_t b)
 {
        chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
        chunk_t oid_a, oid_b, value_a, value_b;
@@ -903,11 +897,11 @@ same_dn(chunk_t a, chunk_t b)
 }
 
 
-/*  compare two distinguished names by comparing the individual RDNs.
+/**
+ *  Compare two distinguished names by comparing the individual RDNs.
  *  A single'*' character designates a wildcard RDN in DN b.
  */
-bool
-match_dn(chunk_t a, chunk_t b, int *wildcards)
+bool match_dn(chunk_t a, chunk_t b, int *wildcards)
 {
        chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
        chunk_t oid_a, oid_b, value_a, value_b;
@@ -981,20 +975,18 @@ match_dn(chunk_t a, chunk_t b, int *wildcards)
        return TRUE;
 }
 
-/*
- *  compare two X.509 certificates by comparing their signatures
+/**
+ *  Compare two X.509 certificates by comparing their signatures
  */
-bool
-same_x509cert(const x509cert_t *a, const x509cert_t *b)
+bool same_x509cert(const x509cert_t *a, const x509cert_t *b)
 {
        return chunk_equals(a->signature, b->signature);
 }
 
-/*  for each link pointing to the certificate
 increase the count by one
+/**
* For each link pointing to the certificate increase the count by one
  */
-void
-share_x509cert(x509cert_t *cert)
+void share_x509cert(x509cert_t *cert)
 {
        if (cert != NULL)
        {
@@ -1002,11 +994,10 @@ share_x509cert(x509cert_t *cert)
        }
 }
 
-/*
- *  add a X.509 user/host certificate to the chained list
+/**
+ *  Add a X.509 user/host certificate to the chained list
  */
-x509cert_t*
-add_x509cert(x509cert_t *cert)
+x509cert_t* add_x509cert(x509cert_t *cert)
 {
        x509cert_t *c = x509certs;
 
@@ -1031,11 +1022,10 @@ add_x509cert(x509cert_t *cert)
        return cert;
 }
 
-/*
- * choose either subject DN or a subjectAltName as connection end ID
+/**
+ * Choose either subject DN or a subjectAltName as connection end ID
  */
-void
-select_x509cert_id(x509cert_t *cert, struct id *end_id)
+void select_x509cert_id(x509cert_t *cert, struct id *end_id)
 {
        bool copy_subject_dn = TRUE;         /* ID is subject DN */
 
@@ -1073,11 +1063,10 @@ select_x509cert_id(x509cert_t *cert, struct id *end_id)
        }
 }
 
-/*
- * check for equality between two key identifiers
+/**
+ * Check for equality between two key identifiers
  */
-bool
-same_keyid(chunk_t a, chunk_t b)
+bool same_keyid(chunk_t a, chunk_t b)
 {
        if (a.ptr == NULL || b.ptr == NULL)
        {
@@ -1086,11 +1075,10 @@ same_keyid(chunk_t a, chunk_t b)
        return chunk_equals(a, b);
 }
 
-/*
- * check for equality between two serial numbers
+/**
+ * Check for equality between two serial numbers
  */
-bool
-same_serial(chunk_t a, chunk_t b)
+bool same_serial(chunk_t a, chunk_t b)
 {
        /* do not compare serial numbers if one of them is not defined */
        if (a.ptr == NULL || b.ptr == NULL)
@@ -1100,11 +1088,11 @@ same_serial(chunk_t a, chunk_t b)
        return chunk_equals(a, b);
 }
 
-/*
- *  get a X.509 certificate with a given issuer found at a certain position
+/**
+ * Get a X.509 certificate with a given issuer found at a certain position
  */
-x509cert_t*
-get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid, x509cert_t *chain)
+x509cert_t* get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid,
+                                                x509cert_t *chain)
 {
        x509cert_t *cert = (chain != NULL)? chain->next : x509certs;
 
@@ -1121,11 +1109,10 @@ get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid, x509cert_t *chain)
        return NULL;
 }
 
-/*
- * encode a linked list of subjectAltNames
+/**
+ * Encode a linked list of subjectAltNames
  */
-chunk_t
-build_subjectAltNames(generalName_t *subjectAltNames)
+chunk_t build_subjectAltNames(generalName_t *subjectAltNames)
 {
        u_char *pos;
        chunk_t names;
@@ -1139,7 +1126,7 @@ build_subjectAltNames(generalName_t *subjectAltNames)
                gn = gn->next;
        }
 
-       pos = build_asn1_object(&names, ASN1_SEQUENCE, len);
+       pos = asn1_build_object(&names, ASN1_SEQUENCE, len);
 
        gn = subjectAltNames;
        while (gn != NULL)
@@ -1153,11 +1140,10 @@ build_subjectAltNames(generalName_t *subjectAltNames)
                                , asn1_wrap(ASN1_OCTET_STRING, "m", names));
 }
 
-/*
- * build a to-be-signed X.509 certificate body
+/**
+ * Build a to-be-signed X.509 certificate body
  */
-static chunk_t
-build_tbs_x509cert(x509cert_t *cert, const RSA_public_key_t *rsa)
+static chunk_t build_tbs_x509cert(x509cert_t *cert, const RSA_public_key_t *rsa)
 {
        /* version is always X.509v3 */
        chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2);
@@ -1177,8 +1163,8 @@ build_tbs_x509cert(x509cert_t *cert, const RSA_public_key_t *rsa)
                                , asn1_algorithmIdentifier(cert->sigAlg)
                                , cert->issuer
                                , asn1_wrap(ASN1_SEQUENCE, "mm"
-                                       , timetoasn1(&cert->notBefore, ASN1_UTCTIME) 
-                                       , timetoasn1(&cert->notAfter,  ASN1_UTCTIME)
+                                       , asn1_from_time(&cert->notBefore, ASN1_UTCTIME) 
+                                       , asn1_from_time(&cert->notAfter,  ASN1_UTCTIME)
                                  )
                                , cert->subject
                                , pkcs1_build_publicKeyInfo(rsa)
@@ -1186,12 +1172,11 @@ build_tbs_x509cert(x509cert_t *cert, const RSA_public_key_t *rsa)
                   );
 }
 
-/*
- * build a DER-encoded X.509 certificate
+/**
+ * Build a DER-encoded X.509 certificate
  */
-void
-build_x509cert(x509cert_t *cert, const RSA_public_key_t *cert_key
-, const RSA_private_key_t *signer_key)
+void build_x509cert(x509cert_t *cert, const RSA_public_key_t *cert_key,
+                                       const RSA_private_key_t *signer_key)
 {
        chunk_t tbs_cert = build_tbs_x509cert(cert, cert_key);
 
@@ -1204,11 +1189,10 @@ build_x509cert(x509cert_t *cert, const RSA_public_key_t *cert_key
                                                                , signature);
 }
 
-/*
- *  free the dynamic memory used to store generalNames
+/**
+ * Free the dynamic memory used to store generalNames
  */
-void
-free_generalNames(generalName_t* gn, bool free_name)
+void free_generalNames(generalName_t* gn, bool free_name)
 {
        while (gn != NULL)
        {
@@ -1222,11 +1206,10 @@ free_generalNames(generalName_t* gn, bool free_name)
        }
 }
 
-/*
- *  free a X.509 certificate
+/**
+ *  Free a X.509 certificate
  */
-void
-free_x509cert(x509cert_t *cert)
+void free_x509cert(x509cert_t *cert)
 {
        if (cert != NULL)
        {
@@ -1238,11 +1221,11 @@ free_x509cert(x509cert_t *cert)
        }
 }
 
-/*  release of a certificate decreases the count by one
- "  the certificate is freed when the counter reaches zero
+/**
+ * Release of a certificate decreases the count by one
+ * the certificate is freed when the counter reaches zero
  */
-void
-release_x509cert(x509cert_t *cert)
+void release_x509cert(x509cert_t *cert)
 {
        if (cert != NULL && --cert->count == 0)
        {
@@ -1256,12 +1239,10 @@ release_x509cert(x509cert_t *cert)
        }
 }
 
-
-/*
- * stores a chained list of end certs and CA certs
+/**
+ * Stores a chained list of end certs and CA certs
  */
-void
-store_x509certs(x509cert_t **firstcert, bool strict)
+void store_x509certs(x509cert_t **firstcert, bool strict)
 {
        x509cert_t *cacerts = NULL;
        x509cert_t **pp = firstcert;
@@ -1339,12 +1320,11 @@ store_x509certs(x509cert_t **firstcert, bool strict)
        }
 }
 
-/*
- *  decrypts an RSA signature using the issuer's certificate
+/**
+ * Decrypts an RSA signature using the issuer's certificate
  */
-static bool
-decrypt_sig(chunk_t sig, int alg, const x509cert_t *issuer_cert,
-                       chunk_t *digest)
+static bool decrypt_sig(chunk_t sig, int alg, const x509cert_t *issuer_cert,
+                                               chunk_t *digest)
 {
        switch (alg)
        {
@@ -1393,12 +1373,11 @@ decrypt_sig(chunk_t sig, int alg, const x509cert_t *issuer_cert,
        }
 }
 
-/*
- *   Check if a signature over binary blob is genuine
+/**
+ * Check if a signature over binary blob is genuine
  */
-bool
-check_signature(chunk_t tbs, chunk_t sig, int digest_alg, int enc_alg
-, const x509cert_t *issuer_cert)
+bool check_signature(chunk_t tbs, chunk_t sig, int digest_alg, int enc_alg,
+                                        const x509cert_t *issuer_cert)
 {
        u_char digest_buf[MAX_DIGEST_LEN];
        u_char decrypted_buf[MAX_DIGEST_LEN];
@@ -1449,27 +1428,21 @@ check_signature(chunk_t tbs, chunk_t sig, int digest_alg, int enc_alg
        return memeq(decrypted.ptr, digest.ptr, digest.len);
 }
 
-/*
- * extracts the basicConstraints extension
+/**
+ * Extracts the basicConstraints extension
  */
-static bool
-parse_basicConstraints(chunk_t blob, int level0)
+static bool parse_basicConstraints(chunk_t blob, int level0)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
        bool isCA = FALSE;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+       parser = asn1_parser_create(basicConstraintsObjects, blob);
+       parser->set_top_level(parser, level0);
 
-       while (objectID < BASIC_CONSTRAINTS_ROOF) {
-
-               if (!extract_object(basicConstraintsObjects, &objectID,
-                                                       &object,&level, &ctx))
-               {
-                        break;
-               }
+       while (parser->iterate(parser, &objectID, &object))
+       {
                if (objectID == BASIC_CONSTRAINTS_CA)
                {
                        isCA = object.len && *object.ptr;
@@ -1477,16 +1450,16 @@ parse_basicConstraints(chunk_t blob, int level0)
                                DBG_log("  %s",(isCA)?"TRUE":"FALSE");
                        )
                }
-               objectID++;
        }
+       parser->destroy(parser);
+
        return isCA;
 }
 
-/*
+/**
  *  Converts a X.500 generalName into an ID
  */
-void
-gntoid(struct id *id, const generalName_t *gn)
+void gntoid(struct id *id, const generalName_t *gn)
 {
        switch(gn->kind)
        {
@@ -1513,11 +1486,11 @@ gntoid(struct id *id, const generalName_t *gn)
        }
 }
 
-/* compute the subjectKeyIdentifier according to section 4.2.1.2 of RFC 3280
+/**
+ * Compute the subjectKeyIdentifier according to section 4.2.1.2 of RFC 3280
  * as the 160 bit SHA-1 hash of the public key
  */
-void
-compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID)
+void compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID)
 {
        SHA1_CTX context;
 
@@ -1529,27 +1502,22 @@ compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID)
        subjectKeyID.len = SHA1_DIGEST_SIZE;
 }
 
-/*
- * extracts an otherName
+/**
+ * Extracts an otherName
  */
-static bool
-parse_otherName(chunk_t blob, int level0)
+static bool parse_otherName(chunk_t blob, int level0)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       int objectID = 0;
-       u_int level;
+       int objectID;
        int oid = OID_UNKNOWN;
+       bool success = FALSE;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+       parser = asn1_parser_create(otherNameObjects, blob);
+       parser->set_top_level(parser, level0);
 
-       while (objectID < ON_OBJ_ROOF)
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx))
-               {
-                        return FALSE;
-               }
-
                switch (objectID)
                {
                case ON_OBJ_ID_TYPE:
@@ -1558,45 +1526,43 @@ parse_otherName(chunk_t blob, int level0)
                case ON_OBJ_VALUE:
                        if (oid == OID_XMPP_ADDR)
                        {
-                               if (!parse_asn1_simple_object(&object, ASN1_UTF8STRING
-                                                                                        , level + 1, "xmppAddr"))
+                               if (!asn1_parse_simple_object(&object, ASN1_UTF8STRING,
+                                                       parser->get_level(parser) + 1, "xmppAddr"))
                                {
-                                       return FALSE;
+                                       goto end;
                                }
                        }
                        break;
                default:
                        break;
                }
-               objectID++;
        }
-       return TRUE;
+       success = parser->success(parser);
+       
+end:
+       parser->destroy(parser);
+       return success;
 }
 
 
-/*
- * extracts a generalName
+/**
+ * Extracts a generalName
  */
-static generalName_t*
-parse_generalName(chunk_t blob, int level0)
+static generalName_t* parse_generalName(chunk_t blob, int level0)
 {
        u_char buf[BUF_LEN];
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       int objectID = 0;
-       u_int level;
+       generalName_t *gn = NULL;
+       int objectID;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
-       while (objectID < GN_OBJ_ROOF)
+       parser = asn1_parser_create(generalNameObjects, blob);
+       parser->set_top_level(parser, level0);
+       
+       while (parser->iterate(parser, &objectID, &object))
        {
                bool valid_gn = FALSE;
                
-               if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx))
-               {
-                        return NULL;
-               }
-
                switch (objectID) {
                case GN_OBJ_RFC822_NAME:
                case GN_OBJ_DNS_NAME:
@@ -1621,8 +1587,10 @@ parse_generalName(chunk_t blob, int level0)
                        valid_gn = TRUE;
                        break;
                case GN_OBJ_OTHER_NAME:
-                       if (!parse_otherName(object, level + 1))
-                               return NULL;
+                       if (!parse_otherName(object, parser->get_level(parser)+1))
+                       {
+                               goto end;
+                       }
                        break;
                case GN_OBJ_X400_ADDRESS:
                case GN_OBJ_EDI_PARTY_NAME:
@@ -1634,55 +1602,53 @@ parse_generalName(chunk_t blob, int level0)
 
                if (valid_gn)
                {
-                       generalName_t *gn = malloc_thing(generalName_t);
+                       gn = malloc_thing(generalName_t);
                        gn->kind = (objectID - GN_OBJ_OTHER_NAME) / 2;
                        gn->name = object;
                        gn->next = NULL;
-                       return gn;
+                       goto end;
                }
-               objectID++;
        }
-       return NULL;
+       
+end:
+       parser->destroy(parser);
+       return gn;
 }
 
-
-/*
- * extracts one or several GNs and puts them into a chained list
+/**
+ * Extracts one or several GNs and puts them into a chained list
  */
-static generalName_t*
-parse_generalNames(chunk_t blob, int level0, bool implicit)
+static generalName_t* parse_generalNames(chunk_t blob, int level0, bool implicit)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
-
+       int objectID;
        generalName_t *top_gn = NULL;
 
-       asn1_init(&ctx, blob, level0, implicit, DBG_RAW);
-
-       while (objectID < GENERAL_NAMES_ROOF)
+       parser = asn1_parser_create(generalNamesObjects, blob);
+       parser->set_top_level(parser, level0);
+       parser->set_flags(parser, implicit, FALSE);
+       
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx))
-               {
-                        return NULL;
-               }
                if (objectID == GENERAL_NAMES_GN)
                {
-                       generalName_t *gn = parse_generalName(object, level+1);
-                       if (gn != NULL)
+                       generalName_t *gn = parse_generalName(object,
+                                                                               parser->get_level(parser)+1);
+                       if (gn)
                        {
                                gn->next = top_gn;
                                top_gn = gn;
                        }
                }
-               objectID++;
        }
+       parser->destroy(parser);
+
        return top_gn;
 }
 
-/*
- * returns a directoryName
+/**
+ * Returns a directoryName
  */
 chunk_t get_directoryName(chunk_t blob, int level, bool implicit)
 {
@@ -1697,80 +1663,31 @@ chunk_t get_directoryName(chunk_t blob, int level, bool implicit)
        return name;
 }
 
-/*
- * extracts and converts a UTCTIME or GENERALIZEDTIME object
+/**
+ * Extracts an authoritykeyIdentifier
  */
-time_t
-parse_time(chunk_t blob, int level0)
+void parse_authorityKeyIdentifier(chunk_t blob, int level0,
+                                                                 chunk_t *authKeyID,
+                                                                 chunk_t *authKeySerialNumber)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
-
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
-       while (objectID < TIME_ROOF)
-       {
-               if (!extract_object(timeObjects, &objectID, &object, &level, &ctx))
-               {
-                        return UNDEFINED_TIME;
-               }
-               if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
-               {
-                       return asn1totime(&object, (objectID == TIME_UTC)
-                                               ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
-               }
-               objectID++;
-       }
-       return UNDEFINED_TIME;
- }
-
-/*
- * extracts a keyIdentifier
- */
-static chunk_t
-parse_keyIdentifier(chunk_t blob, int level0, bool implicit)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-
-       asn1_init(&ctx, blob, level0, implicit, DBG_RAW);
+       int objectID;
 
-       extract_object(keyIdentifierObjects, &objectID, &object, &level, &ctx);
-       return object;
-}
-
-/*
- * extracts an authoritykeyIdentifier
- */
-void
-parse_authorityKeyIdentifier(chunk_t blob, int level0
-       , chunk_t *authKeyID, chunk_t *authKeySerialNumber)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
-       while (objectID < AUTH_KEY_ID_ROOF)
+       parser = asn1_parser_create(authKeyIdentifierObjects, blob);
+       parser->set_top_level(parser, level0);
+       
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(authorityKeyIdentifierObjects, &objectID, &object, &level, &ctx))
-               {
-                        return;
-               }
                switch (objectID)
                {
                case AUTH_KEY_ID_KEY_ID:
-                       *authKeyID = parse_keyIdentifier(object, level+1, TRUE);
+                       *authKeyID = object;
                        break;
                case AUTH_KEY_ID_CERT_ISSUER:
                        {
-                               generalName_t * gn = parse_generalNames(object, level+1, TRUE);
+                               generalName_t * gn = parse_generalNames(object,
+                                                                               parser->get_level(parser) + 1, TRUE);
 
                                free_generalNames(gn, FALSE);
                        }
@@ -1781,31 +1698,26 @@ parse_authorityKeyIdentifier(chunk_t blob, int level0
                default:
                        break;
                }
-               objectID++;
        }
+       parser->destroy(parser);
 }
 
-/*
- * extracts an authorityInfoAcess location
+/**
+ * Extracts an authorityInfoAcess location
  */
-static void
-parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessLocation)
+static void parse_authorityInfoAccess(chunk_t blob, int level0,
+                                                                         chunk_t *accessLocation)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
        int accessMethod = OID_UNKNOWN;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
-       while (objectID < AUTH_INFO_ACCESS_ROOF)
+       parser = asn1_parser_create(authInfoAccessObjects, blob);
+       parser->set_top_level(parser, level0);
+       
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(authorityInfoAccessObjects, &objectID, &object, &level, &ctx))
-               {
-                        return;
-               }
-
                switch (objectID)
                {
                case AUTH_INFO_ACCESS_METHOD:
@@ -1820,7 +1732,7 @@ parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessLocation)
                                        {
                                                if (asn1_length(&object) == ASN1_INVALID_LENGTH)
                                                {
-                                                       return;
+                                                       goto end;
                                                }
                                                DBG(DBG_PARSING,
                                                        DBG_log("  '%.*s'",(int)object.len, object.ptr)
@@ -1830,7 +1742,7 @@ parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessLocation)
                                                if (strncasecmp(object.ptr, "http", 4) == 0)
                                                {
                                                        *accessLocation = object;
-                                                       return;
+                                                       goto end;
                                                }
                                        }
                                        plog("warning: ignoring OCSP InfoAccessLocation with unkown protocol");
@@ -1844,67 +1756,61 @@ parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessLocation)
                default:
                        break;
                }
-               objectID++;
        }
-
+       
+end:
+       parser->destroy(parser);
 }
 
-/*
- * extracts extendedKeyUsage OIDs
+/**
+ * Extracts extendedKeyUsage OIDs
  */
-static bool
-parse_extendedKeyUsage(chunk_t blob, int level0)
+static bool parse_extendedKeyUsage(chunk_t blob, int level0)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
+       bool ocsp_signing = FALSE;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
-       while (objectID < EXT_KEY_USAGE_ROOF)
+       parser = asn1_parser_create(extendedKeyUsageObjects, blob);
+       parser->set_top_level(parser, level0);
+       
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(extendedKeyUsageObjects, &objectID
-                                                       , &object, &level, &ctx))
-               {
-                        return FALSE;
-               }
                if (objectID == EXT_KEY_USAGE_PURPOSE_ID
                && asn1_known_oid(object) == OID_OCSP_SIGNING)
                {
-                       return TRUE;
+                       ocsp_signing = TRUE;
                }
-               objectID++;
        }
-       return FALSE;
+       parser->destroy(parser);
+
+       return ocsp_signing;
 }
 
-/*  extracts one or several crlDistributionPoints and puts them into
- *  a chained list
+/**
+ * Extracts one or several crlDistributionPoints
+ * and puts them into a chained list
  */
-static generalName_t*
-parse_crlDistributionPoints(chunk_t blob, int level0)
+static generalName_t* parse_crlDistributionPoints(chunk_t blob, int level0)
 {
-       asn1_ctx_t ctx;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
 
        generalName_t *top_gn = NULL;      /* top of the chained list */
        generalName_t **tail_gn = &top_gn; /* tail of the chained list */
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
-       while (objectID < CRL_DIST_POINTS_ROOF)
+       parser = asn1_parser_create(crlDistributionPointsObjects, blob);
+       parser->set_top_level(parser, level0);
+       
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(crlDistributionPointsObjects, &objectID,
-                                                       &object, &level, &ctx))
-               {
-                        return NULL;
-               }
                if (objectID == CRL_DIST_POINTS_FULLNAME)
                {
-                       generalName_t *gn = parse_generalNames(object, level+1, TRUE);
+                       generalName_t *gn;
+
+                       gn = parse_generalNames(object, parser->get_level(parser)+1, TRUE);
                        /* append extracted generalNames to existing chained list */
                        *tail_gn = gn;
                        /* find new tail of the chained list */
@@ -1913,38 +1819,76 @@ parse_crlDistributionPoints(chunk_t blob, int level0)
                                tail_gn = &gn->next;  gn = gn->next;
                        }
                }
-               objectID++;
        }
+       parser->destroy(parser);
+
        return top_gn;
 }
 
+/**
+ *  Parses an RSA public key
+ */
+bool parse_RSA_public_key(chunk_t blob, u_int level0, x509cert_t *cert)
+{
+       asn1_parser_t *parser;
+       chunk_t object;
+       int objectID;
+       bool success = FALSE;
+
+       parser = asn1_parser_create(pubkeyObjects, blob);
+       parser->set_top_level(parser, level0);
+
+       while (parser->iterate(parser, &objectID, &object))
+       {
+               switch (objectID) {
+               case PUB_KEY_RSA_PUBLIC_KEY:
+                       cert->subjectPublicKey = object;
+                       break;
+               case PUB_KEY_MODULUS:
+                       if (object.len < RSA_MIN_OCTETS + 1)
+                       {
+                               plog("  " RSA_MIN_OCTETS_UGH);
+                               goto end;
+                       }
+                       if (object.len > RSA_MAX_OCTETS + (size_t)(*object.ptr == 0x00))
+                       {
+                               plog("  " RSA_MAX_OCTETS_UGH);
+                               goto end;
+                       }
+                       cert->modulus = object;
+                       break;
+               case PUB_KEY_EXPONENT:
+                       cert->publicExponent = object;
+                       break;
+               }
+       }
+       success = parser->success(parser);
+
+end:
+       parser->destroy(parser);
+       return success;
+}
 
-/*
+/**
  *  Parses an X.509v3 certificate
  */
-bool
-parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
+bool parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
 {
        u_char  buf[BUF_LEN];
-       asn1_ctx_t ctx;
-       bool critical;
+       asn1_parser_t *parser;
        chunk_t object;
-       u_int level;
-       int objectID = 0;
+       int objectID;
        int extn_oid = OID_UNKNOWN;
+       bool critical;
+       bool success = FALSE;
 
-       asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+       parser = asn1_parser_create(certObjects, blob);
+       parser->set_top_level(parser, level0);
 
-       while (objectID < X509_OBJ_ROOF)
+       while (parser->iterate(parser, &objectID, &object))
        {
-               if (!extract_object(certObjects, &objectID, &object, &level, &ctx))
-               {
-                        return FALSE;
-               }
-
-               /* those objects which will parsed further need the next higher level */
-               level++;
-
+               u_int level = parser->get_level(parser) + 1;
+               
                switch (objectID) {
                case X509_OBJ_CERTIFICATE:
                        cert->certificate = object;
@@ -1962,7 +1906,7 @@ parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
                        cert->serialNumber = object;
                        break;
                case X509_OBJ_SIG_ALG:
-                       cert->sigAlg = parse_algorithmIdentifier(object, level, NULL);
+                       cert->sigAlg = asn1_parse_algorithmIdentifier(object, level, NULL);
                        break;
                case X509_OBJ_ISSUER:
                        cert->issuer = object;
@@ -1972,10 +1916,10 @@ parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
                        )
                        break;
                case X509_OBJ_NOT_BEFORE:
-                       cert->notBefore = parse_time(object, level);
+                       cert->notBefore = asn1_parse_time(object, level);
                        break;
                case X509_OBJ_NOT_AFTER:
-                       cert->notAfter = parse_time(object, level);
+                       cert->notAfter = asn1_parse_time(object, level);
                        break;
                case X509_OBJ_SUBJECT:
                        cert->subject = object;
@@ -1985,47 +1929,32 @@ parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
                        )
                        break;
                case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
-                       if (parse_algorithmIdentifier(object, level, NULL) == OID_RSA_ENCRYPTION)
+                       if (asn1_parse_algorithmIdentifier(object, level, NULL) == OID_RSA_ENCRYPTION)
                        {
                                cert->subjectPublicKeyAlgorithm = PUBKEY_ALG_RSA;
                        }
                        else
                        {
                                plog("  unsupported public key algorithm");
-                               return FALSE;
+                               goto end;
                        }
                        break;
                case X509_OBJ_SUBJECT_PUBLIC_KEY:
-                       if (ctx.blobs[4].len > 0 && *ctx.blobs[4].ptr == 0x00)
+                       if (object.len > 0 && *object.ptr == 0x00)
                        {
                                /* skip initial bit string octet defining 0 unused bits */
-                               ctx.blobs[4].ptr++; ctx.blobs[4].len--;
+                               object = chunk_skip(object, 1);
+                               if (!parse_RSA_public_key(object, level, cert))
+                               {
+                                       goto end;
+                               }
                        }
                        else
                        {
                                plog("  invalid RSA public key format");
-                               return FALSE;
+                               goto end;
                        }
                        break;
-               case X509_OBJ_RSA_PUBLIC_KEY:
-                       cert->subjectPublicKey = object;
-                       break;
-               case X509_OBJ_MODULUS:
-                       if (object.len < RSA_MIN_OCTETS + 1)
-                       {
-                               plog("  " RSA_MIN_OCTETS_UGH);
-                               return FALSE;
-                       }
-                       if (object.len > RSA_MAX_OCTETS + (size_t)(*object.ptr == 0x00))
-                       {
-                               plog("  " RSA_MAX_OCTETS_UGH);
-                               return FALSE;
-                       }
-                       cert->modulus = object;
-                       break;
-               case X509_OBJ_PUBLIC_EXPONENT:
-                       cert->publicExponent = object;
-                       break;
                case X509_OBJ_EXTN_ID:
                        extn_oid = asn1_known_oid(object);
                        break;
@@ -2039,8 +1968,12 @@ parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
                        {
                                switch (extn_oid) {
                                case OID_SUBJECT_KEY_ID:
-                                       cert->subjectKeyID =
-                                               parse_keyIdentifier(object, level, FALSE);
+                                       if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
+                                                                                                 level, "keyIdentifier"))
+                                       {
+                                               goto end;
+                                       }
+                                       cert->subjectKeyID = object;
                                        break;
                                case OID_SUBJECT_ALT_NAME:
                                        cert->subjectAltName =
@@ -2068,10 +2001,10 @@ parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
                                case OID_NS_CA_REVOCATION_URL:
                                case OID_NS_CA_POLICY_URL:
                                case OID_NS_COMMENT:
-                                       if (!parse_asn1_simple_object(&object, ASN1_IA5STRING
+                                       if (!asn1_parse_simple_object(&object, ASN1_IA5STRING
                                        , level, oid_names[extn_oid].name))
                                        {
-                                               return FALSE;
+                                               goto end;
                                        }
                                        break;
                                default:
@@ -2080,7 +2013,7 @@ parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
                        }
                        break;
                case X509_OBJ_ALGORITHM:
-                       cert->algorithm = parse_algorithmIdentifier(object, level, NULL);
+                       cert->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
                        break;
                case X509_OBJ_SIGNATURE:
                        cert->signature = object;
@@ -2088,17 +2021,20 @@ parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
                default:
                        break;
                }
-               objectID++;
        }
+       success = parser->success(parser);
        time(&cert->installed);
-       return TRUE;
+
+end:
+       parser->destroy(parser);
+       return success;
 }
 
-/* verify the validity of a certificate by
+/**
+ * Verify the validity of a certificate by
  * checking the notBefore and notAfter dates
  */
-err_t
-check_validity(const x509cert_t *cert, time_t *until)
+err_t check_validity(const x509cert_t *cert, time_t *until)
 {
        time_t current_time;
 
@@ -2127,11 +2063,10 @@ check_validity(const x509cert_t *cert, time_t *until)
        }
 }
 
-/*
- *  verifies a X.509 certificate
+/**
+ * Verifies a X.509 certificate
  */
-bool
-verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
+bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
 {
        int pathlen;
 
@@ -2270,12 +2205,11 @@ verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
        return FALSE;
 }
 
-/*
- *  list all X.509 certs in a chained list
+/**
+ * List all X.509 certs in a chained list
  */
-void
-list_x509cert_chain(const char *caption, x509cert_t* cert, u_char auth_flags
- , bool utc)
+void list_x509cert_chain(const char *caption, x509cert_t* cert,
+                                                u_char auth_flags, bool utc)
 {
        bool first = TRUE;
        time_t now;
@@ -2346,11 +2280,10 @@ list_x509cert_chain(const char *caption, x509cert_t* cert, u_char auth_flags
        }
 }
 
-/*
- *  list all X.509 end certificates in a chained list
+/**
+ * List all X.509 end certificates in a chained list
  */
-void
-list_x509_end_certs(bool utc)
+void list_x509_end_certs(bool utc)
 {
        list_x509cert_chain("End", x509certs, AUTH_NONE, utc);
 }
index b6a702c..104ef6d 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef _X509_H
 #define _X509_H
 
+#include "constants.h"
 #include "pkcs1.h"
 #include "id.h"
 
index 6681407..62146b2 100644 (file)
@@ -18,15 +18,16 @@ INCLUDES = \
 AM_CFLAGS = \
 -DIPSEC_CONFDIR=\"${confdir}\" \
 -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
--DDEBUG -DNO_PLUTO
+-DDEBUG -DNO_PLUTO \
+-Wformat=0
 
 LIBFREESWANBUILDDIR=$(top_builddir)/src/libfreeswan
 LIBCRYPTOBUILDDIR=$(top_builddir)/src/libcrypto
 
 scepclient_LDADD = \
-asn1.o ca.o crl.o certs.o constants.o defs.o fetch.o id.o keys.o \
-lex.o library.o md2.o md5.o mp_defs.o ocsp.o pem.o pgp.o pkcs1.o \
-pkcs7.o rnd.o sha1.o smartcard.o x509.o \
+ca.o crl.o certs.o constants.o defs.o fetch.o id.o keys.o lex.o library.o \
+md2.o md5.o mp_defs.o ocsp.o pem.o pgp.o pkcs1.o pkcs7.o rnd.o sha1.o \
+smartcard.o x509.o \
 $(LIBSTRONGSWANDIR)/libstrongswan-lite.la \
 $(LIBFREESWANBUILDDIR)/libfreeswan.a \
 $(LIBCRYPTOBUILDDIR)/libcrypto.a \
@@ -51,9 +52,6 @@ endif
 
 dist_man_MANS = scepclient.8
 
-asn1.o :       $(PLUTODIR)/asn1.c $(PLUTODIR)/asn1.h
-               $(COMPILE) $(INCLUDES) -c -o $@ $<
-
 ca.o :         $(PLUTODIR)/ca.c $(PLUTODIR)/ca.h
                $(COMPILE) $(INCLUDES) -c -o $@ $<
 
index d6b53d8..6933ada 100644 (file)
 #include <arpa/inet.h>
 
 #include <freeswan.h>
+#include <asn1/asn1.h>
 #include <asn1/oid.h>
 
 #include "../pluto/constants.h"
 #include "../pluto/defs.h"
-#include "../pluto/asn1.h"
 #include "../pluto/pkcs1.h"
 #include "../pluto/log.h"
 #include "../pluto/x509.h"
@@ -133,7 +133,7 @@ build_req_info_attributes(pkcs10_t* pkcs10)
 
        if (pkcs10->challengePassword.len > 0)
        {
-               asn1_t type = is_printablestring(pkcs10->challengePassword)
+               asn1_t type = asn1_is_printablestring(pkcs10->challengePassword)
                                          ? ASN1_PRINTABLESTRING : ASN1_T61STRING;
 
                challengePassword = asn1_wrap(ASN1_SEQUENCE, "cm"