diff options
Diffstat (limited to 'src/libstrongswan/plugins/openssl/openssl_x509.c')
-rw-r--r-- | src/libstrongswan/plugins/openssl/openssl_x509.c | 93 |
1 files changed, 54 insertions, 39 deletions
diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c index e03a4255d..60c08770b 100644 --- a/src/libstrongswan/plugins/openssl/openssl_x509.c +++ b/src/libstrongswan/plugins/openssl/openssl_x509.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2011 Tobias Brunner - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2011-2017 Tobias Brunner + * HSR Hochschule fuer Technik Rapperswil * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG @@ -154,7 +154,7 @@ struct private_openssl_x509_t { /** * Signature scheme of the certificate */ - signature_scheme_t scheme; + signature_params_t *scheme; /** * subjectAltNames @@ -189,16 +189,6 @@ struct private_openssl_x509_t { }; /** - * Destroy a CRL URI struct - */ -static void crl_uri_destroy(x509_cdp_t *this) -{ - free(this->uri); - DESTROY_IF(this->issuer); - free(this); -} - -/** * Convert a GeneralName to an identification_t. */ static identification_t *general_name2id(GENERAL_NAME *name) @@ -394,7 +384,7 @@ METHOD(certificate_t, has_issuer, id_match_t, METHOD(certificate_t, issued_by, bool, private_openssl_x509_t *this, certificate_t *issuer, - signature_scheme_t *scheme) + signature_params_t **scheme) { public_key_t *key; bool valid; @@ -406,7 +396,8 @@ METHOD(certificate_t, issued_by, bool, { if (this->flags & X509_SELF_SIGNED) { - return TRUE; + valid = TRUE; + goto out; } } else @@ -424,10 +415,6 @@ METHOD(certificate_t, issued_by, bool, return FALSE; } } - if (this->scheme == SIGN_UNKNOWN) - { - return FALSE; - } key = issuer->get_public_key(issuer); if (!key) { @@ -440,12 +427,15 @@ METHOD(certificate_t, issued_by, bool, tbs = openssl_i2chunk(X509_CINF, this->x509->cert_info); #endif X509_get0_signature(&sig, NULL, this->x509); - valid = key->verify(key, this->scheme, tbs, openssl_asn1_str2chunk(sig)); + valid = key->verify(key, this->scheme->scheme, this->scheme->params, tbs, + openssl_asn1_str2chunk(sig)); free(tbs.ptr); key->destroy(key); + +out: if (valid && scheme) { - *scheme = this->scheme; + *scheme = signature_params_clone(this->scheme); } return valid; } @@ -538,6 +528,7 @@ METHOD(certificate_t, destroy, void, { X509_free(this->x509); } + signature_params_destroy(this->scheme); DESTROY_IF(this->subject); DESTROY_IF(this->issuer); DESTROY_IF(this->pubkey); @@ -549,7 +540,8 @@ METHOD(certificate_t, destroy, void, offsetof(identification_t, destroy)); this->issuerAltNames->destroy_offset(this->issuerAltNames, offsetof(identification_t, destroy)); - this->crl_uris->destroy_function(this->crl_uris, (void*)crl_uri_destroy); + this->crl_uris->destroy_function(this->crl_uris, + (void*)x509_cdp_destroy); this->ocsp_uris->destroy_function(this->ocsp_uris, free); this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks, offsetof(traffic_selector_t, destroy)); @@ -739,15 +731,15 @@ static bool parse_extKeyUsage_ext(private_openssl_x509_t *this, /** * Parse CRL distribution points */ -static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this, - X509_EXTENSION *ext) +bool openssl_parse_crlDistributionPoints(X509_EXTENSION *ext, + linked_list_t *list) { CRL_DIST_POINTS *cdps; DIST_POINT *cdp; identification_t *id, *issuer; x509_cdp_t *entry; char *uri; - int i, j, k, point_num, name_num, issuer_num; + int i, j, k, point_num, name_num, issuer_num, len; cdps = X509V3_EXT_d2i(ext); if (!cdps) @@ -770,7 +762,12 @@ static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this, cdp->distpoint->name.fullname, j)); if (id) { - if (asprintf(&uri, "%Y", id) > 0) + len = asprintf(&uri, "%Y", id); + if (!len) + { + free(uri); + } + else if (len > 0) { if (cdp->CRLissuer) { @@ -785,8 +782,7 @@ static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this, .uri = strdup(uri), .issuer = issuer, ); - this->crl_uris->insert_last( - this->crl_uris, entry); + list->insert_last(list, entry); } } free(uri); @@ -796,7 +792,7 @@ static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this, INIT(entry, .uri = uri, ); - this->crl_uris->insert_last(this->crl_uris, entry); + list->insert_last(list, entry); } } id->destroy(id); @@ -820,7 +816,7 @@ static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this, AUTHORITY_INFO_ACCESS *infos; ACCESS_DESCRIPTION *desc; identification_t *id; - int i, num; + int i, num, len; char *uri; infos = X509V3_EXT_d2i(ext); @@ -839,7 +835,12 @@ static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this, id = general_name2id(desc->location); if (id) { - if (asprintf(&uri, "%Y", id) > 0) + len = asprintf(&uri, "%Y", id); + if (!len) + { + free(uri); + } + else if (len > 0) { this->ocsp_uris->insert_last(this->ocsp_uris, uri); } @@ -1025,7 +1026,7 @@ static bool parse_extensions(private_openssl_x509_t *this) ok = parse_extKeyUsage_ext(this, ext); break; case NID_crl_distribution_points: - ok = parse_crlDistributionPoints_ext(this, ext); + ok = openssl_parse_crlDistributionPoints(ext, this->crl_uris); break; #ifndef OPENSSL_NO_RFC3779 case NID_sbgp_ipAddrBlock: @@ -1063,8 +1064,8 @@ static bool parse_certificate(private_openssl_x509_t *this) { const unsigned char *ptr = this->encoding.ptr; hasher_t *hasher; - chunk_t chunk; - ASN1_OBJECT *oid, *oid_tbs; + chunk_t chunk, sig_scheme, sig_scheme_tbs; + ASN1_OBJECT *oid; X509_ALGOR *alg; this->x509 = d2i_X509(NULL, &ptr, this->encoding.len); @@ -1089,6 +1090,10 @@ static bool parse_certificate(private_openssl_x509_t *this) } switch (openssl_asn1_known_oid(oid)) { + case OID_RSASSA_PSS: + /* TODO: we should treat such keys special and use the params as + * restrictions regarding the use of this key (or rather the + * associated private key) */ case OID_RSA_ENCRYPTION: this->pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, BUILD_BLOB_ASN1_DER, @@ -1119,15 +1124,25 @@ static bool parse_certificate(private_openssl_x509_t *this) /* while X509_ALGOR_cmp() is declared in the headers of older OpenSSL * versions, at least on Ubuntu 14.04 it is not actually defined */ X509_get0_signature(NULL, &alg, this->x509); - X509_ALGOR_get0(&oid, NULL, NULL, alg); + sig_scheme = openssl_i2chunk(X509_ALGOR, alg); alg = X509_get0_tbs_sigalg(this->x509); - X509_ALGOR_get0(&oid_tbs, NULL, NULL, alg); - if (!chunk_equals(openssl_asn1_obj2chunk(oid), - openssl_asn1_obj2chunk(oid_tbs))) + sig_scheme_tbs = openssl_i2chunk(X509_ALGOR, alg); + if (!chunk_equals(sig_scheme, sig_scheme_tbs)) + { + free(sig_scheme_tbs.ptr); + free(sig_scheme.ptr); + return FALSE; + } + free(sig_scheme_tbs.ptr); + + INIT(this->scheme); + if (!signature_params_parse(sig_scheme, 0, this->scheme)) { + DBG1(DBG_ASN, "unable to parse signature algorithm"); + free(sig_scheme.ptr); return FALSE; } - this->scheme = signature_scheme_from_oid(openssl_asn1_known_oid(oid)); + free(sig_scheme.ptr); if (!parse_extensions(this)) { |