Skip to content

Commit

Permalink
charon-nm: Simplify certificate enumeration and allow IDs other than DNs
Browse files Browse the repository at this point in the history
This allows using SANs as identity instead of having to use the subject DN.

References #437.
  • Loading branch information
tobiasbrunner committed Jun 14, 2021
1 parent ae71f83 commit 8dbf40d
Showing 1 changed file with 13 additions and 53 deletions.
66 changes: 13 additions & 53 deletions src/charon-nm/nm/nm_creds.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,32 +77,11 @@ struct private_nm_creds_t {
};

/**
* Enumerator for user certificate
* Enumerator for user certificate (lock has to be locked)
*/
static enumerator_t *create_usercert_enumerator(private_nm_creds_t *this,
certificate_type_t cert, key_type_t key)
{
public_key_t *public;

if (cert != CERT_ANY && cert != this->usercert->get_type(this->usercert))
{
return NULL;
}
if (key != KEY_ANY)
{
public = this->usercert->get_public_key(this->usercert);
if (!public)
{
return NULL;
}
if (public->get_type(public) != key)
{
public->destroy(public);
return NULL;
}
public->destroy(public);
}
this->lock->read_lock(this->lock);
return enumerator_create_cleaner(
enumerator_create_single(this->usercert, NULL),
(void*)this->lock->unlock, this->lock);
Expand All @@ -114,6 +93,8 @@ static enumerator_t *create_usercert_enumerator(private_nm_creds_t *this,
typedef struct {
/** ref to credential credential store */
private_nm_creds_t *this;
/** certificate type we are looking for */
certificate_type_t type;
/** type of key we are looking for */
key_type_t key;
/** CA certificate ID */
Expand All @@ -131,55 +112,36 @@ CALLBACK(cert_filter, bool,
cert_data_t *data, enumerator_t *orig, va_list args)
{
certificate_t *cert, **out;
public_key_t *public;

VA_ARGS_VGET(args, out);

while (orig->enumerate(orig, &cert))
{
public = cert->get_public_key(cert);
if (!public)
if (certificate_matches(cert, data->type, data->key, data->id))
{
continue;
}
if (data->key != KEY_ANY && public->get_type(public) != data->key)
{
public->destroy(public);
continue;
}
if (data->id && data->id->get_type(data->id) == ID_KEY_ID &&
public->has_fingerprint(public, data->id->get_encoding(data->id)))
{
public->destroy(public);
*out = cert;
return TRUE;
}
public->destroy(public);
if (data->id && !cert->has_subject(cert, data->id))
{
continue;
}
*out = cert;
return TRUE;
}
return FALSE;
}

/**
* Create enumerator for trusted certificates
* Create enumerator for trusted certificates (lock has to be locked)
*/
static enumerator_t *create_trusted_cert_enumerator(private_nm_creds_t *this,
key_type_t key, identification_t *id)
certificate_type_t type, key_type_t key,
identification_t *id)
{
cert_data_t *data;

INIT(data,
.this = this,
.id = id,
.type = type,
.key = key,
.id = id,
);

this->lock->read_lock(this->lock);
return enumerator_create_filter(
this->certs->create_enumerator(this->certs),
cert_filter, data, cert_data_destroy);
Expand All @@ -189,16 +151,14 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
private_nm_creds_t *this, certificate_type_t cert, key_type_t key,
identification_t *id, bool trusted)
{
this->lock->read_lock(this->lock);

if (id && this->usercert &&
id->equals(id, this->usercert->get_subject(this->usercert)))
certificate_matches(this->usercert, cert, key, id))
{
return create_usercert_enumerator(this, cert, key);
}
if (cert == CERT_X509 || cert == CERT_ANY)
{
return create_trusted_cert_enumerator(this, key, id);
}
return NULL;
return create_trusted_cert_enumerator(this, cert, key, id);
}

METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
Expand Down

0 comments on commit 8dbf40d

Please sign in to comment.