#include "ac.h"
#include "crl.h"
-typedef struct private_builder_t private_builder_t;
-
-struct private_builder_t {
- /** implements builder interface */
- builder_t public;
- /** built credential */
- union {
- void *cred;
- cert_t *cert;
- x509crl_t *crl;
- x509acert_t *ac;
- };
-};
-
/**
- * builder add function for certificates
+ * Load a certificate
*/
-static void cert_add(private_builder_t *this, builder_part_t part, ...)
+static cert_t *builder_load_cert(certificate_type_t type, va_list args)
{
chunk_t blob;
- va_list args;
-
- va_start(args, part);
- blob = va_arg(args, chunk_t);
- va_end(args);
+ bool pgp = FALSE;
- switch (part)
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_BLOB_PGP:
+ pgp = TRUE;
+ /* FALL */
+ case BUILD_BLOB_ASN1_DER:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ }
+ if (blob.ptr)
{
- case BUILD_BLOB_PGP:
+ if (pgp)
{
pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
*pgpcert = pgpcert_empty;
if (parse_pgp(chunk_clone(blob), pgpcert))
{
- this->cert = malloc_thing(cert_t);
- *this->cert = cert_empty;
- this->cert->type = CERT_PGP;
- this->cert->u.pgp = pgpcert;
- }
- else
- {
- plog(" error in OpenPGP certificate");
- free_pgpcert(pgpcert);
+ cert_t *cert = malloc_thing(cert_t);
+ *cert = cert_empty;
+ cert->type = CERT_PGP;
+ cert->u.pgp = pgpcert;
+ return cert;
}
- break;
+ plog(" error in OpenPGP certificate");
+ free_pgpcert(pgpcert);
}
- case BUILD_BLOB_ASN1_DER:
+ else
{
x509cert_t *x509cert = malloc_thing(x509cert_t);
*x509cert = empty_x509cert;
if (parse_x509cert(chunk_clone(blob), 0, x509cert))
{
- this->cert = malloc_thing(cert_t);
- *this->cert = cert_empty;
- this->cert->type = CERT_X509_SIGNATURE;
- this->cert->u.x509 = x509cert;
+ cert_t *cert = malloc_thing(cert_t);
+ *cert = cert_empty;
+ cert->type = CERT_X509_SIGNATURE;
+ cert->u.x509 = x509cert;
+ return cert;
}
- else
- {
- plog(" error in X.509 certificate");
- free_x509cert(x509cert);
- }
- break;
+ plog(" error in X.509 certificate");
+ free_x509cert(x509cert);
}
- default:
- if (this->cert)
- {
- switch (this->cert->type)
- {
- case CERT_X509_SIGNATURE:
- free_x509cert(this->cert->u.x509);
- break;
- case CERT_PGP:
- free_pgpcert(this->cert->u.pgp);
- break;
- default:
- break;
- }
- free(this->cert);
- }
- builder_cancel(&this->public);
- break;
}
+ return NULL;
}
/**
- * builder add function for attribute certificates
+ * Load a attribute certificate
*/
-static void ac_add(private_builder_t *this, builder_part_t part, ...)
+static x509acert_t *builder_load_ac(certificate_type_t type, va_list args)
{
- chunk_t blob;
- va_list args;
+ chunk_t blob = chunk_empty;
+ x509acert_t *ac;
- switch (part)
+ while (TRUE)
{
- case BUILD_BLOB_ASN1_DER:
+ switch (va_arg(args, builder_part_t))
{
- va_start(args, part);
- blob = va_arg(args, chunk_t);
- va_end(args);
-
- this->ac = malloc_thing(x509acert_t);
-
- *this->ac = empty_ac;
-
- if (!parse_ac(chunk_clone(blob), this->ac) &&
- !verify_x509acert(this->ac, FALSE))
- {
- free_acert(this->ac);
- this->ac = NULL;
- }
- break;
+ case BUILD_BLOB_ASN1_DER:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
}
- default:
- if (this->ac)
- {
- free_acert(this->ac);
- }
- builder_cancel(&this->public);
- break;
}
+ if (blob.ptr)
+ {
+ ac = malloc_thing(x509acert_t);
+ *ac = empty_ac;
+ if (parse_ac(chunk_clone(blob), ac) &&
+ verify_x509acert(ac, FALSE))
+ {
+ return ac;
+ }
+ plog(" error in X.509 AC");
+ free_acert(ac);
+ }
+ return NULL;
}
/**
- * builder add function for crls
+ * Load a CRL
*/
-static void crl_add(private_builder_t *this, builder_part_t part, ...)
+static x509crl_t *builder_load_crl(certificate_type_t type, va_list args)
{
chunk_t blob;
- va_list args;
+ x509crl_t *crl;
- switch (part)
+ while (TRUE)
{
- case BUILD_BLOB_ASN1_DER:
+ switch (va_arg(args, builder_part_t))
{
- va_start(args, part);
- blob = va_arg(args, chunk_t);
- va_end(args);
-
- this->crl = malloc_thing(x509crl_t);
- *this->crl = empty_x509crl;
-
- if (!parse_x509crl(chunk_clone(blob), 0, this->crl))
- {
- plog(" error in X.509 crl");
- free_crl(this->crl);
- this->crl = NULL;
- }
- break;
+ case BUILD_BLOB_ASN1_DER:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
}
- default:
- if (this->crl)
- {
- free_crl(this->crl);
- }
- builder_cancel(&this->public);
- break;
}
-}
-
-/**
- * builder build function
- */
-static void *build(private_builder_t *this)
-{
- void *cred;
-
- cred = this->cred;
- free(this);
-
- return cred;
-}
-
-/**
- * builder for pluto credentials
- */
-static builder_t *builder(int subtype)
-{
- private_builder_t *this = malloc_thing(private_builder_t);
-
- switch (subtype)
+ if (blob.ptr)
{
- case CERT_PLUTO_CERT:
- this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))cert_add;
- break;
- case CERT_PLUTO_AC:
- this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))ac_add;
- break;
- case CERT_PLUTO_CRL:
- this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))crl_add;
- break;
- default:
- free(this);
- return NULL;
+ crl = malloc_thing(x509crl_t);
+ *crl = empty_x509crl;
+ if (parse_x509crl(chunk_clone(blob), 0, crl))
+ {
+ return crl;
+ }
+ plog(" error in X.509 crl");
+ free_crl(crl);
}
- this->public.build = (void*(*)(builder_t*))build;
- this->cred = NULL;
-
- return &this->public;
+ return NULL;
}
void init_builder(void)
{
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CERT,
- (builder_constructor_t)builder);
+ (builder_function_t)builder_load_cert);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_AC,
- (builder_constructor_t)builder);
+ (builder_function_t)builder_load_ac);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL,
- (builder_constructor_t)builder);
+ (builder_function_t)builder_load_crl);
}
void free_builder(void)
{
- lib->creds->remove_builder(lib->creds, (builder_constructor_t)builder);
+ lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_cert);
+ lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_ac);
+ lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_crl);
}