charon-nm: Simplify certificate enumeration and allow IDs other than DNs
This allows using SANs as identity instead of having to use the subject DN. References strongswan/strongswan#437.
This commit is contained in:
parent
ae71f8357d
commit
8dbf40d19a
|
@ -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,
|
static enumerator_t *create_usercert_enumerator(private_nm_creds_t *this,
|
||||||
certificate_type_t cert, key_type_t key)
|
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(
|
return enumerator_create_cleaner(
|
||||||
enumerator_create_single(this->usercert, NULL),
|
enumerator_create_single(this->usercert, NULL),
|
||||||
(void*)this->lock->unlock, this->lock);
|
(void*)this->lock->unlock, this->lock);
|
||||||
|
@ -114,6 +93,8 @@ static enumerator_t *create_usercert_enumerator(private_nm_creds_t *this,
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** ref to credential credential store */
|
/** ref to credential credential store */
|
||||||
private_nm_creds_t *this;
|
private_nm_creds_t *this;
|
||||||
|
/** certificate type we are looking for */
|
||||||
|
certificate_type_t type;
|
||||||
/** type of key we are looking for */
|
/** type of key we are looking for */
|
||||||
key_type_t key;
|
key_type_t key;
|
||||||
/** CA certificate ID */
|
/** CA certificate ID */
|
||||||
|
@ -131,55 +112,36 @@ CALLBACK(cert_filter, bool,
|
||||||
cert_data_t *data, enumerator_t *orig, va_list args)
|
cert_data_t *data, enumerator_t *orig, va_list args)
|
||||||
{
|
{
|
||||||
certificate_t *cert, **out;
|
certificate_t *cert, **out;
|
||||||
public_key_t *public;
|
|
||||||
|
|
||||||
VA_ARGS_VGET(args, out);
|
VA_ARGS_VGET(args, out);
|
||||||
|
|
||||||
while (orig->enumerate(orig, &cert))
|
while (orig->enumerate(orig, &cert))
|
||||||
{
|
{
|
||||||
public = cert->get_public_key(cert);
|
if (certificate_matches(cert, data->type, data->key, data->id))
|
||||||
if (!public)
|
|
||||||
{
|
{
|
||||||
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;
|
*out = cert;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
public->destroy(public);
|
|
||||||
if (data->id && !cert->has_subject(cert, data->id))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*out = cert;
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
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,
|
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;
|
cert_data_t *data;
|
||||||
|
|
||||||
INIT(data,
|
INIT(data,
|
||||||
.this = this,
|
.this = this,
|
||||||
.id = id,
|
.type = type,
|
||||||
.key = key,
|
.key = key,
|
||||||
|
.id = id,
|
||||||
);
|
);
|
||||||
|
|
||||||
this->lock->read_lock(this->lock);
|
|
||||||
return enumerator_create_filter(
|
return enumerator_create_filter(
|
||||||
this->certs->create_enumerator(this->certs),
|
this->certs->create_enumerator(this->certs),
|
||||||
cert_filter, data, cert_data_destroy);
|
cert_filter, data, cert_data_destroy);
|
||||||
|
@ -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,
|
private_nm_creds_t *this, certificate_type_t cert, key_type_t key,
|
||||||
identification_t *id, bool trusted)
|
identification_t *id, bool trusted)
|
||||||
{
|
{
|
||||||
|
this->lock->read_lock(this->lock);
|
||||||
|
|
||||||
if (id && this->usercert &&
|
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);
|
return create_usercert_enumerator(this, cert, key);
|
||||||
}
|
}
|
||||||
if (cert == CERT_X509 || cert == CERT_ANY)
|
return create_trusted_cert_enumerator(this, cert, key, id);
|
||||||
{
|
|
||||||
return create_trusted_cert_enumerator(this, key, id);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
|
METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
|
||||||
|
|
Loading…
Reference in New Issue