]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
stroke: Permanently store PINs in credential set
authorTobias Brunner <tobias@strongswan.org>
Thu, 7 Apr 2016 17:08:59 +0000 (19:08 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 6 Jun 2016 12:03:23 +0000 (14:03 +0200)
This fixes authentication with tokens that require the PIN for every
signature.

Fixes #1369.

src/libcharon/plugins/stroke/stroke_cred.c

index 42928882a84eff6e638df7bb376baa7fb6378307..929e6fc843189d6b70789063581b72be4ed4a832 100644 (file)
@@ -754,6 +754,8 @@ typedef struct {
        chunk_t keyid;
        /** number of tries */
        int try;
+       /** provided PIN */
+       shared_key_t *shared;
 } pin_cb_data_t;
 
 /**
@@ -798,7 +800,9 @@ static shared_key_t* pin_cb(pin_cb_data_t *data, shared_key_type_t type,
                        {
                                *match_other = ID_MATCH_NONE;
                        }
-                       return shared_key_create(SHARED_PIN, chunk_clone(secret));
+                       DESTROY_IF(data->shared);
+                       data->shared = shared_key_create(SHARED_PIN, chunk_clone(secret));
+                       return data->shared->get_ref(data->shared);
                }
        }
        return NULL;
@@ -815,7 +819,7 @@ static bool load_pin(mem_cred_t *secrets, chunk_t line, int line_nr,
        private_key_t *key = NULL;
        u_int slot;
        chunk_t chunk;
-       shared_key_t *shared;
+       shared_key_t *shared = NULL;
        identification_t *id;
        mem_cred_t *mem = NULL;
        callback_cred_t *cb = NULL;
@@ -867,10 +871,11 @@ static bool load_pin(mem_cred_t *secrets, chunk_t line, int line_nr,
                        return TRUE;
                }
                /* use callback credential set to prompt for the pin */
-               pin_data.prompt = prompt;
-               pin_data.card = smartcard;
-               pin_data.keyid = chunk;
-               pin_data.try = 0;
+               pin_data = (pin_cb_data_t){
+                       .prompt = prompt,
+                       .card = smartcard,
+                       .keyid = chunk,
+               };
                cb = callback_cred_create_shared((void*)pin_cb, &pin_data);
                lib->credmgr->add_local_set(lib->credmgr, &cb->set, FALSE);
        }
@@ -880,30 +885,48 @@ static bool load_pin(mem_cred_t *secrets, chunk_t line, int line_nr,
                shared = shared_key_create(SHARED_PIN, secret);
                id = identification_create_from_encoding(ID_KEY_ID, chunk);
                mem = mem_cred_create();
-               mem->add_shared(mem, shared, id, NULL);
+               mem->add_shared(mem, shared->get_ref(shared), id, NULL);
                lib->credmgr->add_local_set(lib->credmgr, &mem->set, FALSE);
        }
 
        /* unlock: smartcard needs the pin and potentially calls public set */
        key = (private_key_t*)load_from_smartcard(format, slot, module, keyid,
                                                                                          CRED_PRIVATE_KEY, KEY_ANY);
+
+       if (key)
+       {
+               DBG1(DBG_CFG, "  loaded private key from %.*s", (int)sc.len, sc.ptr);
+               secrets->add_key(secrets, key);
+       }
        if (mem)
        {
+               if (!key)
+               {
+                       shared->destroy(shared);
+                       shared = NULL;
+               }
                lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
                mem->destroy(mem);
        }
        if (cb)
        {
+               if (key)
+               {
+                       shared = pin_data.shared;
+               }
+               else
+               {
+                       DESTROY_IF(pin_data.shared);
+               }
                lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
                cb->destroy(cb);
        }
-       chunk_clear(&chunk);
-
-       if (key)
+       if (shared)
        {
-               DBG1(DBG_CFG, "  loaded private key from %.*s", (int)sc.len, sc.ptr);
-               secrets->add_key(secrets, key);
+               id = identification_create_from_encoding(ID_KEY_ID, chunk);
+               secrets->add_shared(secrets, shared, id, NULL);
        }
+       chunk_clear(&chunk);
        return TRUE;
 }