Updated pluto to the new builder API
[strongswan.git] / src / pluto / builder.c
index 2c3a8ea..52e7efe 100644 (file)
 #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);
 }