charon-cmd: Add support for PKCS#12 files
authorTobias Brunner <tobias@strongswan.org>
Fri, 12 Apr 2013 17:30:03 +0000 (19:30 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 May 2013 13:02:40 +0000 (15:02 +0200)
configure.in
src/charon-cmd/cmd/cmd_connection.c
src/charon-cmd/cmd/cmd_creds.c
src/charon-cmd/cmd/cmd_options.c
src/charon-cmd/cmd/cmd_options.h

index c858a29..87466f2 100644 (file)
@@ -967,9 +967,9 @@ ADD_PLUGIN([revocation],           [s charon nm cmd])
 ADD_PLUGIN([constraints],          [s charon nm cmd])
 ADD_PLUGIN([pubkey],               [s charon cmd])
 ADD_PLUGIN([pkcs1],                [s charon openac scepclient pki scripts manager medsrv attest nm cmd])
-ADD_PLUGIN([pkcs7],                [s scepclient pki scripts])
+ADD_PLUGIN([pkcs7],                [s scepclient pki scripts cmd])
 ADD_PLUGIN([pkcs8],                [s charon openac scepclient pki scripts manager medsrv attest nm cmd])
-ADD_PLUGIN([pkcs12],               [s charon scepclient pki scripts])
+ADD_PLUGIN([pkcs12],               [s charon scepclient pki scripts cmd])
 ADD_PLUGIN([pgp],                  [s charon])
 ADD_PLUGIN([dnskey],               [s charon])
 ADD_PLUGIN([sshkey],               [s charon nm cmd])
index 9c25df9..e48f548 100644 (file)
@@ -391,6 +391,7 @@ METHOD(cmd_connection_t, handle, bool,
                        break;
                case CMD_OPT_RSA:
                case CMD_OPT_AGENT:
+               case CMD_OPT_PKCS12:
                        this->key_seen = TRUE;
                        break;
                case CMD_OPT_LOCAL_TS:
index 4626c6d..526ff7c 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <utils/debug.h>
 #include <credentials/sets/mem_cred.h>
+#include <credentials/containers/pkcs12.h>
 #include <credentials/sets/callback_cred.h>
 
 typedef struct private_cmd_creds_t private_cmd_creds_t;
@@ -70,6 +71,7 @@ static shared_key_t* callback_shared(private_cmd_creds_t *this,
                                                                identification_t *me, identification_t *other,
                                                                id_match_t *match_me, id_match_t *match_other)
 {
+       shared_key_t *shared;
        char *label, *pwd;
 
        if (this->prompted)
@@ -104,7 +106,10 @@ static shared_key_t* callback_shared(private_cmd_creds_t *this,
        {
                *match_other = ID_MATCH_PERFECT;
        }
-       return shared_key_create(type, chunk_clone(chunk_from_str(pwd)));
+       shared = shared_key_create(type, chunk_clone(chunk_from_str(pwd)));
+       /* cache password in case it is required more than once */
+       this->creds->add_shared(this->creds, shared, NULL);
+       return shared->get_ref(shared);
 }
 
 /**
@@ -182,6 +187,40 @@ static void load_agent(private_cmd_creds_t *this)
        this->creds->add_key(this->creds, privkey);
 }
 
+/**
+ * Load a PKCS#12 file from path
+ */
+static void load_pkcs12(private_cmd_creds_t *this, char *path)
+{
+       enumerator_t *enumerator;
+       certificate_t *cert;
+       private_key_t *key;
+       container_t *container;
+       pkcs12_t *pkcs12;
+
+       container = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
+                                                                  BUILD_FROM_FILE, path, BUILD_END);
+       if (!container)
+       {
+               DBG1(DBG_CFG, "loading PKCS#12 file '%s' failed", path);
+               exit(1);
+       }
+       pkcs12 = (pkcs12_t*)container;
+       enumerator = pkcs12->create_cert_enumerator(pkcs12);
+       while (enumerator->enumerate(enumerator, &cert))
+       {
+               this->creds->add_cert(this->creds, TRUE, cert->get_ref(cert));
+       }
+       enumerator->destroy(enumerator);
+       enumerator = pkcs12->create_key_enumerator(pkcs12);
+       while (enumerator->enumerate(enumerator, &key))
+       {
+               this->creds->add_key(this->creds, key->get_ref(key));
+       }
+       enumerator->destroy(enumerator);
+       container->destroy(container);
+}
+
 METHOD(cmd_creds_t, handle, bool,
        private_cmd_creds_t *this, cmd_option_type_t opt, char *arg)
 {
@@ -193,6 +232,9 @@ METHOD(cmd_creds_t, handle, bool,
                case CMD_OPT_RSA:
                        load_key(this, KEY_RSA, arg);
                        break;
+               case CMD_OPT_PKCS12:
+                       load_pkcs12(this, arg);
+                       break;
                case CMD_OPT_IDENTITY:
                        this->identity = arg;
                        break;
index 06d0996..e7dbff7 100644 (file)
@@ -38,6 +38,10 @@ cmd_option_t cmd_options[CMD_OPT_COUNT] = {
          "trusted certificate, for authentication or trust chain validation", {}},
        { CMD_OPT_RSA, "rsa", required_argument, "path",
          "RSA private key to use for authentication", {}},
+       { CMD_OPT_PKCS12, "p12", required_argument, "path",
+         "PKCS#12 file with private key and certificates to use for ", {
+               "authentication and trust chain validation"
+       }},
        { CMD_OPT_AGENT, "agent", optional_argument, "socket",
          "use SSH agent for authentication. If socket is not specified", {
                "it is read from the SSH_AUTH_SOCK environment variable",
index a14896f..7a6080f 100644 (file)
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2013 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
  * Copyright (C) 2013 Martin Willi
  * Copyright (C) 2013 revosec AG
  *
@@ -35,6 +38,7 @@ enum cmd_option_type_t {
        CMD_OPT_REMOTE_IDENTITY,
        CMD_OPT_CERT,
        CMD_OPT_RSA,
+       CMD_OPT_PKCS12,
        CMD_OPT_AGENT,
        CMD_OPT_LOCAL_TS,
        CMD_OPT_REMOTE_TS,