support for hash and URL encoded certificate payloads in charon

This commit is contained in:
Tobias Brunner
2008-04-18 11:24:45 +00:00
parent eed87e1d76
commit 6439267a8c
23 changed files with 760 additions and 160 deletions
+100 -8
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -20,6 +21,7 @@
#include <utils/mutex.h>
#include <utils/linked_list.h>
#include <crypto/hashers/hasher.h>
#include <daemon.h>
@@ -77,6 +79,16 @@ struct ca_section_t {
* OCSP URIs
*/
linked_list_t *ocsp;
/**
* Hashes of certificates issued by this CA
*/
linked_list_t *hashes;
/**
* Base URI used for certificates from this CA
*/
char *certuribase;
};
/**
@@ -90,6 +102,8 @@ static ca_section_t *ca_section_create(char *name, certificate_t *cert)
ca->crl = linked_list_create();
ca->ocsp = linked_list_create();
ca->cert = cert;
ca->hashes = linked_list_create();
ca->certuribase = NULL;
return ca;
}
@@ -100,6 +114,8 @@ static void ca_section_destroy(ca_section_t *this)
{
this->crl->destroy_function(this->crl, free);
this->ocsp->destroy_function(this->ocsp, free);
this->hashes->destroy_offset(this->hashes, offsetof(identification_t, destroy));
free(this->certuribase);
free(this->name);
free(this);
}
@@ -161,6 +177,39 @@ static enumerator_t *create_inner_cdp(ca_section_t *section, cdp_data_t *data)
return enumerator;
}
/**
* inner enumerator constructor for hash and URL
*/
static enumerator_t *create_inner_cdp_hashandurl(ca_section_t *section, cdp_data_t *data)
{
enumerator_t *enumerator = NULL, *hash_enum;
identification_t *current;
if (!data->id || !section->certuribase)
{
return NULL;
}
hash_enum = section->hashes->create_enumerator(section->hashes);
while (hash_enum->enumerate(hash_enum, &current))
{
if (current->matches(current, data->id))
{
chunk_t hash = current->get_encoding(current);
char *hash_str = chunk_to_hex(hash, FALSE);
char *url = malloc(strlen(section->certuribase) + 40 + 1);
strcpy(url, section->certuribase);
strncat(url, hash_str, 40);
free(hash_str);
enumerator = enumerator_create_single(url, free);
break;
}
}
hash_enum->destroy(hash_enum);
return enumerator;
}
/**
* Implementation of credential_set_t.create_cdp_enumerator.
*/
@@ -170,7 +219,8 @@ static enumerator_t *create_cdp_enumerator(private_stroke_ca_t *this,
cdp_data_t *data;
switch (type)
{ /* we serve CRLs and OCSP responders */
{ /* we serve CRLs, OCSP responders and URLs for hash and URL */
case CERT_X509:
case CERT_X509_CRL:
case CERT_X509_OCSP_RESPONSE:
case CERT_ANY:
@@ -185,8 +235,8 @@ static enumerator_t *create_cdp_enumerator(private_stroke_ca_t *this,
this->mutex->lock(this->mutex);
return enumerator_create_nested(this->sections->create_enumerator(this->sections),
(void*)create_inner_cdp, data,
(void*)cdp_data_destroy);
(type == CERT_X509) ? (void*)create_inner_cdp_hashandurl : (void*)create_inner_cdp,
data, (void*)cdp_data_destroy);
}
/**
* Implementation of stroke_ca_t.add.
@@ -221,6 +271,10 @@ static void add(private_stroke_ca_t *this, stroke_msg_t *msg)
{
ca->ocsp->insert_last(ca->ocsp, strdup(msg->add_ca.ocspuri2));
}
if (msg->add_ca.certuribase)
{
ca->certuribase = strdup(msg->add_ca.certuribase);
}
this->mutex->lock(this->mutex);
this->sections->insert_last(this->sections, ca);
this->mutex->unlock(this->mutex);
@@ -284,6 +338,42 @@ static void list_uris(linked_list_t *list, char *label, FILE *out)
enumerator->destroy(enumerator);
}
/**
* Implementation of stroke_ca_t.check_for_hash_and_url.
*/
static void check_for_hash_and_url(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->mutex->lock(this->mutex);
enumerator = this->sections->create_enumerator(this->sections);
while (enumerator->enumerate(enumerator, (void**)&section))
{
if (section->certuribase && cert->issued_by(cert, section->cert))
{
chunk_t hash, encoded = cert->get_encoding(cert);
hasher->allocate_hash(hasher, encoded, &hash);
section->hashes->insert_last(section->hashes,
identification_create_from_encoding(ID_CERT_DER_SHA1, hash));
chunk_free(&hash);
chunk_free(&encoded);
break;
}
}
enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
hasher->destroy(hasher);
}
/**
* Implementation of stroke_ca_t.list.
*/
@@ -307,19 +397,20 @@ static void list(private_stroke_ca_t *this, stroke_msg_t *msg, FILE *out)
first = FALSE;
}
fprintf(out, "\n");
fprintf(out, " authname: \"%D\"\n", cert->get_subject(cert));
fprintf(out, " authname: \"%D\"\n", cert->get_subject(cert));
/* list authkey and keyid */
if (public)
{
fprintf(out, " authkey: %D\n",
fprintf(out, " authkey: %D\n",
public->get_id(public, ID_PUBKEY_SHA1));
fprintf(out, " keyid: %D\n",
fprintf(out, " keyid: %D\n",
public->get_id(public, ID_PUBKEY_INFO_SHA1));
public->destroy(public);
}
list_uris(section->crl, " crluris: ", out);
list_uris(section->ocsp, " ocspuris: ", out);
list_uris(section->crl, " crluris: ", out);
list_uris(section->ocsp, " ocspuris: ", out);
fprintf(out, " certuribase: '%s'\n", section->certuribase);
}
enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
@@ -350,6 +441,7 @@ stroke_ca_t *stroke_ca_create(stroke_cred_t *cred)
this->public.add = (void(*)(stroke_ca_t*, stroke_msg_t *msg))add;
this->public.del = (void(*)(stroke_ca_t*, stroke_msg_t *msg))del;
this->public.list = (void(*)(stroke_ca_t*, stroke_msg_t *msg, FILE *out))list;
this->public.check_for_hash_and_url = (void(*)(stroke_ca_t*, certificate_t*))check_for_hash_and_url;
this->public.destroy = (void(*)(stroke_ca_t*))destroy;
this->sections = linked_list_create();
+8
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -60,6 +61,13 @@ struct stroke_ca_t {
*/
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);
/**
* Destroy a stroke_ca instance.
*/
+8 -1
View File
@@ -42,6 +42,11 @@ struct private_stroke_config_t {
*/
mutex_t *mutex;
/**
* ca sections
*/
stroke_ca_t *ca;
/**
* credentials
*/
@@ -435,6 +440,7 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
cert = this->cred->load_peer(this->cred, msg->add_conn.me.cert);
if (cert)
{
this->ca->check_for_hash_and_url(this->ca, cert);
me = update_peerid(cert, me);
cert->destroy(cert);
}
@@ -805,7 +811,7 @@ static void destroy(private_stroke_config_t *this)
/*
* see header file
*/
stroke_config_t *stroke_config_create(stroke_cred_t *cred)
stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred)
{
private_stroke_config_t *this = malloc_thing(private_stroke_config_t);
@@ -818,6 +824,7 @@ stroke_config_t *stroke_config_create(stroke_cred_t *cred)
this->list = linked_list_create();
this->mutex = mutex_create(MUTEX_RECURSIVE);
this->ca = ca;
this->cred = cred;
return &this->public;
+2 -1
View File
@@ -25,6 +25,7 @@
#include <config/backend.h>
#include <stroke_msg.h>
#include "stroke_ca.h"
#include "stroke_cred.h"
typedef struct stroke_config_t stroke_config_t;
@@ -62,6 +63,6 @@ struct stroke_config_t {
/**
* Create a stroke_config instance.
*/
stroke_config_t *stroke_config_create(stroke_cred_t *cred);
stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred);
#endif /* STROKE_CONFIG_H_ @}*/
+9 -7
View File
@@ -250,13 +250,15 @@ static void stroke_add_ca(private_stroke_socket_t *this,
pop_string(msg, &msg->add_ca.crluri2);
pop_string(msg, &msg->add_ca.ocspuri);
pop_string(msg, &msg->add_ca.ocspuri2);
pop_string(msg, &msg->add_ca.certuribase);
DBG2(DBG_CFG, "ca %s", msg->add_ca.name);
DBG2(DBG_CFG, " cacert=%s", msg->add_ca.cacert);
DBG2(DBG_CFG, " crluri=%s", msg->add_ca.crluri);
DBG2(DBG_CFG, " crluri2=%s", msg->add_ca.crluri2);
DBG2(DBG_CFG, " ocspuri=%s", msg->add_ca.ocspuri);
DBG2(DBG_CFG, " ocspuri2=%s", msg->add_ca.ocspuri2);
DBG2(DBG_CFG, "ca %s", msg->add_ca.name);
DBG2(DBG_CFG, " cacert=%s", msg->add_ca.cacert);
DBG2(DBG_CFG, " crluri=%s", msg->add_ca.crluri);
DBG2(DBG_CFG, " crluri2=%s", msg->add_ca.crluri2);
DBG2(DBG_CFG, " ocspuri=%s", msg->add_ca.ocspuri);
DBG2(DBG_CFG, " ocspuri2=%s", msg->add_ca.ocspuri2);
DBG2(DBG_CFG, " certuribase=%s", msg->add_ca.certuribase);
DBG1(DBG_CFG, "received stroke: add ca '%s'", msg->add_ca.name);
@@ -588,7 +590,7 @@ stroke_socket_t *stroke_socket_create()
this->cred = stroke_cred_create();
this->attribute = stroke_attribute_create();
this->ca = stroke_ca_create(this->cred);
this->config = stroke_config_create(this->cred);
this->config = stroke_config_create(this->ca, this->cred);
this->control = stroke_control_create();
this->list = stroke_list_create();