streamlined file loading labels
[strongswan.git] / src / pluto / certs.c
index 39ff8df..129b58c 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <freeswan.h>
 
 #include "library.h"
 #include "asn1/asn1.h"
+#include "credentials/certificates/certificate.h"
 
 #include "constants.h"
 #include "defs.h"
 #include "log.h"
 #include "id.h"
-#include "pem.h"
 #include "certs.h"
+#include "whack.h"
+#include "builder.h"
 
 /**
  * used for initializatin of certs
@@ -66,70 +69,43 @@ public_key_t* cert_get_public_key(const cert_t cert)
        }
 }
 
-/* load a coded key or certificate file with autodetection
- * of binary DER or base64 PEM ASN.1 formats and armored PGP format
+/**
+ * Passphrase callback to read from whack fd
  */
-bool load_coded_file(char *filename, prompt_pass_t *pass, const char *type,
-                                        chunk_t *blob, bool *pgp)
+chunk_t whack_pass_cb(prompt_pass_t *pass, int try)
 {
-       err_t ugh = NULL;
-
-       FILE *fd = fopen(filename, "r");
+       int n;
 
-       if (fd)
+       if (try > MAX_PROMPT_PASS_TRIALS)
+       {
+               whack_log(RC_LOG_SERIOUS, "invalid passphrase, too many trials");
+               return chunk_empty;
+       }
+       if (try == 1)
        {
-               int bytes;
-               fseek(fd, 0, SEEK_END );
-               blob->len = ftell(fd);
-               rewind(fd);
-               blob->ptr = malloc(blob->len);
-               bytes = fread(blob->ptr, 1, blob->len, fd);
-               fclose(fd);
-               plog("  loaded %s file '%s' (%d bytes)", type, filename, bytes);
+               whack_log(RC_ENTERSECRET, "need passphrase for 'private key'");
+       }
+       else
+       {
+               whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
+       }
 
-               *pgp = FALSE;
+       n = read(pass->fd, pass->secret, PROMPT_PASS_LEN);
 
-               /* try DER format */
-               if (is_asn1(*blob))
-               {
-                       DBG(DBG_PARSING,
-                               DBG_log("  file coded in DER format");
-                       )
-                       return TRUE;
-               }
+       if (n == -1)
+       {
+               whack_log(RC_LOG_SERIOUS, "read(whackfd) failed");
+               return chunk_empty;
+       }
 
-               /* try PEM format */
-               ugh = pemtobin(blob, pass, filename, pgp);
+       pass->secret[n-1] = '\0';
 
-               if (ugh == NULL)
-               {
-                       if (*pgp)
-                       {
-                               DBG(DBG_PARSING,
-                                       DBG_log("  file coded in armored PGP format");
-                               )
-                               return TRUE;
-                       }
-                       if (is_asn1(*blob))
-                       {
-                               DBG(DBG_PARSING,
-                                       DBG_log("  file coded in PEM format");
-                               )
-                               return TRUE;
-                       }
-                       ugh = "file coded in unknown format, discarded";
-               }
-
-               /* a conversion error has occured */
-               plog("  %s", ugh);
-               free(blob->ptr);
-               *blob = chunk_empty;
-       }
-       else
+       if (strlen(pass->secret) == 0)
        {
-               plog("  could not open %s file '%s'", type, filename);
+               whack_log(RC_LOG_SERIOUS, "no passphrase entered, aborted");
+               return chunk_empty;
        }
-       return FALSE;
+       return chunk_create(pass->secret, strlen(pass->secret));
 }
 
 /**
@@ -139,31 +115,40 @@ private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
                                                                key_type_t type)
 {
        private_key_t *key = NULL;
-       chunk_t blob = chunk_empty;
-       bool pgp = FALSE;
-
-       char *path = concatenate_paths(PRIVATE_KEY_PATH, filename);
-
-       if (load_coded_file(path, pass, "private key", &blob, &pgp))
-       {
-               if (pgp)
+       char *path;
+       
+       path = concatenate_paths(PRIVATE_KEY_PATH, filename);
+       if (pass && pass->prompt && pass->fd != NULL_FD)
+       {       /* use passphrase callback */
+               key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
+                                                                BUILD_FROM_FILE, path,
+                                                                BUILD_PASSPHRASE_CALLBACK, whack_pass_cb, pass,
+                                                                BUILD_END);
+               if (key)
                {
-                       parse_pgp(blob, NULL, &key);
+                       whack_log(RC_SUCCESS, "valid passphrase");
                }
-               else
-               {
-                       key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
-                                                                        BUILD_BLOB_ASN1_DER, blob, BUILD_END);
-               }
-               if (key == NULL)
-               {
-                       plog("  syntax error in %s private key file", pgp ? "PGP":"PKCS#");
-               }                       
-               free(blob.ptr);
+       }
+       else if (pass)
+       {       /* use a given passphrase */
+               chunk_t password = chunk_create(pass->secret, strlen(pass->secret));
+               key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
+                                                                BUILD_FROM_FILE, path,
+                                                                BUILD_PASSPHRASE, password, BUILD_END);
        }
        else
+       {       /* no passphrase */
+               key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
+                                                                BUILD_FROM_FILE, path, BUILD_END);
+               
+       }
+       if (key)
        {
-               plog("  error loading RSA private key file");
+               plog("  loaded private key from '%s'", filename);
+       }
+       else
+       {
+               plog("  syntax error in private key file");
        }
        return key;
 }
@@ -171,51 +156,19 @@ private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
 /**
  *  Loads a X.509 or OpenPGP certificate
  */
-bool load_cert(char *filename, const char *label, cert_t *cert)
+bool load_cert(char *filename, const char *label, cert_t *out)
 {
-       bool pgp = FALSE;
-       chunk_t blob = chunk_empty;
-
-       /* initialize cert struct */
-       cert->type = CERT_NONE;
-       cert->u.x509 = NULL;
+       cert_t *cert;
 
-       if (load_coded_file(filename, NULL, label, &blob, &pgp))
+       cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CERT,
+                                                         BUILD_FROM_FILE, filename, BUILD_END);
+       if (cert)
        {
-               if (pgp)
-               {
-                       pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
-                       *pgpcert = pgpcert_empty;
-                       if (parse_pgp(blob, pgpcert, NULL))
-                       {
-                               cert->type = CERT_PGP;
-                               cert->u.pgp = pgpcert;
-                               return TRUE;
-                       }
-                       else
-                       {
-                               plog("  error in OpenPGP certificate");
-                               free_pgpcert(pgpcert);
-                               return FALSE;
-                       }
-               }
-               else
-               {
-                       x509cert_t *x509cert = malloc_thing(x509cert_t);
-                       *x509cert = empty_x509cert;
-                       if (parse_x509cert(blob, 0, x509cert))
-                       {
-                               cert->type = CERT_X509_SIGNATURE;
-                               cert->u.x509 = x509cert;
-                               return TRUE;
-                       }
-                       else
-                       {
-                               plog("  error in X.509 certificate");
-                               free_x509cert(x509cert);
-                               return FALSE;
-                       }
-               }
+               /* the API passes an empty cert_t, we move over and free the built one */
+               plog("  loaded %s certificate from '%s'", label, filename);
+               *out = *cert;
+               free(cert);
+               return TRUE;
        }
        return FALSE;
 }
@@ -227,7 +180,7 @@ bool load_host_cert(char *filename, cert_t *cert)
 {
        char *path = concatenate_paths(HOST_CERT_PATH, filename);
 
-       return load_cert(path, "host cert", cert);
+       return load_cert(path, "host", cert);
 }
 
 /**
@@ -237,7 +190,7 @@ bool load_ca_cert(char *filename, cert_t *cert)
 {
        char *path = concatenate_paths(CA_CERT_PATH, filename);
 
-       return load_cert(path, "CA cert", cert);
+       return load_cert(path, "CA", cert);
 }
 
 /**