openssl: add support for IP addr blocks in X.509 certificates
This commit is contained in:
committed by
Martin Willi
parent
71d740cac6
commit
5e4b1ad20a
@@ -17,6 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2013 Michael Rossberg
|
||||||
|
* Copyright (C) 2013 Technische Universität Ilmenau
|
||||||
|
*
|
||||||
* Copyright (C) 2010 secunet Security Networks AG
|
* Copyright (C) 2010 secunet Security Networks AG
|
||||||
* Copyright (C) 2010 Thomas Egerer
|
* Copyright (C) 2010 Thomas Egerer
|
||||||
*
|
*
|
||||||
@@ -50,7 +53,12 @@
|
|||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
#include <asn1/oid.h>
|
#include <asn1/oid.h>
|
||||||
#include <collections/linked_list.h>
|
#include <collections/linked_list.h>
|
||||||
|
#include <selectors/traffic_selector.h>
|
||||||
|
|
||||||
|
/* IP Addr block extension support was introduced with 0.9.8e */
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x0090805fL
|
||||||
|
#define OPENSSL_NO_RFC3779
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct private_openssl_x509_t private_openssl_x509_t;
|
typedef struct private_openssl_x509_t private_openssl_x509_t;
|
||||||
|
|
||||||
@@ -149,6 +157,12 @@ struct private_openssl_x509_t {
|
|||||||
*/
|
*/
|
||||||
linked_list_t *ocsp_uris;
|
linked_list_t *ocsp_uris;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of ipAddrBlocks as traffic_selector_t
|
||||||
|
*/
|
||||||
|
linked_list_t *ipAddrBlocks;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* References to this cert
|
* References to this cert
|
||||||
*/
|
*/
|
||||||
@@ -283,6 +297,12 @@ METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
|
|||||||
return this->ocsp_uris->create_enumerator(this->ocsp_uris);
|
return this->ocsp_uris->create_enumerator(this->ocsp_uris);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
|
||||||
|
private_openssl_x509_t *this)
|
||||||
|
{
|
||||||
|
return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(certificate_t, get_type, certificate_type_t,
|
METHOD(certificate_t, get_type, certificate_type_t,
|
||||||
private_openssl_x509_t *this)
|
private_openssl_x509_t *this)
|
||||||
{
|
{
|
||||||
@@ -506,6 +526,8 @@ METHOD(certificate_t, destroy, void,
|
|||||||
offsetof(identification_t, destroy));
|
offsetof(identification_t, destroy));
|
||||||
this->crl_uris->destroy_function(this->crl_uris, (void*)crl_uri_destroy);
|
this->crl_uris->destroy_function(this->crl_uris, (void*)crl_uri_destroy);
|
||||||
this->ocsp_uris->destroy_function(this->ocsp_uris, free);
|
this->ocsp_uris->destroy_function(this->ocsp_uris, free);
|
||||||
|
this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
|
||||||
|
offsetof(traffic_selector_t, destroy));
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -542,7 +564,7 @@ static private_openssl_x509_t *create_empty()
|
|||||||
.create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
|
.create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
|
||||||
.create_crl_uri_enumerator = _create_crl_uri_enumerator,
|
.create_crl_uri_enumerator = _create_crl_uri_enumerator,
|
||||||
.create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
|
.create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
|
||||||
.create_ipAddrBlock_enumerator = (void*)enumerator_create_empty,
|
.create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator,
|
||||||
.create_name_constraint_enumerator = (void*)enumerator_create_empty,
|
.create_name_constraint_enumerator = (void*)enumerator_create_empty,
|
||||||
.create_cert_policy_enumerator = (void*)enumerator_create_empty,
|
.create_cert_policy_enumerator = (void*)enumerator_create_empty,
|
||||||
.create_policy_mapping_enumerator = (void*)enumerator_create_empty,
|
.create_policy_mapping_enumerator = (void*)enumerator_create_empty,
|
||||||
@@ -552,6 +574,7 @@ static private_openssl_x509_t *create_empty()
|
|||||||
.issuerAltNames = linked_list_create(),
|
.issuerAltNames = linked_list_create(),
|
||||||
.crl_uris = linked_list_create(),
|
.crl_uris = linked_list_create(),
|
||||||
.ocsp_uris = linked_list_create(),
|
.ocsp_uris = linked_list_create(),
|
||||||
|
.ipAddrBlocks = linked_list_create(),
|
||||||
.pathlen = X509_NO_CONSTRAINT,
|
.pathlen = X509_NO_CONSTRAINT,
|
||||||
.ref = 1,
|
.ref = 1,
|
||||||
);
|
);
|
||||||
@@ -772,6 +795,92 @@ static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_RFC3779
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a single block of ipAddrBlock extension
|
||||||
|
*/
|
||||||
|
static void parse_ipAddrBlock_ext_fam(private_openssl_x509_t *this,
|
||||||
|
IPAddressFamily *fam)
|
||||||
|
{
|
||||||
|
const IPAddressOrRanges *list;
|
||||||
|
IPAddressOrRange *aor;
|
||||||
|
traffic_selector_t *ts;
|
||||||
|
ts_type_t type;
|
||||||
|
chunk_t from, to;
|
||||||
|
int i, afi;
|
||||||
|
|
||||||
|
if (fam->ipAddressChoice->type != IPAddressChoice_addressesOrRanges)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
afi = v3_addr_get_afi(fam);
|
||||||
|
switch (afi)
|
||||||
|
{
|
||||||
|
case IANA_AFI_IPV4:
|
||||||
|
from = chunk_alloca(4);
|
||||||
|
to = chunk_alloca(4);
|
||||||
|
type = TS_IPV4_ADDR_RANGE;
|
||||||
|
break;
|
||||||
|
case IANA_AFI_IPV6:
|
||||||
|
from = chunk_alloca(16);
|
||||||
|
to = chunk_alloca(16);
|
||||||
|
type = TS_IPV6_ADDR_RANGE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list = fam->ipAddressChoice->u.addressesOrRanges;
|
||||||
|
for (i = 0; i < sk_IPAddressOrRange_num(list); i++)
|
||||||
|
{
|
||||||
|
aor = sk_IPAddressOrRange_value(list, i);
|
||||||
|
if (v3_addr_get_range(aor, afi, from.ptr, to.ptr, from.len) > 0)
|
||||||
|
{
|
||||||
|
ts = traffic_selector_create_from_bytes(0, type, from, 0, to, 65535);
|
||||||
|
if (ts)
|
||||||
|
{
|
||||||
|
this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse ipAddrBlock extension
|
||||||
|
*/
|
||||||
|
static bool parse_ipAddrBlock_ext(private_openssl_x509_t *this,
|
||||||
|
X509_EXTENSION *ext)
|
||||||
|
{
|
||||||
|
STACK_OF(IPAddressFamily) *blocks;
|
||||||
|
IPAddressFamily *fam;
|
||||||
|
|
||||||
|
blocks = (STACK_OF(IPAddressFamily)*)X509V3_EXT_d2i(ext);
|
||||||
|
if (!blocks)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v3_addr_is_canonical(blocks))
|
||||||
|
{
|
||||||
|
sk_IPAddressFamily_free(blocks);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sk_IPAddressFamily_num(blocks) > 0)
|
||||||
|
{
|
||||||
|
fam = sk_IPAddressFamily_pop(blocks);
|
||||||
|
parse_ipAddrBlock_ext_fam(this, fam);
|
||||||
|
IPAddressFamily_free(fam);
|
||||||
|
}
|
||||||
|
sk_IPAddressFamily_free(blocks);
|
||||||
|
|
||||||
|
this->flags |= X509_IP_ADDR_BLOCKS;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif /* !OPENSSL_NO_RFC3779 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse authorityKeyIdentifier extension
|
* Parse authorityKeyIdentifier extension
|
||||||
*/
|
*/
|
||||||
@@ -857,6 +966,11 @@ static bool parse_extensions(private_openssl_x509_t *this)
|
|||||||
case NID_crl_distribution_points:
|
case NID_crl_distribution_points:
|
||||||
ok = parse_crlDistributionPoints_ext(this, ext);
|
ok = parse_crlDistributionPoints_ext(this, ext);
|
||||||
break;
|
break;
|
||||||
|
#ifndef OPENSSL_NO_RFC3779
|
||||||
|
case NID_sbgp_ipAddrBlock:
|
||||||
|
ok = parse_ipAddrBlock_ext(this, ext);
|
||||||
|
break;
|
||||||
|
#endif /* !OPENSSL_NO_RFC3779 */
|
||||||
default:
|
default:
|
||||||
ok = X509_EXTENSION_get_critical(ext) == 0 ||
|
ok = X509_EXTENSION_get_critical(ext) == 0 ||
|
||||||
!lib->settings->get_bool(lib->settings,
|
!lib->settings->get_bool(lib->settings,
|
||||||
|
|||||||
Reference in New Issue
Block a user