diff options
author | Yves-Alexis Perez <corsac@corsac.net> | 2017-05-30 20:59:31 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@corsac.net> | 2017-05-30 20:59:31 +0200 |
commit | bba25e2ff6c4a193acb54560ea4417537bd2954e (patch) | |
tree | 9e074fe343f9ab6f5ce1e9c5142d9a6cf180fcda /src/libstrongswan/plugins/x509 | |
parent | 05ddd767992d68bb38c7f16ece142e8c2e9ae016 (diff) | |
download | vyos-strongswan-bba25e2ff6c4a193acb54560ea4417537bd2954e.tar.gz vyos-strongswan-bba25e2ff6c4a193acb54560ea4417537bd2954e.zip |
New upstream version 5.5.3
Diffstat (limited to 'src/libstrongswan/plugins/x509')
-rw-r--r-- | src/libstrongswan/plugins/x509/Makefile.in | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_ac.c | 44 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_cert.c | 309 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_crl.c | 54 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_ocsp_response.c | 54 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_pkcs10.c | 16 |
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; } |