Support module names in %smartcard specifier, streamlined smartcard building
authorMartin Willi <martin@revosec.ch>
Thu, 15 Jul 2010 10:23:50 +0000 (12:23 +0200)
committerMartin Willi <martin@revosec.ch>
Wed, 4 Aug 2010 07:26:20 +0000 (09:26 +0200)
src/libcharon/plugins/stroke/stroke_cred.c
src/libstrongswan/credentials/builder.c
src/libstrongswan/credentials/builder.h
src/libstrongswan/plugins/openssl/openssl_plugin.c
src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c

index 2816b9b..14f2214 100644 (file)
@@ -929,9 +929,14 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
                else if (match("PIN", &token))
                {
                        chunk_t sc = chunk_empty, secret = chunk_empty;
-                       char smartcard[32], keyid[22], pin[32];
+                       char smartcard[64], keyid[64], pin[64], module[64], *pos;
                        private_key_t *key;
                        u_int slot;
+                       enum {
+                               SC_FORMAT_SLOT_MODULE_KEYID,
+                               SC_FORMAT_SLOT_KEYID,
+                               SC_FORMAT_KEYID,
+                       } format;
 
                        err_t ugh = extract_value(&sc, &line);
 
@@ -948,16 +953,31 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
                        snprintf(smartcard, sizeof(smartcard), "%.*s", sc.len, sc.ptr);
                        smartcard[sizeof(smartcard) - 1] = '\0';
 
-                       /* parse slot and key id. only two formats are supported.
-                        * first try %smartcard<slot>:<keyid> */
-                       if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2)
+                       /* parse slot and key id. Three formats are supported:
+                        * - %smartcard<slot>@<module>:<keyid>
+                        * - %smartcard<slot>:<keyid>
+                        * - %smartcard:<keyid>
+                        */
+                       if (sscanf(smartcard, "%%smartcard%u@%s", &slot, module) == 2)
                        {
-                               snprintf(smartcard, sizeof(smartcard), "%u:%s", slot, keyid);
+                               pos = strchr(module, ':');
+                               if (!pos)
+                               {
+                                       DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is "
+                                                "invalid", line_nr);
+                                       goto error;
+                               }
+                               *pos = '\0';
+                               strcpy(keyid, pos + 1);
+                               format = SC_FORMAT_SLOT_MODULE_KEYID;
+                       }
+                       else if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2)
+                       {
+                               format = SC_FORMAT_SLOT_KEYID;
                        }
-                       /* then try %smartcard:<keyid> */
                        else if (sscanf(smartcard, "%%smartcard:%s", keyid) == 1)
                        {
-                               snprintf(smartcard, sizeof(smartcard), "%s", keyid);
+                               format = SC_FORMAT_KEYID;
                        }
                        else
                        {
@@ -980,11 +1000,30 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
                        snprintf(pin, sizeof(pin), "%.*s", secret.len, secret.ptr);
                        pin[sizeof(pin) - 1] = '\0';
 
-                       /* we assume an RSA key */
-                       key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
-                                                                        BUILD_SMARTCARD_KEYID, smartcard,
-                                                                        BUILD_SMARTCARD_PIN, pin, BUILD_END);
-
+                       switch (format)
+                       {
+                               case SC_FORMAT_SLOT_MODULE_KEYID:
+                                       key = lib->creds->create(lib->creds,
+                                                                       CRED_PRIVATE_KEY, KEY_ANY,
+                                                                       BUILD_PKCS11_SLOT, slot,
+                                                                       BUILD_PKCS11_MODULE, module,
+                                                                       BUILD_PKCS11_KEYID, keyid,
+                                                                       BUILD_PKCS11_PIN, pin, BUILD_END);
+                                       break;
+                               case SC_FORMAT_SLOT_KEYID:
+                                       key = lib->creds->create(lib->creds,
+                                                                       CRED_PRIVATE_KEY, KEY_ANY,
+                                                                       BUILD_PKCS11_SLOT, slot,
+                                                                       BUILD_PKCS11_KEYID, keyid,
+                                                                       BUILD_PKCS11_PIN, pin, BUILD_END);
+                                       break;
+                               case SC_FORMAT_KEYID:
+                                       key = lib->creds->create(lib->creds,
+                                                                       CRED_PRIVATE_KEY, KEY_ANY,
+                                                                       BUILD_PKCS11_KEYID, keyid,
+                                                                       BUILD_PKCS11_PIN, pin, BUILD_END);
+                                       break;
+                       }
                        if (key)
                        {
                                DBG1(DBG_CFG, "  loaded private key from %.*s", sc.len, sc.ptr);
index cfb708e..1fa1377 100644 (file)
@@ -45,8 +45,10 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
        "BUILD_PATHLEN",
        "BUILD_X509_FLAG",
        "BUILD_REVOKED_ENUMERATOR",
-       "BUILD_SMARTCARD_KEYID",
-       "BUILD_SMARTCARD_PIN",
+       "BUILD_PKCS11_MODULE",
+       "BUILD_PKCS11_SLOT",
+       "BUILD_PKCS11_KEYID",
+       "BUILD_PKCS11_PIN",
        "BUILD_RSA_MODULUS",
        "BUILD_RSA_PUB_EXP",
        "BUILD_RSA_PRIV_EXP",
index ffb09f7..d13ada0 100644 (file)
@@ -103,10 +103,14 @@ enum builder_part_t {
        BUILD_X509_FLAG,
        /** enumerator_t over (chunk_t serial, time_t date, crl_reason_t reason) */
        BUILD_REVOKED_ENUMERATOR,
-       /** key ID of a key on a smartcard, null terminated char* ([slot:]keyid) */
-       BUILD_SMARTCARD_KEYID,
-       /** pin to access a key on a smartcard, null terminated char* */
-       BUILD_SMARTCARD_PIN,
+       /** friendly name of a PKCS#11 module, null terminated char* */
+       BUILD_PKCS11_MODULE,
+       /** slot specifier for a token in a PKCS#11 module, int */
+       BUILD_PKCS11_SLOT,
+       /** key ID of a key on a token, null terminated char* */
+       BUILD_PKCS11_KEYID,
+       /** pin to access a token, null terminated char* */
+       BUILD_PKCS11_PIN,
        /** modulus (n) of a RSA key, chunk_t */
        BUILD_RSA_MODULUS,
        /** public exponent (e) of a RSA key, chunk_t */
index 31697dc..ab08a20 100644 (file)
@@ -318,7 +318,7 @@ plugin_t *openssl_plugin_create()
                                        (builder_function_t)openssl_rsa_private_key_load);
        lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
                                        (builder_function_t)openssl_rsa_private_key_gen);
-       lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+       lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
                                        (builder_function_t)openssl_rsa_private_key_connect);
        lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
                                        (builder_function_t)openssl_rsa_public_key_load);
index 5817ade..b7b6e79 100644 (file)
@@ -451,21 +451,28 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
 {
 #ifndef OPENSSL_NO_ENGINE
        private_openssl_rsa_private_key_t *this;
-       char *keyid = NULL, *pin = NULL;
+       char *keyid = NULL, *pin = NULL, *engine_id = NULL;
+       char keyname[64];
        EVP_PKEY *key;
-       char *engine_id;
        ENGINE *engine;
+       int slot = -1;
 
        while (TRUE)
        {
                switch (va_arg(args, builder_part_t))
                {
-                       case BUILD_SMARTCARD_KEYID:
+                       case BUILD_PKCS11_KEYID:
                                keyid = va_arg(args, char*);
                                continue;
-                       case BUILD_SMARTCARD_PIN:
+                       case BUILD_PKCS11_PIN:
                                pin = va_arg(args, char*);
                                continue;
+                       case BUILD_PKCS11_SLOT:
+                               slot = va_arg(args, int);
+                               continue;
+                       case BUILD_PKCS11_MODULE:
+                               engine_id = va_arg(args, char*);
+                               continue;
                        case BUILD_END:
                                break;
                        default:
@@ -478,8 +485,20 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
                return NULL;
        }
 
-       engine_id = lib->settings->get_str(lib->settings,
+       if (slot == -1)
+       {
+               snprintf(keyname, sizeof(keyname), "%s", keyid);
+       }
+       else
+       {
+               snprintf(keyname, sizeof(keyname), "%d:%s", slot, keyid);
+       }
+
+       if (!engine_id)
+       {
+               engine_id = lib->settings->get_str(lib->settings,
                                                "libstrongswan.plugins.openssl.engine_id", "pkcs11");
+       }
        engine = ENGINE_by_id(engine_id);
        if (!engine)
        {
@@ -499,11 +518,11 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
                return NULL;
        }
 
-       key = ENGINE_load_private_key(engine, keyid, NULL, NULL);
+       key = ENGINE_load_private_key(engine, keyname, NULL, NULL);
        if (!key)
        {
                DBG1(DBG_LIB, "failed to load private key with ID '%s' from "
-                        "engine '%s'", keyid, engine_id);
+                        "engine '%s'", keyname, engine_id);
                ENGINE_free(engine);
                return NULL;
        }
@@ -512,6 +531,11 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
        this = create_empty();
        this->rsa = EVP_PKEY_get1_RSA(key);
        this->engine = TRUE;
+       if (!this->rsa)
+       {
+               destroy(this);
+               return NULL;
+       }
 
        return &this->public;
 #else /* OPENSSL_NO_ENGINE */