Updated x509 plugin to the new builder API
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
|
||||
* Copyright (C) 2003 Martin Berner, Lukas Suter
|
||||
* Copyright (C) 2002-2008 Andreas Steffen
|
||||
* Copyright (C) 2009 Martin Willi
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -940,140 +941,93 @@ static private_x509_ac_t *create_empty(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* create X.509 attribute certificate from a chunk
|
||||
* See header.
|
||||
*/
|
||||
static private_x509_ac_t* create_from_chunk(chunk_t chunk)
|
||||
x509_ac_t *x509_ac_load(certificate_type_t type, va_list args)
|
||||
{
|
||||
private_x509_ac_t *this = create_empty();
|
||||
chunk_t blob = chunk_empty;
|
||||
|
||||
this->encoding = chunk;
|
||||
if (!parse_certificate(this))
|
||||
while (TRUE)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
typedef struct private_builder_t private_builder_t;
|
||||
/**
|
||||
* Builder implementation for certificate loading
|
||||
*/
|
||||
struct private_builder_t {
|
||||
/** implements the builder interface */
|
||||
builder_t public;
|
||||
/** X.509 attribute certificate to build */
|
||||
private_x509_ac_t *ac;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of builder_t.build
|
||||
*/
|
||||
static private_x509_ac_t* build(private_builder_t *this)
|
||||
{
|
||||
private_x509_ac_t *ac = this->ac;
|
||||
|
||||
free(this);
|
||||
|
||||
/* synthesis if encoding does not exist */
|
||||
if (ac && ac->encoding.ptr == NULL)
|
||||
{
|
||||
if (ac->holderCert && ac->signerCert && ac->signerKey)
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
ac->encoding = build_ac(ac);
|
||||
return ac;
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
blob = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (blob.ptr)
|
||||
{
|
||||
private_x509_ac_t *ac = create_empty();
|
||||
|
||||
ac->encoding = chunk_clone(blob);
|
||||
if (parse_certificate(ac))
|
||||
{
|
||||
return &ac->public;
|
||||
}
|
||||
destroy(ac);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ac;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of builder_t.add
|
||||
* See header.
|
||||
*/
|
||||
static void add(private_builder_t *this, builder_part_t part, ...)
|
||||
x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args)
|
||||
{
|
||||
va_list args;
|
||||
certificate_t *cert;
|
||||
chunk_t chunk;
|
||||
private_x509_ac_t *ac;
|
||||
|
||||
va_start(args, part);
|
||||
switch (part)
|
||||
ac = create_empty();
|
||||
while (TRUE)
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
if (this->ac)
|
||||
{
|
||||
destroy(this->ac);
|
||||
}
|
||||
chunk = va_arg(args, chunk_t);
|
||||
this->ac = create_from_chunk(chunk_clone(chunk));
|
||||
break;
|
||||
case BUILD_NOT_BEFORE_TIME:
|
||||
this->ac->notBefore = va_arg(args, time_t);
|
||||
break;
|
||||
case BUILD_NOT_AFTER_TIME:
|
||||
this->ac->notAfter = va_arg(args, time_t);
|
||||
break;
|
||||
case BUILD_SERIAL:
|
||||
chunk = va_arg(args, chunk_t);
|
||||
this->ac->serialNumber = chunk_clone(chunk);
|
||||
break;
|
||||
case BUILD_IETF_GROUP_ATTR:
|
||||
ietfAttr_list_create_from_string(va_arg(args, char*),
|
||||
this->ac->groups);
|
||||
break;
|
||||
case BUILD_CERT:
|
||||
cert = va_arg(args, certificate_t*);
|
||||
if (cert->get_type(cert) == CERT_X509)
|
||||
{
|
||||
this->ac->holderCert = cert->get_ref(cert);
|
||||
}
|
||||
break;
|
||||
case BUILD_SIGNING_CERT:
|
||||
cert = va_arg(args, certificate_t*);
|
||||
if (cert->get_type(cert) == CERT_X509)
|
||||
{
|
||||
this->ac->signerCert = cert->get_ref(cert);
|
||||
}
|
||||
break;
|
||||
case BUILD_SIGNING_KEY:
|
||||
this->ac->signerKey = va_arg(args, private_key_t*);
|
||||
this->ac->signerKey->get_ref(this->ac->signerKey);
|
||||
break;
|
||||
default:
|
||||
/* abort if unsupported option */
|
||||
if (this->ac)
|
||||
{
|
||||
destroy(this->ac);
|
||||
}
|
||||
builder_cancel(&this->public);
|
||||
break;
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder construction function
|
||||
*/
|
||||
builder_t *x509_ac_builder(certificate_type_t type)
|
||||
{
|
||||
private_builder_t *this;
|
||||
|
||||
if (type != CERT_X509_AC)
|
||||
{
|
||||
return NULL;
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_NOT_BEFORE_TIME:
|
||||
ac->notBefore = va_arg(args, time_t);
|
||||
continue;
|
||||
case BUILD_NOT_AFTER_TIME:
|
||||
ac->notAfter = va_arg(args, time_t);
|
||||
continue;
|
||||
case BUILD_SERIAL:
|
||||
ac->serialNumber = chunk_clone(va_arg(args, chunk_t));
|
||||
continue;
|
||||
case BUILD_IETF_GROUP_ATTR:
|
||||
ietfAttr_list_create_from_string(va_arg(args, char*), ac->groups);
|
||||
continue;
|
||||
case BUILD_CERT:
|
||||
ac->holderCert = va_arg(args, certificate_t*);
|
||||
ac->holderCert->get_ref(ac->holderCert);
|
||||
continue;
|
||||
case BUILD_SIGNING_CERT:
|
||||
ac->signerCert = va_arg(args, certificate_t*);
|
||||
ac->signerCert->get_ref(ac->signerCert);
|
||||
continue;
|
||||
case BUILD_SIGNING_KEY:
|
||||
ac->signerKey = va_arg(args, private_key_t*);
|
||||
ac->signerKey->get_ref(ac->signerKey);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
destroy(ac);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this = malloc_thing(private_builder_t);
|
||||
|
||||
this->ac = create_empty();
|
||||
this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
|
||||
this->public.build = (void*(*)(builder_t *this))build;
|
||||
|
||||
return &this->public;
|
||||
if (ac->signerKey && ac->holderCert && ac->signerCert &&
|
||||
ac->holderCert->get_type(ac->holderCert) == CERT_X509 &&
|
||||
ac->signerCert->get_type(ac->signerCert) == CERT_X509)
|
||||
{
|
||||
ac->encoding = build_ac(ac);
|
||||
return &ac->public;
|
||||
}
|
||||
destroy(ac);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
|
||||
* Copyright (C) 2003 Martin Berner, Lukas Suter
|
||||
* Copyright (C) 2002-2008 Andreas Steffen
|
||||
* Copyright (C) 2009 Martin Willi
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -24,6 +25,7 @@
|
||||
#ifndef X509_AC_H_
|
||||
#define X509_AC_H_
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/certificates/ac.h>
|
||||
|
||||
typedef struct x509_ac_t x509_ac_t;
|
||||
@@ -40,18 +42,28 @@ struct x509_ac_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the building facility for X.509 attribute certificates.
|
||||
*
|
||||
* The resulting builder accepts:
|
||||
* BUILD_USER_CERT: user certificate, exactly one
|
||||
* BUILD_SIGNER_CERT: signer certificate, exactly one
|
||||
* BUILD_SIGNER_KEY: signer private key, exactly one
|
||||
* BUILD_SERIAL: serial number, exactly one
|
||||
* BUILD_GROUP_ATTR: group attribute, optional, several possible
|
||||
* Load a X.509 attribute certificate.
|
||||
*
|
||||
* @param type certificate type, CERT_X509_AC only
|
||||
* @return builder instance to build X.509 attribute certificates
|
||||
* @param args builder_part_t argument list
|
||||
* @return X.509 Attribute certificate, NULL on failure
|
||||
*/
|
||||
builder_t *x509_ac_builder(certificate_type_t type);
|
||||
x509_ac_t *x509_ac_load(certificate_type_t type, va_list args);
|
||||
|
||||
/**
|
||||
* Generate a X.509 attribute certificate.
|
||||
*
|
||||
* Accepted build parts:
|
||||
* BUILD_USER_CERT: user certificate
|
||||
* BUILD_SIGNER_CERT: signer certificate
|
||||
* BUILD_SIGNER_KEY: signer private key
|
||||
* BUILD_SERIAL: serial number
|
||||
* BUILD_GROUP_ATTR: group attribute, several possible
|
||||
*
|
||||
* @param type certificate type, CERT_X509_AC only
|
||||
* @param args builder_part_t argument list
|
||||
* @return X.509 Attribute certificate, NULL on failure
|
||||
*/
|
||||
x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args);
|
||||
|
||||
#endif /** X509_AC_H_ @}*/
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
|
||||
* Copyright (C) 2002 Mario Strasser
|
||||
* Copyright (C) 2000-2006 Andreas Steffen
|
||||
* Copyright (C) 2006-2008 Martin Willi
|
||||
* Copyright (C) 2006-2009 Martin Willi
|
||||
* Copyright (C) 2008 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -675,6 +675,11 @@ static const asn1Object_t certObjects[] = {
|
||||
#define X509_OBJ_ALGORITHM 24
|
||||
#define X509_OBJ_SIGNATURE 25
|
||||
|
||||
/**
|
||||
* forward declaration
|
||||
*/
|
||||
static bool issued_by(private_x509_cert_t *this, certificate_t *issuer);
|
||||
|
||||
/**
|
||||
* Parses an X.509v3 certificate
|
||||
*/
|
||||
@@ -810,6 +815,25 @@ static bool parse_certificate(private_x509_cert_t *this)
|
||||
|
||||
end:
|
||||
parser->destroy(parser);
|
||||
if (success)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
|
||||
/* check if the certificate is self-signed */
|
||||
if (issued_by(this, &this->public.interface.interface))
|
||||
{
|
||||
this->flags |= X509_SELF_SIGNED;
|
||||
}
|
||||
/* create certificate hash */
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||
if (hasher == NULL)
|
||||
{
|
||||
DBG1(" unable to create hash of certificate, SHA1 not supported");
|
||||
return NULL;
|
||||
}
|
||||
hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash);
|
||||
hasher->destroy(hasher);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -910,17 +934,18 @@ static bool issued_by(private_x509_cert_t *this, certificate_t *issuer)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get the public key of the issuer */
|
||||
key = issuer->get_public_key(issuer);
|
||||
|
||||
/* determine signature scheme */
|
||||
scheme = signature_scheme_from_oid(this->algorithm);
|
||||
|
||||
if (scheme == SIGN_UNKNOWN || key == NULL)
|
||||
if (scheme == SIGN_UNKNOWN)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* get the public key of the issuer */
|
||||
key = issuer->get_public_key(issuer);
|
||||
if (!key)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* TODO: add a lightweight check option (comparing auth/subject keyids only) */
|
||||
valid = key->verify(key, scheme, this->tbsCertificate, this->signature);
|
||||
key->destroy(key);
|
||||
return valid;
|
||||
@@ -1149,64 +1174,11 @@ static private_x509_cert_t* create_empty(void)
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* create an X.509 certificate from a chunk
|
||||
*/
|
||||
static private_x509_cert_t *create_from_chunk(chunk_t chunk)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
private_x509_cert_t *this = create_empty();
|
||||
|
||||
this->encoding = chunk;
|
||||
this->parsed = TRUE;
|
||||
if (!parse_certificate(this))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check if the certificate is self-signed */
|
||||
if (issued_by(this, &this->public.interface.interface))
|
||||
{
|
||||
this->flags |= X509_SELF_SIGNED;
|
||||
}
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||
if (hasher == NULL)
|
||||
{
|
||||
DBG1(" unable to create hash of certificate, SHA1 not supported");
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash);
|
||||
hasher->destroy(hasher);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
typedef struct private_builder_t private_builder_t;
|
||||
/**
|
||||
* Builder implementation for certificate loading
|
||||
*/
|
||||
struct private_builder_t {
|
||||
/** implements the builder interface */
|
||||
builder_t public;
|
||||
/** loaded certificate */
|
||||
private_x509_cert_t *cert;
|
||||
/** additional flags to enforce */
|
||||
x509_flag_t flags;
|
||||
/** certificate to sign, if we generate a new cert */
|
||||
certificate_t *sign_cert;
|
||||
/** private key to sign, if we generate a new cert */
|
||||
private_key_t *sign_key;
|
||||
/** digest algorithm to be used for signature */
|
||||
hash_algorithm_t digest_alg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate and sign a new certificate
|
||||
*/
|
||||
static bool generate(private_builder_t *this)
|
||||
static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
|
||||
private_key_t *sign_key, int digest_alg)
|
||||
{
|
||||
chunk_t extensions = chunk_empty;
|
||||
chunk_t basicConstraints = chunk_empty, subjectAltNames = chunk_empty;
|
||||
@@ -1218,11 +1190,11 @@ static bool generate(private_builder_t *this)
|
||||
enumerator_t *enumerator;
|
||||
identification_t *id;
|
||||
|
||||
subject = this->cert->subject;
|
||||
if (this->sign_cert)
|
||||
subject = cert->subject;
|
||||
if (sign_cert)
|
||||
{
|
||||
issuer = this->sign_cert->get_subject(this->sign_cert);
|
||||
if (!this->cert->public_key)
|
||||
issuer = sign_cert->get_subject(sign_cert);
|
||||
if (!cert->public_key)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1230,65 +1202,64 @@ static bool generate(private_builder_t *this)
|
||||
else
|
||||
{ /* self signed */
|
||||
issuer = subject;
|
||||
if (!this->cert->public_key)
|
||||
if (!cert->public_key)
|
||||
{
|
||||
this->cert->public_key = this->sign_key->get_public_key(this->sign_key);
|
||||
cert->public_key = sign_key->get_public_key(sign_key);
|
||||
}
|
||||
this->flags |= X509_SELF_SIGNED;
|
||||
cert->flags |= X509_SELF_SIGNED;
|
||||
}
|
||||
this->cert->issuer = issuer->clone(issuer);
|
||||
if (!this->cert->notBefore)
|
||||
cert->issuer = issuer->clone(issuer);
|
||||
if (!cert->notBefore)
|
||||
{
|
||||
this->cert->notBefore = time(NULL);
|
||||
cert->notBefore = time(NULL);
|
||||
}
|
||||
if (!this->cert->notAfter)
|
||||
if (!cert->notAfter)
|
||||
{ /* defaults to 1 year from now */
|
||||
this->cert->notAfter = this->cert->notBefore + 60 * 60 * 24 * 365;
|
||||
cert->notAfter = cert->notBefore + 60 * 60 * 24 * 365;
|
||||
}
|
||||
this->cert->flags = this->flags;
|
||||
|
||||
/* select signature scheme */
|
||||
switch (this->sign_key->get_type(this->sign_key))
|
||||
switch (sign_key->get_type(sign_key))
|
||||
{
|
||||
case KEY_RSA:
|
||||
switch (this->digest_alg)
|
||||
switch (digest_alg)
|
||||
{
|
||||
case HASH_MD5:
|
||||
this->cert->algorithm = OID_MD5_WITH_RSA;
|
||||
cert->algorithm = OID_MD5_WITH_RSA;
|
||||
break;
|
||||
case HASH_SHA1:
|
||||
this->cert->algorithm = OID_SHA1_WITH_RSA;
|
||||
cert->algorithm = OID_SHA1_WITH_RSA;
|
||||
break;
|
||||
case HASH_SHA224:
|
||||
this->cert->algorithm = OID_SHA224_WITH_RSA;
|
||||
cert->algorithm = OID_SHA224_WITH_RSA;
|
||||
break;
|
||||
case HASH_SHA256:
|
||||
this->cert->algorithm = OID_SHA256_WITH_RSA;
|
||||
cert->algorithm = OID_SHA256_WITH_RSA;
|
||||
break;
|
||||
case HASH_SHA384:
|
||||
this->cert->algorithm = OID_SHA384_WITH_RSA;
|
||||
cert->algorithm = OID_SHA384_WITH_RSA;
|
||||
break;
|
||||
case HASH_SHA512:
|
||||
this->cert->algorithm = OID_SHA512_WITH_RSA;
|
||||
cert->algorithm = OID_SHA512_WITH_RSA;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case KEY_ECDSA:
|
||||
switch (this->digest_alg)
|
||||
switch (digest_alg)
|
||||
{
|
||||
case HASH_SHA1:
|
||||
this->cert->algorithm = OID_ECDSA_WITH_SHA1;
|
||||
cert->algorithm = OID_ECDSA_WITH_SHA1;
|
||||
break;
|
||||
case HASH_SHA256:
|
||||
this->cert->algorithm = OID_ECDSA_WITH_SHA256;
|
||||
cert->algorithm = OID_ECDSA_WITH_SHA256;
|
||||
break;
|
||||
case HASH_SHA384:
|
||||
this->cert->algorithm = OID_ECDSA_WITH_SHA384;
|
||||
cert->algorithm = OID_ECDSA_WITH_SHA384;
|
||||
break;
|
||||
case HASH_SHA512:
|
||||
this->cert->algorithm = OID_ECDSA_WITH_SHA512;
|
||||
cert->algorithm = OID_ECDSA_WITH_SHA512;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
@@ -1297,16 +1268,15 @@ static bool generate(private_builder_t *this)
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
scheme = signature_scheme_from_oid(this->cert->algorithm);
|
||||
scheme = signature_scheme_from_oid(cert->algorithm);
|
||||
|
||||
if (!this->cert->public_key->get_encoding(this->cert->public_key,
|
||||
KEY_PUB_SPKI_ASN1_DER, &key_info))
|
||||
if (!cert->public_key->get_encoding(cert->public_key,
|
||||
KEY_PUB_SPKI_ASN1_DER, &key_info))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
enumerator = this->cert->subjectAltNames->create_enumerator(
|
||||
this->cert->subjectAltNames);
|
||||
enumerator = cert->subjectAltNames->create_enumerator(cert->subjectAltNames);
|
||||
while (enumerator->enumerate(enumerator, &id))
|
||||
{
|
||||
int context;
|
||||
@@ -1344,7 +1314,7 @@ static bool generate(private_builder_t *this)
|
||||
asn1_wrap(ASN1_SEQUENCE, "m", subjectAltNames)));
|
||||
}
|
||||
|
||||
if (this->flags & X509_CA)
|
||||
if (cert->flags & X509_CA)
|
||||
{
|
||||
chunk_t yes, keyid;
|
||||
|
||||
@@ -1357,8 +1327,8 @@ static bool generate(private_builder_t *this)
|
||||
asn1_wrap(ASN1_SEQUENCE, "m",
|
||||
asn1_wrap(ASN1_BOOLEAN, "c", yes))));
|
||||
/* add subjectKeyIdentifier to CA certificates */
|
||||
if (this->cert->public_key->get_fingerprint(this->cert->public_key,
|
||||
KEY_ID_PUBKEY_SHA1, &keyid))
|
||||
if (cert->public_key->get_fingerprint(cert->public_key,
|
||||
KEY_ID_PUBKEY_SHA1, &keyid))
|
||||
{
|
||||
subjectKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||
asn1_build_known_oid(OID_SUBJECT_KEY_ID),
|
||||
@@ -1366,12 +1336,11 @@ static bool generate(private_builder_t *this)
|
||||
asn1_wrap(ASN1_OCTET_STRING, "c", keyid)));
|
||||
}
|
||||
}
|
||||
if (this->sign_key)
|
||||
if (sign_key)
|
||||
{ /* add the keyid authKeyIdentifier for non self-signed certificates */
|
||||
chunk_t keyid;
|
||||
|
||||
if (this->sign_key->get_fingerprint(this->sign_key,
|
||||
KEY_ID_PUBKEY_SHA1, &keyid))
|
||||
if (sign_key->get_fingerprint(sign_key, KEY_ID_PUBKEY_SHA1, &keyid))
|
||||
{
|
||||
authKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||
asn1_build_known_oid(OID_AUTHORITY_KEY_ID),
|
||||
@@ -1388,181 +1357,146 @@ static bool generate(private_builder_t *this)
|
||||
authKeyIdentifier, subjectAltNames));
|
||||
}
|
||||
|
||||
this->cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm",
|
||||
cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm",
|
||||
asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2),
|
||||
asn1_integer("c", this->cert->serialNumber),
|
||||
asn1_algorithmIdentifier(this->cert->algorithm),
|
||||
asn1_integer("c", cert->serialNumber),
|
||||
asn1_algorithmIdentifier(cert->algorithm),
|
||||
issuer->get_encoding(issuer),
|
||||
asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||
asn1_from_time(&this->cert->notBefore, ASN1_UTCTIME),
|
||||
asn1_from_time(&this->cert->notAfter, ASN1_UTCTIME)),
|
||||
asn1_from_time(&cert->notBefore, ASN1_UTCTIME),
|
||||
asn1_from_time(&cert->notAfter, ASN1_UTCTIME)),
|
||||
subject->get_encoding(subject),
|
||||
key_info, extensions);
|
||||
|
||||
if (!this->sign_key->sign(this->sign_key, scheme,
|
||||
this->cert->tbsCertificate, &this->cert->signature))
|
||||
if (!sign_key->sign(sign_key, scheme, cert->tbsCertificate, &cert->signature))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
this->cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
|
||||
this->cert->tbsCertificate,
|
||||
asn1_algorithmIdentifier(this->cert->algorithm),
|
||||
asn1_bitstring("c", this->cert->signature));
|
||||
cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm", cert->tbsCertificate,
|
||||
asn1_algorithmIdentifier(cert->algorithm),
|
||||
asn1_bitstring("c", cert->signature));
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||
if (!hasher)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
hasher->allocate_hash(hasher, this->cert->encoding,
|
||||
&this->cert->encoding_hash);
|
||||
hasher->allocate_hash(hasher, cert->encoding, &cert->encoding_hash);
|
||||
hasher->destroy(hasher);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of builder_t.build
|
||||
* See header.
|
||||
*/
|
||||
static private_x509_cert_t *build(private_builder_t *this)
|
||||
x509_cert_t *x509_cert_load(certificate_type_t type, va_list args)
|
||||
{
|
||||
chunk_t blob = chunk_empty;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
blob = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (blob.ptr)
|
||||
{
|
||||
private_x509_cert_t *cert = create_empty();
|
||||
|
||||
cert->encoding = chunk_clone(blob);
|
||||
if (parse_certificate(cert))
|
||||
{
|
||||
cert->parsed = TRUE;
|
||||
return &cert->public;
|
||||
}
|
||||
destroy(cert);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header.
|
||||
*/
|
||||
x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
|
||||
{
|
||||
private_x509_cert_t *cert;
|
||||
certificate_t *sign_cert = NULL;
|
||||
private_key_t *sign_key = NULL;
|
||||
hash_algorithm_t digest_alg = HASH_SHA1;
|
||||
|
||||
if (this->cert)
|
||||
cert = create_empty();
|
||||
while (TRUE)
|
||||
{
|
||||
this->cert->flags |= this->flags;
|
||||
if (!this->cert->encoding.ptr)
|
||||
{ /* generate a new certificate */
|
||||
if (!this->sign_key || !generate(this))
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_X509_FLAG:
|
||||
cert->flags |= va_arg(args, x509_flag_t);
|
||||
continue;
|
||||
case BUILD_SIGNING_KEY:
|
||||
sign_key = va_arg(args, private_key_t*);
|
||||
continue;
|
||||
case BUILD_SIGNING_CERT:
|
||||
sign_cert = va_arg(args, certificate_t*);
|
||||
continue;
|
||||
case BUILD_PUBLIC_KEY:
|
||||
cert->public_key = va_arg(args, public_key_t*);
|
||||
cert->public_key->get_ref(cert->public_key);
|
||||
continue;
|
||||
case BUILD_SUBJECT:
|
||||
cert->subject = va_arg(args, identification_t*);
|
||||
cert->subject = cert->subject->clone(cert->subject);
|
||||
continue;
|
||||
case BUILD_SUBJECT_ALTNAMES:
|
||||
{
|
||||
destroy(this->cert);
|
||||
free(this);
|
||||
enumerator_t *enumerator;
|
||||
identification_t *id;
|
||||
linked_list_t *list;
|
||||
|
||||
list = va_arg(args, linked_list_t*);
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, &id))
|
||||
{
|
||||
cert->subjectAltNames->insert_last(
|
||||
cert->subjectAltNames, id->clone(id));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
continue;
|
||||
}
|
||||
case BUILD_NOT_BEFORE_TIME:
|
||||
cert->notBefore = va_arg(args, time_t);
|
||||
continue;
|
||||
case BUILD_NOT_AFTER_TIME:
|
||||
cert->notAfter = va_arg(args, time_t);
|
||||
continue;
|
||||
case BUILD_SERIAL:
|
||||
cert->serialNumber = chunk_clone(va_arg(args, chunk_t));
|
||||
continue;
|
||||
case BUILD_DIGEST_ALG:
|
||||
digest_alg = va_arg(args, int);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
destroy(cert);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
cert = this->cert;
|
||||
free(this);
|
||||
return cert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of builder_t.add
|
||||
*/
|
||||
static void add(private_builder_t *this, builder_part_t part, ...)
|
||||
{
|
||||
va_list args;
|
||||
chunk_t chunk;
|
||||
bool handled = TRUE;
|
||||
|
||||
va_start(args, part);
|
||||
switch (part)
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
chunk = va_arg(args, chunk_t);
|
||||
this->cert = create_from_chunk(chunk_clone(chunk));
|
||||
break;
|
||||
case BUILD_X509_FLAG:
|
||||
this->flags = va_arg(args, x509_flag_t);
|
||||
break;
|
||||
case BUILD_SIGNING_KEY:
|
||||
this->sign_key = va_arg(args, private_key_t*);
|
||||
break;
|
||||
case BUILD_SIGNING_CERT:
|
||||
this->sign_cert = va_arg(args, certificate_t*);
|
||||
break;
|
||||
default:
|
||||
/* all other parts need an empty cert */
|
||||
if (!this->cert)
|
||||
{
|
||||
this->cert = create_empty();
|
||||
}
|
||||
handled = FALSE;
|
||||
break;
|
||||
}
|
||||
if (handled)
|
||||
{
|
||||
va_end(args);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (part)
|
||||
{
|
||||
case BUILD_PUBLIC_KEY:
|
||||
{
|
||||
public_key_t *key = va_arg(args, public_key_t*);
|
||||
this->cert->public_key = key->get_ref(key);
|
||||
break;
|
||||
}
|
||||
case BUILD_SUBJECT:
|
||||
{
|
||||
identification_t *id = va_arg(args, identification_t*);
|
||||
this->cert->subject = id->clone(id);
|
||||
break;
|
||||
}
|
||||
case BUILD_SUBJECT_ALTNAMES:
|
||||
{
|
||||
identification_t *id;
|
||||
enumerator_t *enumerator;
|
||||
linked_list_t *list = va_arg(args, linked_list_t*);
|
||||
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, &id))
|
||||
{
|
||||
this->cert->subjectAltNames->insert_last(
|
||||
this->cert->subjectAltNames, id->clone(id));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
break;
|
||||
}
|
||||
case BUILD_NOT_BEFORE_TIME:
|
||||
this->cert->notBefore = va_arg(args, time_t);
|
||||
break;
|
||||
case BUILD_NOT_AFTER_TIME:
|
||||
this->cert->notAfter = va_arg(args, time_t);
|
||||
break;
|
||||
case BUILD_SERIAL:
|
||||
{
|
||||
chunk_t serial = va_arg(args, chunk_t);
|
||||
this->cert->serialNumber = chunk_clone(serial);
|
||||
break;
|
||||
}
|
||||
case BUILD_DIGEST_ALG:
|
||||
this->digest_alg = va_arg(args, int);
|
||||
break;
|
||||
default:
|
||||
/* abort if unsupported option */
|
||||
if (this->cert)
|
||||
{
|
||||
destroy(this->cert);
|
||||
}
|
||||
builder_cancel(&this->public);
|
||||
break;
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder construction function
|
||||
*/
|
||||
builder_t *x509_cert_builder(certificate_type_t type)
|
||||
{
|
||||
private_builder_t *this;
|
||||
|
||||
if (type != CERT_X509)
|
||||
if (sign_key && generate(cert, sign_cert, sign_key, digest_alg))
|
||||
{
|
||||
return NULL;
|
||||
return &cert->public;
|
||||
}
|
||||
|
||||
this = malloc_thing(private_builder_t);
|
||||
|
||||
this->cert = NULL;
|
||||
this->flags = 0;
|
||||
this->sign_cert = NULL;
|
||||
this->sign_key = NULL;
|
||||
this->digest_alg = HASH_SHA1;
|
||||
this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
|
||||
this->public.build = (void*(*)(builder_t *this))build;
|
||||
|
||||
return &this->public;
|
||||
destroy(cert);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
typedef struct x509_cert_t x509_cert_t;
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/certificates/x509.h>
|
||||
|
||||
/**
|
||||
@@ -37,11 +38,29 @@ struct x509_cert_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the building facility for x509 certificates
|
||||
* Load a X.509 certificate.
|
||||
*
|
||||
* This function takes a BUILD_BLOB_ASN1_DER.
|
||||
*
|
||||
* @param type certificate type, CERT_X509 only
|
||||
* @return builder instance to build certificate
|
||||
* @param args builder_part_t argument list
|
||||
* @return X.509 certificate, NULL on failure
|
||||
*/
|
||||
builder_t *x509_cert_builder(certificate_type_t type);
|
||||
x509_cert_t *x509_cert_load(certificate_type_t type, va_list args);
|
||||
|
||||
/**
|
||||
* Generate a X.509 certificate.
|
||||
*
|
||||
* To issue a self-signed certificate, the function takes:
|
||||
* BUILD_SUBJECT, BUILD_SUBJECT_ALTNAMES, BUILD_SIGNING_KEY, BUILD_X509_FLAG,
|
||||
* BUILD_NOT_BEFORE_TIME, BUILD_NOT_AFTER_TIME, BUILD_SERIAL, BUILD_DIGEST_ALG.
|
||||
* To issue certificates from a CA, additionally pass:
|
||||
* BUILD_SIGNING_CERT and BUILD_PUBLIC_KEY.
|
||||
*
|
||||
* @param type certificate type, CERT_X509 only
|
||||
* @param args builder_part_t argument list
|
||||
* @return X.509 certificate, NULL on failure
|
||||
*/
|
||||
x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args);
|
||||
|
||||
#endif /** X509_CERT_H_ @}*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -593,78 +593,38 @@ static private_x509_crl_t* create_empty(void)
|
||||
return this;
|
||||
}
|
||||
|
||||
typedef struct private_builder_t private_builder_t;
|
||||
/**
|
||||
* Builder implementation for certificate loading
|
||||
* See header.
|
||||
*/
|
||||
struct private_builder_t {
|
||||
/** implements the builder interface */
|
||||
builder_t public;
|
||||
/** CRL chunk to build from */
|
||||
chunk_t blob;
|
||||
x509_crl_t *x509_crl_load(certificate_type_t type, va_list args)
|
||||
{
|
||||
chunk_t blob = chunk_empty;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
blob = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (blob.ptr)
|
||||
{
|
||||
private_x509_crl_t *crl = create_empty();
|
||||
|
||||
crl->encoding = chunk_clone(blob);
|
||||
if (parse(crl))
|
||||
{
|
||||
return &crl->public;
|
||||
}
|
||||
destroy(crl);
|
||||
}
|
||||
return NULL;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of builder_t.build
|
||||
*/
|
||||
static private_x509_crl_t *build(private_builder_t *this)
|
||||
{
|
||||
private_x509_crl_t *crl = NULL;
|
||||
|
||||
if (this->blob.len && this->blob.ptr)
|
||||
{
|
||||
crl = create_empty();
|
||||
crl->encoding = chunk_clone(this->blob);
|
||||
if (!parse(crl))
|
||||
{
|
||||
destroy(crl);
|
||||
crl = NULL;
|
||||
}
|
||||
}
|
||||
free(this);
|
||||
return crl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of builder_t.add
|
||||
*/
|
||||
static void add(private_builder_t *this, builder_part_t part, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
switch (part)
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
{
|
||||
va_start(args, part);
|
||||
this->blob = va_arg(args, chunk_t);
|
||||
va_end(args);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
builder_cancel(&this->public);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder construction function
|
||||
*/
|
||||
builder_t *x509_crl_builder(certificate_type_t type)
|
||||
{
|
||||
private_builder_t *this;
|
||||
|
||||
if (type != CERT_X509_CRL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
this = malloc_thing(private_builder_t);
|
||||
|
||||
this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
|
||||
this->public.build = (void*(*)(builder_t *this))build;
|
||||
|
||||
this->blob = chunk_empty;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
typedef struct x509_crl_t x509_crl_t;
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/certificates/crl.h>
|
||||
|
||||
/**
|
||||
@@ -36,13 +37,13 @@ struct x509_crl_t {
|
||||
crl_t crl;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create the building facility for x509 certificate revocation lists.
|
||||
* Load a X.509 CRL.
|
||||
*
|
||||
* @param type certificate type, CERT_X509_CRL only
|
||||
* @return builder instance to build certificate
|
||||
* @param args builder_part_t argument list
|
||||
* @return X.509 CRL, NULL on failure
|
||||
*/
|
||||
builder_t *x509_crl_builder(certificate_type_t type);
|
||||
x509_crl_t *x509_crl_load(certificate_type_t type, va_list args);
|
||||
|
||||
#endif /** X509_CRL_H_ @}*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Copyright (C) 2007 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
* Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
|
||||
@@ -508,26 +508,56 @@ static private_x509_ocsp_request_t *create_empty()
|
||||
return this;
|
||||
}
|
||||
|
||||
typedef struct private_builder_t private_builder_t;
|
||||
/**
|
||||
* Builder implementation for certificate loading
|
||||
* See header.
|
||||
*/
|
||||
struct private_builder_t {
|
||||
/** implements the builder interface */
|
||||
builder_t public;
|
||||
/** OCSP request to build */
|
||||
private_x509_ocsp_request_t *req;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of builder_t.build
|
||||
*/
|
||||
static x509_ocsp_request_t *build(private_builder_t *this)
|
||||
x509_ocsp_request_t *x509_ocsp_request_gen(certificate_type_t type, va_list args)
|
||||
{
|
||||
private_x509_ocsp_request_t *req;
|
||||
certificate_t *cert;
|
||||
private_key_t *private;
|
||||
identification_t *subject;
|
||||
|
||||
req = this->req;
|
||||
free(this);
|
||||
req = create_empty();
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_CA_CERT:
|
||||
cert = va_arg(args, certificate_t*);
|
||||
if (cert->get_type(cert) == CERT_X509)
|
||||
{
|
||||
req->ca = (x509_t*)cert->get_ref(cert);
|
||||
}
|
||||
continue;
|
||||
case BUILD_CERT:
|
||||
cert = va_arg(args, certificate_t*);
|
||||
if (cert->get_type(cert) == CERT_X509)
|
||||
{
|
||||
req->candidates->insert_last(req->candidates,
|
||||
cert->get_ref(cert));
|
||||
}
|
||||
continue;
|
||||
case BUILD_SIGNING_CERT:
|
||||
cert = va_arg(args, certificate_t*);
|
||||
req->cert = cert->get_ref(cert);
|
||||
continue;
|
||||
case BUILD_SIGNING_KEY:
|
||||
private = va_arg(args, private_key_t*);
|
||||
req->key = private->get_ref(private);
|
||||
continue;
|
||||
case BUILD_SUBJECT:
|
||||
subject = va_arg(args, identification_t*);
|
||||
req->requestor = subject->clone(subject);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
destroy(req);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (req->ca)
|
||||
{
|
||||
req->encoding = build_OCSPRequest(req);
|
||||
@@ -537,76 +567,3 @@ static x509_ocsp_request_t *build(private_builder_t *this)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of builder_t.add
|
||||
*/
|
||||
static void add(private_builder_t *this, builder_part_t part, ...)
|
||||
{
|
||||
va_list args;
|
||||
certificate_t *cert;
|
||||
identification_t *subject;
|
||||
private_key_t *private;
|
||||
|
||||
va_start(args, part);
|
||||
switch (part)
|
||||
{
|
||||
case BUILD_CA_CERT:
|
||||
cert = va_arg(args, certificate_t*);
|
||||
if (cert->get_type(cert) == CERT_X509)
|
||||
{
|
||||
this->req->ca = (x509_t*)cert->get_ref(cert);
|
||||
}
|
||||
break;
|
||||
case BUILD_CERT:
|
||||
cert = va_arg(args, certificate_t*);
|
||||
if (cert->get_type(cert) == CERT_X509)
|
||||
{
|
||||
this->req->candidates->insert_last(this->req->candidates,
|
||||
cert->get_ref(cert));
|
||||
}
|
||||
break;
|
||||
case BUILD_SIGNING_CERT:
|
||||
cert = va_arg(args, certificate_t*);
|
||||
this->req->cert = cert->get_ref(cert);
|
||||
break;
|
||||
case BUILD_SIGNING_KEY:
|
||||
private = va_arg(args, private_key_t*);
|
||||
this->req->key = private->get_ref(private);
|
||||
break;
|
||||
case BUILD_SUBJECT:
|
||||
subject = va_arg(args, identification_t*);
|
||||
this->req->requestor = subject->clone(subject);
|
||||
break;
|
||||
default:
|
||||
/* cancel if option not supported */
|
||||
if (this->req)
|
||||
{
|
||||
destroy(this->req);
|
||||
}
|
||||
builder_cancel(&this->public);
|
||||
break;
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder construction function
|
||||
*/
|
||||
builder_t *x509_ocsp_request_builder(certificate_type_t type)
|
||||
{
|
||||
private_builder_t *this;
|
||||
|
||||
if (type != CERT_X509_OCSP_REQUEST)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this = malloc_thing(private_builder_t);
|
||||
|
||||
this->req = create_empty();
|
||||
this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
|
||||
this->public.build = (void*(*)(builder_t *this))build;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifndef X509_OCSP_REQUEST_H_
|
||||
#define X509_OCSP_REQUEST_H_
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/certificates/ocsp_request.h>
|
||||
|
||||
typedef struct x509_ocsp_request_t x509_ocsp_request_t;
|
||||
@@ -37,7 +38,7 @@ struct x509_ocsp_request_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the building facility for OCSP requests.
|
||||
* Generate a X.509 OCSP request.
|
||||
*
|
||||
* The resulting builder accepts:
|
||||
* BUILD_CA_CERT: CA of the checked certificates, exactly one
|
||||
@@ -46,9 +47,10 @@ struct x509_ocsp_request_t {
|
||||
* BUILD_SIGNING_CERT: certificate to create requestor signature, optional
|
||||
* BUILD_SIGNING_KEY: private key to create requestor signature, optional
|
||||
*
|
||||
* @param type certificate type, CERT_X509_OCSP_REQUEST only
|
||||
* @return builder instance to build OCSP requests
|
||||
* @param type certificate type, CERT_X509_OCSP_REQUEST only
|
||||
* @param args builder_part_t argument list
|
||||
* @return OCSP request, NULL on failure
|
||||
*/
|
||||
builder_t *x509_ocsp_request_builder(certificate_type_t type);
|
||||
x509_ocsp_request_t *x509_ocsp_request_gen(certificate_type_t type, va_list args);
|
||||
|
||||
#endif /** X509_OCSP_REQUEST_H_ @}*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Copyright (C) 2007 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
* Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
|
||||
@@ -853,7 +853,7 @@ static void destroy(private_x509_ocsp_response_t *this)
|
||||
/**
|
||||
* load an OCSP response
|
||||
*/
|
||||
static x509_ocsp_response_t *load(chunk_t data)
|
||||
static x509_ocsp_response_t *load(chunk_t blob)
|
||||
{
|
||||
private_x509_ocsp_response_t *this;
|
||||
|
||||
@@ -876,7 +876,7 @@ static x509_ocsp_response_t *load(chunk_t data)
|
||||
this->public.interface.create_cert_enumerator = (enumerator_t*(*)(ocsp_response_t*))create_cert_enumerator;
|
||||
|
||||
this->ref = 1;
|
||||
this->encoding = data;
|
||||
this->encoding = chunk_clone(blob);
|
||||
this->tbsResponseData = chunk_empty;
|
||||
this->responderId = NULL;
|
||||
this->producedAt = UNDEFINED_TIME;
|
||||
@@ -895,78 +895,32 @@ static x509_ocsp_response_t *load(chunk_t data)
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
||||
typedef struct private_builder_t private_builder_t;
|
||||
/**
|
||||
* Builder implementation for certificate loading
|
||||
* See header.
|
||||
*/
|
||||
struct private_builder_t {
|
||||
/** implements the builder interface */
|
||||
builder_t public;
|
||||
/** loaded response */
|
||||
x509_ocsp_response_t *res;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of builder_t.build
|
||||
*/
|
||||
static x509_ocsp_response_t *build(private_builder_t *this)
|
||||
x509_ocsp_response_t *x509_ocsp_response_load(certificate_type_t type,
|
||||
va_list args)
|
||||
{
|
||||
x509_ocsp_response_t *res = this->res;
|
||||
chunk_t blob = chunk_empty;
|
||||
|
||||
free(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of builder_t.add
|
||||
*/
|
||||
static void add(private_builder_t *this, builder_part_t part, ...)
|
||||
{
|
||||
if (!this->res)
|
||||
while (TRUE)
|
||||
{
|
||||
va_list args;
|
||||
chunk_t chunk;
|
||||
|
||||
switch (part)
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
{
|
||||
va_start(args, part);
|
||||
chunk = va_arg(args, chunk_t);
|
||||
this->res = load(chunk_clone(chunk));
|
||||
va_end(args);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
blob = va_arg(args, chunk_t);
|
||||
continue;
|
||||
case BUILD_END:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (this->res)
|
||||
if (blob.ptr)
|
||||
{
|
||||
destroy((private_x509_ocsp_response_t*)this->res);
|
||||
return load(blob);
|
||||
}
|
||||
builder_cancel(&this->public);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder construction function
|
||||
*/
|
||||
builder_t *x509_ocsp_response_builder(certificate_type_t type)
|
||||
{
|
||||
private_builder_t *this;
|
||||
|
||||
if (type != CERT_X509_OCSP_RESPONSE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this = malloc_thing(private_builder_t);
|
||||
|
||||
this->res = NULL;
|
||||
this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
|
||||
this->public.build = (void*(*)(builder_t *this))build;
|
||||
|
||||
return &this->public;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifndef X509_OCSP_RESPONSE_H_
|
||||
#define X509_OCSP_RESPONSE_H_
|
||||
|
||||
#include <credentials/builder.h>
|
||||
#include <credentials/certificates/ocsp_response.h>
|
||||
|
||||
typedef struct x509_ocsp_response_t x509_ocsp_response_t;
|
||||
@@ -37,11 +38,13 @@ struct x509_ocsp_response_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the building facility for OCSP responses.
|
||||
* Load a X.509 OCSP response.
|
||||
*
|
||||
* @param type certificate type, CERT_X509_OCSP_RESPONSE only
|
||||
* @return builder instance to build OCSP responses
|
||||
* @param args builder_part_t argument list
|
||||
* @return OCSP response, NULL on failure
|
||||
*/
|
||||
builder_t *x509_ocsp_response_builder(certificate_type_t type);
|
||||
x509_ocsp_response_t *x509_ocsp_response_load(certificate_type_t type,
|
||||
va_list args);
|
||||
|
||||
#endif /** X509_OCSP_RESPONSE_H_ @}*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -41,15 +41,19 @@ struct private_x509_plugin_t {
|
||||
static void destroy(private_x509_plugin_t *this)
|
||||
{
|
||||
lib->creds->remove_builder(lib->creds,
|
||||
(builder_constructor_t)x509_cert_builder);
|
||||
(builder_function_t)x509_cert_gen);
|
||||
lib->creds->remove_builder(lib->creds,
|
||||
(builder_constructor_t)x509_ac_builder);
|
||||
(builder_function_t)x509_cert_load);
|
||||
lib->creds->remove_builder(lib->creds,
|
||||
(builder_constructor_t)x509_crl_builder);
|
||||
(builder_function_t)x509_ac_gen);
|
||||
lib->creds->remove_builder(lib->creds,
|
||||
(builder_constructor_t)x509_ocsp_request_builder);
|
||||
(builder_function_t)x509_ac_load);
|
||||
lib->creds->remove_builder(lib->creds,
|
||||
(builder_constructor_t)x509_ocsp_response_builder);
|
||||
(builder_function_t)x509_crl_load);
|
||||
lib->creds->remove_builder(lib->creds,
|
||||
(builder_function_t)x509_ocsp_request_gen);
|
||||
lib->creds->remove_builder(lib->creds,
|
||||
(builder_function_t)x509_ocsp_response_load);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -63,15 +67,19 @@ plugin_t *plugin_create()
|
||||
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
|
||||
|
||||
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||
(builder_constructor_t)x509_cert_builder);
|
||||
(builder_function_t)x509_cert_gen);
|
||||
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||
(builder_function_t)x509_cert_load);
|
||||
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
|
||||
(builder_constructor_t)x509_ac_builder);
|
||||
(builder_function_t)x509_ac_gen);
|
||||
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
|
||||
(builder_function_t)x509_ac_load);
|
||||
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
|
||||
(builder_constructor_t)x509_crl_builder);
|
||||
(builder_function_t)x509_crl_load);
|
||||
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
|
||||
(builder_constructor_t)x509_ocsp_request_builder);
|
||||
(builder_function_t)x509_ocsp_request_gen);
|
||||
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
|
||||
(builder_constructor_t)x509_ocsp_response_builder);
|
||||
(builder_function_t)x509_ocsp_response_load);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user