aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2009-04-20 20:53:38 +0000
committerAndreas Steffen <andreas.steffen@strongswan.org>2009-04-20 20:53:38 +0000
commit08b2d288a1281d672533428fb1d8170dff9e5e08 (patch)
tree040f1eaa97f5f3c243b67b59a47d7e8742779e42
parent09f706ec3e69e1899ba3efb9eaf248f35d5c6aaa (diff)
downloadstrongswan-08b2d288a1281d672533428fb1d8170dff9e5e08.tar.bz2
strongswan-08b2d288a1281d672533428fb1d8170dff9e5e08.tar.xz
scepclient and pluto use asn1 from libstrongswan
-rw-r--r--src/charon/Makefile.am3
-rw-r--r--src/charon/plugins/nm/Makefile.am2
-rw-r--r--src/charon/plugins/sql/Makefile.am3
-rw-r--r--src/charon/plugins/stroke/Makefile.am5
-rw-r--r--src/charon/plugins/updown/Makefile.am2
-rw-r--r--src/dumm/Makefile.am4
-rw-r--r--src/libstrongswan/Makefile.am8
-rw-r--r--src/libstrongswan/asn1/asn1.c2
-rw-r--r--src/libstrongswan/asn1/asn1.h3
-rw-r--r--src/libstrongswan/asn1/asn1_parser.c2
-rw-r--r--src/libstrongswan/asn1/asn1_parser.h4
-rw-r--r--src/libstrongswan/chunk.c4
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.am2
-rw-r--r--src/openac/Makefile.am3
-rw-r--r--src/pluto/Makefile.am4
-rw-r--r--src/pluto/ac.c405
-rw-r--r--src/pluto/asn1.c825
-rw-r--r--src/pluto/asn1.h142
-rw-r--r--src/pluto/certs.c56
-rw-r--r--src/pluto/certs.h11
-rw-r--r--src/pluto/connections.c3
-rw-r--r--src/pluto/crl.c201
-rw-r--r--src/pluto/defs.c3
-rw-r--r--src/pluto/defs.h2
-rw-r--r--src/pluto/fetch.c3
-rw-r--r--src/pluto/ipsec_doi.c1
-rw-r--r--src/pluto/mp_defs.c17
-rw-r--r--src/pluto/mp_defs.h3
-rw-r--r--src/pluto/ocsp.c582
-rw-r--r--src/pluto/pkcs1.c228
-rw-r--r--src/pluto/pkcs7.c319
-rw-r--r--src/pluto/x509.c1077
-rw-r--r--src/pluto/x509.h1
-rw-r--r--src/scepclient/Makefile.am12
-rw-r--r--src/scepclient/pkcs10.c4
-rw-r--r--src/scepclient/rsakey.c1
-rw-r--r--src/scepclient/scep.c110
-rw-r--r--src/scepclient/scepclient.c24
38 files changed, 1517 insertions, 2564 deletions
diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am
index 13c87105e..037f81956 100644
--- a/src/charon/Makefile.am
+++ b/src/charon/Makefile.am
@@ -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
diff --git a/src/charon/plugins/nm/Makefile.am b/src/charon/plugins/nm/Makefile.am
index 9c8c64fe1..ffd38e8b7 100644
--- a/src/charon/plugins/nm/Makefile.am
+++ b/src/charon/plugins/nm/Makefile.am
@@ -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 = \
diff --git a/src/charon/plugins/sql/Makefile.am b/src/charon/plugins/sql/Makefile.am
index ea39ce0d5..1e9694456 100644
--- a/src/charon/plugins/sql/Makefile.am
+++ b/src/charon/plugins/sql/Makefile.am
@@ -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 \
diff --git a/src/charon/plugins/stroke/Makefile.am b/src/charon/plugins/stroke/Makefile.am
index 7a341102b..a8ab074da 100644
--- a/src/charon/plugins/stroke/Makefile.am
+++ b/src/charon/plugins/stroke/Makefile.am
@@ -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
diff --git a/src/charon/plugins/updown/Makefile.am b/src/charon/plugins/updown/Makefile.am
index de60d9fbf..21bb733da 100644
--- a/src/charon/plugins/updown/Makefile.am
+++ b/src/charon/plugins/updown/Makefile.am
@@ -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 = \
diff --git a/src/dumm/Makefile.am b/src/dumm/Makefile.am
index 029290fb6..730767642 100644
--- a/src/dumm/Makefile.am
+++ b/src/dumm/Makefile.am
@@ -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
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index f18549e55..c8c94acb9 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -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
diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c
index fa614ef56..de8c5ea4c 100644
--- a/src/libstrongswan/asn1/asn1.c
+++ b/src/libstrongswan/asn1/asn1.c
@@ -21,7 +21,7 @@
#include <string.h>
#include <time.h>
-#include <library.h>
+#include <utils.h>
#include <debug.h>
#include "oid.h"
diff --git a/src/libstrongswan/asn1/asn1.h b/src/libstrongswan/asn1/asn1.h
index cc0010ad1..e29ffa84e 100644
--- a/src/libstrongswan/asn1/asn1.h
+++ b/src/libstrongswan/asn1/asn1.h
@@ -27,7 +27,8 @@
#include <stdarg.h>
-#include <library.h>
+#include <utils.h>
+#include <chunk.h>
/**
* Definition of some primitive ASN1 types
diff --git a/src/libstrongswan/asn1/asn1_parser.c b/src/libstrongswan/asn1/asn1_parser.c
index 68c5e7307..e6ca599b6 100644
--- a/src/libstrongswan/asn1/asn1_parser.c
+++ b/src/libstrongswan/asn1/asn1_parser.c
@@ -21,7 +21,7 @@
#include <string.h>
#include <time.h>
-#include <library.h>
+#include <utils.h>
#include <debug.h>
#include "asn1.h"
diff --git a/src/libstrongswan/asn1/asn1_parser.h b/src/libstrongswan/asn1/asn1_parser.h
index f0e21125c..6ac74ad67 100644
--- a/src/libstrongswan/asn1/asn1_parser.h
+++ b/src/libstrongswan/asn1/asn1_parser.h
@@ -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
diff --git a/src/libstrongswan/chunk.c b/src/libstrongswan/chunk.c
index 24ac5e8e7..d165300c1 100644
--- a/src/libstrongswan/chunk.c
+++ b/src/libstrongswan/chunk.c
@@ -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);
diff --git a/src/libstrongswan/plugins/x509/Makefile.am b/src/libstrongswan/plugins/x509/Makefile.am
index 3f9f85c36..a4f3990f8 100644
--- a/src/libstrongswan/plugins/x509/Makefile.am
+++ b/src/libstrongswan/plugins/x509/Makefile.am
@@ -1,7 +1,7 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan
-AM_CFLAGS = -rdynamic
+AM_CFLAGS = -rdynamic -Wformat=0
plugin_LTLIBRARIES = libstrongswan-x509.la
diff --git a/src/openac/Makefile.am b/src/openac/Makefile.am
index 005486779..cc9b72e16 100644
--- a/src/openac/Makefile.am
+++ b/src/openac/Makefile.am
@@ -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
diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am
index d6db237b5..78862baa2 100644
--- a/src/pluto/Makefile.am
+++ b/src/pluto/Makefile.am
@@ -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 \
diff --git a/src/pluto/ac.c b/src/pluto/ac.c
index d661557db..302cc67db 100644
--- a/src/pluto/ac.c
+++ b/src/pluto/ac.c
@@ -25,10 +25,11 @@
#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"
@@ -38,120 +39,125 @@
#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
index b7605395e..000000000
--- a/src/pluto/asn1.c
+++ /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
index cbc923bac..000000000
--- a/src/pluto/asn1.h
+++ /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 */
-
diff --git a/src/pluto/certs.c b/src/pluto/certs.c
index c9c270c8a..74ec36368 100644
--- a/src/pluto/certs.c
+++ b/src/pluto/certs.c
@@ -21,10 +21,11 @@
#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"
@@ -32,16 +33,15 @@
#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)
{
diff --git a/src/pluto/certs.h b/src/pluto/certs.h
index a3701460a..9c913a8a7 100644
--- a/src/pluto/certs.h
+++ b/src/pluto/certs.h
@@ -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);
diff --git a/src/pluto/connections.c b/src/pluto/connections.c
index cbb48f631..163463062 100644
--- a/src/pluto/connections.c
+++ b/src/pluto/connections.c
@@ -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;
diff --git a/src/pluto/crl.c b/src/pluto/crl.c
index d186abac8..f419af0eb 100644
--- a/src/pluto/crl.c
+++ b/src/pluto/crl.c
@@ -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
@@ -25,11 +27,13 @@
#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"
@@ -43,64 +47,64 @@
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
diff --git a/src/pluto/defs.c b/src/pluto/defs.c
index 84c269aa0..7b327e7e0 100644
--- a/src/pluto/defs.c
+++ b/src/pluto/defs.c
@@ -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;
diff --git a/src/pluto/defs.h b/src/pluto/defs.h
index ac4f20e3c..160681b2e 100644
--- a/src/pluto/defs.h
+++ b/src/pluto/defs.h
@@ -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);
diff --git a/src/pluto/fetch.c b/src/pluto/fetch.c
index e191f38c5..a8919e630 100644
--- a/src/pluto/fetch.c
+++ b/src/pluto/fetch.c
@@ -38,11 +38,12 @@
#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"
diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c
index 2f3de9ce1..7e53e4069 100644
--- a/src/pluto/ipsec_doi.c
+++ b/src/pluto/ipsec_doi.c
@@ -58,7 +58,6 @@
#include "whack.h"
#include "fetch.h"
#include "pkcs7.h"
-#include "asn1.h"
#include "sha1.h"
#include "md5.h"
diff --git a/src/pluto/mp_defs.c b/src/pluto/mp_defs.c
index 201effc29..ee9dd0360 100644
--- a/src/pluto/mp_defs.c
+++ b/src/pluto/mp_defs.c
@@ -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);
+}
+
diff --git a/src/pluto/mp_defs.h b/src/pluto/mp_defs.h
index 7b3b569ed..fa6d67fdd 100644
--- a/src/pluto/mp_defs.h
+++ b/src/pluto/mp_defs.h
@@ -20,10 +20,11 @@
#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) { \
diff --git a/src/pluto/ocsp.c b/src/pluto/ocsp.c
index ef270cd6c..2516391c2 100644
--- a/src/pluto/ocsp.c
+++ b/src/pluto/ocsp.c
@@ -26,6 +26,10 @@
#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"
@@ -33,10 +37,8 @@
#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);
}
}
diff --git a/src/pluto/pkcs1.c b/src/pluto/pkcs1.c
index b7ef1072a..73fa7cc06 100644
--- a/src/pluto/pkcs1.c
+++ b/src/pluto/pkcs1.c
@@ -23,11 +23,13 @@
#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);
}
-
diff --git a/src/pluto/pkcs7.c b/src/pluto/pkcs7.c
index 8283a0699..7fa2cb3a4 100644
--- a/src/pluto/pkcs7.c
+++ b/src/pluto/pkcs7.c
@@ -22,10 +22,12 @@
#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;
diff --git a/src/pluto/x509.c b/src/pluto/x509.c
index 5d308eb90..7ef163683 100644
--- a/src/pluto/x509.c
+++ b/src/pluto/x509.c
@@ -28,13 +28,15 @@
#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"
@@ -46,218 +48,190 @@
#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);
}
diff --git a/src/pluto/x509.h b/src/pluto/x509.h
index b6a702c6a..104ef6d62 100644
--- a/src/pluto/x509.h
+++ b/src/pluto/x509.h
@@ -20,6 +20,7 @@
#ifndef _X509_H
#define _X509_H
+#include "constants.h"
#include "pkcs1.h"
#include "id.h"
diff --git a/src/scepclient/Makefile.am b/src/scepclient/Makefile.am
index 6681407ca..62146b246 100644
--- a/src/scepclient/Makefile.am
+++ b/src/scepclient/Makefile.am
@@ -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 $@ $<
diff --git a/src/scepclient/pkcs10.c b/src/scepclient/pkcs10.c
index d6b53d8d0..6933adaf8 100644
--- a/src/scepclient/pkcs10.c
+++ b/src/scepclient/pkcs10.c
@@ -26,11 +26,11 @@
#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"
diff --git a/src/scepclient/rsakey.c b/src/scepclient/rsakey.c
index 87ec37cb2..9f40b32a7 100644
--- a/src/scepclient/rsakey.c
+++ b/src/scepclient/rsakey.c
@@ -36,7 +36,6 @@
#include "../pluto/defs.h"
#include "../pluto/mp_defs.h"
#include "../pluto/log.h"
-#include "../pluto/asn1.h"
#include "../pluto/pkcs1.h"
#include "rsakey.h"
diff --git a/src/scepclient/scep.c b/src/scepclient/scep.c
index 1d921ba99..f880fe734 100644
--- a/src/scepclient/scep.c
+++ b/src/scepclient/scep.c
@@ -24,6 +24,9 @@
#include <stdlib.h>
#include <freeswan.h>
+
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
#include <asn1/oid.h>
#ifdef LIBCURL
@@ -33,7 +36,6 @@
#include "../pluto/constants.h"
#include "../pluto/defs.h"
#include "../pluto/rnd.h"
-#include "../pluto/asn1.h"
#include "../pluto/pkcs1.h"
#include "../pluto/fetch.h"
#include "../pluto/log.h"
@@ -62,62 +64,60 @@ static const chunk_t ASN1_transId_oid =
static const char *pkiStatus_values[] = { "0", "2", "3" };
static const char *pkiStatus_names[] = {
- "SUCCESS",
- "FAILURE",
- "PENDING",
- "UNKNOWN"
+ "SUCCESS",
+ "FAILURE",
+ "PENDING",
+ "UNKNOWN"
};
static const char *msgType_values[] = { "3", "19", "20", "21", "22" };
static const char *msgType_names[] = {
- "CertRep",
- "PKCSReq",
- "GetCertInitial",
- "GetCert",
- "GetCRL",
- "Unknown"
+ "CertRep",
+ "PKCSReq",
+ "GetCertInitial",
+ "GetCert",
+ "GetCRL",
+ "Unknown"
};
static const char *failInfo_reasons[] = {
- "badAlg - unrecognized or unsupported algorithm identifier",
- "badMessageCheck - integrity check failed",
- "badRequest - transaction not permitted or supported",
- "badTime - Message time field was not sufficiently close to the system time",
- "badCertId - No certificate could be identified matching the provided criteria"
+ "badAlg - unrecognized or unsupported algorithm identifier",
+ "badMessageCheck - integrity check failed",
+ "badRequest - transaction not permitted or supported",
+ "badTime - Message time field was not sufficiently close to the system time",
+ "badCertId - No certificate could be identified matching the provided criteria"
};
const scep_attributes_t empty_scep_attributes = {
- SCEP_Unknown_MSG , /* msgType */
- SCEP_UNKNOWN , /* pkiStatus */
- SCEP_unknown_REASON, /* failInfo */
- { NULL, 0 } , /* transID */
- { NULL, 0 } , /* senderNonce */
- { NULL, 0 } , /* recipientNonce */
+ SCEP_Unknown_MSG , /* msgType */
+ SCEP_UNKNOWN , /* pkiStatus */
+ SCEP_unknown_REASON, /* failInfo */
+ { NULL, 0 } , /* transID */
+ { NULL, 0 } , /* senderNonce */
+ { NULL, 0 } , /* recipientNonce */
};
/* ASN.1 definition of the X.501 atttribute type */
static const asn1Object_t attributesObjects[] = {
- { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */
- { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */
- { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */
- { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */
+ { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */
+ { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
#define ATTRIBUTE_OBJ_TYPE 2
#define ATTRIBUTE_OBJ_VALUE 4
-#define ATTRIBUTE_OBJ_ROOF 7
-/*
- * extract and store an attribute
+/**
+ * Extract and store an attribute
*/
-static bool
-extract_attribute(int oid, chunk_t object, u_int level
-, scep_attributes_t *attrs)
+static bool extract_attribute(int oid, chunk_t object, u_int level,
+ scep_attributes_t *attrs)
{
asn1_t type = ASN1_EOC;
const char *name = "none";
@@ -167,7 +167,7 @@ extract_attribute(int oid, chunk_t object, u_int level
if (type == ASN1_EOC)
return TRUE;
- if (!parse_asn1_simple_object(&object, type, level+1, name))
+ if (!asn1_parse_simple_object(&object, type, level+1, name))
return FALSE;
switch (oid)
@@ -227,41 +227,41 @@ extract_attribute(int oid, chunk_t object, u_int level
return TRUE;
}
-/*
- * parse X.501 attributes
+/**
+ * Parse X.501 attributes
*/
-bool
-parse_attributes(chunk_t blob, scep_attributes_t *attrs)
+bool parse_attributes(chunk_t blob, scep_attributes_t *attrs)
{
- asn1_ctx_t ctx;
+ asn1_parser_t *parser;
chunk_t object;
- u_int level;
int oid = OID_UNKNOWN;
- int objectID = 0;
-
- asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
+ int objectID;
+ bool success = FALSE;
+ parser = asn1_parser_create(attributesObjects, blob);
DBG(DBG_CONTROL | DBG_PARSING,
DBG_log("parsing attributes")
)
- while (objectID < ATTRIBUTE_OBJ_ROOF)
+
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(attributesObjects, &objectID
- , &object, &level, &ctx))
- return FALSE;
-
switch (objectID)
{
case ATTRIBUTE_OBJ_TYPE:
oid = asn1_known_oid(object);
break;
case ATTRIBUTE_OBJ_VALUE:
- if (!extract_attribute(oid, object, level, attrs))
- return FALSE;
+ if (!extract_attribute(oid, object, parser->get_level(parser), attrs))
+ {
+ goto end;
+ }
}
- objectID++;
}
- return TRUE;
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
}
/* generates a unique fingerprint of the pkcs10 request
diff --git a/src/scepclient/scepclient.c b/src/scepclient/scepclient.c
index eb1c2af42..d8d44fdbc 100644
--- a/src/scepclient/scepclient.c
+++ b/src/scepclient/scepclient.c
@@ -38,13 +38,13 @@
#include <freeswan.h>
#include <library.h>
#include <debug.h>
+#include <asn1/asn1.h>
#include <asn1/oid.h>
#include <utils/optionsfrom.h>
#include "../pluto/constants.h"
#include "../pluto/defs.h"
#include "../pluto/log.h"
-#include "../pluto/asn1.h"
#include "../pluto/pkcs1.h"
#include "../pluto/pkcs7.h"
#include "../pluto/certs.h"
@@ -604,7 +604,7 @@ int main(int argc, char **argv)
usage("date format must be YYMMDDHHMMSSZ");
{
chunk_t date = { optarg, 13 };
- notBefore = asn1totime(&date, ASN1_UTCTIME);
+ notBefore = asn1_to_time(&date, ASN1_UTCTIME);
}
continue;
@@ -613,7 +613,7 @@ int main(int argc, char **argv)
usage("date format must be YYMMDDHHMMSSZ");
{
chunk_t date = { optarg, 13 };
- notAfter = asn1totime(&date, ASN1_UTCTIME);
+ notAfter = asn1_to_time(&date, ASN1_UTCTIME);
}
continue;
@@ -800,7 +800,7 @@ int main(int argc, char **argv)
if (filetype_in & PKCS1) /* load an RSA key pair from file */
{
prompt_pass_t pass = { "", FALSE, STDIN_FILENO };
- const char *path = concatenate_paths(PRIVATE_KEY_PATH, file_in_pkcs1);
+ char *path = concatenate_paths(PRIVATE_KEY_PATH, file_in_pkcs1);
ugh = load_rsa_private_key(path, &pass, private_key);
}
@@ -877,9 +877,9 @@ int main(int argc, char **argv)
*/
if (filetype_out & PKCS10)
{
- const char *path = concatenate_paths(REQ_PATH, file_out_pkcs10);
+ char *path = concatenate_paths(REQ_PATH, file_out_pkcs10);
- if (!chunk_write(pkcs10->request,path, "pkcs10", 0022, force))
+ if (!chunk_write(pkcs10->request, path, "pkcs10", 0022, force))
exit_scepclient("could not write pkcs10 file '%s'", path);
filetype_out &= ~PKCS10; /* delete PKCS10 flag */
@@ -895,7 +895,7 @@ int main(int argc, char **argv)
*/
if (filetype_out & PKCS1)
{
- const char *path = concatenate_paths(PRIVATE_KEY_PATH, file_out_pkcs1);
+ char *path = concatenate_paths(PRIVATE_KEY_PATH, file_out_pkcs1);
DBG(DBG_CONTROL,
DBG_log("building pkcs1 object:")
@@ -938,7 +938,7 @@ int main(int argc, char **argv)
*/
if (filetype_out & CERT_SELF)
{
- const char *path = concatenate_paths(HOST_CERT_PATH, file_out_cert_self);
+ char *path = concatenate_paths(HOST_CERT_PATH, file_out_cert_self);
if (!chunk_write(x509_signer->certificate, path, "self-signed cert", 0022, force))
exit_scepclient("could not write self-signed cert file '%s'", path);
@@ -955,7 +955,7 @@ int main(int argc, char **argv)
* load ca encryption certificate
*/
{
- const char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_enc);
+ char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_enc);
cert_t cert;
if (!load_cert(path, "encryption cacert", &cert))
@@ -994,7 +994,7 @@ int main(int argc, char **argv)
*/
if (filetype_out & PKCS7)
{
- const char *path = concatenate_paths(REQ_PATH, file_out_pkcs7);
+ char *path = concatenate_paths(REQ_PATH, file_out_pkcs7);
if (!chunk_write(pkcs7, path, "pkcs7 encrypted request", 0022, force))
exit_scepclient("could not write pkcs7 file '%s'", path);
@@ -1012,7 +1012,7 @@ int main(int argc, char **argv)
*/
if (filetype_out & CERT)
{
- const char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_sig);
+ char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_sig);
cert_t cert;
time_t poll_start;
@@ -1094,7 +1094,7 @@ int main(int argc, char **argv)
envelopedData = data.content;
if (data.type != OID_PKCS7_DATA
- || !parse_asn1_simple_object(&envelopedData, ASN1_OCTET_STRING, 0, "data"))
+ || !asn1_parse_simple_object(&envelopedData, ASN1_OCTET_STRING, 0, "data"))
{
exit_scepclient("contentInfo is not of type 'data'");
}