swanctl: Cache entered PKCS#12 decryption secret

It is usually used more than once, but most likely the same for decryption and
MAC verification.
This commit is contained in:
Martin Willi 2015-03-11 16:52:54 +01:00
parent 54cdf847cc
commit 1e366429fd

View File

@ -179,14 +179,23 @@ static bool load_key_anytype(vici_conn_t *conn, command_format_options_t format,
return loaded; return loaded;
} }
/**
* Data passed to password callback
*/
typedef struct {
char prompt[128];
mem_cred_t *cache;
} cb_data_t;
/** /**
* Callback function to prompt for private key passwords * Callback function to prompt for private key passwords
*/ */
CALLBACK(password_cb, shared_key_t*, CALLBACK(password_cb, shared_key_t*,
char *prompt, shared_key_type_t type, cb_data_t *data, shared_key_type_t type,
identification_t *me, identification_t *other, identification_t *me, identification_t *other,
id_match_t *match_me, id_match_t *match_other) id_match_t *match_me, id_match_t *match_other)
{ {
shared_key_t *shared;
char *pwd = NULL; char *pwd = NULL;
if (type != SHARED_PRIVATE_KEY_PASS) if (type != SHARED_PRIVATE_KEY_PASS)
@ -194,7 +203,7 @@ CALLBACK(password_cb, shared_key_t*,
return NULL; return NULL;
} }
#ifdef HAVE_GETPASS #ifdef HAVE_GETPASS
pwd = getpass(prompt); pwd = getpass(data->prompt);
#endif #endif
if (!pwd || strlen(pwd) == 0) if (!pwd || strlen(pwd) == 0)
{ {
@ -208,7 +217,10 @@ CALLBACK(password_cb, shared_key_t*,
{ {
*match_other = ID_MATCH_PERFECT; *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 secret if it is required more than once (PKCS#12) */
data->cache->add_shared(data->cache, shared, NULL);
return shared->get_ref(shared);
} }
/** /**
@ -250,21 +262,26 @@ static void* decrypt(char *name, char *type, chunk_t encoding)
int subtype; int subtype;
void *cred; void *cred;
callback_cred_t *cb; callback_cred_t *cb;
char buf[128]; cb_data_t data;
if (!determine_credtype(type, &credtype, &subtype)) if (!determine_credtype(type, &credtype, &subtype))
{ {
return NULL; return NULL;
} }
snprintf(buf, sizeof(buf), "Password for %s file '%s': ", type, name); snprintf(data.prompt, sizeof(data.prompt), "Password for %s file '%s': ",
type, name);
cb = callback_cred_create_shared(password_cb, buf); data.cache = mem_cred_create();
lib->credmgr->add_set(lib->credmgr, &data.cache->set);
cb = callback_cred_create_shared(password_cb, &data);
lib->credmgr->add_set(lib->credmgr, &cb->set); lib->credmgr->add_set(lib->credmgr, &cb->set);
cred = lib->creds->create(lib->creds, credtype, subtype, cred = lib->creds->create(lib->creds, credtype, subtype,
BUILD_BLOB_PEM, encoding, BUILD_END); BUILD_BLOB_PEM, encoding, BUILD_END);
lib->credmgr->remove_set(lib->credmgr, &data.cache->set);
data.cache->destroy(data.cache);
lib->credmgr->remove_set(lib->credmgr, &cb->set); lib->credmgr->remove_set(lib->credmgr, &cb->set);
cb->destroy(cb); cb->destroy(cb);