diff options
author | Tobias Brunner <tobias@strongswan.org> | 2017-10-02 15:57:17 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2017-11-08 16:48:10 +0100 |
commit | 5f7be58177404488fb9d89a4c7ccd4c9781310da (patch) | |
tree | b11b7269885358d6cc255322bdee94d521f01d68 | |
parent | 84b1c06d0ee5b2cb7ff174eb72523a78efda5944 (diff) | |
download | strongswan-5f7be58177404488fb9d89a4c7ccd4c9781310da.tar.bz2 strongswan-5f7be58177404488fb9d89a4c7ccd4c9781310da.tar.xz |
ikev2: Verify RSASSA-PSS signatures via RFC 7427 signature auth
-rw-r--r-- | src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c index 4ac25580f..3c58d9beb 100644 --- a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c +++ b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 2008-2015 Tobias Brunner + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter - * 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 @@ -61,8 +61,9 @@ struct private_pubkey_authenticator_t { * Parse authentication data used for Signature Authentication as per RFC 7427 */ static bool parse_signature_auth_data(chunk_t *auth_data, key_type_t *key_type, - signature_scheme_t *scheme) + signature_params_t *params) { + chunk_t parameters = chunk_empty; uint8_t len; int oid; @@ -72,14 +73,29 @@ static bool parse_signature_auth_data(chunk_t *auth_data, key_type_t *key_type, } len = auth_data->ptr[0]; *auth_data = chunk_skip(*auth_data, 1); - /* we currently don't support schemes that require parameters */ - oid = asn1_parse_algorithmIdentifier(*auth_data, 1, NULL); - *scheme = signature_scheme_from_oid(oid); - if (*scheme == SIGN_UNKNOWN) + oid = asn1_parse_algorithmIdentifier(*auth_data, 1, ¶meters); + params->scheme = signature_scheme_from_oid(oid); + switch (params->scheme) { - return FALSE; + 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, 0, pss)) + { + DBG1(DBG_IKE, "failed parsing RSASSA-PSS parameters"); + free(pss); + return FALSE; + } + params->params = pss; + break; + } + default: + break; } - *key_type = key_type_from_signature_scheme(*scheme); + *key_type = key_type_from_signature_scheme(params->scheme); *auth_data = chunk_skip(*auth_data, len); return TRUE; } @@ -410,7 +426,6 @@ METHOD(authenticator_t, process, status_t, auth_cfg_t *auth, *current_auth; enumerator_t *enumerator; key_type_t key_type = KEY_ECDSA; - signature_scheme_t scheme; signature_params_t *params; status_t status = NOT_FOUND; const char *reason = "unsupported"; @@ -421,25 +436,26 @@ METHOD(authenticator_t, process, status_t, { return FAILED; } + INIT(params); auth_method = auth_payload->get_auth_method(auth_payload); auth_data = auth_payload->get_data(auth_payload); switch (auth_method) { case AUTH_RSA: key_type = KEY_RSA; - scheme = SIGN_RSA_EMSA_PKCS1_SHA1; + params->scheme = SIGN_RSA_EMSA_PKCS1_SHA1; break; case AUTH_ECDSA_256: - scheme = SIGN_ECDSA_256; + params->scheme = SIGN_ECDSA_256; break; case AUTH_ECDSA_384: - scheme = SIGN_ECDSA_384; + params->scheme = SIGN_ECDSA_384; break; case AUTH_ECDSA_521: - scheme = SIGN_ECDSA_521; + params->scheme = SIGN_ECDSA_521; break; case AUTH_DS: - if (parse_signature_auth_data(&auth_data, &key_type, &scheme)) + if (parse_signature_auth_data(&auth_data, &key_type, params)) { break; } @@ -448,12 +464,10 @@ METHOD(authenticator_t, process, status_t, default: DBG1(DBG_IKE, "%N authentication %s", auth_method_names, auth_method, reason); + signature_params_destroy(params); return INVALID_ARG; } id = this->ike_sa->get_other_id(this->ike_sa); - INIT(params, - .scheme = scheme, - ); if (!get_auth_octets_scheme(this, TRUE, id, &octets, ¶ms)) { return FAILED; @@ -465,7 +479,8 @@ METHOD(authenticator_t, process, status_t, key_type, id, auth, online); while (enumerator->enumerate(enumerator, &public, ¤t_auth)) { - if (public->verify(public, params->scheme, NULL, octets, auth_data)) + if (public->verify(public, params->scheme, params->params, octets, + auth_data)) { DBG1(DBG_IKE, "authentication of '%Y' with %N successful", id, auth_method == AUTH_DS ? signature_scheme_names : auth_method_names, |