ikev2: Verify RSASSA-PSS signatures via RFC 7427 signature auth
This commit is contained in:
@@ -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-2009 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* 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
|
* 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
|
* 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
|
* 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,
|
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;
|
uint8_t len;
|
||||||
int oid;
|
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];
|
len = auth_data->ptr[0];
|
||||||
*auth_data = chunk_skip(*auth_data, 1);
|
*auth_data = chunk_skip(*auth_data, 1);
|
||||||
/* we currently don't support schemes that require parameters */
|
oid = asn1_parse_algorithmIdentifier(*auth_data, 1, ¶meters);
|
||||||
oid = asn1_parse_algorithmIdentifier(*auth_data, 1, NULL);
|
params->scheme = signature_scheme_from_oid(oid);
|
||||||
*scheme = signature_scheme_from_oid(oid);
|
switch (params->scheme)
|
||||||
if (*scheme == SIGN_UNKNOWN)
|
|
||||||
{
|
{
|
||||||
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);
|
*auth_data = chunk_skip(*auth_data, len);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -410,7 +426,6 @@ METHOD(authenticator_t, process, status_t,
|
|||||||
auth_cfg_t *auth, *current_auth;
|
auth_cfg_t *auth, *current_auth;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
key_type_t key_type = KEY_ECDSA;
|
key_type_t key_type = KEY_ECDSA;
|
||||||
signature_scheme_t scheme;
|
|
||||||
signature_params_t *params;
|
signature_params_t *params;
|
||||||
status_t status = NOT_FOUND;
|
status_t status = NOT_FOUND;
|
||||||
const char *reason = "unsupported";
|
const char *reason = "unsupported";
|
||||||
@@ -421,25 +436,26 @@ METHOD(authenticator_t, process, status_t,
|
|||||||
{
|
{
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
INIT(params);
|
||||||
auth_method = auth_payload->get_auth_method(auth_payload);
|
auth_method = auth_payload->get_auth_method(auth_payload);
|
||||||
auth_data = auth_payload->get_data(auth_payload);
|
auth_data = auth_payload->get_data(auth_payload);
|
||||||
switch (auth_method)
|
switch (auth_method)
|
||||||
{
|
{
|
||||||
case AUTH_RSA:
|
case AUTH_RSA:
|
||||||
key_type = KEY_RSA;
|
key_type = KEY_RSA;
|
||||||
scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
|
params->scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
|
||||||
break;
|
break;
|
||||||
case AUTH_ECDSA_256:
|
case AUTH_ECDSA_256:
|
||||||
scheme = SIGN_ECDSA_256;
|
params->scheme = SIGN_ECDSA_256;
|
||||||
break;
|
break;
|
||||||
case AUTH_ECDSA_384:
|
case AUTH_ECDSA_384:
|
||||||
scheme = SIGN_ECDSA_384;
|
params->scheme = SIGN_ECDSA_384;
|
||||||
break;
|
break;
|
||||||
case AUTH_ECDSA_521:
|
case AUTH_ECDSA_521:
|
||||||
scheme = SIGN_ECDSA_521;
|
params->scheme = SIGN_ECDSA_521;
|
||||||
break;
|
break;
|
||||||
case AUTH_DS:
|
case AUTH_DS:
|
||||||
if (parse_signature_auth_data(&auth_data, &key_type, &scheme))
|
if (parse_signature_auth_data(&auth_data, &key_type, params))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -448,12 +464,10 @@ METHOD(authenticator_t, process, status_t,
|
|||||||
default:
|
default:
|
||||||
DBG1(DBG_IKE, "%N authentication %s", auth_method_names,
|
DBG1(DBG_IKE, "%N authentication %s", auth_method_names,
|
||||||
auth_method, reason);
|
auth_method, reason);
|
||||||
|
signature_params_destroy(params);
|
||||||
return INVALID_ARG;
|
return INVALID_ARG;
|
||||||
}
|
}
|
||||||
id = this->ike_sa->get_other_id(this->ike_sa);
|
id = this->ike_sa->get_other_id(this->ike_sa);
|
||||||
INIT(params,
|
|
||||||
.scheme = scheme,
|
|
||||||
);
|
|
||||||
if (!get_auth_octets_scheme(this, TRUE, id, &octets, ¶ms))
|
if (!get_auth_octets_scheme(this, TRUE, id, &octets, ¶ms))
|
||||||
{
|
{
|
||||||
return FAILED;
|
return FAILED;
|
||||||
@@ -465,7 +479,8 @@ METHOD(authenticator_t, process, status_t,
|
|||||||
key_type, id, auth, online);
|
key_type, id, auth, online);
|
||||||
while (enumerator->enumerate(enumerator, &public, ¤t_auth))
|
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,
|
DBG1(DBG_IKE, "authentication of '%Y' with %N successful", id,
|
||||||
auth_method == AUTH_DS ? signature_scheme_names : auth_method_names,
|
auth_method == AUTH_DS ? signature_scheme_names : auth_method_names,
|
||||||
|
|||||||
Reference in New Issue
Block a user