summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/x509
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/x509')
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.c44
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c309
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.c54
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.c54
-rw-r--r--src/libstrongswan/plugins/x509/x509_pkcs10.c16
6 files changed, 314 insertions, 165 deletions
diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
index 8d7f9a810..e1ed6b7ee 100644
--- a/src/libstrongswan/plugins/x509/Makefile.in
+++ b/src/libstrongswan/plugins/x509/Makefile.in
@@ -357,6 +357,7 @@ docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
fips_mode = @fips_mode@
+fuzz_plugins = @fuzz_plugins@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
host = @host@
@@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@
json_LIBS = @json_LIBS@
libdir = @libdir@
libexecdir = @libexecdir@
+libfuzzer = @libfuzzer@
libiptc_CFLAGS = @libiptc_CFLAGS@
libiptc_LIBS = @libiptc_LIBS@
linux_headers = @linux_headers@
diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
index aea8eb53d..ba459288b 100644
--- a/src/libstrongswan/plugins/x509/x509_ac.c
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -1,9 +1,8 @@
/*
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
* Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2002-2014 Andreas Steffen
+ * Copyright (C) 2002-2017 Andreas Steffen
* Copyright (C) 2009 Martin Willi
- *
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -177,7 +176,7 @@ static chunk_t ASN1_noRevAvail_ext = chunk_from_chars(
/**
* declaration of function implemented in x509_cert.c
*/
-extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
+extern bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
linked_list_t *list);
/**
* parses a directoryName
@@ -191,7 +190,11 @@ static bool parse_directoryName(chunk_t blob, int level, bool implicit,
linked_list_t *list;
list = linked_list_create();
- x509_parse_generalNames(blob, level, implicit, list);
+ if (!x509_parse_generalNames(blob, level, implicit, list))
+ {
+ list->destroy(list);
+ return FALSE;
+ }
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, &directoryName))
@@ -801,20 +804,27 @@ METHOD(ac_t, get_authKeyIdentifier, chunk_t,
return this->authKeyIdentifier;
}
-/**
- * Filter function for attribute enumeration
- */
-static bool attr_filter(void *null, group_t **in, ac_group_type_t *type,
- void *in2, chunk_t *out)
+CALLBACK(attr_filter, bool,
+ void *null, enumerator_t *orig, va_list args)
{
- if ((*in)->type == AC_GROUP_TYPE_STRING &&
- !chunk_printable((*in)->value, NULL, 0))
- { /* skip non-printable strings */
- return FALSE;
+ group_t *group;
+ ac_group_type_t *type;
+ chunk_t *out;
+
+ VA_ARGS_VGET(args, type, out);
+
+ while (orig->enumerate(orig, &group))
+ {
+ if (group->type == AC_GROUP_TYPE_STRING &&
+ !chunk_printable(group->value, NULL, 0))
+ { /* skip non-printable strings */
+ continue;
+ }
+ *type = group->type;
+ *out = group->value;
+ return TRUE;
}
- *type = (*in)->type;
- *out = (*in)->value;
- return TRUE;
+ return FALSE;
}
METHOD(ac_t, create_group_enumerator, enumerator_t*,
@@ -822,7 +832,7 @@ METHOD(ac_t, create_group_enumerator, enumerator_t*,
{
return enumerator_create_filter(
this->groups->create_enumerator(this->groups),
- (void*)attr_filter, NULL, NULL);
+ attr_filter, NULL, NULL);
}
METHOD(certificate_t, get_type, certificate_type_t,
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index b77c5db4d..974e687f9 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -2,10 +2,10 @@
* Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
* Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
* Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2000-2006 Andreas Steffen
+ * Copyright (C) 2000-2017 Andreas Steffen
* Copyright (C) 2006-2009 Martin Willi
* Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * 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
@@ -218,6 +218,29 @@ struct private_x509_cert_t {
};
/**
+ * Convert a generalName to a string
+ */
+static bool gn_to_string(identification_t *id, char **uri)
+{
+ int len;
+
+#ifdef USE_FUZZING
+ chunk_t proper;
+ chunk_printable(id->get_encoding(id), &proper, '?');
+ len = asprintf(uri, "%.*s", (int)proper.len, proper.ptr);
+ chunk_free(&proper);
+#else
+ len = asprintf(uri, "%Y", id);
+#endif
+ if (!len)
+ {
+ free(*uri);
+ return FALSE;
+ }
+ return len > 0;
+}
+
+/**
* Destroy a CertificateDistributionPoint
*/
static void crl_uri_destroy(x509_cdp_t *this)
@@ -280,13 +303,14 @@ static const asn1Object_t basicConstraintsObjects[] = {
/**
* Extracts the basicConstraints extension
*/
-static void parse_basicConstraints(chunk_t blob, int level0,
+static bool parse_basicConstraints(chunk_t blob, int level0,
private_x509_cert_t *this)
{
asn1_parser_t *parser;
chunk_t object;
int objectID;
bool isCA = FALSE;
+ bool success;
parser = asn1_parser_create(basicConstraintsObjects, blob);
parser->set_top_level(parser, level0);
@@ -313,7 +337,10 @@ static void parse_basicConstraints(chunk_t blob, int level0,
break;
}
}
+ success = parser->success(parser);
parser->destroy(parser);
+
+ return success;
}
/**
@@ -502,11 +529,14 @@ static const asn1Object_t generalNamesObjects[] = {
/**
* Extracts one or several GNs and puts them into a chained list
*/
-void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list)
+bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
+ linked_list_t *list)
{
asn1_parser_t *parser;
chunk_t object;
+ identification_t *gn;
int objectID;
+ bool success = FALSE;
parser = asn1_parser_create(generalNamesObjects, blob);
parser->set_top_level(parser, level0);
@@ -516,16 +546,20 @@ void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_lis
{
if (objectID == GENERAL_NAMES_GN)
{
- identification_t *gn = parse_generalName(object,
- parser->get_level(parser)+1);
-
- if (gn)
+ gn = parse_generalName(object, parser->get_level(parser)+1);
+ if (!gn)
{
- list->insert_last(list, (void *)gn);
+ goto end;
}
+ list->insert_last(list, (void *)gn);
}
}
+ success = parser->success(parser);
+
+end:
parser->destroy(parser);
+
+ return success;
}
/**
@@ -579,6 +613,7 @@ chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, int level0,
}
}
parser->destroy(parser);
+
return authKeyIdentifier;
}
@@ -599,13 +634,14 @@ static const asn1Object_t authInfoAccessObjects[] = {
/**
* Extracts an authorityInfoAcess location
*/
-static void parse_authorityInfoAccess(chunk_t blob, int level0,
+static bool parse_authorityInfoAccess(chunk_t blob, int level0,
private_x509_cert_t *this)
{
asn1_parser_t *parser;
chunk_t object;
int objectID;
int accessMethod = OID_UNKNOWN;
+ bool success = FALSE;
parser = asn1_parser_create(authInfoAccessObjects, blob);
parser->set_top_level(parser, level0);
@@ -636,7 +672,7 @@ static void parse_authorityInfoAccess(chunk_t blob, int level0,
}
DBG2(DBG_ASN, " '%Y'", id);
if (accessMethod == OID_OCSP &&
- asprintf(&uri, "%Y", id) > 0)
+ gn_to_string(id, &uri))
{
this->ocsp_uris->insert_last(this->ocsp_uris, uri);
}
@@ -653,9 +689,12 @@ static void parse_authorityInfoAccess(chunk_t blob, int level0,
break;
}
}
+ success = parser->success(parser);
end:
parser->destroy(parser);
+
+ return success;
}
/**
@@ -726,12 +765,13 @@ static const asn1Object_t extendedKeyUsageObjects[] = {
/**
* Extracts extendedKeyUsage OIDs
*/
-static void parse_extendedKeyUsage(chunk_t blob, int level0,
+static bool parse_extendedKeyUsage(chunk_t blob, int level0,
private_x509_cert_t *this)
{
asn1_parser_t *parser;
chunk_t object;
int objectID;
+ bool success;
parser = asn1_parser_create(extendedKeyUsageObjects, blob);
parser->set_top_level(parser, level0);
@@ -762,27 +802,30 @@ static void parse_extendedKeyUsage(chunk_t blob, int level0,
}
}
}
+ success = parser->success(parser);
parser->destroy(parser);
+
+ return success;
}
/**
* 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, "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_OBJ }, /* 10 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
- { 0, "exit", ASN1_EOC, ASN1_EXIT }
+ { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_CHOICE }, /* 2 */
+ { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */
+ { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 4 */
+ { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */
+ { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 6 */
+ { 2, "end opt/choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 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_OBJ }, /* 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 1
#define CRL_DIST_POINTS_FULLNAME 3
@@ -801,7 +844,7 @@ static void add_cdps(linked_list_t *list, linked_list_t *uris,
while (uris->remove_last(uris, (void**)&id) == SUCCESS)
{
- if (asprintf(&uri, "%Y", id) > 0)
+ if (gn_to_string(id, &uri))
{
if (issuers->get_count(issuers))
{
@@ -836,13 +879,14 @@ static void add_cdps(linked_list_t *list, linked_list_t *uris,
/**
* Extracts one or several crlDistributionPoints into a list
*/
-void x509_parse_crlDistributionPoints(chunk_t blob, int level0,
+bool x509_parse_crlDistributionPoints(chunk_t blob, int level0,
linked_list_t *list)
{
linked_list_t *uris, *issuers;
asn1_parser_t *parser;
chunk_t object;
int objectID;
+ bool success = FALSE;
uris = linked_list_create();
issuers = linked_list_create();
@@ -857,37 +901,45 @@ void x509_parse_crlDistributionPoints(chunk_t blob, int level0,
add_cdps(list, uris, issuers);
break;
case CRL_DIST_POINTS_FULLNAME:
- x509_parse_generalNames(object, parser->get_level(parser) + 1,
- TRUE, uris);
+ if (!x509_parse_generalNames(object,
+ parser->get_level(parser) + 1, TRUE, uris))
+ {
+ goto end;
+ }
break;
case CRL_DIST_POINTS_ISSUER:
- x509_parse_generalNames(object, parser->get_level(parser) + 1,
- TRUE, issuers);
+ if (!x509_parse_generalNames(object,
+ parser->get_level(parser) + 1, TRUE, issuers))
+ {
+ goto end;
+ }
break;
default:
break;
}
}
- parser->destroy(parser);
-
+ success = parser->success(parser);
add_cdps(list, uris, issuers);
- uris->destroy(uris);
- issuers->destroy(issuers);
+end:
+ parser->destroy(parser);
+ uris->destroy_offset(uris, offsetof(identification_t, destroy));
+ issuers->destroy_offset(issuers, offsetof(identification_t, destroy));
+
+ return success;
}
/**
* ASN.1 definition of nameConstraints
*/
static const asn1Object_t nameConstraintsObjects[] = {
- { 0, "nameConstraints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 0, "nameConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
{ 1, "permittedSubtrees", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 1 */
{ 2, "generalSubtree", ASN1_SEQUENCE, ASN1_BODY }, /* 2 */
{ 1, "end loop", ASN1_EOC, ASN1_END }, /* 3 */
{ 1, "excludedSubtrees", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_LOOP }, /* 4 */
{ 2, "generalSubtree", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */
{ 1, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 7 */
{ 0, "exit", ASN1_EOC, ASN1_EXIT }
};
#define NAME_CONSTRAINT_PERMITTED 2
@@ -896,13 +948,14 @@ static const asn1Object_t nameConstraintsObjects[] = {
/**
* Parse permitted/excluded nameConstraints
*/
-static void parse_nameConstraints(chunk_t blob, int level0,
+static bool parse_nameConstraints(chunk_t blob, int level0,
private_x509_cert_t *this)
{
asn1_parser_t *parser;
identification_t *id;
chunk_t object;
int objectID;
+ bool success = FALSE;
parser = asn1_parser_create(nameConstraintsObjects, blob);
parser->set_top_level(parser, level0);
@@ -913,59 +966,69 @@ static void parse_nameConstraints(chunk_t blob, int level0,
{
case NAME_CONSTRAINT_PERMITTED:
id = parse_generalName(object, parser->get_level(parser) + 1);
- if (id)
+ if (!id)
{
- this->permitted_names->insert_last(this->permitted_names, id);
+ goto end;
}
+ this->permitted_names->insert_last(this->permitted_names, id);
break;
case NAME_CONSTRAINT_EXCLUDED:
id = parse_generalName(object, parser->get_level(parser) + 1);
- if (id)
+ if (!id)
{
- this->excluded_names->insert_last(this->excluded_names, id);
+ goto end;
}
+ this->excluded_names->insert_last(this->excluded_names, id);
break;
default:
break;
}
}
+ success = parser->success(parser);
+
+end:
parser->destroy(parser);
+
+ return success;
}
/**
* ASN.1 definition of a certificatePolicies extension
*/
static const asn1Object_t certificatePoliciesObject[] = {
- { 0, "certificatePolicies", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "policyInformation", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "policyId", ASN1_OID, ASN1_BODY }, /* 2 */
- { 2, "qualifiers", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 3 */
- { 3, "qualifierInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 4 */
- { 4, "qualifierId", ASN1_OID, ASN1_BODY }, /* 5 */
- { 4, "cPSuri", ASN1_IA5STRING, ASN1_OPT|ASN1_BODY }, /* 6 */
- { 4, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
- { 4, "userNotice", ASN1_SEQUENCE, ASN1_OPT|ASN1_BODY }, /* 8 */
- { 5, "explicitText", ASN1_EOC, ASN1_RAW }, /* 9 */
- { 4, "end choice", ASN1_EOC, ASN1_END }, /* 10 */
- { 2, "end opt/loop", ASN1_EOC, ASN1_END }, /* 12 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 13 */
- { 0, "exit", ASN1_EOC, ASN1_EXIT }
+ { 0, "certificatePolicies", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "policyInformation", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "policyId", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "qualifiers", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 3 */
+ { 3, "qualifierInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 4 */
+ { 4, "qualifierId", ASN1_OID, ASN1_BODY }, /* 5 */
+ { 4, "qualifier", ASN1_EOC, ASN1_CHOICE }, /* 6 */
+ { 5, "cPSuri", ASN1_IA5STRING, ASN1_OPT|ASN1_BODY }, /* 7 */
+ { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 8 */
+ { 5, "userNotice", ASN1_SEQUENCE, ASN1_OPT|ASN1_BODY }, /* 9 */
+ { 6, "explicitText", ASN1_EOC, ASN1_RAW }, /* 10 */
+ { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 11 */
+ { 4, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 12 */
+ { 2, "end opt/loop", ASN1_EOC, ASN1_END }, /* 13 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 14 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-#define CERT_POLICY_ID 2
-#define CERT_POLICY_QUALIFIER_ID 5
-#define CERT_POLICY_CPS_URI 6
-#define CERT_POLICY_EXPLICIT_TEXT 9
+#define CERT_POLICY_ID 2
+#define CERT_POLICY_QUALIFIER_ID 5
+#define CERT_POLICY_CPS_URI 7
+#define CERT_POLICY_EXPLICIT_TEXT 10
/**
* Parse certificatePolicies
*/
-static void parse_certificatePolicies(chunk_t blob, int level0,
+static bool parse_certificatePolicies(chunk_t blob, int level0,
private_x509_cert_t *this)
{
x509_cert_policy_t *policy = NULL;
asn1_parser_t *parser;
chunk_t object;
int objectID, qualifier = OID_UNKNOWN;
+ bool success;
parser = asn1_parser_create(certificatePoliciesObject, blob);
parser->set_top_level(parser, level0);
@@ -998,7 +1061,10 @@ static void parse_certificatePolicies(chunk_t blob, int level0,
break;
}
}
+ success = parser->success(parser);
parser->destroy(parser);
+
+ return success;
}
/**
@@ -1019,13 +1085,14 @@ static const asn1Object_t policyMappingsObjects[] = {
/**
* Parse policyMappings
*/
-static void parse_policyMappings(chunk_t blob, int level0,
+static bool parse_policyMappings(chunk_t blob, int level0,
private_x509_cert_t *this)
{
x509_policy_mapping_t *map = NULL;
asn1_parser_t *parser;
chunk_t object;
int objectID;
+ bool success;
parser = asn1_parser_create(policyMappingsObjects, blob);
parser->set_top_level(parser, level0);
@@ -1054,7 +1121,10 @@ static void parse_policyMappings(chunk_t blob, int level0,
break;
}
}
+ success = parser->success(parser);
parser->destroy(parser);
+
+ return success;
}
/**
@@ -1076,12 +1146,13 @@ static const asn1Object_t policyConstraintsObjects[] = {
/**
* Parse policyConstraints
*/
-static void parse_policyConstraints(chunk_t blob, int level0,
+static bool parse_policyConstraints(chunk_t blob, int level0,
private_x509_cert_t *this)
{
asn1_parser_t *parser;
chunk_t object;
int objectID;
+ bool success;
parser = asn1_parser_create(policyConstraintsObjects, blob);
parser->set_top_level(parser, level0);
@@ -1100,34 +1171,41 @@ static void parse_policyConstraints(chunk_t blob, int level0,
break;
}
}
+ success = parser->success(parser);
parser->destroy(parser);
+
+ return success;
}
/**
* ASN.1 definition of ipAddrBlocks according to RFC 3779
*/
static const asn1Object_t ipAddrBlocksObjects[] = {
- { 0, "ipAddrBlocks", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "ipAddressFamily", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
- { 2, "inherit", ASN1_NULL, ASN1_OPT|ASN1_NONE }, /* 3 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
- { 2, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 5 */
- { 3, "addressPrefix", ASN1_BIT_STRING, ASN1_OPT|ASN1_BODY }, /* 6 */
- { 3, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
- { 3, "addressRange", ASN1_SEQUENCE, ASN1_OPT|ASN1_NONE }, /* 8 */
- { 4, "min", ASN1_BIT_STRING, ASN1_BODY }, /* 9 */
- { 4, "max", ASN1_BIT_STRING, ASN1_BODY }, /* 10 */
- { 3, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
- { 2, "end opt/loop", ASN1_EOC, ASN1_END }, /* 12 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 13 */
- { 0, "exit", ASN1_EOC, ASN1_EXIT }
+ { 0, "ipAddrBlocks", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "ipAddressFamily", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
+ { 2, "ipAddressChoice", ASN1_EOC, ASN1_CHOICE }, /* 3 */
+ { 3, "inherit", ASN1_NULL, ASN1_OPT }, /* 4 */
+ { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 5 */
+ { 3, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 6 */
+ { 4, "addressOrRange", ASN1_EOC, ASN1_CHOICE }, /* 7 */
+ { 5, "addressPrefix", ASN1_BIT_STRING, ASN1_OPT|ASN1_BODY }, /* 8 */
+ { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 9 */
+ { 5, "addressRange", ASN1_SEQUENCE, ASN1_OPT }, /* 10 */
+ { 6, "min", ASN1_BIT_STRING, ASN1_BODY }, /* 11 */
+ { 6, "max", ASN1_BIT_STRING, ASN1_BODY }, /* 12 */
+ { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 13 */
+ { 4, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 14 */
+ { 3, "end loop/choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 15 */
+ { 2, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 16 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 17 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
#define IP_ADDR_BLOCKS_FAMILY 2
-#define IP_ADDR_BLOCKS_INHERIT 3
-#define IP_ADDR_BLOCKS_PREFIX 6
-#define IP_ADDR_BLOCKS_MIN 9
-#define IP_ADDR_BLOCKS_MAX 10
+#define IP_ADDR_BLOCKS_INHERIT 4
+#define IP_ADDR_BLOCKS_PREFIX 8
+#define IP_ADDR_BLOCKS_MIN 11
+#define IP_ADDR_BLOCKS_MAX 12
static bool check_address_object(ts_type_t ts_type, chunk_t object)
{
@@ -1171,7 +1249,7 @@ static bool check_address_object(ts_type_t ts_type, chunk_t object)
return TRUE;
}
-static void parse_ipAddrBlocks(chunk_t blob, int level0,
+static bool parse_ipAddrBlocks(chunk_t blob, int level0,
private_x509_cert_t *this)
{
asn1_parser_t *parser;
@@ -1179,6 +1257,7 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0,
ts_type_t ts_type = 0;
traffic_selector_t *ts;
int objectID;
+ bool success = FALSE;
parser = asn1_parser_create(ipAddrBlocksObjects, blob);
parser->set_top_level(parser, level0);
@@ -1240,10 +1319,13 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0,
break;
}
}
+ success = parser->success(parser);
this->flags |= X509_IP_ADDR_BLOCKS;
end:
parser->destroy(parser);
+
+ return success;
}
/**
@@ -1387,43 +1469,74 @@ static bool parse_certificate(private_x509_cert_t *this)
this->subjectKeyIdentifier = object;
break;
case OID_SUBJECT_ALT_NAME:
- x509_parse_generalNames(object, level, FALSE,
- this->subjectAltNames);
+ if (!x509_parse_generalNames(object, level, FALSE,
+ this->subjectAltNames))
+ {
+ goto end;
+ }
break;
case OID_BASIC_CONSTRAINTS:
- parse_basicConstraints(object, level, this);
+ if (!parse_basicConstraints(object, level, this))
+ {
+ goto end;
+ }
break;
case OID_CRL_DISTRIBUTION_POINTS:
- x509_parse_crlDistributionPoints(object, level,
- this->crl_uris);
+ if (!x509_parse_crlDistributionPoints(object, level,
+ this->crl_uris))
+ {
+ goto end;
+ }
break;
case OID_AUTHORITY_KEY_ID:
- this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
- level, &this->authKeySerialNumber);
+ chunk_free(&this->authKeyIdentifier);
+ this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(
+ object, level, &this->authKeySerialNumber);
break;
case OID_AUTHORITY_INFO_ACCESS:
- parse_authorityInfoAccess(object, level, this);
+ if (!parse_authorityInfoAccess(object, level, this))
+ {
+ goto end;
+ }
break;
case OID_KEY_USAGE:
parse_keyUsage(object, this);
break;
case OID_EXTENDED_KEY_USAGE:
- parse_extendedKeyUsage(object, level, this);
+ if (!parse_extendedKeyUsage(object, level, this))
+ {
+ goto end;
+ }
break;
case OID_IP_ADDR_BLOCKS:
- parse_ipAddrBlocks(object, level, this);
+ if (!parse_ipAddrBlocks(object, level, this))
+ {
+ goto end;
+ }
break;
case OID_NAME_CONSTRAINTS:
- parse_nameConstraints(object, level, this);
+ if (!parse_nameConstraints(object, level, this))
+ {
+ goto end;
+ }
break;
case OID_CERTIFICATE_POLICIES:
- parse_certificatePolicies(object, level, this);
+ if (!parse_certificatePolicies(object, level, this))
+ {
+ goto end;
+ }
break;
case OID_POLICY_MAPPINGS:
- parse_policyMappings(object, level, this);
+ if (!parse_policyMappings(object, level, this))
+ {
+ goto end;
+ }
break;
case OID_POLICY_CONSTRAINTS:
- parse_policyConstraints(object, level, this);
+ if (!parse_policyConstraints(object, level, this))
+ {
+ goto end;
+ }
break;
case OID_INHIBIT_ANY_POLICY:
if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
index 4d7e7bd10..d8913ad73 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.c
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2008-2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2017 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
@@ -149,7 +150,7 @@ extern chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, int level0,
/**
* from x509_cert
*/
-extern void x509_parse_crlDistributionPoints(chunk_t blob, int level0,
+extern bool x509_parse_crlDistributionPoints(chunk_t blob, int level0,
linked_list_t *list);
/**
@@ -309,8 +310,11 @@ static bool parse(private_x509_crl_t *this)
this->crlNumber = object;
break;
case OID_FRESHEST_CRL:
- x509_parse_crlDistributionPoints(object, level,
- this->crl_uris);
+ if (!x509_parse_crlDistributionPoints(object, level,
+ this->crl_uris))
+ {
+ goto end;
+ }
break;
case OID_DELTA_CRL_INDICATOR:
if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
@@ -360,25 +364,33 @@ end:
return success;
}
-/**
- * enumerator filter callback for create_enumerator
- */
-static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2,
- time_t *date, void *p3, crl_reason_t *reason)
+CALLBACK(filter, bool,
+ void *data, enumerator_t *orig, va_list args)
{
- if (serial)
- {
- *serial = (*revoked)->serial;
- }
- if (date)
- {
- *date = (*revoked)->date;
- }
- if (reason)
+ revoked_t *revoked;
+ crl_reason_t *reason;
+ chunk_t *serial;
+ time_t *date;
+
+ VA_ARGS_VGET(args, serial, date, reason);
+
+ if (orig->enumerate(orig, &revoked))
{
- *reason = (*revoked)->reason;
+ if (serial)
+ {
+ *serial = revoked->serial;
+ }
+ if (date)
+ {
+ *date = revoked->date;
+ }
+ if (reason)
+ {
+ *reason = revoked->reason;
+ }
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
METHOD(crl_t, get_serial, chunk_t,
@@ -418,7 +430,7 @@ METHOD(crl_t, create_enumerator, enumerator_t*,
{
return enumerator_create_filter(
this->revoked->create_enumerator(this->revoked),
- (void*)filter, NULL, NULL);
+ filter, NULL, NULL);
}
METHOD(certificate_t, get_type, certificate_type_t,
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
index b46af30fe..140e9bfa9 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -228,32 +228,38 @@ METHOD(ocsp_response_t, create_cert_enumerator, enumerator_t*,
return this->certs->create_enumerator(this->certs);
}
-/**
- * enumerator filter callback for create_response_enumerator
- */
-static bool filter(void *data, single_response_t **response,
- chunk_t *serialNumber,
- void *p2, cert_validation_t *status,
- void *p3, time_t *revocationTime,
- void *p4, crl_reason_t *revocationReason)
+CALLBACK(filter, bool,
+ void *data, enumerator_t *orig, va_list args)
{
- if (serialNumber)
- {
- *serialNumber = (*response)->serialNumber;
- }
- if (status)
- {
- *status = (*response)->status;
- }
- if (revocationTime)
- {
- *revocationTime = (*response)->revocationTime;
- }
- if (revocationReason)
+ single_response_t *response;
+ cert_validation_t *status;
+ crl_reason_t *revocationReason;
+ chunk_t *serialNumber;
+ time_t *revocationTime;
+
+ VA_ARGS_VGET(args, serialNumber, status, revocationTime, revocationReason);
+
+ if (orig->enumerate(orig, &response))
{
- *revocationReason = (*response)->revocationReason;
+ if (serialNumber)
+ {
+ *serialNumber = response->serialNumber;
+ }
+ if (status)
+ {
+ *status = response->status;
+ }
+ if (revocationTime)
+ {
+ *revocationTime = response->revocationTime;
+ }
+ if (revocationReason)
+ {
+ *revocationReason = response->revocationReason;
+ }
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*,
@@ -261,7 +267,7 @@ METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*,
{
return enumerator_create_filter(
this->responses->create_enumerator(this->responses),
- (void*)filter, NULL, NULL);
+ filter, NULL, NULL);
}
/**
diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c
index 20561f7e2..e39e24bff 100644
--- a/src/libstrongswan/plugins/x509/x509_pkcs10.c
+++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c
@@ -1,7 +1,6 @@
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2009 Andreas Steffen
- *
+ * Copyright (C) 2009-2017 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -101,7 +100,8 @@ struct private_x509_pkcs10_t {
/**
* Imported from x509_cert.c
*/
-extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list);
+extern bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
+ linked_list_t *list);
extern chunk_t x509_build_subjectAltNames(linked_list_t *list);
METHOD(certificate_t, get_type, certificate_type_t,
@@ -290,8 +290,11 @@ static bool parse_extension_request(private_x509_pkcs10_t *this, chunk_t blob, i
switch (extn_oid)
{
case OID_SUBJECT_ALT_NAME:
- x509_parse_generalNames(object, level, FALSE,
- this->subjectAltNames);
+ if (!x509_parse_generalNames(object, level, FALSE,
+ this->subjectAltNames))
+ {
+ goto end;
+ }
break;
default:
break;
@@ -303,7 +306,10 @@ static bool parse_extension_request(private_x509_pkcs10_t *this, chunk_t blob, i
}
}
success = parser->success(parser);
+
+end:
parser->destroy(parser);
+
return success;
}