From 6143f926eff1685ec073e13d458734225742503f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 25 Apr 2018 11:10:48 +0200 Subject: [PATCH] ike: Reject certificates that are not compliant with RFC 4945 --- .../authenticators/pubkey_v1_authenticator.c | 27 ++++++++++++++++- .../authenticators/pubkey_authenticator.c | 29 +++++++++++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c index 41be15a087..9e5833efc2 100644 --- a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c +++ b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c @@ -18,6 +18,7 @@ #include #include #include +#include typedef struct private_pubkey_v1_authenticator_t private_pubkey_v1_authenticator_t; @@ -130,6 +131,29 @@ METHOD(authenticator_t, build, status_t, return status; } +/** + * Check if the end-entity certificate, if any, is compliant with RFC 4945 + */ +static bool is_compliant_cert(auth_cfg_t *auth) +{ + certificate_t *cert; + x509_t *x509; + + cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT); + if (!cert || cert->get_type(cert) != CERT_X509) + { + return TRUE; + } + x509 = (x509_t*)cert; + if (x509->get_flags(x509) & X509_IKE_COMPLIANT) + { + return TRUE; + } + DBG1(DBG_IKE, "rejecting certificate without digitalSignature or " + "nonRepudiation keyUsage flags"); + return FALSE; +} + METHOD(authenticator_t, process, status_t, private_pubkey_v1_authenticator_t *this, message_t *message) { @@ -176,7 +200,8 @@ METHOD(authenticator_t, process, status_t, id, auth, TRUE); while (enumerator->enumerate(enumerator, &public, ¤t_auth)) { - if (public->verify(public, scheme, NULL, hash, sig)) + if (public->verify(public, scheme, NULL, hash, sig) && + is_compliant_cert(current_auth)) { DBG1(DBG_IKE, "authentication of '%Y' with %N successful", id, signature_scheme_names, scheme); diff --git a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c index c6c4829102..652b837fe3 100644 --- a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c +++ b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2017 Tobias Brunner + * Copyright (C) 2008-2018 Tobias Brunner * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * HSR Hochschule fuer Technik Rapperswil @@ -23,6 +23,7 @@ #include #include #include +#include typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t; @@ -414,6 +415,29 @@ METHOD(authenticator_t, build, status_t, return status; } +/** + * Check if the end-entity certificate, if any, is compliant with RFC 4945 + */ +static bool is_compliant_cert(auth_cfg_t *auth) +{ + certificate_t *cert; + x509_t *x509; + + cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT); + if (!cert || cert->get_type(cert) != CERT_X509) + { + return TRUE; + } + x509 = (x509_t*)cert; + if (x509->get_flags(x509) & X509_IKE_COMPLIANT) + { + return TRUE; + } + DBG1(DBG_IKE, "rejecting certificate without digitalSignature or " + "nonRepudiation keyUsage flags"); + return FALSE; +} + METHOD(authenticator_t, process, status_t, private_pubkey_authenticator_t *this, message_t *message) { @@ -479,7 +503,8 @@ METHOD(authenticator_t, process, status_t, while (enumerator->enumerate(enumerator, &public, ¤t_auth)) { if (public->verify(public, params->scheme, params->params, octets, - auth_data)) + auth_data) && + is_compliant_cert(current_auth)) { if (auth_method != AUTH_DS) { -- 2.47.2