enforcing x509_flags on certificate construction
This commit is contained in:
@@ -710,9 +710,9 @@ static x509_t* load_cert(char *path, x509_flag_t flag)
|
|||||||
{
|
{
|
||||||
bool pgp = FALSE;
|
bool pgp = FALSE;
|
||||||
chunk_t chunk;
|
chunk_t chunk;
|
||||||
x509_flag_t flags;
|
|
||||||
x509_t *x509;
|
x509_t *x509;
|
||||||
certificate_t *cert;
|
certificate_t *cert;
|
||||||
|
time_t notBefore, notAfter, now;
|
||||||
|
|
||||||
if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
|
if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
|
||||||
{
|
{
|
||||||
@@ -721,7 +721,9 @@ static x509_t* load_cert(char *path, x509_flag_t flag)
|
|||||||
}
|
}
|
||||||
x509 = (x509_t*)lib->creds->create(lib->creds,
|
x509 = (x509_t*)lib->creds->create(lib->creds,
|
||||||
CRED_CERTIFICATE, CERT_X509,
|
CRED_CERTIFICATE, CERT_X509,
|
||||||
BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
|
BUILD_BLOB_ASN1_DER, chunk,
|
||||||
|
BUILD_X509_FLAG, flag,
|
||||||
|
BUILD_END);
|
||||||
if (x509 == NULL)
|
if (x509 == NULL)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, " could not load certificate file '%s'", path);
|
DBG1(DBG_CFG, " could not load certificate file '%s'", path);
|
||||||
@@ -729,32 +731,19 @@ static x509_t* load_cert(char *path, x509_flag_t flag)
|
|||||||
}
|
}
|
||||||
DBG1(DBG_CFG, " loaded certificate file '%s'", path);
|
DBG1(DBG_CFG, " loaded certificate file '%s'", path);
|
||||||
|
|
||||||
|
/* check validity */
|
||||||
cert = &x509->interface;
|
cert = &x509->interface;
|
||||||
flags = x509->get_flags(x509);
|
now = time(NULL);
|
||||||
|
cert->get_validity(cert, &now, ¬Before, ¬After);
|
||||||
/* check basicConstraints */
|
if (now > notAfter)
|
||||||
if ((flag & X509_CA) && !(flags & X509_CA))
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, " isCA basicConstraint is not set, certificate discarded");
|
DBG1(DBG_CFG, " certificate expired at %T, discarded", ¬After);
|
||||||
cert->destroy(cert);
|
cert->destroy(cert);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (now < notBefore)
|
||||||
/* check validity */
|
|
||||||
{
|
{
|
||||||
time_t notBefore, notAfter, now = time(NULL);
|
DBG1(DBG_CFG, " certificate not valid before %T", ¬Before);
|
||||||
|
|
||||||
cert->get_validity(cert, &now, ¬Before, ¬After);
|
|
||||||
if (now > notAfter)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, " certificate expired at %T, discarded", ¬After);
|
|
||||||
cert->destroy(cert);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (now < notBefore)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, " certificate not valid before %T", ¬Before);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return x509;
|
return x509;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,5 +27,6 @@ ENUM(builder_part_names, BUILD_BLOB_ASN1_DER, BUILD_END,
|
|||||||
"BUILD_ISSUER_ALTNAME",
|
"BUILD_ISSUER_ALTNAME",
|
||||||
"BUILD_CA_CERT",
|
"BUILD_CA_CERT",
|
||||||
"BUILD_CERT",
|
"BUILD_CERT",
|
||||||
|
"BUILD_X509_FLAG",
|
||||||
"BUILD_END",
|
"BUILD_END",
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -58,8 +58,10 @@ enum builder_part_t {
|
|||||||
BUILD_ISSUER_ALTNAME,
|
BUILD_ISSUER_ALTNAME,
|
||||||
/** a CA certificate, certificate_t* */
|
/** a CA certificate, certificate_t* */
|
||||||
BUILD_CA_CERT,
|
BUILD_CA_CERT,
|
||||||
/** a certificcate, certificate_t* */
|
/** a certificate, certificate_t* */
|
||||||
BUILD_CERT,
|
BUILD_CERT,
|
||||||
|
/** enforce an additional X509 flag, x509_flag_t */
|
||||||
|
BUILD_X509_FLAG,
|
||||||
/** end of variable argument builder list */
|
/** end of variable argument builder list */
|
||||||
BUILD_END,
|
BUILD_END,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <utils/linked_list.h>
|
#include <utils/linked_list.h>
|
||||||
#include <utils/mutex.h>
|
#include <utils/mutex.h>
|
||||||
|
#include <credentials/certificates/x509.h>
|
||||||
|
|
||||||
typedef struct private_credential_factory_t private_credential_factory_t;
|
typedef struct private_credential_factory_t private_credential_factory_t;
|
||||||
|
|
||||||
@@ -147,6 +148,9 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
|
|||||||
case BUILD_BLOB_ASN1_DER:
|
case BUILD_BLOB_ASN1_DER:
|
||||||
builder->add(builder, part, va_arg(args, chunk_t));
|
builder->add(builder, part, va_arg(args, chunk_t));
|
||||||
continue;
|
continue;
|
||||||
|
case BUILD_X509_FLAG:
|
||||||
|
builder->add(builder, part, va_arg(args, x509_flag_t));
|
||||||
|
continue;
|
||||||
case BUILD_KEY_SIZE:
|
case BUILD_KEY_SIZE:
|
||||||
builder->add(builder, part, va_arg(args, u_int));
|
builder->add(builder, part, va_arg(args, u_int));
|
||||||
continue;
|
continue;
|
||||||
@@ -164,7 +168,7 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
|
|||||||
default:
|
default:
|
||||||
DBG1("builder part %N not supported by factory",
|
DBG1("builder part %N not supported by factory",
|
||||||
builder_part_names, part);
|
builder_part_names, part);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -219,6 +223,7 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case BUILD_KEY_SIZE:
|
case BUILD_KEY_SIZE:
|
||||||
|
case BUILD_X509_FLAG:
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
DBG1("builder part %N not supported by factory",
|
DBG1("builder part %N not supported by factory",
|
||||||
|
|||||||
@@ -1143,7 +1143,7 @@ static void destroy(private_x509_cert_t *this)
|
|||||||
/**
|
/**
|
||||||
* load x509 certificate from a chunk
|
* load x509 certificate from a chunk
|
||||||
*/
|
*/
|
||||||
static x509_cert_t *load(chunk_t chunk)
|
static private_x509_cert_t *load(chunk_t chunk)
|
||||||
{
|
{
|
||||||
private_x509_cert_t *this = malloc_thing(private_x509_cert_t);
|
private_x509_cert_t *this = malloc_thing(private_x509_cert_t);
|
||||||
|
|
||||||
@@ -1188,7 +1188,7 @@ static x509_cert_t *load(chunk_t chunk)
|
|||||||
{
|
{
|
||||||
this->flags |= X509_SELF_SIGNED;
|
this->flags |= X509_SELF_SIGNED;
|
||||||
}
|
}
|
||||||
return &this->public;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct private_builder_t private_builder_t;
|
typedef struct private_builder_t private_builder_t;
|
||||||
@@ -1199,7 +1199,9 @@ struct private_builder_t {
|
|||||||
/** implements the builder interface */
|
/** implements the builder interface */
|
||||||
builder_t public;
|
builder_t public;
|
||||||
/** loaded certificate */
|
/** loaded certificate */
|
||||||
x509_cert_t *cert;
|
private_x509_cert_t *cert;
|
||||||
|
/** additional flags to enforce */
|
||||||
|
x509_flag_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1207,10 +1209,12 @@ struct private_builder_t {
|
|||||||
*/
|
*/
|
||||||
static x509_cert_t *build(private_builder_t *this)
|
static x509_cert_t *build(private_builder_t *this)
|
||||||
{
|
{
|
||||||
x509_cert_t *cert = this->cert;
|
private_x509_cert_t *cert;
|
||||||
|
|
||||||
|
cert = this->cert;
|
||||||
|
cert->flags |= this->flags;
|
||||||
free(this);
|
free(this);
|
||||||
return cert;
|
return &cert->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1220,25 +1224,28 @@ static void add(private_builder_t *this, builder_part_t part, ...)
|
|||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
if (this->cert)
|
va_start(args, part);
|
||||||
{
|
|
||||||
DBG1("ignoring surplus build part %N", builder_part_names, part);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (part)
|
switch (part)
|
||||||
{
|
{
|
||||||
case BUILD_BLOB_ASN1_DER:
|
case BUILD_BLOB_ASN1_DER:
|
||||||
{
|
{
|
||||||
va_start(args, part);
|
if (this->cert)
|
||||||
|
{
|
||||||
|
destroy(this->cert);
|
||||||
|
}
|
||||||
this->cert = load(va_arg(args, chunk_t));
|
this->cert = load(va_arg(args, chunk_t));
|
||||||
va_end(args);
|
break;
|
||||||
|
}
|
||||||
|
case BUILD_X509_FLAG:
|
||||||
|
{
|
||||||
|
this->flags = va_arg(args, x509_flag_t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
DBG1("ignoring unsupported build part %N", builder_part_names, part);
|
DBG1("ignoring unsupported build part %N", builder_part_names, part);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1256,6 +1263,7 @@ builder_t *x509_cert_builder(certificate_type_t type)
|
|||||||
this = malloc_thing(private_builder_t);
|
this = malloc_thing(private_builder_t);
|
||||||
|
|
||||||
this->cert = NULL;
|
this->cert = NULL;
|
||||||
|
this->flags = 0;
|
||||||
this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
|
this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
|
||||||
this->public.build = (void*(*)(builder_t *this))build;
|
this->public.build = (void*(*)(builder_t *this))build;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user