Merge branch 'hash-url-multi-level'
Adds support to send intermediate CA certificates in hash-and-URL encoding. For that it moves the generation of URLs from the config backends to the ike-cert-post task. Fixes #3234.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008-2015 Tobias Brunner
|
* Copyright (C) 2008-2019 Tobias Brunner
|
||||||
* Copyright (C) 2008 Martin Willi
|
* Copyright (C) 2008 Martin Willi
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@@ -89,11 +89,6 @@ struct ca_section_t {
|
|||||||
*/
|
*/
|
||||||
linked_list_t *ocsp;
|
linked_list_t *ocsp;
|
||||||
|
|
||||||
/**
|
|
||||||
* Hashes of certificates issued by this CA
|
|
||||||
*/
|
|
||||||
linked_list_t *hashes;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base URI used for certificates from this CA
|
* Base URI used for certificates from this CA
|
||||||
*/
|
*/
|
||||||
@@ -132,7 +127,6 @@ static ca_section_t *ca_section_create(char *name, char *path)
|
|||||||
ca->path = strdup(path);
|
ca->path = strdup(path);
|
||||||
ca->crl = linked_list_create();
|
ca->crl = linked_list_create();
|
||||||
ca->ocsp = linked_list_create();
|
ca->ocsp = linked_list_create();
|
||||||
ca->hashes = linked_list_create();
|
|
||||||
ca->certuribase = NULL;
|
ca->certuribase = NULL;
|
||||||
return ca;
|
return ca;
|
||||||
}
|
}
|
||||||
@@ -144,7 +138,6 @@ static void ca_section_destroy(ca_section_t *this)
|
|||||||
{
|
{
|
||||||
this->crl->destroy_function(this->crl, free);
|
this->crl->destroy_function(this->crl, free);
|
||||||
this->ocsp->destroy_function(this->ocsp, free);
|
this->ocsp->destroy_function(this->ocsp, free);
|
||||||
this->hashes->destroy_offset(this->hashes, offsetof(identification_t, destroy));
|
|
||||||
this->cert->destroy(this->cert);
|
this->cert->destroy(this->cert);
|
||||||
free(this->certuribase);
|
free(this->certuribase);
|
||||||
free(this->path);
|
free(this->path);
|
||||||
@@ -308,32 +301,18 @@ static enumerator_t *create_inner_cdp(ca_section_t *section, cdp_data_t *data)
|
|||||||
*/
|
*/
|
||||||
static enumerator_t *create_inner_cdp_hashandurl(ca_section_t *section, cdp_data_t *data)
|
static enumerator_t *create_inner_cdp_hashandurl(ca_section_t *section, cdp_data_t *data)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator = NULL, *hash_enum;
|
enumerator_t *enumerator = NULL;
|
||||||
identification_t *current;
|
|
||||||
|
|
||||||
if (!data->id || !section->certuribase)
|
if (!data->id || !section->certuribase)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_enum = section->hashes->create_enumerator(section->hashes);
|
if (section->cert->has_subject(section->cert, data->id) != ID_MATCH_NONE)
|
||||||
while (hash_enum->enumerate(hash_enum, ¤t))
|
|
||||||
{
|
{
|
||||||
if (current->matches(current, data->id))
|
enumerator = enumerator_create_single(strdup(section->certuribase),
|
||||||
{
|
free);
|
||||||
char *url, *hash;
|
|
||||||
|
|
||||||
url = malloc(strlen(section->certuribase) + 40 + 1);
|
|
||||||
strcpy(url, section->certuribase);
|
|
||||||
hash = chunk_to_hex(current->get_encoding(current), NULL, FALSE).ptr;
|
|
||||||
strncat(url, hash, 40);
|
|
||||||
free(hash);
|
|
||||||
|
|
||||||
enumerator = enumerator_create_single(url, free);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
hash_enum->destroy(hash_enum);
|
|
||||||
return enumerator;
|
return enumerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,46 +600,6 @@ static void list_uris(linked_list_t *list, char *label, FILE *out)
|
|||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(stroke_ca_t, check_for_hash_and_url, void,
|
|
||||||
private_stroke_ca_t *this, certificate_t* cert)
|
|
||||||
{
|
|
||||||
ca_section_t *section;
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
|
|
||||||
hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
|
||||||
if (hasher == NULL)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "unable to use hash-and-url: sha1 not supported");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->lock->write_lock(this->lock);
|
|
||||||
enumerator = this->sections->create_enumerator(this->sections);
|
|
||||||
while (enumerator->enumerate(enumerator, (void**)§ion))
|
|
||||||
{
|
|
||||||
if (section->certuribase && cert->issued_by(cert, section->cert, NULL))
|
|
||||||
{
|
|
||||||
chunk_t hash, encoded;
|
|
||||||
|
|
||||||
if (cert->get_encoding(cert, CERT_ASN1_DER, &encoded))
|
|
||||||
{
|
|
||||||
if (hasher->allocate_hash(hasher, encoded, &hash))
|
|
||||||
{
|
|
||||||
section->hashes->insert_last(section->hashes,
|
|
||||||
identification_create_from_encoding(ID_KEY_ID, hash));
|
|
||||||
chunk_free(&hash);
|
|
||||||
}
|
|
||||||
chunk_free(&encoded);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
this->lock->unlock(this->lock);
|
|
||||||
|
|
||||||
hasher->destroy(hasher);
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(stroke_ca_t, list, void,
|
METHOD(stroke_ca_t, list, void,
|
||||||
private_stroke_ca_t *this, stroke_msg_t *msg, FILE *out)
|
private_stroke_ca_t *this, stroke_msg_t *msg, FILE *out)
|
||||||
{
|
{
|
||||||
@@ -740,7 +679,6 @@ stroke_ca_t *stroke_ca_create()
|
|||||||
.get_cert_ref = _get_cert_ref,
|
.get_cert_ref = _get_cert_ref,
|
||||||
.reload_certs = _reload_certs,
|
.reload_certs = _reload_certs,
|
||||||
.replace_certs = _replace_certs,
|
.replace_certs = _replace_certs,
|
||||||
.check_for_hash_and_url = _check_for_hash_and_url,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.sections = linked_list_create(),
|
.sections = linked_list_create(),
|
||||||
|
|||||||
@@ -58,13 +58,6 @@ struct stroke_ca_t {
|
|||||||
*/
|
*/
|
||||||
void (*list)(stroke_ca_t *this, stroke_msg_t *msg, FILE *out);
|
void (*list)(stroke_ca_t *this, stroke_msg_t *msg, FILE *out);
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a certificate can be made available through hash and URL.
|
|
||||||
*
|
|
||||||
* @param cert peer certificate
|
|
||||||
*/
|
|
||||||
void (*check_for_hash_and_url)(stroke_ca_t *this, certificate_t* cert);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a reference to a CA certificate if it is already stored,
|
* Get a reference to a CA certificate if it is already stored,
|
||||||
* otherwise returns the same certificate.
|
* otherwise returns the same certificate.
|
||||||
|
|||||||
@@ -425,10 +425,6 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
|
|||||||
certificate = this->cred->load_peer(this->cred, cert);
|
certificate = this->cred->load_peer(this->cred, cert);
|
||||||
if (certificate)
|
if (certificate)
|
||||||
{
|
{
|
||||||
if (local)
|
|
||||||
{
|
|
||||||
this->ca->check_for_hash_and_url(this->ca, certificate);
|
|
||||||
}
|
|
||||||
cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate);
|
cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate);
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Tobias Brunner
|
* Copyright (C) 2016-2019 Tobias Brunner
|
||||||
* Copyright (C) 2015 Andreas Steffen
|
* Copyright (C) 2015 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@@ -87,11 +87,6 @@ struct authority_t {
|
|||||||
*/
|
*/
|
||||||
linked_list_t *ocsp_uris;
|
linked_list_t *ocsp_uris;
|
||||||
|
|
||||||
/**
|
|
||||||
* Hashes of certificates issued by this CA
|
|
||||||
*/
|
|
||||||
linked_list_t *hashes;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base URI used for certificates from this CA
|
* Base URI used for certificates from this CA
|
||||||
*/
|
*/
|
||||||
@@ -109,7 +104,6 @@ static authority_t *authority_create(char *name)
|
|||||||
.name = strdup(name),
|
.name = strdup(name),
|
||||||
.crl_uris = linked_list_create(),
|
.crl_uris = linked_list_create(),
|
||||||
.ocsp_uris = linked_list_create(),
|
.ocsp_uris = linked_list_create(),
|
||||||
.hashes = linked_list_create(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return authority;
|
return authority;
|
||||||
@@ -122,7 +116,6 @@ static void authority_destroy(authority_t *this)
|
|||||||
{
|
{
|
||||||
this->crl_uris->destroy_function(this->crl_uris, free);
|
this->crl_uris->destroy_function(this->crl_uris, free);
|
||||||
this->ocsp_uris->destroy_function(this->ocsp_uris, free);
|
this->ocsp_uris->destroy_function(this->ocsp_uris, free);
|
||||||
this->hashes->destroy_offset(this->hashes, offsetof(identification_t, destroy));
|
|
||||||
DESTROY_IF(this->cert);
|
DESTROY_IF(this->cert);
|
||||||
free(this->cert_uri_base);
|
free(this->cert_uri_base);
|
||||||
free(this->name);
|
free(this->name);
|
||||||
@@ -694,32 +687,18 @@ static enumerator_t *create_inner_cdp(authority_t *authority, cdp_data_t *data)
|
|||||||
static enumerator_t *create_inner_cdp_hashandurl(authority_t *authority,
|
static enumerator_t *create_inner_cdp_hashandurl(authority_t *authority,
|
||||||
cdp_data_t *data)
|
cdp_data_t *data)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator = NULL, *hash_enum;
|
enumerator_t *enumerator = NULL;
|
||||||
identification_t *current;
|
|
||||||
|
|
||||||
if (!data->id || !authority->cert_uri_base)
|
if (!data->id || !authority->cert_uri_base)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_enum = authority->hashes->create_enumerator(authority->hashes);
|
if (authority->cert->has_subject(authority->cert, data->id) != ID_MATCH_NONE)
|
||||||
while (hash_enum->enumerate(hash_enum, ¤t))
|
|
||||||
{
|
{
|
||||||
if (current->matches(current, data->id))
|
enumerator = enumerator_create_single(strdup(authority->cert_uri_base),
|
||||||
{
|
free);
|
||||||
char *url, *hash;
|
|
||||||
|
|
||||||
url = malloc(strlen(authority->cert_uri_base) + 40 + 1);
|
|
||||||
strcpy(url, authority->cert_uri_base);
|
|
||||||
hash = chunk_to_hex(current->get_encoding(current), NULL, FALSE).ptr;
|
|
||||||
strncat(url, hash, 40);
|
|
||||||
free(hash);
|
|
||||||
|
|
||||||
enumerator = enumerator_create_single(url, free);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
hash_enum->destroy(hash_enum);
|
|
||||||
return enumerator;
|
return enumerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -752,48 +731,6 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
|
|||||||
(void*)create_inner_cdp, data, (void*)cdp_data_destroy);
|
(void*)create_inner_cdp, data, (void*)cdp_data_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(vici_authority_t, check_for_hash_and_url, void,
|
|
||||||
private_vici_authority_t *this, certificate_t* cert)
|
|
||||||
{
|
|
||||||
authority_t *authority;
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
hasher_t *hasher;
|
|
||||||
|
|
||||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
|
||||||
if (hasher == NULL)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "unable to use hash-and-url: sha1 not supported");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->lock->write_lock(this->lock);
|
|
||||||
enumerator = this->authorities->create_enumerator(this->authorities);
|
|
||||||
while (enumerator->enumerate(enumerator, &authority))
|
|
||||||
{
|
|
||||||
if (authority->cert_uri_base &&
|
|
||||||
cert->issued_by(cert, authority->cert, NULL))
|
|
||||||
{
|
|
||||||
chunk_t hash, encoded;
|
|
||||||
|
|
||||||
if (cert->get_encoding(cert, CERT_ASN1_DER, &encoded))
|
|
||||||
{
|
|
||||||
if (hasher->allocate_hash(hasher, encoded, &hash))
|
|
||||||
{
|
|
||||||
authority->hashes->insert_last(authority->hashes,
|
|
||||||
identification_create_from_encoding(ID_KEY_ID, hash));
|
|
||||||
chunk_free(&hash);
|
|
||||||
}
|
|
||||||
chunk_free(&encoded);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
this->lock->unlock(this->lock);
|
|
||||||
|
|
||||||
hasher->destroy(hasher);
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(vici_authority_t, destroy, void,
|
METHOD(vici_authority_t, destroy, void,
|
||||||
private_vici_authority_t *this)
|
private_vici_authority_t *this)
|
||||||
{
|
{
|
||||||
@@ -822,7 +759,6 @@ vici_authority_t *vici_authority_create(vici_dispatcher_t *dispatcher,
|
|||||||
.create_cdp_enumerator = _create_cdp_enumerator,
|
.create_cdp_enumerator = _create_cdp_enumerator,
|
||||||
.cache_cert = (void*)nop,
|
.cache_cert = (void*)nop,
|
||||||
},
|
},
|
||||||
.check_for_hash_and_url = _check_for_hash_and_url,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.dispatcher = dispatcher,
|
.dispatcher = dispatcher,
|
||||||
|
|||||||
@@ -36,13 +36,6 @@ struct vici_authority_t {
|
|||||||
*/
|
*/
|
||||||
credential_set_t set;
|
credential_set_t set;
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a certificate can be made available through hash and URL.
|
|
||||||
*
|
|
||||||
* @param cert end entity certificate
|
|
||||||
*/
|
|
||||||
void (*check_for_hash_and_url)(vici_authority_t *this, certificate_t* cert);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a vici_authority_t.
|
* Destroy a vici_authority_t.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1417,14 +1417,8 @@ CALLBACK(parse_cert_policy, bool,
|
|||||||
*/
|
*/
|
||||||
static bool add_cert(auth_data_t *auth, auth_rule_t rule, certificate_t *cert)
|
static bool add_cert(auth_data_t *auth, auth_rule_t rule, certificate_t *cert)
|
||||||
{
|
{
|
||||||
vici_authority_t *authority;
|
|
||||||
vici_cred_t *cred;
|
vici_cred_t *cred;
|
||||||
|
|
||||||
if (rule == AUTH_RULE_SUBJECT_CERT)
|
|
||||||
{
|
|
||||||
authority = auth->request->this->authority;
|
|
||||||
authority->check_for_hash_and_url(authority, cert);
|
|
||||||
}
|
|
||||||
cred = auth->request->this->cred;
|
cred = auth->request->this->cred;
|
||||||
cert = cred->add_cert(cred, cert);
|
cert = cred->add_cert(cred, cert);
|
||||||
auth->cfg->add(auth->cfg, rule, cert);
|
auth->cfg->add(auth->cfg, rule, cert);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 Tobias Brunner
|
* Copyright (C) 2008-2019 Tobias Brunner
|
||||||
* Copyright (C) 2006-2009 Martin Willi
|
* Copyright (C) 2006-2009 Martin Willi
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@@ -48,17 +48,58 @@ struct private_ike_cert_post_t {
|
|||||||
bool initiator;
|
bool initiator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the payload for a hash-and-URL encoded certificate
|
||||||
|
*/
|
||||||
|
static bool build_hash_url_payload(char *base, certificate_t *cert,
|
||||||
|
cert_payload_t **payload)
|
||||||
|
{
|
||||||
|
hasher_t *hasher;
|
||||||
|
chunk_t hash, encoded;
|
||||||
|
char *url, *hex_hash;
|
||||||
|
|
||||||
|
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||||
|
if (!hasher)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "unable to use hash-and-url: SHA-1 not supported");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cert->get_encoding(cert, CERT_ASN1_DER, &encoded))
|
||||||
|
{
|
||||||
|
hasher->destroy(hasher);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!hasher->allocate_hash(hasher, encoded, &hash))
|
||||||
|
{
|
||||||
|
hasher->destroy(hasher);
|
||||||
|
chunk_free(&encoded);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
chunk_free(&encoded);
|
||||||
|
hasher->destroy(hasher);
|
||||||
|
|
||||||
|
url = malloc(strlen(base) + 40 + 1);
|
||||||
|
strcpy(url, base);
|
||||||
|
hex_hash = chunk_to_hex(hash, NULL, FALSE).ptr;
|
||||||
|
strncat(url, hex_hash, 40);
|
||||||
|
free(hex_hash);
|
||||||
|
|
||||||
|
DBG1(DBG_IKE, "sending hash-and-url \"%s\"", url);
|
||||||
|
*payload = cert_payload_create_from_hash_and_url(hash, url);
|
||||||
|
chunk_free(&hash);
|
||||||
|
free(url);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the cert payload, if possible with "Hash and URL"
|
* Generates the cert payload, if possible with "Hash and URL"
|
||||||
*/
|
*/
|
||||||
static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this,
|
static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this,
|
||||||
certificate_t *cert)
|
certificate_t *cert)
|
||||||
{
|
{
|
||||||
hasher_t *hasher;
|
|
||||||
identification_t *id;
|
|
||||||
chunk_t hash, encoded ;
|
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
char *url;
|
char *base;
|
||||||
cert_payload_t *payload = NULL;
|
cert_payload_t *payload = NULL;
|
||||||
|
|
||||||
if (!this->ike_sa->supports_extension(this->ike_sa, EXT_HASH_AND_URL))
|
if (!this->ike_sa->supports_extension(this->ike_sa, EXT_HASH_AND_URL))
|
||||||
@@ -66,42 +107,14 @@ static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this,
|
|||||||
return cert_payload_create_from_cert(PLV2_CERTIFICATE, cert);
|
return cert_payload_create_from_cert(PLV2_CERTIFICATE, cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
enumerator = lib->credmgr->create_cdp_enumerator(lib->credmgr, CERT_X509,
|
||||||
if (!hasher)
|
cert->get_issuer(cert));
|
||||||
{
|
if (!enumerator->enumerate(enumerator, &base) ||
|
||||||
DBG1(DBG_IKE, "unable to use hash-and-url: sha1 not supported");
|
!build_hash_url_payload(base, cert, &payload))
|
||||||
return cert_payload_create_from_cert(PLV2_CERTIFICATE, cert);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cert->get_encoding(cert, CERT_ASN1_DER, &encoded))
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "encoding certificate for cert payload failed");
|
|
||||||
hasher->destroy(hasher);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!hasher->allocate_hash(hasher, encoded, &hash))
|
|
||||||
{
|
|
||||||
hasher->destroy(hasher);
|
|
||||||
chunk_free(&encoded);
|
|
||||||
return cert_payload_create_from_cert(PLV2_CERTIFICATE, cert);
|
|
||||||
}
|
|
||||||
chunk_free(&encoded);
|
|
||||||
hasher->destroy(hasher);
|
|
||||||
id = identification_create_from_encoding(ID_KEY_ID, hash);
|
|
||||||
|
|
||||||
enumerator = lib->credmgr->create_cdp_enumerator(lib->credmgr, CERT_X509, id);
|
|
||||||
if (enumerator->enumerate(enumerator, &url))
|
|
||||||
{
|
|
||||||
payload = cert_payload_create_from_hash_and_url(hash, url);
|
|
||||||
DBG1(DBG_IKE, "sending hash-and-url \"%s\"", url);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
payload = cert_payload_create_from_cert(PLV2_CERTIFICATE, cert);
|
payload = cert_payload_create_from_cert(PLV2_CERTIFICATE, cert);
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
chunk_free(&hash);
|
|
||||||
id->destroy(id);
|
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +158,7 @@ static void add_im_certs(private_ike_cert_post_t *this, auth_cfg_t *auth,
|
|||||||
{
|
{
|
||||||
if (type == AUTH_RULE_IM_CERT)
|
if (type == AUTH_RULE_IM_CERT)
|
||||||
{
|
{
|
||||||
payload = cert_payload_create_from_cert(PLV2_CERTIFICATE, cert);
|
payload = build_cert_payload(this, cert);
|
||||||
if (payload)
|
if (payload)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "sending issuer cert \"%Y\"",
|
DBG1(DBG_IKE, "sending issuer cert \"%Y\"",
|
||||||
|
|||||||
@@ -513,6 +513,13 @@ do
|
|||||||
cp ${RESEARCH_CERT} ${TEST}/hosts/moon/${SWANCTL_DIR}/x509ca
|
cp ${RESEARCH_CERT} ${TEST}/hosts/moon/${SWANCTL_DIR}/x509ca
|
||||||
done
|
done
|
||||||
|
|
||||||
|
for t in rw-hash-and-url-multi-level
|
||||||
|
do
|
||||||
|
TEST="${TEST_DIR}/swanctl/${t}"
|
||||||
|
mkdir -p ${TEST}/hosts/carol/${SWANCTL_DIR}/x509ca
|
||||||
|
cp ${RESEARCH_CERT} ${TEST}/hosts/carol/${SWANCTL_DIR}/x509ca
|
||||||
|
done
|
||||||
|
|
||||||
# Convert Research CA certificate into DER format
|
# Convert Research CA certificate into DER format
|
||||||
openssl x509 -in ${RESEARCH_CERT} -outform der -out ${RESEARCH_CERT_DER}
|
openssl x509 -in ${RESEARCH_CERT} -outform der -out ${RESEARCH_CERT_DER}
|
||||||
|
|
||||||
@@ -562,6 +569,13 @@ do
|
|||||||
cp ${SALES_CERT} ${TEST}/hosts/moon/${SWANCTL_DIR}/x509ca
|
cp ${SALES_CERT} ${TEST}/hosts/moon/${SWANCTL_DIR}/x509ca
|
||||||
done
|
done
|
||||||
|
|
||||||
|
for t in rw-hash-and-url-multi-level
|
||||||
|
do
|
||||||
|
TEST="${TEST_DIR}/swanctl/${t}"
|
||||||
|
mkdir -p ${TEST}/hosts/dave/${SWANCTL_DIR}/x509ca
|
||||||
|
cp ${SALES_CERT} ${TEST}/hosts/dave/${SWANCTL_DIR}/x509ca
|
||||||
|
done
|
||||||
|
|
||||||
# Convert Sales CA certificate into DER format
|
# Convert Sales CA certificate into DER format
|
||||||
openssl x509 -in ${SALES_CERT} -outform der -out ${SALES_CERT_DER}
|
openssl x509 -in ${SALES_CERT} -outform der -out ${SALES_CERT_DER}
|
||||||
|
|
||||||
@@ -936,7 +950,7 @@ do
|
|||||||
cp ${TEST_CERT} ${TEST}/hosts/carol/${IPSEC_DIR}/certs
|
cp ${TEST_CERT} ${TEST}/hosts/carol/${IPSEC_DIR}/certs
|
||||||
done
|
done
|
||||||
|
|
||||||
for t in multi-level-ca ocsp-multi-level
|
for t in multi-level-ca rw-hash-and-url-multi-level ocsp-multi-level
|
||||||
do
|
do
|
||||||
TEST="${TEST_DIR}/swanctl/${t}"
|
TEST="${TEST_DIR}/swanctl/${t}"
|
||||||
mkdir -p ${TEST}/hosts/carol/${SWANCTL_DIR}/rsa
|
mkdir -p ${TEST}/hosts/carol/${SWANCTL_DIR}/rsa
|
||||||
@@ -1051,7 +1065,7 @@ do
|
|||||||
cp ${TEST_CERT} ${TEST}/hosts/dave/${IPSEC_DIR}/certs
|
cp ${TEST_CERT} ${TEST}/hosts/dave/${IPSEC_DIR}/certs
|
||||||
done
|
done
|
||||||
|
|
||||||
for t in multi-level-ca ocsp-multi-level
|
for t in multi-level-ca rw-hash-and-url-multi-level ocsp-multi-level
|
||||||
do
|
do
|
||||||
TEST="${TEST_DIR}/swanctl/${t}"
|
TEST="${TEST_DIR}/swanctl/${t}"
|
||||||
mkdir -p ${TEST}/hosts/dave/${SWANCTL_DIR}/rsa
|
mkdir -p ${TEST}/hosts/dave/${SWANCTL_DIR}/rsa
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
The VPN gateway <b>moon</b> controls the access to the hosts <b>alice</b> and
|
||||||
|
<b>venus</b> by means of two different Intermediate CAs. Access to
|
||||||
|
<b>alice</b> is granted to users presenting a certificate issued by the Research CA
|
||||||
|
whereas <b>venus</b> can only be reached with a certificate issued by the
|
||||||
|
Sales CA. The roadwarriors <b>carol</b> and <b>dave</b> have certificates from
|
||||||
|
the Research CA and Sales CA, respectively. Therefore <b>carol</b> can access
|
||||||
|
<b>alice</b> and <b>dave</b> can reach <b>venus</b>.
|
||||||
|
<p/>
|
||||||
|
The gateway <b>moon</b> doesn't have the intermediate CA certificate installed
|
||||||
|
and instead of sending the actual certificates, the two clients send "Hash and URL"
|
||||||
|
certificate payloads. The gateway fetches the certificates via HTTP from server
|
||||||
|
<b>winnetou</b>.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
carol::cat /var/log/daemon.log::fetched certificate.*moon.strongswan.org::YES
|
||||||
|
dave:: cat /var/log/daemon.log::fetched certificate.*moon.strongswan.org::YES
|
||||||
|
moon:: cat /var/log/daemon.log::fetched certificate.*[email protected]::YES
|
||||||
|
moon:: cat /var/log/daemon.log::fetched certificate.*CN=Research CA::YES
|
||||||
|
moon:: cat /var/log/daemon.log::fetched certificate.*[email protected]::YES
|
||||||
|
moon:: cat /var/log/daemon.log::fetched certificate.*CN=Sales CA::YES
|
||||||
|
moon:: cat /var/log/daemon.log::fetching crl from.*http.*research.crl::YES
|
||||||
|
moon:: cat /var/log/daemon.log::crl correctly signed by.*Research CA::YES
|
||||||
|
moon:: cat /var/log/daemon.log::fetching crl from.*http.*sales.crl::YES
|
||||||
|
moon:: cat /var/log/daemon.log::crl correctly signed by.*Sales CA::YES
|
||||||
|
moon:: cat /var/log/daemon.log::fetching crl from.*http.*strongswan.crl::YES
|
||||||
|
moon:: cat /var/log/daemon.log::crl correctly signed by.*strongSwan Root CA::YES
|
||||||
|
carol::swanctl --list-sas --raw 2> /dev/null::home.*version=2 state=ESTABLISHED local-host=192.168.0.100 local-port=4500 local-id=C=CH, O=strongSwan Project, OU=Research, [email protected] remote-host=192.168.0.1 remote-port=4500 remote-id=moon.strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=ECP_256.*child-sas.*alice.*state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128.*local-ts=\[192.168.0.100/32] remote-ts=\[10.1.0.10/32]::YES
|
||||||
|
moon:: swanctl --list-sas --raw 2> /dev/null::research.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=4500 local-id=moon.strongswan.org remote-host=192.168.0.100 remote-port=4500 remote-id=C=CH, O=strongSwan Project, OU=Research, [email protected].*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=ECP_256.*child-sas.*alice.*state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128.*local-ts=\[10.1.0.10/32] remote-ts=\[192.168.0.100/32]::YES
|
||||||
|
carol::cat /var/log/daemon.log::received TS_UNACCEPTABLE notify, no CHILD_SA built::YES
|
||||||
|
carol::swanctl --list-sas --raw 2> /dev/null::home.*version=2 state=ESTABLISHED.*child-sas.*venus.*state=INSTALLED::NO
|
||||||
|
moon:: swanctl --list-sas --raw 2> /dev/null::sales.*version=2 state=ESTABLISHED.*remote-host=192.168.0.100 remote-port=4500 [email protected].*child-sas.*venus.*state=INSTALLED::NO
|
||||||
|
dave:: cat /var/log/daemon.log::received TS_UNACCEPTABLE notify, no CHILD_SA built::YES
|
||||||
|
dave:: swanctl --list-sas --raw 2> /dev/null::home.*version=2 state=ESTABLISHED.*child-sas.*alice.*state=INSTALLED::NO
|
||||||
|
moon:: swanctl --list-sas --raw 2> /dev/null::research.*version=2 state=ESTABLISHED.*remote-host=192.168.0.100 remote-port=4500 [email protected].*child-sas.*alice.*state=INSTALLED::NO
|
||||||
|
dave:: swanctl --list-sas --raw 2> /dev/null::home.*version=2 state=ESTABLISHED local-host=192.168.0.200 local-port=4500 local-id=C=CH, O=strongSwan Project, OU=Sales, [email protected] remote-host=192.168.0.1 remote-port=4500 remote-id=moon.strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=ECP_256.*child-sas.*venus.*state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128.*local-ts=\[192.168.0.200/32] remote-ts=\[10.1.0.20/32]::YES
|
||||||
|
moon:: swanctl --list-sas --raw 2> /dev/null::sales.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=4500 local-id=moon.strongswan.org remote-host=192.168.0.200 remote-port=4500 remote-id=C=CH, O=strongSwan Project, OU=Sales, [email protected].*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=ECP_256.*child-sas.*venus.*state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128.*local-ts=\[10.1.0.20/32] remote-ts=\[192.168.0.200/32]::YES
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# /etc/strongswan.conf - strongSwan configuration file
|
||||||
|
|
||||||
|
swanctl {
|
||||||
|
load = pem pkcs1 x509 revocation constraints pubkey openssl random
|
||||||
|
}
|
||||||
|
|
||||||
|
charon-systemd {
|
||||||
|
load = pem pkcs1 x509 revocation constraints pubkey openssl random nonce curl kernel-netlink socket-default vici
|
||||||
|
|
||||||
|
hash_and_url = yes
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
connections {
|
||||||
|
|
||||||
|
home {
|
||||||
|
remote_addrs = 192.168.0.1
|
||||||
|
|
||||||
|
local {
|
||||||
|
auth = pubkey
|
||||||
|
certs = carolCert.pem
|
||||||
|
}
|
||||||
|
remote {
|
||||||
|
auth = pubkey
|
||||||
|
id = moon.strongswan.org
|
||||||
|
revocation = strict
|
||||||
|
}
|
||||||
|
children {
|
||||||
|
alice {
|
||||||
|
remote_ts = 10.1.0.10/32
|
||||||
|
esp_proposals = aes128-sha256-ecp256
|
||||||
|
}
|
||||||
|
venus {
|
||||||
|
remote_ts = 10.1.0.20/32
|
||||||
|
esp_proposals = aes128-sha256-ecp256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
version = 2
|
||||||
|
proposals = aes128-sha256-ecp256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorities {
|
||||||
|
|
||||||
|
strongswan {
|
||||||
|
cacert = strongswanCert.pem
|
||||||
|
cert_uri_base = http://winnetou.strongswan.org/certs/
|
||||||
|
}
|
||||||
|
|
||||||
|
research {
|
||||||
|
cacert = researchCert.pem
|
||||||
|
cert_uri_base = http://winnetou.strongswan.org/certs/research/
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# /etc/strongswan.conf - strongSwan configuration file
|
||||||
|
|
||||||
|
swanctl {
|
||||||
|
load = pem pkcs1 x509 revocation constraints pubkey openssl random
|
||||||
|
}
|
||||||
|
|
||||||
|
charon-systemd {
|
||||||
|
load = pem pkcs1 x509 revocation constraints pubkey openssl random nonce curl kernel-netlink socket-default vici
|
||||||
|
|
||||||
|
hash_and_url = yes
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
connections {
|
||||||
|
|
||||||
|
home {
|
||||||
|
remote_addrs = 192.168.0.1
|
||||||
|
|
||||||
|
local {
|
||||||
|
auth = pubkey
|
||||||
|
certs = daveCert.pem
|
||||||
|
}
|
||||||
|
remote {
|
||||||
|
auth = pubkey
|
||||||
|
id = moon.strongswan.org
|
||||||
|
revocation = strict
|
||||||
|
}
|
||||||
|
children {
|
||||||
|
alice {
|
||||||
|
remote_ts = 10.1.0.10/32
|
||||||
|
esp_proposals = aes128-sha256-ecp256
|
||||||
|
}
|
||||||
|
venus {
|
||||||
|
remote_ts = 10.1.0.20/32
|
||||||
|
esp_proposals = aes128-sha256-ecp256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
version = 2
|
||||||
|
proposals = aes128-sha256-ecp256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorities {
|
||||||
|
|
||||||
|
strongswan {
|
||||||
|
cacert = strongswanCert.pem
|
||||||
|
cert_uri_base = http://winnetou.strongswan.org/certs/
|
||||||
|
}
|
||||||
|
|
||||||
|
sales {
|
||||||
|
cacert = salesCert.pem
|
||||||
|
cert_uri_base = http://winnetou.strongswan.org/certs/sales/
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# /etc/strongswan.conf - strongSwan configuration file
|
||||||
|
|
||||||
|
swanctl {
|
||||||
|
load = pem pkcs1 x509 revocation constraints pubkey openssl random
|
||||||
|
}
|
||||||
|
|
||||||
|
charon-systemd {
|
||||||
|
load = pem pkcs1 x509 revocation constraints pubkey openssl random nonce curl kernel-netlink socket-default vici
|
||||||
|
|
||||||
|
hash_and_url = yes
|
||||||
|
}
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
connections {
|
||||||
|
|
||||||
|
research {
|
||||||
|
local_addrs = 192.168.0.1
|
||||||
|
|
||||||
|
local {
|
||||||
|
auth = pubkey
|
||||||
|
certs = moonCert.pem
|
||||||
|
id = moon.strongswan.org
|
||||||
|
}
|
||||||
|
remote {
|
||||||
|
auth = pubkey
|
||||||
|
id = "C=CH, O=strongSwan Project, OU=Research, CN=*"
|
||||||
|
}
|
||||||
|
children {
|
||||||
|
alice {
|
||||||
|
local_ts = 10.1.0.10/32
|
||||||
|
esp_proposals = aes128-sha256-ecp256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
version = 2
|
||||||
|
proposals = aes128-sha256-ecp256
|
||||||
|
}
|
||||||
|
|
||||||
|
sales {
|
||||||
|
local_addrs = 192.168.0.1
|
||||||
|
|
||||||
|
local {
|
||||||
|
auth = pubkey
|
||||||
|
certs = moonCert.pem
|
||||||
|
id = moon.strongswan.org
|
||||||
|
}
|
||||||
|
remote {
|
||||||
|
auth = pubkey
|
||||||
|
id = "C=CH, O=strongSwan Project, OU=Sales, CN=*"
|
||||||
|
}
|
||||||
|
children {
|
||||||
|
venus {
|
||||||
|
local_ts = 10.1.0.20/32
|
||||||
|
esp_proposals = aes128-sha256-ecp256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
version = 2
|
||||||
|
proposals = aes128-sha256-ecp256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorities {
|
||||||
|
|
||||||
|
strongswan {
|
||||||
|
cacert = strongswanCert.pem
|
||||||
|
cert_uri_base = http://winnetou.strongswan.org/certs/
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
carol::swanctl --terminate --ike home 2> /dev/null
|
||||||
|
dave::swanctl --terminate --ike home 2> /dev/null
|
||||||
|
carol::systemctl stop strongswan
|
||||||
|
dave::systemctl stop strongswan
|
||||||
|
moon::systemctl stop strongswan
|
||||||
|
carol::cd /etc/swanctl; rm -r rsa/* x509/* x509ca/*
|
||||||
|
dave::cd /etc/swanctl; rm -r rsa/* x509/* x509ca/*
|
||||||
|
moon::cd /etc/swanctl; rm -r rsa/* x509/* x509ca/*
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
moon::systemctl start strongswan
|
||||||
|
carol::systemctl start strongswan
|
||||||
|
dave::systemctl start strongswan
|
||||||
|
moon::expect-connection research
|
||||||
|
carol::expect-connection alice
|
||||||
|
carol::swanctl --initiate --child alice 2> /dev/null
|
||||||
|
carol::swanctl --initiate --child venus 2> /dev/null
|
||||||
|
dave::expect-connection alice
|
||||||
|
dave::swanctl --initiate --child alice 2> /dev/null
|
||||||
|
dave::swanctl --initiate --child venus 2> /dev/null
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# This configuration file provides information on the
|
||||||
|
# guest instances used for this test
|
||||||
|
|
||||||
|
# All guest instances that are required for this test
|
||||||
|
#
|
||||||
|
VIRTHOSTS="alice venus moon carol winnetou dave"
|
||||||
|
|
||||||
|
# Corresponding block diagram
|
||||||
|
#
|
||||||
|
DIAGRAM="a-v-m-c-w-d.png"
|
||||||
|
|
||||||
|
# Guest instances on which tcpdump is to be started
|
||||||
|
#
|
||||||
|
TCPDUMPHOSTS="moon"
|
||||||
|
|
||||||
|
# Guest instances on which IPsec is started
|
||||||
|
# Used for IPsec logging purposes
|
||||||
|
#
|
||||||
|
IPSECHOSTS="moon carol dave"
|
||||||
|
|
||||||
|
# charon controlled by swanctl
|
||||||
|
#
|
||||||
|
SWANCTL=1
|
||||||
Reference in New Issue
Block a user