Merge branch 'multi-cert'
Allows the configuration of multiple certificates in leftcert, and select the correct certificate to use based on the received certificate requests.
This commit is contained in:
@@ -1083,6 +1083,29 @@ static private_key_t *get_private_by_cert(private_credential_manager_t *this,
|
||||
return private;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the actually used certificate to front, so it gets returned with get()
|
||||
*/
|
||||
static void prefer_cert(auth_cfg_t *auth, certificate_t *cert)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
auth_rule_t rule;
|
||||
certificate_t *current;
|
||||
|
||||
enumerator = auth->create_enumerator(auth);
|
||||
while (enumerator->enumerate(enumerator, &rule, ¤t))
|
||||
{
|
||||
if (rule == AUTH_RULE_SUBJECT_CERT)
|
||||
{
|
||||
current->get_ref(current);
|
||||
auth->replace(auth, enumerator, AUTH_RULE_SUBJECT_CERT, cert);
|
||||
cert = current;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert);
|
||||
}
|
||||
|
||||
METHOD(credential_manager_t, get_private, private_key_t*,
|
||||
private_credential_manager_t *this, key_type_t type, identification_t *id,
|
||||
auth_cfg_t *auth)
|
||||
@@ -1091,6 +1114,7 @@ METHOD(credential_manager_t, get_private, private_key_t*,
|
||||
certificate_t *cert;
|
||||
private_key_t *private = NULL;
|
||||
auth_cfg_t *trustchain;
|
||||
auth_rule_t rule;
|
||||
|
||||
/* check if this is a lookup by key ID, and do it if so */
|
||||
if (id && id->get_type(id) == ID_KEY_ID)
|
||||
@@ -1104,7 +1128,35 @@ METHOD(credential_manager_t, get_private, private_key_t*,
|
||||
|
||||
if (auth)
|
||||
{
|
||||
/* if a specific certificate is preferred, check for a matching key */
|
||||
/* try to find a trustchain with one of the configured subject certs */
|
||||
enumerator = auth->create_enumerator(auth);
|
||||
while (enumerator->enumerate(enumerator, &rule, &cert))
|
||||
{
|
||||
if (rule == AUTH_RULE_SUBJECT_CERT)
|
||||
{
|
||||
private = get_private_by_cert(this, cert, type);
|
||||
if (private)
|
||||
{
|
||||
trustchain = build_trustchain(this, cert, auth);
|
||||
if (trustchain)
|
||||
{
|
||||
auth->merge(auth, trustchain, FALSE);
|
||||
prefer_cert(auth, cert->get_ref(cert));
|
||||
trustchain->destroy(trustchain);
|
||||
break;
|
||||
}
|
||||
private->destroy(private);
|
||||
private = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (private)
|
||||
{
|
||||
return private;
|
||||
}
|
||||
|
||||
/* if none yielded a trustchain, enforce the first configured cert */
|
||||
cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
|
||||
if (cert)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user