static void load_peer_cert(private_stroke_t *this,
char *filename, identification_t **id)
{
+ certificate_t *cert;
char path[PATH_MAX];
- x509_t *x509;
identification_t *peerid = *id;
if (*filename == '/')
{
snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename);
}
-
- x509 = x509_create_from_file(path, "end entity cert", 0);
-
- if (x509)
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path,
+ BUILD_X509_FLAG, 0,
+ BUILD_END);
+ if (cert)
{
- certificate_t *cert = &x509->interface;;
identification_t *subject = cert->get_subject(cert);
if (!cert->has_subject(cert, peerid))
peerid->destroy(peerid);
*id = subject->clone(subject);
}
- add_x509_cert(this, x509);
+ add_x509_cert(this, (x509_t*)cert);
}
}
*/
static certificate_t* load_ca_cert(private_stroke_t *this, char *filename)
{
+ certificate_t *cert;
char path[PATH_MAX];
- x509_t *x509;
if (*filename == '/')
{
{
snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
}
-
- x509 = x509_create_from_file(path, "ca cert", X509_CA);
-
- if (x509)
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path,
+ BUILD_X509_FLAG, X509_CA,
+ BUILD_END);
+ if (cert)
{
- return add_x509_cert(this, x509);
+ return add_x509_cert(this, (x509_t*)cert);
}
else
{
/**
* load trusted certificates from a directory
*/
-static void load_certdir(private_stroke_t *this, char *path, char* label,
+static void load_certdir(private_stroke_t *this, char *path,
certificate_type_t type, x509_flag_t flag)
{
struct stat st;
while (enumerator->enumerate(enumerator, NULL, &file, &st))
{
+ certificate_t *cert;
+
if (!S_ISREG(st.st_mode))
{
/* skip special file */
switch (type)
{
case CERT_X509:
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file,
+ BUILD_X509_FLAG, flag,
+ BUILD_END);
+ if (cert)
{
- x509_t *x509 = x509_create_from_file(file, label, flag);
-
- if (x509)
- {
- add_x509_cert(this, x509);
- }
+ add_x509_cert(this, (x509_t*)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)
{
- crl_t *crl = crl_create_from_file(file);
-
- if (crl)
+ /* only trusted crls are added to the store */
+ if (verify_crl((crl_t*)cert))
+ {
+ add_crl(this, (crl_t*)cert);
+ }
+ else
{
- certificate_t *cert = &crl->certificate;
-
- /* only trusted crls are added to the store */
- if (verify_crl(crl))
- {
- add_crl(this, crl);
- }
- else
- {
- DBG1(DBG_CFG, " crl discarded");
- cert->destroy(cert);
- }
+ DBG1(DBG_CFG, " crl discarded");
+ cert->destroy(cert);
}
}
break;
case CERT_X509_AC:
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509_AC,
+ BUILD_FROM_FILE, file,
+ BUILD_END);
+ if (cert)
{
- ac_t *ac = ac_create_from_file(file);
-
- if (ac)
- {
- certificate_t *cert = &ac->certificate;
-
cert->destroy(cert);
- }
}
break;
default:
{
DBG1(DBG_CFG, "rereading ca certificates from '%s'",
CA_CERTIFICATE_DIR);
- load_certdir(this, CA_CERTIFICATE_DIR, "ca cert", CERT_X509, X509_CA);
+ 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, "ocsp cert", CERT_X509,
+ load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509,
X509_OCSP_SIGNER);
}
if (msg->reread.flags & REREAD_AACERTS)
{
DBG1(DBG_CFG, "rereading aa certificates from '%s'",
AA_CERTIFICATE_DIR);
- load_certdir(this, AA_CERTIFICATE_DIR, "aa cert", CERT_X509, X509_AA);
+ load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
}
if (msg->reread.flags & REREAD_ACERTS)
{
DBG1(DBG_CFG, "rereading attribute certificates from '%s'",
ATTR_CERTIFICATE_DIR);
- load_certdir(this, ATTR_CERTIFICATE_DIR, "attr cert", CERT_X509_AC, 0);
+ load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0);
}
if (msg->reread.flags & REREAD_CRLS)
{
DBG1(DBG_CFG, "rereading crls from '%s'",
CRL_DIR);
- load_certdir(this, CRL_DIR, "crl", CERT_X509_CRL, 0);
+ load_certdir(this, CRL_DIR, CERT_X509_CRL, 0);
}
}
{
DBG1(DBG_CFG, "loading ca certificates from '%s'",
CA_CERTIFICATE_DIR);
- load_certdir(this, CA_CERTIFICATE_DIR, "ca cert", CERT_X509, X509_CA);
+ load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
DBG1(DBG_CFG, "loading aa certificates from '%s'",
AA_CERTIFICATE_DIR);
- load_certdir(this, AA_CERTIFICATE_DIR, "aa cert", CERT_X509, X509_AA);
+ load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
DBG1(DBG_CFG, "loading ocsp signer certificates from '%s'",
OCSP_CERTIFICATE_DIR);
- load_certdir(this, OCSP_CERTIFICATE_DIR, "ocsp cert", CERT_X509, X509_OCSP_SIGNER);
+ load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509, X509_OCSP_SIGNER);
DBG1(DBG_CFG, "loading attribute certificates from '%s'",
ATTR_CERTIFICATE_DIR);
- load_certdir(this, ATTR_CERTIFICATE_DIR, "attr cert", CERT_X509_AC, 0);
+ load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0);
DBG1(DBG_CFG, "loading crls from '%s'",
CRL_DIR);
- load_certdir(this, CRL_DIR, "crl", CERT_X509_CRL, 0);
+ load_certdir(this, CRL_DIR, CERT_X509_CRL, 0);
}
/*
credentials/keys/shared_key.c credentials/keys/shared_key.h \
credentials/certificates/certificate.c credentials/certificates/certificate.h \
credentials/certificates/x509.h credentials/certificates/x509.c \
-credentials/certificates/ac.h credentials/certificates/ac.c \
+credentials/certificates/ac.h \
credentials/certificates/crl.h credentials/certificates/crl.c \
credentials/certificates/ocsp_request.h credentials/certificates/ocsp_request.c \
credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \
+++ /dev/null
-/*
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2002-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * $Id: ac.h 3300 2007-10-12 21:53:18Z andreas $
- */
-
-#include <library.h>
-#include <debug.h>
-#include <asn1/pem.h>
-
-#include "ac.h"
-
-/*
- * Defined in header.
- */
-ac_t* ac_create_from_file(char *path)
-{
- ac_t *ac;
- bool pgp = FALSE;
- chunk_t chunk;
-
- if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
- {
- DBG1(" could not load attr cert file '%s'", path);
- return NULL;
- }
-/* ac = (ac_t*)lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509_AC,
- BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
-*/
- ac = NULL;
- if (ac == NULL)
- {
- DBG1(" could not parse loaded attr cert file '%s'", path);
- return NULL;
- }
- DBG1(" loaded attr cert file '%s'", path);
- return ac;
-}
-
-
bool (*equals_holder) (const ac_t *this, const ac_t *other);
};
-/**
- * Load and parse an X.509 attribute certificate file
- */
-ac_t* ac_create_from_file(char *path);
-
#endif /* AC_H_ @}*/
* $Id$
*/
-#include <library.h>
-#include <debug.h>
-#include <asn1/pem.h>
#include "crl.h"
ENUM(crl_reason_names, CRL_UNSPECIFIED, CRL_REMOVE_FROM_CRL,
"reason #7",
"remove from crl",
);
-
-/*
- * Defined in header.
- */
-crl_t* crl_create_from_file(char *path)
-{
- crl_t *crl;
- bool pgp = FALSE;
- chunk_t chunk;
-
- if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
- {
- DBG1(" could not load crl file '%s'", path);
- return NULL;
- }
- crl = (crl_t*)lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509_CRL,
- BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
- if (crl == NULL)
- {
- DBG1(" could not parse loaded crl file '%s'", path);
- return NULL;
- }
- DBG1(" loaded crl file '%s'", path);
- return crl;
-}
};
-/**
- * Load and parse an X.509 crl file
- */
-crl_t* crl_create_from_file(char *path);
-
#endif /* CRL_H_ @}*/
* $Id$
*/
-#include <library.h>
-#include <debug.h>
-#include <asn1/pem.h>
-
#include "x509.h"
ENUM(x509_flag_names, X509_CA, X509_SELF_SIGNED,
"X509_SELF_SIGNED",
);
-/*
- * Defined in header.
- */
-x509_t* x509_create_from_file(char *path, char *label, x509_flag_t flag)
-{
- bool pgp = FALSE;
- chunk_t chunk;
- x509_t *x509;
- certificate_t *cert;
- time_t notBefore, notAfter, now;
-
- if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
- {
- DBG1(" could not load %s file '%s'", label, path);
- return NULL;
- }
- x509 = (x509_t*)lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, chunk,
- BUILD_X509_FLAG, flag,
- BUILD_END);
- if (x509 == NULL)
- {
- DBG1(" could not parse loaded %s file '%s'",label, path);
- return NULL;
- }
- DBG1(" loaded %s file '%s'", label, path);
-
- /* check validity */
- cert = &x509->interface;
- now = time(NULL);
- cert->get_validity(cert, &now, ¬Before, ¬After);
- if (now > notAfter)
- {
- DBG1(" certificate expired at %T, discarded", ¬After);
- cert->destroy(cert);
- return NULL;
- }
- if (now < notBefore)
- {
- DBG1(" certificate not valid before %T", ¬Before);
- }
- return x509;
-}
-
-
enumerator_t* (*create_ocsp_uri_enumerator)(x509_t *this);
};
-/**
- * Load and parse an X.509 certificate file
- */
-x509_t* x509_create_from_file(char *path, char *label, x509_flag_t flag);
-
#endif /* X509_H_ @}*/
#include <utils/linked_list.h>
#include <credentials/certificates/x509.h>
+extern identification_t* x509_parse_authorityKeyIdentifier(chunk_t blob,
+ int level0, chunk_t *authKeySerialNumber);
+
typedef struct private_x509_ac_t private_x509_ac_t;
/**
x509_ac_t public;
/**
- * X.509 attribute certificate in DER format
+ * X.509 attribute certificate encoding in ASN.1 DER format
*/
chunk_t encoding;
identification_t *issuerName;
/**
- * Signature algorithm
- */
- int algorithm;
-
- /**
* Start time of certificate validity
*/
time_t notBefore;
bool noRevAvail;
/**
+ * Signature algorithm
+ */
+ int algorithm;
+
+ /**
* Signature
*/
chunk_t signature;
{ 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 54 */
};
-#define AC_OBJ_CERTIFICATE 0
#define AC_OBJ_CERTIFICATE_INFO 1
#define AC_OBJ_VERSION 2
#define AC_OBJ_HOLDER_ISSUER 5
#define AC_OBJ_ROOF 55
/**
+ * Parses an X.509 attribute certificate
+ */
+static bool parse(private_x509_ac_t *this)
+{
+ return FALSE;
+}
+/**
+ * parses a directoryName
+ */
+static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name)
+{
+ bool has_directoryName;
+ linked_list_t *list = linked_list_create();
+
+ x509_parse_generalNames(blob, level, implicit, list);
+ has_directoryName = list->get_count(list) > 0;
+
+ if (has_directoryName)
+ {
+ iterator_t *iterator = list->create_iterator(list, TRUE);
+ identification_t *directoryName;
+ bool first = TRUE;
+
+ while (iterator->iterate(iterator, (void**)&directoryName))
+ {
+ if (first)
+ {
+ *name = directoryName;
+ first = FALSE;
+ }
+ else
+ {
+ DBG1("more than one directory name - first selected");
+ directoryName->destroy(directoryName);
+ }
+ }
+ iterator->destroy(iterator);
+ }
+ else
+ {
+ DBG1("no directoryName found");
+ }
+
+ list->destroy(list);
+ return has_directoryName;
+}
+
+/**
+ * parses roleSyntax
+ */
+static void parse_roleSyntax(chunk_t blob, int level0)
+{
+ asn1_ctx_t ctx;
+ chunk_t object;
+ u_int level;
+ int objectID = 0;
+
+ asn1_init(&ctx, blob, level0, FALSE, FALSE);
+ while (objectID < ROLE_ROOF)
+ {
+ if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx))
+ {
+ return;
+ }
+
+ switch (objectID)
+ {
+ default:
+ break;
+ }
+ objectID++;
+ }
+}
+
+/**
+ * Parses an X.509 attribute certificate
+ */
+static bool parse_certificate(private_x509_ac_t *this)
+{
+ asn1_ctx_t ctx;
+ bool critical;
+ chunk_t object;
+ u_int level;
+ int objectID = 0;
+ int type = OID_UNKNOWN;
+ int extn_oid = OID_UNKNOWN;
+ int sig_alg = OID_UNKNOWN;
+
+ asn1_init(&ctx, this->encoding, 0, FALSE, FALSE);
+ while (objectID < AC_OBJ_ROOF)
+ {
+ if (!extract_object(acObjects, &objectID, &object, &level, &ctx))
+ {
+ return FALSE;
+ }
+
+ /* those objects which will parsed further need the next higher level */
+ level++;
+
+ switch (objectID)
+ {
+ case AC_OBJ_CERTIFICATE_INFO:
+ this->certificateInfo = object;
+ break;
+ case AC_OBJ_VERSION:
+ this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
+ DBG2(" v%d", this->version);
+ if (this->version != 2)
+ {
+ DBG1("v%d attribute certificates are not supported", this->version);
+ return FALSE;
+ }
+ break;
+ case AC_OBJ_HOLDER_ISSUER:
+ if (!parse_directoryName(object, level, FALSE, &this->holderIssuer))
+ {
+ return FALSE;
+ }
+ break;
+ case AC_OBJ_HOLDER_SERIAL:
+ this->holderSerial = object;
+ break;
+ case AC_OBJ_ENTITY_NAME:
+ if (!parse_directoryName(object, level, TRUE, &this->entityName))
+ {
+ return FALSE;
+ }
+ break;
+ case AC_OBJ_ISSUER_NAME:
+ if (!parse_directoryName(object, level, FALSE, &this->issuerName))
+ {
+ return FALSE;
+ }
+ break;
+ case AC_OBJ_SIG_ALG:
+ sig_alg = parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case AC_OBJ_SERIAL_NUMBER:
+ this->serialNumber = object;
+ break;
+ case AC_OBJ_NOT_BEFORE:
+ this->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case AC_OBJ_NOT_AFTER:
+ this->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case AC_OBJ_ATTRIBUTE_TYPE:
+ type = known_oid(object);
+ break;
+ case AC_OBJ_ATTRIBUTE_VALUE:
+ {
+ switch (type)
+ {
+ case OID_AUTHENTICATION_INFO:
+ DBG2(" need to parse authenticationInfo");
+ break;
+ case OID_ACCESS_IDENTITY:
+ DBG2(" need to parse accessIdentity");
+ break;
+ case OID_CHARGING_IDENTITY:
+ ietfAttr_list_create_from_chunk(object, this->charging, level);
+ break;
+ case OID_GROUP:
+ ietfAttr_list_create_from_chunk(object, this->groups, level);
+ break;
+ case OID_ROLE:
+ parse_roleSyntax(object, level);
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case AC_OBJ_EXTN_ID:
+ extn_oid = known_oid(object);
+ break;
+ case AC_OBJ_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG2(" %s",(critical)?"TRUE":"FALSE");
+ break;
+ case AC_OBJ_EXTN_VALUE:
+ {
+ switch (extn_oid)
+ {
+ case OID_CRL_DISTRIBUTION_POINTS:
+ DBG2(" need to parse crlDistributionPoints");
+ break;
+ case OID_AUTHORITY_KEY_ID:
+ this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
+ level, &this->authKeySerialNumber);
+ break;
+ break;
+ case OID_TARGET_INFORMATION:
+ DBG2(" need to parse targetInformation");
+ break;
+ case OID_NO_REV_AVAIL:
+ this->noRevAvail = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case AC_OBJ_ALGORITHM:
+ this->algorithm != parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case AC_OBJ_SIGNATURE:
+ this->signature = object;
+ break;
+ default:
+ break;
+ }
+ objectID++;
+ }
+ return TRUE;
+}
+
+/**
* build directoryName
*/
static chunk_t build_directoryName(asn1_t tag, chunk_t name)
/**
* create an empty but initialized X.509 attribute certificate
*/
-static private_x509_ac_t *create_empty()
+static private_x509_ac_t *create_empty(void)
{
private_x509_ac_t *this = malloc_thing(private_x509_ac_t);
return this;
}
+/**
+ * create X.509 attribute certificate from a chunk
+ */
+static private_x509_ac_t* create_from_chunk(chunk_t chunk)
+{
+ private_x509_ac_t *this = create_empty();
+
+ this->encoding = chunk;
+ if (!parse_certificate(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return this;
+}
+
+/**
+ * create X.509 crl from a file
+ */
+static private_x509_ac_t* create_from_file(char *path)
+{
+ bool pgp = FALSE;
+ chunk_t chunk;
+ private_x509_ac_t *this;
+
+ if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
+ {
+ return NULL;
+ }
+
+ this = create_from_chunk(chunk);
+
+ if (this == NULL)
+ {
+ DBG1(" could not parse loaded attribute certificate file '%s'", path);
+ return NULL;
+ }
+ DBG1(" loaded attribute certificate file '%s'", path);
+ return this;
+}
+
typedef struct private_builder_t private_builder_t;
/**
* Builder implementation for certificate loading
/**
* Implementation of builder_t.build
*/
-static x509_ac_t *build(private_builder_t *this)
+static private_x509_ac_t* build(private_builder_t *this)
{
- private_x509_ac_t *ac;
-
- ac = this->ac;
+ private_x509_ac_t *ac = this->ac;
+
free(this);
- if (ac->holderCert && ac->signerCert && ac->signerKey)
+
+ /* synthesis if TRUE or analysis if FALSE */
+ if (ac->encoding.ptr == NULL)
{
- ac->encoding = build_ac(ac);
- return &ac->public;
+ if (ac->holderCert && ac->signerCert && ac->signerKey)
+ {
+ ac->encoding = build_ac(ac);
+ return ac;
+ }
+ destroy(ac);
+ return NULL;
}
- destroy(ac);
- return NULL;
}
/**
va_start(args, part);
switch (part)
{
+ case BUILD_FROM_FILE:
+ if (this->ac)
+ {
+ destroy(this->ac);
+ }
+ this->ac = create_from_file(va_arg(args, char*));
+ break;
+ case BUILD_BLOB_ASN1_DER:
+ if (this->ac)
+ {
+ destroy(this->ac);
+ }
+ this->ac = create_from_chunk(va_arg(args, chunk_t));
+ break;
case BUILD_NOT_BEFORE_TIME:
this->ac->notBefore = va_arg(args, time_t);
break;
x509_cert_t public;
/**
- * DER encoded X.509 certificate
+ * X.509 certificate encoding in ASN.1 DER format
*/
chunk_t encoding;
u_int level;
int objectID = 0;
int extn_oid = OID_UNKNOWN;
- int key_alg = 0;
- int sig_alg = 0;
+ int key_alg = OID_UNKNOWN;
+ int sig_alg = OID_UNKNOWN;
chunk_t subjectPublicKey = chunk_empty;
asn1_init(&ctx, this->encoding, 0, FALSE, FALSE);
}
/**
- * load x509 certificate from a chunk
+ * create an empty but initialized X.509 certificate
*/
-static private_x509_cert_t *load(chunk_t chunk)
+static private_x509_cert_t* create_empty(void)
{
private_x509_cert_t *this = malloc_thing(private_x509_cert_t);
this->public.interface.create_crl_uri_enumerator = (enumerator_t* (*)(x509_t*))create_crl_uri_enumerator;
this->public.interface.create_ocsp_uri_enumerator = (enumerator_t* (*)(x509_t*))create_ocsp_uri_enumerator;
- this->encoding = chunk;
+ this->encoding = chunk_empty;
this->public_key = NULL;
this->subject = NULL;
this->issuer = NULL;
this->authKeySerialNumber = chunk_empty;
this->flags = 0;
this->ref = 1;
-
+
+ return this;
+}
+
+/**
+ * create an X.509 certificate from a chunk
+ */
+static private_x509_cert_t *create_from_chunk(chunk_t chunk)
+{
+ private_x509_cert_t *this = create_empty();
+
+ this->encoding = chunk;
if (!parse_certificate(this))
{
destroy(this);
return NULL;
}
-
+
/* check if the certificate is self-signed */
if (issued_by(this, &this->public.interface.interface, TRUE))
{
return this;
}
+/**
+ * create an X.509 certificate from a file
+ */
+static private_x509_cert_t *create_from_file(char *path)
+{
+ bool pgp = FALSE;
+ chunk_t chunk;
+ private_x509_cert_t *this;
+
+ if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
+ {
+ return NULL;
+ }
+
+ this = create_from_chunk(chunk);
+
+ if (this == NULL)
+ {
+ DBG1(" could not parse loaded certificate file '%s'",path);
+ return NULL;
+ }
+ DBG1(" loaded certificate file '%s'", path);
+ return this;
+
+}
+
typedef struct private_builder_t private_builder_t;
/**
* Builder implementation for certificate loading
/**
* Implementation of builder_t.build
*/
-static x509_cert_t *build(private_builder_t *this)
+static private_x509_cert_t *build(private_builder_t *this)
{
- private_x509_cert_t *cert;
-
- cert = this->cert;
- cert->flags |= this->flags;
+ private_x509_cert_t *cert = this->cert;
+ x509_flag_t flags = this->flags;
+
free(this);
- return &cert->public;
+ if (cert == NULL)
+ {
+ return NULL;
+ }
+ if ((flags & X509_CA) && !(cert->flags & X509_CA))
+ {
+ DBG1(" ca certificate must have ca basic constraint set, discarded");
+ destroy(cert);
+ return NULL;
+ }
+ cert->flags |= flags;
+ return cert;
}
/**
va_start(args, part);
switch (part)
{
+ case BUILD_FROM_FILE:
+ this->cert = create_from_file(va_arg(args, char*));
+ break;
case BUILD_BLOB_ASN1_DER:
- if (this->cert)
- {
- destroy(this->cert);
- }
- this->cert = load(va_arg(args, chunk_t));
+ this->cert = create_from_chunk(va_arg(args, chunk_t));
break;
case BUILD_X509_FLAG:
this->flags = va_arg(args, x509_flag_t);
x509_crl_t public;
/**
- * X.509 crl in DER format
+ * X.509 crl encoding in ASN.1 DER format
*/
- chunk_t certificateList;
+ chunk_t encoding;
/**
* X.509 crl body over which signature is computed
u_int level;
int objectID = 0;
- asn1_init(&ctx, this->certificateList, 0, FALSE, FALSE);
+ asn1_init(&ctx, this->encoding, 0, FALSE, FALSE);
while (objectID < CRL_OBJ_ROOF)
{
if (!extract_object(crlObjects, &objectID, &object, &level, &ctx))
*/
static chunk_t get_encoding(private_x509_crl_t *this)
{
- return chunk_clone(this->certificateList);
+ return chunk_clone(this->encoding);
}
/**
this->revoked->destroy_function(this->revoked, free);
DESTROY_IF(this->issuer);
DESTROY_IF(this->authKeyIdentifier);
- free(this->certificateList.ptr);
+ free(this->encoding.ptr);
free(this);
}
}
/**
- * load a X509 CRL from a chunk of date (ASN1 DER)
+ * create an empty but initialized X.509 crl
*/
-static x509_crl_t *load(chunk_t chunk)
+static private_x509_crl_t* create_empty(void)
{
private_x509_crl_t *this = malloc_thing(private_x509_crl_t);
this->public.crl.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
this->public.crl.certificate.destroy = (void (*)(certificate_t *this))destroy;
- this->certificateList = chunk;
+ this->encoding = chunk_empty;
this->tbsCertList = chunk_empty;
this->issuer = NULL;
this->crlNumber = chunk_empty;
this->authKeySerialNumber = chunk_empty;
this->ref = 1;
+ return this;
+}
+
+/**
+ * create an X.509 crl from a chunk
+ */
+static private_x509_crl_t* create_from_chunk(chunk_t chunk)
+{
+ private_x509_crl_t *this = create_empty();
+
+ this->encoding = chunk;
if (!parse(this))
{
destroy(this);
return NULL;
}
+ return this;
+}
+
+/**
+ * create an X.509 crl from a file
+ */
+static private_x509_crl_t* create_from_file(char *path)
+{
+ bool pgp = FALSE;
+ chunk_t chunk;
+ private_x509_crl_t *this;
- return &this->public;
+ if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
+ {
+ return NULL;
+ }
+
+ this = create_from_chunk(chunk);
+
+ if (this == NULL)
+ {
+ DBG1(" could not parse loaded crl file '%s'",path);
+ return NULL;
+ }
+ DBG1(" loaded crl file '%s'", path);
+ return this;
}
typedef struct private_builder_t private_builder_t;
/** implements the builder interface */
builder_t public;
/** loaded CRL */
- x509_crl_t *crl;
+ private_x509_crl_t *crl;
};
/**
* Implementation of builder_t.build
*/
-static x509_crl_t *build(private_builder_t *this)
+static private_x509_crl_t *build(private_builder_t *this)
{
- x509_crl_t *crl = this->crl;
+ private_x509_crl_t *crl = this->crl;
free(this);
return crl;
return;
}
+ va_start(args, part);
switch (part)
{
+ case BUILD_FROM_FILE:
+ this->crl = create_from_file(va_arg(args, char*));
+ break;
case BUILD_BLOB_ASN1_DER:
{
- va_start(args, part);
- this->crl = load(va_arg(args, chunk_t));
- va_end(args);
+ this->crl = create_from_chunk(va_arg(args, chunk_t));
break;
}
default:
DBG1("ignoring unsupported build part %N", builder_part_names, part);
break;
}
+ va_end(args);
}
/**
/* load the signer's X.509 certificate */
if (certfile != NULL)
{
- x509_t *x509 = x509_create_from_file(certfile, "signer cert", 0);
-
- if (x509 == NULL)
+ signerCert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, certfile,
+ BUILD_X509_FLAG, 0,
+ BUILD_END);
+ if (signerCert == NULL)
{
goto end;
}
- signerCert = &x509->interface;
}
/* load the users's X.509 certificate */
if (usercertfile != NULL)
{
- x509_t *x509 = x509_create_from_file(usercertfile, "user cert", 0);
-
- if (x509 == NULL)
+ userCert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, usercertfile,
+ BUILD_X509_FLAG, 0,
+ BUILD_END);
+ if (userCert == NULL)
{
goto end;
}
- userCert = &x509->interface;
}
/* compute validity interval */