stroke: Atomically replace CA and AA certificates when reloading them

Previously it was possible that certificates were not found between the
time the credential sets were cleared and the certificates got readded.
This commit is contained in:
Tobias Brunner
2015-08-20 19:19:37 +02:00
parent 58db4edb2c
commit 99610f406d
+45 -34
View File
@@ -386,7 +386,8 @@ METHOD(stroke_cred_t, load_pubkey, certificate_t*,
/** /**
* Load a CA certificate from disk * Load a CA certificate from disk
*/ */
static void load_x509_ca(private_stroke_cred_t *this, char *file) static void load_x509_ca(private_stroke_cred_t *this, char *file,
mem_cred_t *creds)
{ {
certificate_t *cert; certificate_t *cert;
@@ -415,7 +416,7 @@ static void load_x509_ca(private_stroke_cred_t *this, char *file)
{ {
DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'", DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
cert->get_subject(cert), file); cert->get_subject(cert), file);
this->cacerts->add_cert(this->cacerts, TRUE, cert); creds->add_cert(creds, TRUE, cert);
} }
} }
else else
@@ -427,7 +428,8 @@ static void load_x509_ca(private_stroke_cred_t *this, char *file)
/** /**
* Load AA certificate with flags from disk * Load AA certificate with flags from disk
*/ */
static void load_x509_aa(private_stroke_cred_t *this, char *file) static void load_x509_aa(private_stroke_cred_t *this,char *file,
mem_cred_t *creds)
{ {
certificate_t *cert; certificate_t *cert;
@@ -438,7 +440,7 @@ static void load_x509_aa(private_stroke_cred_t *this, char *file)
{ {
DBG1(DBG_CFG, " loaded AA certificate \"%Y\" from '%s'", DBG1(DBG_CFG, " loaded AA certificate \"%Y\" from '%s'",
cert->get_subject(cert), file); cert->get_subject(cert), file);
this->aacerts->add_cert(this->aacerts, TRUE, cert); creds->add_cert(creds, TRUE, cert);
} }
else else
{ {
@@ -449,7 +451,8 @@ static void load_x509_aa(private_stroke_cred_t *this, char *file)
/** /**
* Load a certificate with flags from disk * Load a certificate with flags from disk
*/ */
static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag) static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag,
mem_cred_t *creds)
{ {
certificate_t *cert; certificate_t *cert;
@@ -461,7 +464,7 @@ static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag)
{ {
DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'", DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
cert->get_subject(cert), file); cert->get_subject(cert), file);
this->creds->add_cert(this->creds, TRUE, cert); creds->add_cert(creds, TRUE, cert);
} }
else else
{ {
@@ -472,7 +475,8 @@ static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag)
/** /**
* Load a CRL from a file * Load a CRL from a file
*/ */
static void load_x509_crl(private_stroke_cred_t *this, char *file) static void load_x509_crl(private_stroke_cred_t *this, char *file,
mem_cred_t *creds)
{ {
certificate_t *cert; certificate_t *cert;
@@ -480,8 +484,8 @@ static void load_x509_crl(private_stroke_cred_t *this, char *file)
BUILD_FROM_FILE, file, BUILD_END); BUILD_FROM_FILE, file, BUILD_END);
if (cert) if (cert)
{ {
this->creds->add_crl(this->creds, (crl_t*)cert);
DBG1(DBG_CFG, " loaded crl from '%s'", file); DBG1(DBG_CFG, " loaded crl from '%s'", file);
creds->add_crl(creds, (crl_t*)cert);
} }
else else
{ {
@@ -492,7 +496,8 @@ static void load_x509_crl(private_stroke_cred_t *this, char *file)
/** /**
* Load an attribute certificate from a file * Load an attribute certificate from a file
*/ */
static void load_x509_ac(private_stroke_cred_t *this, char *file) static void load_x509_ac(private_stroke_cred_t *this, char *file,
mem_cred_t *creds)
{ {
certificate_t *cert; certificate_t *cert;
@@ -501,7 +506,7 @@ static void load_x509_ac(private_stroke_cred_t *this, char *file)
if (cert) if (cert)
{ {
DBG1(DBG_CFG, " loaded attribute certificate from '%s'", file); DBG1(DBG_CFG, " loaded attribute certificate from '%s'", file);
this->creds->add_cert(this->creds, FALSE, cert); creds->add_cert(creds, FALSE, cert);
} }
else else
{ {
@@ -513,7 +518,8 @@ static void load_x509_ac(private_stroke_cred_t *this, char *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,
mem_cred_t *creds)
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
struct stat st; struct stat st;
@@ -534,22 +540,22 @@ static void load_certdir(private_stroke_cred_t *this, char *path,
case CERT_X509: case CERT_X509:
if (flag & X509_CA) if (flag & X509_CA)
{ {
load_x509_ca(this, file); load_x509_ca(this, file, creds);
} }
else if (flag & X509_AA) else if (flag & X509_AA)
{ {
load_x509_aa(this, file); load_x509_aa(this, file, creds);
} }
else else
{ {
load_x509(this, file, flag); load_x509(this, file, flag, creds);
} }
break; break;
case CERT_X509_CRL: case CERT_X509_CRL:
load_x509_crl(this, file); load_x509_crl(this, file, creds);
break; break;
case CERT_X509_AC: case CERT_X509_AC:
load_x509_ac(this, file); load_x509_ac(this, file, creds);
break; break;
default: default:
break; break;
@@ -1350,67 +1356,72 @@ static void load_certs(private_stroke_cred_t *this)
{ {
DBG1(DBG_CFG, "loading ca certificates from '%s'", DBG1(DBG_CFG, "loading ca certificates from '%s'",
CA_CERTIFICATE_DIR); CA_CERTIFICATE_DIR);
load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA); load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA, this->cacerts);
DBG1(DBG_CFG, "loading aa certificates from '%s'", DBG1(DBG_CFG, "loading aa certificates from '%s'",
AA_CERTIFICATE_DIR); AA_CERTIFICATE_DIR);
load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA); load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA, this->aacerts);
DBG1(DBG_CFG, "loading ocsp signer certificates from '%s'", DBG1(DBG_CFG, "loading ocsp signer certificates from '%s'",
OCSP_CERTIFICATE_DIR); OCSP_CERTIFICATE_DIR);
load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509, X509_OCSP_SIGNER); load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509, X509_OCSP_SIGNER,
this->creds);
DBG1(DBG_CFG, "loading attribute certificates from '%s'", DBG1(DBG_CFG, "loading attribute certificates from '%s'",
ATTR_CERTIFICATE_DIR); ATTR_CERTIFICATE_DIR);
load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0); load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0, this->creds);
DBG1(DBG_CFG, "loading crls from '%s'", DBG1(DBG_CFG, "loading crls from '%s'",
CRL_DIR); CRL_DIR);
load_certdir(this, CRL_DIR, CERT_X509_CRL, 0); load_certdir(this, CRL_DIR, CERT_X509_CRL, 0, this->creds);
} }
METHOD(stroke_cred_t, reread, void, METHOD(stroke_cred_t, reread, void,
private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt) private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt)
{ {
mem_cred_t *creds;
if (msg->reread.flags & REREAD_SECRETS) if (msg->reread.flags & REREAD_SECRETS)
{ {
DBG1(DBG_CFG, "rereading secrets"); DBG1(DBG_CFG, "rereading secrets");
load_secrets(this, NULL, this->secrets_file, 0, prompt); load_secrets(this, NULL, this->secrets_file, 0, prompt);
} }
creds = mem_cred_create();
if (msg->reread.flags & REREAD_CACERTS) if (msg->reread.flags & REREAD_CACERTS)
{ {
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); load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA, creds);
this->cacerts->replace_certs(this->cacerts, creds, FALSE);
lib->credmgr->flush_cache(lib->credmgr, CERT_X509); lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
}
if (msg->reread.flags & REREAD_OCSPCERTS)
{
DBG1(DBG_CFG, "rereading ocsp signer certificates from '%s'",
OCSP_CERTIFICATE_DIR);
load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509,
X509_OCSP_SIGNER);
} }
if (msg->reread.flags & REREAD_AACERTS) if (msg->reread.flags & REREAD_AACERTS)
{ {
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); load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA, creds);
this->aacerts->replace_certs(this->aacerts, creds, FALSE);
lib->credmgr->flush_cache(lib->credmgr, CERT_X509); lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA); }
creds->destroy(creds);
if (msg->reread.flags & REREAD_OCSPCERTS)
{
DBG1(DBG_CFG, "rereading ocsp signer certificates from '%s'",
OCSP_CERTIFICATE_DIR);
load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509,
X509_OCSP_SIGNER, this->creds);
} }
if (msg->reread.flags & REREAD_ACERTS) if (msg->reread.flags & REREAD_ACERTS)
{ {
DBG1(DBG_CFG, "rereading attribute certificates from '%s'", DBG1(DBG_CFG, "rereading attribute certificates from '%s'",
ATTR_CERTIFICATE_DIR); ATTR_CERTIFICATE_DIR);
load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0); load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0, this->creds);
} }
if (msg->reread.flags & REREAD_CRLS) if (msg->reread.flags & REREAD_CRLS)
{ {
DBG1(DBG_CFG, "rereading crls from '%s'", DBG1(DBG_CFG, "rereading crls from '%s'",
CRL_DIR); CRL_DIR);
load_certdir(this, CRL_DIR, CERT_X509_CRL, 0); load_certdir(this, CRL_DIR, CERT_X509_CRL, 0, this->creds);
} }
} }