diff options
Diffstat (limited to 'src/libstrongswan/credentials')
18 files changed, 742 insertions, 99 deletions
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index 07da596e4..d1be7b401 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2016 Tobias Brunner + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2007-2009 Martin Willi * Copyright (C) 2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil @@ -216,8 +216,6 @@ static void init_entry(entry_t *this, auth_rule_t type, va_list args) case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: case AUTH_RULE_BLISS_STRENGTH: - case AUTH_RULE_SIGNATURE_SCHEME: - case AUTH_RULE_IKE_SIGNATURE_SCHEME: case AUTH_RULE_CERT_VALIDATION_SUSPENDED: /* integer type */ this->value = (void*)(uintptr_t)va_arg(args, u_int); @@ -232,6 +230,8 @@ static void init_entry(entry_t *this, auth_rule_t type, va_list args) case AUTH_RULE_IM_CERT: case AUTH_RULE_SUBJECT_CERT: case AUTH_RULE_CERT_POLICY: + case AUTH_RULE_SIGNATURE_SCHEME: + case AUTH_RULE_IKE_SIGNATURE_SCHEME: case AUTH_HELPER_IM_CERT: case AUTH_HELPER_SUBJECT_CERT: case AUTH_HELPER_IM_HASH_URL: @@ -267,8 +267,6 @@ static bool entry_equals(entry_t *e1, entry_t *e2) case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: case AUTH_RULE_BLISS_STRENGTH: - case AUTH_RULE_SIGNATURE_SCHEME: - case AUTH_RULE_IKE_SIGNATURE_SCHEME: case AUTH_RULE_CERT_VALIDATION_SUSPENDED: { return e1->value == e2->value; @@ -301,6 +299,11 @@ static bool entry_equals(entry_t *e1, entry_t *e2) return id1->equals(id1, id2); } + case AUTH_RULE_SIGNATURE_SCHEME: + case AUTH_RULE_IKE_SIGNATURE_SCHEME: + { + return signature_params_equal(e1->value, e2->value); + } case AUTH_RULE_CERT_POLICY: case AUTH_RULE_XAUTH_BACKEND: case AUTH_HELPER_IM_HASH_URL: @@ -351,6 +354,12 @@ static void destroy_entry_value(entry_t *entry) free(entry->value); break; } + case AUTH_RULE_SIGNATURE_SCHEME: + case AUTH_RULE_IKE_SIGNATURE_SCHEME: + { + signature_params_destroy(entry->value); + break; + } case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: @@ -360,8 +369,6 @@ static void destroy_entry_value(entry_t *entry) case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: case AUTH_RULE_BLISS_STRENGTH: - case AUTH_RULE_SIGNATURE_SCHEME: - case AUTH_RULE_IKE_SIGNATURE_SCHEME: case AUTH_RULE_CERT_VALIDATION_SUSPENDED: case AUTH_RULE_MAX: break; @@ -394,8 +401,6 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator, case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: case AUTH_RULE_BLISS_STRENGTH: - case AUTH_RULE_SIGNATURE_SCHEME: - case AUTH_RULE_IKE_SIGNATURE_SCHEME: case AUTH_RULE_CERT_VALIDATION_SUSPENDED: /* integer type */ entry->value = (void*)(uintptr_t)va_arg(args, u_int); @@ -410,6 +415,8 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator, case AUTH_RULE_IM_CERT: case AUTH_RULE_SUBJECT_CERT: case AUTH_RULE_CERT_POLICY: + case AUTH_RULE_SIGNATURE_SCHEME: + case AUTH_RULE_IKE_SIGNATURE_SCHEME: case AUTH_HELPER_IM_CERT: case AUTH_HELPER_SUBJECT_CERT: case AUTH_HELPER_IM_HASH_URL: @@ -472,9 +479,6 @@ METHOD(auth_cfg_t, get, void*, case AUTH_RULE_ECDSA_STRENGTH: case AUTH_RULE_BLISS_STRENGTH: return (void*)0; - case AUTH_RULE_SIGNATURE_SCHEME: - case AUTH_RULE_IKE_SIGNATURE_SCHEME: - return (void*)HASH_UNKNOWN; case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: return (void*)VALIDATION_FAILED; @@ -491,6 +495,8 @@ METHOD(auth_cfg_t, get, void*, case AUTH_RULE_IM_CERT: case AUTH_RULE_SUBJECT_CERT: case AUTH_RULE_CERT_POLICY: + case AUTH_RULE_SIGNATURE_SCHEME: + case AUTH_RULE_IKE_SIGNATURE_SCHEME: case AUTH_HELPER_IM_CERT: case AUTH_HELPER_SUBJECT_CERT: case AUTH_HELPER_IM_HASH_URL: @@ -526,18 +532,46 @@ static void add(private_auth_cfg_t *this, auth_rule_t type, ...) } } +/** + * Create a constraint for RSA/PSS signatures + */ +static signature_params_t *create_rsa_pss_constraint(char *token) +{ + signature_params_t *params = NULL; + hash_algorithm_t hash; + + if (enum_from_name(hash_algorithm_short_names, token, &hash)) + { + rsa_pss_params_t pss = { + .hash = hash, + .mgf1_hash = hash, + .salt_len = RSA_PSS_SALT_LEN_DEFAULT, + }; + signature_params_t pss_params = { + .scheme = SIGN_RSA_EMSA_PSS, + .params = &pss, + }; + params = signature_params_clone(&pss_params); + } + return params; +} + METHOD(auth_cfg_t, add_pubkey_constraints, void, private_auth_cfg_t *this, char* constraints, bool ike) { enumerator_t *enumerator; - bool is_ike = FALSE, ike_added = FALSE; + bool ike_added = FALSE, rsa_pss; key_type_t expected_type = -1; auth_rule_t expected_strength = AUTH_RULE_MAX; + signature_params_t *params; int strength; - char *token; + char *token, *key_token = NULL; auth_rule_t type; void *value; + rsa_pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE, + lib->ns); + enumerator = enumerator_create_token(constraints, "-", ""); while (enumerator->enumerate(enumerator, &token)) { @@ -583,67 +617,117 @@ METHOD(auth_cfg_t, add_pubkey_constraints, void, } if (streq(token, "rsa") || streq(token, "ike:rsa")) { + key_token = token; + expected_type = KEY_RSA; + expected_strength = AUTH_RULE_RSA_STRENGTH; + continue; + } + if (streq(token, "rsa/pss") || streq(token, "ike:rsa/pss")) + { + key_token = token; expected_type = KEY_RSA; expected_strength = AUTH_RULE_RSA_STRENGTH; - is_ike = strpfx(token, "ike:"); continue; } if (streq(token, "ecdsa") || streq(token, "ike:ecdsa")) { + key_token = token; expected_type = KEY_ECDSA; expected_strength = AUTH_RULE_ECDSA_STRENGTH; - is_ike = strpfx(token, "ike:"); continue; } if (streq(token, "ed25519") || streq(token, "ike:ed25519")) { + key_token = token; expected_type = KEY_ED25519; - is_ike = strpfx(token, "ike:"); continue; } if (streq(token, "ed448") || streq(token, "ike:ed448")) { + key_token = token; expected_type = KEY_ED448; - is_ike = strpfx(token, "ike:"); continue; } if (streq(token, "bliss") || streq(token, "ike:bliss")) { + key_token = token; expected_type = KEY_BLISS; expected_strength = AUTH_RULE_BLISS_STRENGTH; - is_ike = strpfx(token, "ike:"); continue; } if (streq(token, "pubkey") || streq(token, "ike:pubkey")) { + key_token = token; expected_type = KEY_ANY; - is_ike = strpfx(token, "ike:"); continue; } - if (is_ike && !ike) + if (key_token && strpfx(key_token, "ike:") && !ike) { continue; } - for (i = 0; i < countof(schemes); i++) + if (key_token && streq(key_token + strlen(key_token) - 3, "pss")) + { + params = create_rsa_pss_constraint(token); + if (params) + { + if (strpfx(key_token, "ike:")) + { + add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params); + ike_added = TRUE; + } + else + { + add(this, AUTH_RULE_SIGNATURE_SCHEME, params); + } + found = TRUE; + } + } + else { - if (streq(schemes[i].name, token)) + if (rsa_pss) { - if (expected_type == KEY_ANY || expected_type == schemes[i].key) + if (expected_type == KEY_ANY || + expected_type == KEY_RSA) { - if (is_ike) + params = create_rsa_pss_constraint(token); + if (params) { - add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, - (uintptr_t)schemes[i].scheme); - ike_added = TRUE; + if (strpfx(key_token, "ike:")) + { + add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params); + ike_added = TRUE; + } + else + { + add(this, AUTH_RULE_SIGNATURE_SCHEME, params); + } + found = TRUE; } - else + } + } + for (i = 0; i < countof(schemes); i++) + { + if (streq(schemes[i].name, token)) + { + if (expected_type == KEY_ANY || + expected_type == schemes[i].key) { - add(this, AUTH_RULE_SIGNATURE_SCHEME, - (uintptr_t)schemes[i].scheme); + INIT(params, + .scheme = schemes[i].scheme, + ); + if (strpfx(key_token, "ike:")) + { + add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params); + ike_added = TRUE; + } + else + { + add(this, AUTH_RULE_SIGNATURE_SCHEME, params); + } } + found = TRUE; } - found = TRUE; } } if (!found) @@ -666,7 +750,7 @@ METHOD(auth_cfg_t, add_pubkey_constraints, void, if (type == AUTH_RULE_SIGNATURE_SCHEME) { add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, - (uintptr_t)value); + signature_params_clone(value)); } } enumerator->destroy(enumerator); @@ -681,20 +765,20 @@ static bool complies_scheme(private_auth_cfg_t *this, auth_cfg_t *constraints, { enumerator_t *e1, *e2; auth_rule_t t1, t2; - signature_scheme_t scheme; - void *value; + signature_params_t *params, *constraint; bool success = TRUE; e2 = create_enumerator(this); - while (e2->enumerate(e2, &t2, &scheme)) + while (e2->enumerate(e2, &t2, ¶ms)) { if (t2 == type) { success = FALSE; e1 = constraints->create_enumerator(constraints); - while (e1->enumerate(e1, &t1, &value)) + while (e1->enumerate(e1, &t1, &constraint)) { - if (t1 == type && (uintptr_t)value == scheme) + if (t1 == type && + signature_params_comply(constraint, params)) { success = TRUE; break; @@ -707,7 +791,7 @@ static bool complies_scheme(private_auth_cfg_t *this, auth_cfg_t *constraints, { DBG1(DBG_CFG, "%s signature scheme %N not acceptable", AUTH_RULE_SIGNATURE_SCHEME == type ? "X.509" : "IKE", - signature_scheme_names, (int)scheme); + signature_scheme_names, params->scheme); } break; } @@ -725,7 +809,7 @@ METHOD(auth_cfg_t, complies, bool, bool ca_match = FALSE, cert_match = FALSE; identification_t *require_group = NULL; certificate_t *require_ca = NULL, *require_cert = NULL; - signature_scheme_t ike_scheme = SIGN_UNKNOWN, scheme = SIGN_UNKNOWN; + signature_params_t *ike_scheme = NULL, *scheme = NULL; u_int strength = 0; auth_rule_t t1, t2; char *key_type; @@ -928,12 +1012,12 @@ METHOD(auth_cfg_t, complies, bool, } case AUTH_RULE_IKE_SIGNATURE_SCHEME: { - ike_scheme = (uintptr_t)value; + ike_scheme = value; break; } case AUTH_RULE_SIGNATURE_SCHEME: { - scheme = (uintptr_t)value; + scheme = value; break; } case AUTH_RULE_CERT_POLICY: @@ -983,12 +1067,12 @@ METHOD(auth_cfg_t, complies, bool, /* Check if we have a matching constraint (or none at all) for used * signature schemes. */ - if (success && scheme != SIGN_UNKNOWN) + if (success && scheme) { success = complies_scheme(this, constraints, AUTH_RULE_SIGNATURE_SCHEME, log_error); } - if (success && ike_scheme != SIGN_UNKNOWN) + if (success && ike_scheme) { success = complies_scheme(this, constraints, AUTH_RULE_IKE_SIGNATURE_SCHEME, log_error); @@ -1114,8 +1198,6 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: case AUTH_RULE_BLISS_STRENGTH: - case AUTH_RULE_SIGNATURE_SCHEME: - case AUTH_RULE_IKE_SIGNATURE_SCHEME: case AUTH_RULE_CERT_VALIDATION_SUSPENDED: { add(this, type, (uintptr_t)value); @@ -1132,6 +1214,12 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy add(this, type, id->clone(id)); break; } + case AUTH_RULE_SIGNATURE_SCHEME: + case AUTH_RULE_IKE_SIGNATURE_SCHEME: + { + add(this, type, signature_params_clone(value)); + break; + } case AUTH_RULE_XAUTH_BACKEND: case AUTH_RULE_CERT_POLICY: case AUTH_HELPER_IM_HASH_URL: @@ -1286,11 +1374,15 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: case AUTH_RULE_BLISS_STRENGTH: - case AUTH_RULE_SIGNATURE_SCHEME: - case AUTH_RULE_IKE_SIGNATURE_SCHEME: case AUTH_RULE_CERT_VALIDATION_SUSPENDED: clone->add(clone, type, (uintptr_t)value); break; + case AUTH_RULE_SIGNATURE_SCHEME: + case AUTH_RULE_IKE_SIGNATURE_SCHEME: + { + clone->add(clone, type, signature_params_clone(value)); + break; + } case AUTH_RULE_MAX: break; } diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h index 7191dc1bc..2eb448546 100644 --- a/src/libstrongswan/credentials/auth_cfg.h +++ b/src/libstrongswan/credentials/auth_cfg.h @@ -106,9 +106,9 @@ enum auth_rule_t { AUTH_RULE_ECDSA_STRENGTH, /** required BLISS public key strength, u_int in bits */ AUTH_RULE_BLISS_STRENGTH, - /** required signature scheme, signature_scheme_t */ + /** required signature scheme, signature_params_t* */ AUTH_RULE_SIGNATURE_SCHEME, - /** required signature scheme for IKE authentication, signature_scheme_t */ + /** required signature scheme for IKE authentication, signature_params_t* */ AUTH_RULE_IKE_SIGNATURE_SCHEME, /** certificatePolicy constraint, numerical OID as char* */ AUTH_RULE_CERT_POLICY, diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c index baa17c47d..0239ee17e 100644 --- a/src/libstrongswan/credentials/builder.c +++ b/src/libstrongswan/credentials/builder.c @@ -37,6 +37,7 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END, "BUILD_NOT_BEFORE_TIME", "BUILD_NOT_AFTER_TIME", "BUILD_SERIAL", + "BUILD_SIGNATURE_SCHEME", "BUILD_DIGEST_ALG", "BUILD_ENCRYPTION_ALG", "BUILD_AC_GROUP_STRINGS", diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h index 1c6f5001b..7928ef487 100644 --- a/src/libstrongswan/credentials/builder.h +++ b/src/libstrongswan/credentials/builder.h @@ -56,7 +56,7 @@ enum builder_part_t { BUILD_BLOB_PEM, /** OpenPGP key blob, chunk_t */ BUILD_BLOB_PGP, - /** DNS public key blob (RFC 4034, RSA specifc RFC 3110), chunk_t */ + /** DNS public key blob (RFC 4034, RSA specific RFC 3110), chunk_t */ BUILD_BLOB_DNSKEY, /** SSH public key blob (RFC 4253), chunk_t */ BUILD_BLOB_SSHKEY, @@ -84,6 +84,8 @@ enum builder_part_t { BUILD_NOT_AFTER_TIME, /** a serial number in binary form, chunk_t */ BUILD_SERIAL, + /** signature scheme and parameters for signature, signature_params_t* */ + BUILD_SIGNATURE_SCHEME, /** digest algorithm to be used for signature, hash_algorithm_t */ BUILD_DIGEST_ALG, /** encryption algorithm to use, encryption_algorithm_t */ diff --git a/src/libstrongswan/credentials/certificates/certificate.h b/src/libstrongswan/credentials/certificates/certificate.h index d59126bd5..6dc5c7694 100644 --- a/src/libstrongswan/credentials/certificates/certificate.h +++ b/src/libstrongswan/credentials/certificates/certificate.h @@ -25,9 +25,9 @@ typedef struct certificate_t certificate_t; typedef enum certificate_type_t certificate_type_t; typedef enum cert_validation_t cert_validation_t; -#include <library.h> #include <utils/identification.h> #include <credentials/keys/public_key.h> +#include <credentials/keys/signature_params.h> #include <credentials/cred_encoding.h> /** @@ -139,11 +139,12 @@ struct certificate_t { * Check if this certificate is issued and signed by a specific issuer. * * @param issuer issuer's certificate - * @param scheme receives signature scheme used during verification + * @param scheme receives used signature scheme and parameters, if + * given (allocated) * @return TRUE if certificate issued by issuer and trusted */ bool (*issued_by)(certificate_t *this, certificate_t *issuer, - signature_scheme_t *scheme); + signature_params_t **scheme); /** * Get the public key associated to this certificate. diff --git a/src/libstrongswan/credentials/certificates/x509.c b/src/libstrongswan/credentials/certificates/x509.c index 5eefa0bb4..d39ba1997 100644 --- a/src/libstrongswan/credentials/certificates/x509.c +++ b/src/libstrongswan/credentials/certificates/x509.c @@ -25,3 +25,12 @@ ENUM_NEXT(x509_flag_names, X509_ANY, X509_ANY, X509_OCSP_SIGNER, "ANY"); ENUM_END(x509_flag_names, X509_ANY); +/* + * Described in header + */ +void x509_cdp_destroy(x509_cdp_t *this) +{ + free(this->uri); + DESTROY_IF(this->issuer); + free(this); +} diff --git a/src/libstrongswan/credentials/certificates/x509.h b/src/libstrongswan/credentials/certificates/x509.h index 601c034ef..2c640e2da 100644 --- a/src/libstrongswan/credentials/certificates/x509.h +++ b/src/libstrongswan/credentials/certificates/x509.h @@ -210,8 +210,11 @@ struct x509_t { * @return enumerator over x509_policy_mapping */ enumerator_t* (*create_policy_mapping_enumerator)(x509_t *this); - - }; +/** + * Destroy an x509_cdp_t instance. + */ +void x509_cdp_destroy(x509_cdp_t *this); + #endif /** X509_H_ @}*/ diff --git a/src/libstrongswan/credentials/containers/pkcs12.c b/src/libstrongswan/credentials/containers/pkcs12.c index 9e7815d04..8cc6a6c63 100644 --- a/src/libstrongswan/credentials/containers/pkcs12.c +++ b/src/libstrongswan/credentials/containers/pkcs12.c @@ -15,6 +15,7 @@ #include "pkcs12.h" +#include <library.h> #include <utils/debug.h> /** diff --git a/src/libstrongswan/credentials/cred_encoding.h b/src/libstrongswan/credentials/cred_encoding.h index 0b6536430..1129357ba 100644 --- a/src/libstrongswan/credentials/cred_encoding.h +++ b/src/libstrongswan/credentials/cred_encoding.h @@ -25,7 +25,7 @@ typedef struct cred_encoding_t cred_encoding_t; typedef enum cred_encoding_type_t cred_encoding_type_t; typedef enum cred_encoding_part_t cred_encoding_part_t; -#include <library.h> +#include <utils/chunk.h> /** * Credential encoder function implementing encoding/fingerprinting. diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index 9be7407ef..21b23f543 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -488,7 +488,7 @@ METHOD(credential_manager_t, remove_local_set, void, METHOD(credential_manager_t, issued_by, bool, private_credential_manager_t *this, certificate_t *subject, - certificate_t *issuer, signature_scheme_t *scheme) + certificate_t *issuer, signature_params_t **scheme) { if (this->cache) { @@ -661,7 +661,7 @@ static certificate_t *get_pretrusted_cert(private_credential_manager_t *this, */ static certificate_t *get_issuer_cert(private_credential_manager_t *this, certificate_t *subject, bool trusted, - signature_scheme_t *scheme) + signature_params_t **scheme) { enumerator_t *enumerator; certificate_t *issuer = NULL, *candidate; @@ -723,7 +723,7 @@ static bool verify_trust_chain(private_credential_manager_t *this, { certificate_t *current, *issuer; auth_cfg_t *auth; - signature_scheme_t scheme; + signature_params_t *scheme; int pathlen; auth = auth_cfg_create(); diff --git a/src/libstrongswan/credentials/credential_manager.h b/src/libstrongswan/credentials/credential_manager.h index 022ca566c..d99f29b85 100644 --- a/src/libstrongswan/credentials/credential_manager.h +++ b/src/libstrongswan/credentials/credential_manager.h @@ -241,12 +241,13 @@ struct credential_manager_t { * * @param subject subject certificate to check * @param issuer issuer certificate that potentially has signed subject - * @param scheme receives used signature scheme, if given + * @param scheme receives used signature scheme and parameters, if + * given (allocated) * @return TRUE if issuer signed subject */ bool (*issued_by)(credential_manager_t *this, certificate_t *subject, certificate_t *issuer, - signature_scheme_t *scheme); + signature_params_t **scheme); /** * Register a credential set to the manager. diff --git a/src/libstrongswan/credentials/keys/private_key.h b/src/libstrongswan/credentials/keys/private_key.h index b9f7dad55..d7cfdd74d 100644 --- a/src/libstrongswan/credentials/keys/private_key.h +++ b/src/libstrongswan/credentials/keys/private_key.h @@ -1,6 +1,7 @@ /* + * Copyright (C) 2017 Tobias Brunner * Copyright (C) 2007 Martin Willi - * 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 @@ -42,11 +43,12 @@ struct private_key_t { * Create a signature over a chunk of data. * * @param scheme signature scheme to use + * @param params optional parameters required by the specified scheme * @param data chunk of data to sign * @param signature where to allocate created signature * @return TRUE if signature created */ - bool (*sign)(private_key_t *this, signature_scheme_t scheme, + bool (*sign)(private_key_t *this, signature_scheme_t scheme, void *params, chunk_t data, chunk_t *signature); /** * Decrypt a chunk of data. diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c index 87f7e6664..89fa9b348 100644 --- a/src/libstrongswan/credentials/keys/public_key.c +++ b/src/libstrongswan/credentials/keys/public_key.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2015 Tobias Brunner - * Copyright (C) 2007 Martin Willi + * Copyright (C) 2015-2017 Tobias Brunner * Copyright (C) 2014-2016 Andreas Steffen + * Copyright (C) 2007 Martin Willi * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,6 +18,7 @@ #include <asn1/oid.h> #include "public_key.h" +#include "signature_params.h" ENUM(key_type_names, KEY_ANY, KEY_BLISS, "ANY", @@ -42,6 +43,7 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_BLISS_WITH_SHA3_512, "RSA_EMSA_PKCS1_SHA3_256", "RSA_EMSA_PKCS1_SHA3_384", "RSA_EMSA_PKCS1_SHA3_512", + "RSA_EMSA_PSS", "ECDSA_WITH_SHA1_DER", "ECDSA_WITH_SHA256_DER", "ECDSA_WITH_SHA384_DER", @@ -146,6 +148,8 @@ signature_scheme_t signature_scheme_from_oid(int oid) return SIGN_RSA_EMSA_PKCS1_SHA3_384; case OID_RSASSA_PKCS1V15_WITH_SHA3_512: return SIGN_RSA_EMSA_PKCS1_SHA3_512; + case OID_RSASSA_PSS: + return SIGN_RSA_EMSA_PSS; case OID_ECDSA_WITH_SHA1: case OID_EC_PUBLICKEY: return SIGN_ECDSA_WITH_SHA1_DER; @@ -210,6 +214,8 @@ int signature_scheme_to_oid(signature_scheme_t scheme) return OID_RSASSA_PKCS1V15_WITH_SHA3_384; case SIGN_RSA_EMSA_PKCS1_SHA3_512: return OID_RSASSA_PKCS1V15_WITH_SHA3_384; + case SIGN_RSA_EMSA_PSS: + return OID_RSASSA_PSS; case SIGN_ECDSA_WITH_SHA1_DER: return OID_ECDSA_WITH_SHA1; case SIGN_ECDSA_WITH_SHA256_DER: @@ -239,26 +245,42 @@ int signature_scheme_to_oid(signature_scheme_t scheme) } /** + * Parameters for RSA/PSS signature schemes + */ +#define PSS_PARAMS(bits) static rsa_pss_params_t pss_params_sha##bits = { \ + .hash = HASH_SHA##bits, \ + .mgf1_hash = HASH_SHA##bits, \ + .salt_len = RSA_PSS_SALT_LEN_DEFAULT, \ +} + +PSS_PARAMS(256); +PSS_PARAMS(384); +PSS_PARAMS(512); + +/** * Map for signature schemes to the key type and maximum key size allowed. * We only cover schemes with hash algorithms supported by IKEv2 signature * authentication. */ static struct { - signature_scheme_t scheme; key_type_t type; int max_keysize; + signature_params_t params; } scheme_map[] = { - { SIGN_RSA_EMSA_PKCS1_SHA2_256, KEY_RSA, 3072 }, - { SIGN_RSA_EMSA_PKCS1_SHA2_384, KEY_RSA, 7680 }, - { SIGN_RSA_EMSA_PKCS1_SHA2_512, KEY_RSA, 0 }, - { SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, 256 }, - { SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, 384 }, - { SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, 0 }, - { SIGN_ED25519, KEY_ED25519, 0 }, - { SIGN_ED448, KEY_ED448, 0 }, - { SIGN_BLISS_WITH_SHA2_256, KEY_BLISS, 128 }, - { SIGN_BLISS_WITH_SHA2_384, KEY_BLISS, 192 }, - { SIGN_BLISS_WITH_SHA2_512, KEY_BLISS, 0 } + { KEY_RSA, 3072, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha256, }}, + { KEY_RSA, 7680, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha384, }}, + { KEY_RSA, 0, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha512, }}, + { KEY_RSA, 3072, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_256 }}, + { KEY_RSA, 7680, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_384 }}, + { KEY_RSA, 0, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_512 }}, + { KEY_ECDSA, 256, { .scheme = SIGN_ECDSA_WITH_SHA256_DER }}, + { KEY_ECDSA, 384, { .scheme = SIGN_ECDSA_WITH_SHA384_DER }}, + { KEY_ECDSA, 0, { .scheme = SIGN_ECDSA_WITH_SHA512_DER }}, + { KEY_ED25519, 0, { .scheme = SIGN_ED25519 }}, + { KEY_ED448, 0, { .scheme = SIGN_ED448 }}, + { KEY_BLISS, 128, { .scheme = SIGN_BLISS_WITH_SHA2_256 }}, + { KEY_BLISS, 192, { .scheme = SIGN_BLISS_WITH_SHA2_384 }}, + { KEY_BLISS, 0, { .scheme = SIGN_BLISS_WITH_SHA2_512 }}, }; /** @@ -274,9 +296,9 @@ typedef struct { METHOD(enumerator_t, signature_schemes_enumerate, bool, private_enumerator_t *this, va_list args) { - signature_scheme_t *scheme; + signature_params_t **params; - VA_ARGS_VGET(args, scheme); + VA_ARGS_VGET(args, params); while (++this->index < countof(scheme_map)) { @@ -284,7 +306,7 @@ METHOD(enumerator_t, signature_schemes_enumerate, bool, (this->size <= scheme_map[this->index].max_keysize || !scheme_map[this->index].max_keysize)) { - *scheme = scheme_map[this->index].scheme; + *params = &scheme_map[this->index].params; return TRUE; } } @@ -332,6 +354,7 @@ key_type_t key_type_from_signature_scheme(signature_scheme_t scheme) case SIGN_RSA_EMSA_PKCS1_SHA3_256: case SIGN_RSA_EMSA_PKCS1_SHA3_384: case SIGN_RSA_EMSA_PKCS1_SHA3_512: + case SIGN_RSA_EMSA_PSS: return KEY_RSA; case SIGN_ECDSA_WITH_SHA1_DER: case SIGN_ECDSA_WITH_SHA256_DER: diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h index 06c1aa488..877ed20a2 100644 --- a/src/libstrongswan/credentials/keys/public_key.h +++ b/src/libstrongswan/credentials/keys/public_key.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2015 Tobias Brunner - * Copyright (C) 2007 Martin Willi + * Copyright (C) 2015-2017 Tobias Brunner * Copyright (C) 2014-2017 Andreas Steffen + * Copyright (C) 2007 Martin Willi * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ typedef enum key_type_t key_type_t; typedef enum signature_scheme_t signature_scheme_t; typedef enum encryption_scheme_t encryption_scheme_t; -#include <library.h> #include <utils/identification.h> #include <credentials/cred_encoding.h> @@ -89,6 +88,8 @@ enum signature_scheme_t { SIGN_RSA_EMSA_PKCS1_SHA3_384, /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-3_512 */ SIGN_RSA_EMSA_PKCS1_SHA3_512, + /** EMSA-PSS signature as in PKCS#1 using RSA */ + SIGN_RSA_EMSA_PSS, /** ECDSA with SHA-1 using DER encoding as in RFC 3279 */ SIGN_ECDSA_WITH_SHA1_DER, /** ECDSA with SHA-256 using DER encoding as in RFC 3279 */ @@ -168,12 +169,13 @@ struct public_key_t { /** * Verifies a signature against a chunk of data. * - * @param scheme signature scheme to use for verification, may be default + * @param scheme signature scheme to use for verification + * @param params optional parameters required by the specified scheme * @param data data to check signature against * @param signature signature to check * @return TRUE if signature matches */ - bool (*verify)(public_key_t *this, signature_scheme_t scheme, + bool (*verify)(public_key_t *this, signature_scheme_t scheme, void *params, chunk_t data, chunk_t signature); /** @@ -279,11 +281,11 @@ int signature_scheme_to_oid(signature_scheme_t scheme); /** * Enumerate signature schemes that are appropriate for a key of the given type - * and size|strength. + * and size|strength ordered by increasing strength. * * @param type type of the key * @param size size or strength of the key - * @return enumerator over signature_scheme_t (increasing strength) + * @return enumerator over signature_params_t* (by strength) */ enumerator_t *signature_schemes_for_key(key_type_t type, int size); diff --git a/src/libstrongswan/credentials/keys/signature_params.c b/src/libstrongswan/credentials/keys/signature_params.c new file mode 100644 index 000000000..6b4d22e7b --- /dev/null +++ b/src/libstrongswan/credentials/keys/signature_params.c @@ -0,0 +1,366 @@ +/* + * Copyright (C) 2017 Tobias Brunner + * 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 + * 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. + */ + +#include "signature_params.h" + +#include <asn1/oid.h> +#include <asn1/asn1_parser.h> + +/** + * Determine the salt length in case it is not configured + */ +static ssize_t rsa_pss_salt_length(rsa_pss_params_t *pss) +{ + ssize_t salt_len = pss->salt_len; + + if (salt_len <= RSA_PSS_SALT_LEN_DEFAULT) + { + salt_len = hasher_hash_size(pss->hash); + if (!salt_len) + { + return -1; + } + } + return salt_len; +} + +/** + * Compare two signature schemes and their parameters + */ +static bool compare_params(signature_params_t *a, signature_params_t *b, + bool strict) +{ + if (!a && !b) + { + return TRUE; + } + if (!a || !b) + { + return FALSE; + } + if (a->scheme != b->scheme) + { + return FALSE; + } + if (!a->params && !b->params) + { + return TRUE; + } + if (a->params && b->params) + { + switch (a->scheme) + { + case SIGN_RSA_EMSA_PSS: + { + rsa_pss_params_t *pss_a = a->params, *pss_b = b->params; + + return pss_a->hash == pss_b->hash && + pss_a->mgf1_hash == pss_b->mgf1_hash && + (!strict || + rsa_pss_salt_length(pss_a) == rsa_pss_salt_length(pss_b)); + } + default: + break; + } + } + return FALSE; +} + +/* + * Described in header + */ +bool signature_params_equal(signature_params_t *a, signature_params_t *b) +{ + return compare_params(a, b, TRUE); +} + +/* + * Described in header + */ +bool signature_params_comply(signature_params_t *c, signature_params_t *s) +{ /* the salt is variable, so it does not necessarily have to be the same */ + return compare_params(c, s, FALSE); +} + +/* + * Described in header + */ +signature_params_t *signature_params_clone(signature_params_t *this) +{ + signature_params_t *clone; + + if (!this) + { + return NULL; + } + + INIT(clone, + .scheme = this->scheme, + ); + if (this->params) + { + switch (this->scheme) + { + case SIGN_RSA_EMSA_PSS: + { + rsa_pss_params_t *pss, *pss_clone; + + pss = this->params; + INIT(pss_clone, + .hash = pss->hash, + .mgf1_hash = pss->mgf1_hash, + .salt_len = pss->salt_len, + /* ignore salt as only used for unit tests */ + ); + clone->params = pss_clone; + break; + } + default: + break; + } + } + return clone; +} + +/* + * Described in header + */ +void signature_params_destroy(signature_params_t *this) +{ + if (this) + { + free(this->params); + free(this); + } +} + +/* + * Described in header + */ +void signature_params_clear(signature_params_t *this) +{ + if (this) + { + free(this->params); + this->params = NULL; + this->scheme = SIGN_UNKNOWN; + } +} + +/* + * Described in header + */ +bool signature_params_parse(chunk_t asn1, int level0, + signature_params_t *params) +{ + chunk_t parameters = chunk_empty; + int oid; + + oid = asn1_parse_algorithmIdentifier(asn1, level0, ¶meters); + params->scheme = signature_scheme_from_oid(oid); + switch (params->scheme) + { + case SIGN_UNKNOWN: + return FALSE; + case SIGN_RSA_EMSA_PSS: + { + rsa_pss_params_t *pss = malloc_thing(rsa_pss_params_t); + + if (!rsa_pss_params_parse(parameters, level0+1, pss)) + { + DBG1(DBG_IKE, "failed parsing RSASSA-PSS parameters"); + free(pss); + return FALSE; + } + params->params = pss; + break; + } + default: + params->params = NULL; + break; + } + return TRUE; +} + +/* + * Described in header + */ +bool signature_params_build(signature_params_t *params, chunk_t *asn1) +{ + chunk_t parameters = chunk_empty; + int oid; + + oid = signature_scheme_to_oid(params->scheme); + if (oid == OID_UNKNOWN) + { + return FALSE; + } + if (params->scheme == SIGN_RSA_EMSA_PSS && + !rsa_pss_params_build(params->params, ¶meters)) + { + return FALSE; + } + if (parameters.len) + { + *asn1 = asn1_algorithmIdentifier_params(oid, parameters); + } + else + { + *asn1 = asn1_algorithmIdentifier(oid); + } + return TRUE; +} + +/** + * ASN.1 definition of RSASSA-PSS-params + */ +static const asn1Object_t RSASSAPSSParamsObjects[] = { + { 0, "RSASSA-PSS-params", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "DEFAULT SHA-1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 1 */ + { 2, "hashAlgorithm", ASN1_EOC, ASN1_RAW }, /* 2 */ + { 1, "DEFAULT MGF1SHA1", ASN1_CONTEXT_C_1, ASN1_DEF }, /* 3 */ + { 2, "maskGenAlgorithm",ASN1_EOC, ASN1_RAW }, /* 4 */ + { 1, "DEFAULT 20", ASN1_CONTEXT_C_2, ASN1_DEF }, /* 5 */ + { 2, "saltLength", ASN1_INTEGER, ASN1_BODY }, /* 6 */ + { 1, "DEFAULT 1", ASN1_CONTEXT_C_3, ASN1_DEF }, /* 7 */ + { 2, "trailerField", ASN1_INTEGER, ASN1_BODY }, /* 8 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define RSASSA_PSS_PARAMS_HASH_ALG 2 +#define RSASSA_PSS_PARAMS_MGF_ALG 4 +#define RSASSA_PSS_PARAMS_SALT_LEN 6 +#define RSASSA_PSS_PARAMS_TRAILER 8 + +/* + * Described in header + */ +bool rsa_pss_params_parse(chunk_t asn1, int level0, rsa_pss_params_t *params) +{ + asn1_parser_t *parser; + chunk_t object; + int objectID, alg; + bool success = FALSE; + + params->hash = HASH_SHA1; + params->mgf1_hash = HASH_SHA1; + params->salt_len = HASH_SIZE_SHA1; + + parser = asn1_parser_create(RSASSAPSSParamsObjects, asn1); + parser->set_top_level(parser, level0); + + while (parser->iterate(parser, &objectID, &object)) + { + u_int level = parser->get_level(parser)+1; + + switch (objectID) + { + case RSASSA_PSS_PARAMS_HASH_ALG: + if (object.len) + { + alg = asn1_parse_algorithmIdentifier(object, level, NULL); + params->hash = hasher_algorithm_from_oid(alg); + if (params->hash == HASH_UNKNOWN) + { + goto end; + } + } + break; + case RSASSA_PSS_PARAMS_MGF_ALG: + if (object.len) + { + chunk_t hash; + + alg = asn1_parse_algorithmIdentifier(object, level, &hash); + if (alg != OID_MGF1) + { + goto end; + } + alg = asn1_parse_algorithmIdentifier(hash, level+1, NULL); + params->mgf1_hash = hasher_algorithm_from_oid(alg); + if (params->mgf1_hash == HASH_UNKNOWN) + { + goto end; + } + } + break; + case RSASSA_PSS_PARAMS_SALT_LEN: + if (object.len) + { + params->salt_len = (size_t)asn1_parse_integer_uint64(object); + } + break; + case RSASSA_PSS_PARAMS_TRAILER: + if (object.len && (object.len != 1 || *object.ptr != 1)) + { + goto end; + } + break; + default: + break; + } + } + success = parser->success(parser); + +end: + parser->destroy(parser); + return success; +} + +/* + * Described in header + */ +bool rsa_pss_params_build(rsa_pss_params_t *params, chunk_t *asn1) +{ + chunk_t hash = chunk_empty, mgf = chunk_empty, slen = chunk_empty; + ssize_t salt_len; + int alg; + + if (params->hash != HASH_SHA1) + { /* with SHA-1 we MUST omit the field */ + alg = hasher_algorithm_to_oid(params->hash); + if (alg == OID_UNKNOWN) + { + return FALSE; + } + hash = asn1_algorithmIdentifier(alg); + } + if (params->mgf1_hash != HASH_SHA1) + { /* with MGF1-SHA1 we MUST omit the field */ + alg = hasher_algorithm_to_oid(params->mgf1_hash); + if (alg == OID_UNKNOWN) + { + chunk_free(&hash); + return FALSE; + } + mgf = asn1_algorithmIdentifier_params(OID_MGF1, + asn1_algorithmIdentifier(alg)); + } + salt_len = rsa_pss_salt_length(params); + if (salt_len < 0) + { + chunk_free(&hash); + chunk_free(&mgf); + return FALSE; + } + else if (salt_len != HASH_SIZE_SHA1) + { + slen = asn1_integer("m", asn1_integer_from_uint64(salt_len)); + } + *asn1 = asn1_wrap(ASN1_SEQUENCE, "mmm", + hash.len ? asn1_wrap(ASN1_CONTEXT_C_0, "m", hash) : chunk_empty, + mgf.len ? asn1_wrap(ASN1_CONTEXT_C_1, "m", mgf) : chunk_empty, + slen.len ? asn1_wrap(ASN1_CONTEXT_C_2, "m", slen) : chunk_empty); + return TRUE; +} diff --git a/src/libstrongswan/credentials/keys/signature_params.h b/src/libstrongswan/credentials/keys/signature_params.h new file mode 100644 index 000000000..6934c5e88 --- /dev/null +++ b/src/libstrongswan/credentials/keys/signature_params.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2017 Tobias Brunner + * 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 + * 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. + */ + +/** + * @defgroup signature_params signature_params + * @{ @ingroup keys + */ + +#ifndef SIGNATURE_PARAMS_H_ +#define SIGNATURE_PARAMS_H_ + +typedef struct signature_params_t signature_params_t; +typedef struct rsa_pss_params_t rsa_pss_params_t; + +#include <crypto/hashers/hasher.h> + +/** + * Signature scheme with parameters + */ +struct signature_params_t { + /** Signature scheme */ + signature_scheme_t scheme; + /** Parameters, depending on scheme */ + void *params; +}; + +/** + * Compare two signature schemes and their parameters + * + * @param a first scheme + * @param b second scheme + * @return TRUE if schemes and parameters are equal + */ +bool signature_params_equal(signature_params_t *a, signature_params_t *b); + +/** + * Compare two signature schemes and their parameters + * + * @param c constraint + * @param s scheme + * @return TRUE if scheme complies to constraint + */ +bool signature_params_comply(signature_params_t *c, signature_params_t *s); + +/** + * Clone the given scheme and parameters, if any + * + * @return cloned object + */ +signature_params_t *signature_params_clone(signature_params_t *this); + +/** + * Destroy the given scheme and parameters, if any + */ +void signature_params_destroy(signature_params_t *this); + +/** + * Clear the given parameters, if any, sets the scheme to SIGN_UNKNOWN + */ +void signature_params_clear(signature_params_t *this); + +/** + * Parse an ASN.1 algorithmIdentifier with parameters denoting a signature + * scheme. + * + * @param asn1 ASN.1 encoded RSASSA-PSS-params + * @param level0 current level of the ASN.1 parser + * @param params parsed parameters + * @return TRUE if successfully parsed + */ +bool signature_params_parse(chunk_t asn1, int level0, + signature_params_t *params); + +/** + * Build ASN.1 algorithmIdentifier with parameters denoting a signature scheme. + * + * @param params signature scheme and parameters to encode + * @param asn1 ASN.1 encoded algorithmIdentifier (allocated) + * @return TRUE if successfully built + */ +bool signature_params_build(signature_params_t *params, chunk_t *asn1); + +/** + * Parameters for SIGN_RSA_EMSA_PSS signature scheme + */ +struct rsa_pss_params_t { + /** Hash algorithm */ + hash_algorithm_t hash; + /** Hash for the MGF1 function */ + hash_algorithm_t mgf1_hash; + /** Salt length, use RSA_PSS_SALT_LEN_DEFAULT for length equal to hash */ + ssize_t salt_len; + /** Salt value, for unit tests (not all implementations support this) */ + chunk_t salt; +#define RSA_PSS_SALT_LEN_DEFAULT -1 +}; + +/** + * Parse the given ASN.1 algorithm identifier params + * + * @param asn1 ASN.1 encoded RSASSA-PSS-params + * @param level0 current level of the ASN.1 parser + * @param params parsed parameters + * @return TRUE if successfully parsed + */ +bool rsa_pss_params_parse(chunk_t asn1, int level0, rsa_pss_params_t *params); + +/** + * Build ASN.1 algorithm identifier params + * + * @param params parameters to encode + * @param asn1 ASN.1 encoded RSASSA-PSS-params (allocated) + * @return TRUE if successfully built + */ +bool rsa_pss_params_build(rsa_pss_params_t *params, chunk_t *asn1); + +#endif /** SIGNATURE_PARAMS_H_ @}*/ diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c index 92d5efdc6..0e64f0350 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.c +++ b/src/libstrongswan/credentials/sets/cert_cache.c @@ -48,9 +48,9 @@ struct relation_t { certificate_t *issuer; /** - * Signature scheme used to sign this relation + * Signature scheme and parameters used to sign this relation */ - signature_scheme_t scheme; + signature_params_t *scheme; /** * Cache hits @@ -84,7 +84,7 @@ struct private_cert_cache_t { */ static void cache(private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer, - signature_scheme_t scheme) + signature_params_t *scheme) { relation_t *rel; int i, offset, try; @@ -118,7 +118,8 @@ static void cache(private_cert_cache_t *this, { rel->subject->destroy(rel->subject); rel->subject = subject->get_ref(subject); - rel->scheme = scheme; + signature_params_destroy(rel->scheme); + rel->scheme = signature_params_clone(scheme); return rel->lock->unlock(rel->lock); } } @@ -139,7 +140,7 @@ static void cache(private_cert_cache_t *this, { rel->subject = subject->get_ref(subject); rel->issuer = issuer->get_ref(issuer); - rel->scheme = scheme; + rel->scheme = signature_params_clone(scheme); return rel->lock->unlock(rel->lock); } rel->lock->unlock(rel->lock); @@ -165,10 +166,11 @@ static void cache(private_cert_cache_t *this, { rel->subject->destroy(rel->subject); rel->issuer->destroy(rel->issuer); + signature_params_destroy(rel->scheme); } rel->subject = subject->get_ref(subject); rel->issuer = issuer->get_ref(issuer); - rel->scheme = scheme; + rel->scheme = signature_params_clone(scheme); rel->hits = 0; return rel->lock->unlock(rel->lock); } @@ -180,11 +182,11 @@ static void cache(private_cert_cache_t *this, METHOD(cert_cache_t, issued_by, bool, private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer, - signature_scheme_t *schemep) + signature_params_t **schemep) { certificate_t *cached_issuer = NULL; relation_t *found = NULL, *current; - signature_scheme_t scheme; + signature_params_t *scheme; int i; for (i = 0; i < CACHE_SIZE; i++) @@ -202,7 +204,7 @@ METHOD(cert_cache_t, issued_by, bool, found = current; if (schemep) { - *schemep = current->scheme; + *schemep = signature_params_clone(current->scheme); } } else if (!cached_issuer) @@ -225,6 +227,10 @@ METHOD(cert_cache_t, issued_by, bool, { *schemep = scheme; } + else + { + signature_params_destroy(scheme); + } DESTROY_IF(cached_issuer); return TRUE; } @@ -383,8 +389,10 @@ METHOD(cert_cache_t, flush, void, { rel->subject->destroy(rel->subject); rel->issuer->destroy(rel->issuer); + signature_params_destroy(rel->scheme); rel->subject = NULL; rel->issuer = NULL; + rel->scheme = NULL; rel->hits = 0; } } @@ -405,6 +413,7 @@ METHOD(cert_cache_t, destroy, void, { rel->subject->destroy(rel->subject); rel->issuer->destroy(rel->issuer); + signature_params_destroy(rel->scheme); } rel->lock->destroy(rel->lock); } @@ -438,6 +447,7 @@ cert_cache_t *cert_cache_create() { this->relations[i].subject = NULL; this->relations[i].issuer = NULL; + this->relations[i].scheme = NULL; this->relations[i].hits = 0; this->relations[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT); } diff --git a/src/libstrongswan/credentials/sets/cert_cache.h b/src/libstrongswan/credentials/sets/cert_cache.h index 2bcdbe464..2235bc30d 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.h +++ b/src/libstrongswan/credentials/sets/cert_cache.h @@ -45,12 +45,13 @@ struct cert_cache_t { * * @param subject certificate to verify * @param issuer issuing certificate to verify subject - * @param scheme receives used signature scheme, if given + * @param scheme receives used signature scheme and parameters, if + * given (allocated) * @return TRUE if subject issued by issuer */ bool (*issued_by)(cert_cache_t *this, certificate_t *subject, certificate_t *issuer, - signature_scheme_t *scheme); + signature_params_t **scheme); /** * Flush the certificate cache. |