ike: Reject certificates that are not compliant with RFC 4945
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
#include <sa/ikev1/keymat_v1.h>
|
#include <sa/ikev1/keymat_v1.h>
|
||||||
#include <encoding/payloads/hash_payload.h>
|
#include <encoding/payloads/hash_payload.h>
|
||||||
|
#include <credentials/certificates/x509.h>
|
||||||
|
|
||||||
typedef struct private_pubkey_v1_authenticator_t private_pubkey_v1_authenticator_t;
|
typedef struct private_pubkey_v1_authenticator_t private_pubkey_v1_authenticator_t;
|
||||||
|
|
||||||
@@ -130,6 +131,29 @@ METHOD(authenticator_t, build, status_t,
|
|||||||
return status;
|
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,
|
METHOD(authenticator_t, process, status_t,
|
||||||
private_pubkey_v1_authenticator_t *this, message_t *message)
|
private_pubkey_v1_authenticator_t *this, message_t *message)
|
||||||
{
|
{
|
||||||
@@ -176,7 +200,8 @@ METHOD(authenticator_t, process, status_t,
|
|||||||
id, auth, TRUE);
|
id, auth, TRUE);
|
||||||
while (enumerator->enumerate(enumerator, &public, ¤t_auth))
|
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",
|
DBG1(DBG_IKE, "authentication of '%Y' with %N successful",
|
||||||
id, signature_scheme_names, scheme);
|
id, signature_scheme_names, scheme);
|
||||||
|
|||||||
@@ -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-2009 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <asn1/asn1.h>
|
#include <asn1/asn1.h>
|
||||||
#include <asn1/oid.h>
|
#include <asn1/oid.h>
|
||||||
#include <collections/array.h>
|
#include <collections/array.h>
|
||||||
|
#include <credentials/certificates/x509.h>
|
||||||
|
|
||||||
typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t;
|
typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t;
|
||||||
|
|
||||||
@@ -414,6 +415,29 @@ METHOD(authenticator_t, build, status_t,
|
|||||||
return status;
|
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,
|
METHOD(authenticator_t, process, status_t,
|
||||||
private_pubkey_authenticator_t *this, message_t *message)
|
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))
|
while (enumerator->enumerate(enumerator, &public, ¤t_auth))
|
||||||
{
|
{
|
||||||
if (public->verify(public, params->scheme, params->params, octets,
|
if (public->verify(public, params->scheme, params->params, octets,
|
||||||
auth_data))
|
auth_data) &&
|
||||||
|
is_compliant_cert(current_auth))
|
||||||
{
|
{
|
||||||
if (auth_method != AUTH_DS)
|
if (auth_method != AUTH_DS)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user