Merge branch 'stroke-purge-on-reread'
Remove all previously loaded certificates during "ipsec reread", finally allowing the removal of CA certificates from a running daemon. Fixes #842, #700, #305.
This commit is contained in:
@@ -210,15 +210,18 @@ flushes and rereads all secrets defined in \fIipsec.secrets\fP.
|
|||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
.B "rereadcacerts"
|
.B "rereadcacerts"
|
||||||
reads all certificate files contained in the \fI/etc/ipsec.d/cacerts\fP
|
removes previously loaded CA certificates, reads all certificate files
|
||||||
directory and adds them to the list of Certification Authority (CA)
|
contained in the \fI/etc/ipsec.d/cacerts\fP directory and adds them to the list
|
||||||
certificates.
|
of Certification Authority (CA) certificates. This does not affect certificates
|
||||||
|
explicitly defined in a
|
||||||
|
.BR ipsec.conf (5)
|
||||||
|
ca section, which may be separately updated using the \fBupdate\fP command.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
.B "rereadaacerts"
|
.B "rereadaacerts"
|
||||||
reads all certificate files contained in the \fI/etc/ipsec.d/aacerts\fP
|
removes previously loaded AA certificates, reads all certificate files
|
||||||
directory and adds them to the list of Authorization Authority (AA)
|
contained in the \fI/etc/ipsec.d/aacerts\fP directory and adds them to the list
|
||||||
certificates.
|
of Authorization Authority (AA) certificates.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
.B "rereadocspcerts"
|
.B "rereadocspcerts"
|
||||||
|
|||||||
@@ -119,6 +119,84 @@ static void ca_section_destroy(ca_section_t *this)
|
|||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data for the certificate enumerator
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
private_stroke_ca_t *this;
|
||||||
|
certificate_type_t cert;
|
||||||
|
key_type_t key;
|
||||||
|
identification_t *id;
|
||||||
|
} cert_data_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* destroy cert_data
|
||||||
|
*/
|
||||||
|
static void cert_data_destroy(cert_data_t *data)
|
||||||
|
{
|
||||||
|
data->this->lock->unlock(data->this->lock);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* filter function for certs enumerator
|
||||||
|
*/
|
||||||
|
static bool certs_filter(cert_data_t *data, ca_section_t **in,
|
||||||
|
certificate_t **out)
|
||||||
|
{
|
||||||
|
public_key_t *public;
|
||||||
|
certificate_t *cert = (*in)->cert;
|
||||||
|
|
||||||
|
if (data->cert == CERT_ANY || data->cert == cert->get_type(cert))
|
||||||
|
{
|
||||||
|
public = cert->get_public_key(cert);
|
||||||
|
if (public)
|
||||||
|
{
|
||||||
|
if (data->key == KEY_ANY || data->key == public->get_type(public))
|
||||||
|
{
|
||||||
|
if (data->id && public->has_fingerprint(public,
|
||||||
|
data->id->get_encoding(data->id)))
|
||||||
|
{
|
||||||
|
public->destroy(public);
|
||||||
|
*out = cert;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public->destroy(public);
|
||||||
|
}
|
||||||
|
else if (data->key != KEY_ANY)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (data->id == NULL || cert->has_subject(cert, data->id))
|
||||||
|
{
|
||||||
|
*out = cert;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
||||||
|
private_stroke_ca_t *this, certificate_type_t cert, key_type_t key,
|
||||||
|
identification_t *id, bool trusted)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
cert_data_t *data;
|
||||||
|
|
||||||
|
INIT(data,
|
||||||
|
.this = this,
|
||||||
|
.cert = cert,
|
||||||
|
.key = key,
|
||||||
|
.id = id,
|
||||||
|
);
|
||||||
|
|
||||||
|
this->lock->read_lock(this->lock);
|
||||||
|
enumerator = this->sections->create_enumerator(this->sections);
|
||||||
|
return enumerator_create_filter(enumerator, (void*)certs_filter, data,
|
||||||
|
(void*)cert_data_destroy);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* data to pass to create_inner_cdp
|
* data to pass to create_inner_cdp
|
||||||
*/
|
*/
|
||||||
@@ -438,7 +516,7 @@ stroke_ca_t *stroke_ca_create(stroke_cred_t *cred)
|
|||||||
.public = {
|
.public = {
|
||||||
.set = {
|
.set = {
|
||||||
.create_private_enumerator = (void*)return_null,
|
.create_private_enumerator = (void*)return_null,
|
||||||
.create_cert_enumerator = (void*)return_null,
|
.create_cert_enumerator = _create_cert_enumerator,
|
||||||
.create_shared_enumerator = (void*)return_null,
|
.create_shared_enumerator = (void*)return_null,
|
||||||
.create_cdp_enumerator = _create_cdp_enumerator,
|
.create_cdp_enumerator = _create_cdp_enumerator,
|
||||||
.cache_cert = (void*)nop,
|
.cache_cert = (void*)nop,
|
||||||
@@ -456,4 +534,3 @@ stroke_ca_t *stroke_ca_create(stroke_cred_t *cred)
|
|||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,10 +70,20 @@ struct private_stroke_cred_t {
|
|||||||
char *secrets_file;
|
char *secrets_file;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* credentials
|
* credentials: end entity certs, attribute certs, CRLs, etc.
|
||||||
*/
|
*/
|
||||||
mem_cred_t *creds;
|
mem_cred_t *creds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CA certificates
|
||||||
|
*/
|
||||||
|
mem_cred_t *cacerts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute Authority certificates
|
||||||
|
*/
|
||||||
|
mem_cred_t *aacerts;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ignore missing CA basic constraint (i.e. treat all certificates in
|
* ignore missing CA basic constraint (i.e. treat all certificates in
|
||||||
* ipsec.conf ca sections and ipsec.d/cacerts as CA certificates)
|
* ipsec.conf ca sections and ipsec.d/cacerts as CA certificates)
|
||||||
@@ -231,7 +241,7 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
|
|||||||
}
|
}
|
||||||
DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
|
DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
|
||||||
cert->get_subject(cert), filename);
|
cert->get_subject(cert), filename);
|
||||||
return this->creds->add_cert_ref(this->creds, TRUE, cert);
|
return this->creds->get_cert_ref(this->creds, cert);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -373,134 +383,184 @@ METHOD(stroke_cred_t, load_pubkey, certificate_t*,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a CA certificate from disk
|
||||||
|
*/
|
||||||
|
static void load_x509_ca(private_stroke_cred_t *this, char *file)
|
||||||
|
{
|
||||||
|
certificate_t *cert;
|
||||||
|
|
||||||
|
if (this->force_ca_cert)
|
||||||
|
{ /* treat certificate as CA cert even it has no CA basic constraint */
|
||||||
|
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||||
|
BUILD_FROM_FILE, file,
|
||||||
|
BUILD_X509_FLAG, X509_CA, BUILD_END);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||||
|
BUILD_FROM_FILE, file, BUILD_END);
|
||||||
|
}
|
||||||
|
if (cert)
|
||||||
|
{
|
||||||
|
x509_t *x509 = (x509_t*)cert;
|
||||||
|
|
||||||
|
if (!(x509->get_flags(x509) & X509_CA))
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, " ca certificate \"%Y\" lacks ca basic constraint, "
|
||||||
|
"discarded", cert->get_subject(cert));
|
||||||
|
cert->destroy(cert);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
|
||||||
|
cert->get_subject(cert), file);
|
||||||
|
this->cacerts->add_cert(this->cacerts, TRUE, cert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, " loading ca certificate from '%s' failed", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load AA certificate with flags from disk
|
||||||
|
*/
|
||||||
|
static void load_x509_aa(private_stroke_cred_t *this, char *file)
|
||||||
|
{
|
||||||
|
certificate_t *cert;
|
||||||
|
|
||||||
|
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||||
|
BUILD_FROM_FILE, file,
|
||||||
|
BUILD_X509_FLAG, X509_AA, BUILD_END);
|
||||||
|
if (cert)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, " loaded AA certificate \"%Y\" from '%s'",
|
||||||
|
cert->get_subject(cert), file);
|
||||||
|
this->aacerts->add_cert(this->aacerts, TRUE, cert);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, " loading AA certificate from '%s' failed", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a certificate with flags from disk
|
||||||
|
*/
|
||||||
|
static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag)
|
||||||
|
{
|
||||||
|
certificate_t *cert;
|
||||||
|
|
||||||
|
/* for all other flags, we add them to the certificate. */
|
||||||
|
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||||
|
BUILD_FROM_FILE, file,
|
||||||
|
BUILD_X509_FLAG, flag, BUILD_END);
|
||||||
|
if (cert)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
|
||||||
|
cert->get_subject(cert), file);
|
||||||
|
this->creds->add_cert(this->creds, TRUE, cert);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, " loading certificate from '%s' failed", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a CRL from a file
|
||||||
|
*/
|
||||||
|
static void load_x509_crl(private_stroke_cred_t *this, char *file)
|
||||||
|
{
|
||||||
|
certificate_t *cert;
|
||||||
|
|
||||||
|
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
|
||||||
|
BUILD_FROM_FILE, file, BUILD_END);
|
||||||
|
if (cert)
|
||||||
|
{
|
||||||
|
this->creds->add_crl(this->creds, (crl_t*)cert);
|
||||||
|
DBG1(DBG_CFG, " loaded crl from '%s'", file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, " loading crl from '%s' failed", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load an attribute certificate from a file
|
||||||
|
*/
|
||||||
|
static void load_x509_ac(private_stroke_cred_t *this, char *file)
|
||||||
|
{
|
||||||
|
certificate_t *cert;
|
||||||
|
|
||||||
|
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
|
||||||
|
BUILD_FROM_FILE, file, BUILD_END);
|
||||||
|
if (cert)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, " loaded attribute certificate from '%s'", file);
|
||||||
|
this->creds->add_cert(this->creds, FALSE, cert);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, " loading attribute certificate from '%s' failed", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load trusted certificates from a directory
|
* load trusted certificates from a directory
|
||||||
*/
|
*/
|
||||||
static void load_certdir(private_stroke_cred_t *this, char *path,
|
static void load_certdir(private_stroke_cred_t *this, char *path,
|
||||||
certificate_type_t type, x509_flag_t flag)
|
certificate_type_t type, x509_flag_t flag)
|
||||||
{
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *file;
|
char *file;
|
||||||
|
|
||||||
enumerator_t *enumerator = enumerator_create_directory(path);
|
enumerator = enumerator_create_directory(path);
|
||||||
|
if (enumerator)
|
||||||
if (!enumerator)
|
{
|
||||||
|
while (enumerator->enumerate(enumerator, NULL, &file, &st))
|
||||||
|
{
|
||||||
|
if (!S_ISREG(st.st_mode))
|
||||||
|
{
|
||||||
|
/* skip special file */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case CERT_X509:
|
||||||
|
if (flag & X509_CA)
|
||||||
|
{
|
||||||
|
load_x509_ca(this, file);
|
||||||
|
}
|
||||||
|
else if (flag & X509_AA)
|
||||||
|
{
|
||||||
|
load_x509_aa(this, file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
load_x509(this, file, flag);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CERT_X509_CRL:
|
||||||
|
load_x509_crl(this, file);
|
||||||
|
break;
|
||||||
|
case CERT_X509_AC:
|
||||||
|
load_x509_ac(this, file);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, " reading directory failed");
|
DBG1(DBG_CFG, " reading directory failed");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (enumerator->enumerate(enumerator, NULL, &file, &st))
|
|
||||||
{
|
|
||||||
certificate_t *cert;
|
|
||||||
|
|
||||||
if (!S_ISREG(st.st_mode))
|
|
||||||
{
|
|
||||||
/* skip special file */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case CERT_X509:
|
|
||||||
if (flag & X509_CA)
|
|
||||||
{
|
|
||||||
if (this->force_ca_cert)
|
|
||||||
{ /* treat this certificate as CA cert even it has no
|
|
||||||
* CA basic constraint */
|
|
||||||
cert = lib->creds->create(lib->creds,
|
|
||||||
CRED_CERTIFICATE, CERT_X509,
|
|
||||||
BUILD_FROM_FILE, file, BUILD_X509_FLAG,
|
|
||||||
X509_CA, BUILD_END);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cert = lib->creds->create(lib->creds,
|
|
||||||
CRED_CERTIFICATE, CERT_X509,
|
|
||||||
BUILD_FROM_FILE, file, BUILD_END);
|
|
||||||
}
|
|
||||||
if (cert)
|
|
||||||
{
|
|
||||||
x509_t *x509 = (x509_t*)cert;
|
|
||||||
|
|
||||||
if (!(x509->get_flags(x509) & X509_CA))
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, " ca certificate \"%Y\" lacks "
|
|
||||||
"ca basic constraint, discarded",
|
|
||||||
cert->get_subject(cert));
|
|
||||||
cert->destroy(cert);
|
|
||||||
cert = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, " loaded ca certificate \"%Y\" "
|
|
||||||
"from '%s'", cert->get_subject(cert), file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, " loading ca certificate from '%s' "
|
|
||||||
"failed", file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ /* for all other flags, we add them to the certificate. */
|
|
||||||
cert = lib->creds->create(lib->creds,
|
|
||||||
CRED_CERTIFICATE, CERT_X509,
|
|
||||||
BUILD_FROM_FILE, file,
|
|
||||||
BUILD_X509_FLAG, flag, BUILD_END);
|
|
||||||
if (cert)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
|
|
||||||
cert->get_subject(cert), file);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, " loading certificate from '%s' "
|
|
||||||
"failed", file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cert)
|
|
||||||
{
|
|
||||||
this->creds->add_cert(this->creds, TRUE, cert);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CERT_X509_CRL:
|
|
||||||
cert = lib->creds->create(lib->creds,
|
|
||||||
CRED_CERTIFICATE, CERT_X509_CRL,
|
|
||||||
BUILD_FROM_FILE, file,
|
|
||||||
BUILD_END);
|
|
||||||
if (cert)
|
|
||||||
{
|
|
||||||
this->creds->add_crl(this->creds, (crl_t*)cert);
|
|
||||||
DBG1(DBG_CFG, " loaded crl from '%s'", file);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, " loading crl from '%s' failed", file);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CERT_X509_AC:
|
|
||||||
cert = lib->creds->create(lib->creds,
|
|
||||||
CRED_CERTIFICATE, CERT_X509_AC,
|
|
||||||
BUILD_FROM_FILE, file,
|
|
||||||
BUILD_END);
|
|
||||||
if (cert)
|
|
||||||
{
|
|
||||||
this->creds->add_cert(this->creds, FALSE, cert);
|
|
||||||
DBG1(DBG_CFG, " loaded attribute certificate from '%s'",
|
|
||||||
file);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, " loading attribute certificate from '%s' "
|
|
||||||
"failed", file);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(stroke_cred_t, cache_cert, void,
|
METHOD(stroke_cred_t, cache_cert, void,
|
||||||
@@ -1321,6 +1381,8 @@ METHOD(stroke_cred_t, reread, void,
|
|||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "rereading ca certificates from '%s'",
|
DBG1(DBG_CFG, "rereading ca certificates from '%s'",
|
||||||
CA_CERTIFICATE_DIR);
|
CA_CERTIFICATE_DIR);
|
||||||
|
this->cacerts->clear(this->cacerts);
|
||||||
|
lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
|
||||||
load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
|
load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
|
||||||
}
|
}
|
||||||
if (msg->reread.flags & REREAD_OCSPCERTS)
|
if (msg->reread.flags & REREAD_OCSPCERTS)
|
||||||
@@ -1334,6 +1396,8 @@ METHOD(stroke_cred_t, reread, void,
|
|||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "rereading aa certificates from '%s'",
|
DBG1(DBG_CFG, "rereading aa certificates from '%s'",
|
||||||
AA_CERTIFICATE_DIR);
|
AA_CERTIFICATE_DIR);
|
||||||
|
this->aacerts->clear(this->aacerts);
|
||||||
|
lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
|
||||||
load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
|
load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
|
||||||
}
|
}
|
||||||
if (msg->reread.flags & REREAD_ACERTS)
|
if (msg->reread.flags & REREAD_ACERTS)
|
||||||
@@ -1359,7 +1423,11 @@ METHOD(stroke_cred_t, add_shared, void,
|
|||||||
METHOD(stroke_cred_t, destroy, void,
|
METHOD(stroke_cred_t, destroy, void,
|
||||||
private_stroke_cred_t *this)
|
private_stroke_cred_t *this)
|
||||||
{
|
{
|
||||||
|
lib->credmgr->remove_set(lib->credmgr, &this->aacerts->set);
|
||||||
|
lib->credmgr->remove_set(lib->credmgr, &this->cacerts->set);
|
||||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
|
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
|
||||||
|
this->aacerts->destroy(this->aacerts);
|
||||||
|
this->cacerts->destroy(this->cacerts);
|
||||||
this->creds->destroy(this->creds);
|
this->creds->destroy(this->creds);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
@@ -1392,9 +1460,13 @@ stroke_cred_t *stroke_cred_create()
|
|||||||
"%s.plugins.stroke.secrets_file", SECRETS_FILE,
|
"%s.plugins.stroke.secrets_file", SECRETS_FILE,
|
||||||
lib->ns),
|
lib->ns),
|
||||||
.creds = mem_cred_create(),
|
.creds = mem_cred_create(),
|
||||||
|
.cacerts = mem_cred_create(),
|
||||||
|
.aacerts = mem_cred_create(),
|
||||||
);
|
);
|
||||||
|
|
||||||
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
|
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
|
||||||
|
lib->credmgr->add_set(lib->credmgr, &this->cacerts->set);
|
||||||
|
lib->credmgr->add_set(lib->credmgr, &this->aacerts->set);
|
||||||
|
|
||||||
this->force_ca_cert = lib->settings->get_bool(lib->settings,
|
this->force_ca_cert = lib->settings->get_bool(lib->settings,
|
||||||
"%s.plugins.stroke.ignore_missing_ca_basic_constraint",
|
"%s.plugins.stroke.ignore_missing_ca_basic_constraint",
|
||||||
|
|||||||
@@ -50,10 +50,13 @@ struct stroke_cred_t {
|
|||||||
void (*reread)(stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt);
|
void (*reread)(stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a CA certificate, and serve it through the credential_set.
|
* Load a CA certificate.
|
||||||
|
*
|
||||||
|
* This method does not add the loaded CA certificate to the internal
|
||||||
|
* credentail set, but returns it only.
|
||||||
*
|
*
|
||||||
* @param filename file to load CA cert from
|
* @param filename file to load CA cert from
|
||||||
* @return reference to loaded certificate, or NULL
|
* @return loaded certificate, or NULL
|
||||||
*/
|
*/
|
||||||
certificate_t* (*load_ca)(stroke_cred_t *this, char *filename);
|
certificate_t* (*load_ca)(stroke_cred_t *this, char *filename);
|
||||||
|
|
||||||
|
|||||||
@@ -192,6 +192,24 @@ METHOD(mem_cred_t, add_cert_ref, certificate_t*,
|
|||||||
return add_cert_internal(this, trusted, cert);
|
return add_cert_internal(this, trusted, cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(mem_cred_t, get_cert_ref, certificate_t*,
|
||||||
|
private_mem_cred_t *this, certificate_t *cert)
|
||||||
|
{
|
||||||
|
certificate_t *cached;
|
||||||
|
|
||||||
|
this->lock->write_lock(this->lock);
|
||||||
|
if (this->untrusted->find_first(this->untrusted,
|
||||||
|
(linked_list_match_t)certificate_equals,
|
||||||
|
(void**)&cached, cert) == SUCCESS)
|
||||||
|
{
|
||||||
|
cert->destroy(cert);
|
||||||
|
cert = cached->get_ref(cached);
|
||||||
|
}
|
||||||
|
this->lock->unlock(this->lock);
|
||||||
|
|
||||||
|
return cert;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(mem_cred_t, add_crl, bool,
|
METHOD(mem_cred_t, add_crl, bool,
|
||||||
private_mem_cred_t *this, crl_t *crl)
|
private_mem_cred_t *this, crl_t *crl)
|
||||||
{
|
{
|
||||||
@@ -736,6 +754,7 @@ mem_cred_t *mem_cred_create()
|
|||||||
},
|
},
|
||||||
.add_cert = _add_cert,
|
.add_cert = _add_cert,
|
||||||
.add_cert_ref = _add_cert_ref,
|
.add_cert_ref = _add_cert_ref,
|
||||||
|
.get_cert_ref = _get_cert_ref,
|
||||||
.add_crl = _add_crl,
|
.add_crl = _add_crl,
|
||||||
.add_key = _add_key,
|
.add_key = _add_key,
|
||||||
.add_shared = _add_shared,
|
.add_shared = _add_shared,
|
||||||
|
|||||||
@@ -58,6 +58,18 @@ struct mem_cred_t {
|
|||||||
certificate_t *(*add_cert_ref)(mem_cred_t *this, bool trusted,
|
certificate_t *(*add_cert_ref)(mem_cred_t *this, bool trusted,
|
||||||
certificate_t *cert);
|
certificate_t *cert);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an existing reference to the same certificate.
|
||||||
|
*
|
||||||
|
* Searches for the same certficate in the set, and returns a reference
|
||||||
|
* to it, destroying the passed certificate. If the passed certificate
|
||||||
|
* is not found, it is just returned.
|
||||||
|
*
|
||||||
|
* @param cert certificate to look up
|
||||||
|
* @return the same certificate, potentially different instance
|
||||||
|
*/
|
||||||
|
certificate_t* (*get_cert_ref)(mem_cred_t *this, certificate_t *cert);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an X.509 CRL to the credential set.
|
* Add an X.509 CRL to the credential set.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user