stroke: Permanently store PINs in credential set
This fixes authentication with tokens that require the PIN for every signature. Fixes #1369.
This commit is contained in:
@@ -754,6 +754,8 @@ typedef struct {
|
|||||||
chunk_t keyid;
|
chunk_t keyid;
|
||||||
/** number of tries */
|
/** number of tries */
|
||||||
int try;
|
int try;
|
||||||
|
/** provided PIN */
|
||||||
|
shared_key_t *shared;
|
||||||
} pin_cb_data_t;
|
} 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;
|
*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;
|
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;
|
private_key_t *key = NULL;
|
||||||
u_int slot;
|
u_int slot;
|
||||||
chunk_t chunk;
|
chunk_t chunk;
|
||||||
shared_key_t *shared;
|
shared_key_t *shared = NULL;
|
||||||
identification_t *id;
|
identification_t *id;
|
||||||
mem_cred_t *mem = NULL;
|
mem_cred_t *mem = NULL;
|
||||||
callback_cred_t *cb = 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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
/* use callback credential set to prompt for the pin */
|
/* use callback credential set to prompt for the pin */
|
||||||
pin_data.prompt = prompt;
|
pin_data = (pin_cb_data_t){
|
||||||
pin_data.card = smartcard;
|
.prompt = prompt,
|
||||||
pin_data.keyid = chunk;
|
.card = smartcard,
|
||||||
pin_data.try = 0;
|
.keyid = chunk,
|
||||||
|
};
|
||||||
cb = callback_cred_create_shared((void*)pin_cb, &pin_data);
|
cb = callback_cred_create_shared((void*)pin_cb, &pin_data);
|
||||||
lib->credmgr->add_local_set(lib->credmgr, &cb->set, FALSE);
|
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);
|
shared = shared_key_create(SHARED_PIN, secret);
|
||||||
id = identification_create_from_encoding(ID_KEY_ID, chunk);
|
id = identification_create_from_encoding(ID_KEY_ID, chunk);
|
||||||
mem = mem_cred_create();
|
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);
|
lib->credmgr->add_local_set(lib->credmgr, &mem->set, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unlock: smartcard needs the pin and potentially calls public set */
|
/* unlock: smartcard needs the pin and potentially calls public set */
|
||||||
key = (private_key_t*)load_from_smartcard(format, slot, module, keyid,
|
key = (private_key_t*)load_from_smartcard(format, slot, module, keyid,
|
||||||
CRED_PRIVATE_KEY, KEY_ANY);
|
CRED_PRIVATE_KEY, KEY_ANY);
|
||||||
if (mem)
|
|
||||||
{
|
|
||||||
lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
|
|
||||||
mem->destroy(mem);
|
|
||||||
}
|
|
||||||
if (cb)
|
|
||||||
{
|
|
||||||
lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
|
|
||||||
cb->destroy(cb);
|
|
||||||
}
|
|
||||||
chunk_clear(&chunk);
|
|
||||||
|
|
||||||
if (key)
|
if (key)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, " loaded private key from %.*s", (int)sc.len, sc.ptr);
|
DBG1(DBG_CFG, " loaded private key from %.*s", (int)sc.len, sc.ptr);
|
||||||
secrets->add_key(secrets, key);
|
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);
|
||||||
|
}
|
||||||
|
if (shared)
|
||||||
|
{
|
||||||
|
id = identification_create_from_encoding(ID_KEY_ID, chunk);
|
||||||
|
secrets->add_shared(secrets, shared, id, NULL);
|
||||||
|
}
|
||||||
|
chunk_clear(&chunk);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user