From aaeb02de1b283267303cb287efde845d406645ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Wed, 3 May 2006 16:40:09 +0000 Subject: [PATCH] Use the prompter from the lock function. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17417 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/hx509/ks_p11.c | 75 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/lib/hx509/ks_p11.c b/lib/hx509/ks_p11.c index c8c6055c1..cb47e10eb 100644 --- a/lib/hx509/ks_p11.c +++ b/lib/hx509/ks_p11.c @@ -55,13 +55,14 @@ struct p11_module { CK_BBOOL token; char *name; hx509_certs certs; + char *pin; } slot; }; #define P11SESSION(module) ((module)->session) #define P11FUNC(module,f,args) (*(module)->funcs->C_##f)args -static int p11_get_session(struct p11_module *, struct p11_slot *); +static int p11_get_session(struct p11_module *, struct p11_slot *, hx509_lock); static int p11_put_session(struct p11_module *, struct p11_slot *); static void p11_release_module(struct p11_module *); @@ -119,7 +120,7 @@ p11_rsa_private_encrypt(int flen, ck_sigsize = RSA_size(rsa); - p11_get_session(p11rsa->p, p11rsa->slot); + p11_get_session(p11rsa->p, p11rsa->slot, NULL); ret = P11FUNC(p11rsa->p, SignInit, (P11SESSION(p11rsa->slot), &mechanism, key)); @@ -156,7 +157,7 @@ p11_rsa_private_decrypt(int flen, const unsigned char *from, unsigned char *to, ck_sigsize = RSA_size(rsa); - p11_get_session(p11rsa->p, p11rsa->slot); + p11_get_session(p11rsa->p, p11rsa->slot, NULL); ret = P11FUNC(p11rsa->p, DecryptInit, (P11SESSION(p11rsa->slot), &mechanism, key)); @@ -250,7 +251,9 @@ p11_init_slot(struct p11_module *p, CK_SLOT_ID id, struct p11_slot *slot) } static int -p11_get_session(struct p11_module *p, struct p11_slot *slot) +p11_get_session(struct p11_module *p, + struct p11_slot *slot, + hx509_lock lock) { CK_RV ret; @@ -267,25 +270,65 @@ p11_get_session(struct p11_module *p, struct p11_slot *slot) slot->flags |= P11_SESSION; - if ((slot->flags & P11_LOGIN_REQ) && (slot->flags & P11_LOGIN_DONE) == 0) { + /* + * If we have have to login, and haven't tried before and have a + * prompter or known to work pin code. + * + * This code is very conversative and only uses the prompter in + * the hx509_lock, the reason is that its bad to try many + * passwords on a pkcs11 token, it might lock up and have to be + * unlocked by a administrator. + * + * XXX try harder to not use pin several times on the same card. + */ + + if ( (slot->flags & P11_LOGIN_REQ) + && (slot->flags & P11_LOGIN_DONE) == 0 + && (lock || slot->pin)) + { + hx509_prompt prompt; char pin[20]; - char *prompt; + char *str; slot->flags |= P11_LOGIN_DONE; - asprintf(&prompt, "PIN code for %s: ", slot->name); + if (slot->pin == NULL) { - if (UI_UTIL_read_pw_string(pin, sizeof(pin), prompt, 0)) { - free(prompt); - return EINVAL; + memset(&prompt, 0, sizeof(prompt)); + + asprintf(&str, "PIN code for %s: ", slot->name); + prompt.prompt = str; + prompt.hidden = 1; + prompt.type = HX509_PROMPT_TYPE_PASSWORD; + prompt.reply.data = pin; + prompt.reply.length = sizeof(pin); + + ret = hx509_lock_prompt(lock, &prompt); + if (ret) { + free(str); + return ret; + } + free(str); + } else { + strlcpy(pin, slot->pin, sizeof(pin)); } - free(prompt); ret = P11FUNC(p, Login, (P11SESSION(slot), CKU_USER, (unsigned char*)pin, strlen(pin))); - if (ret != CKR_OK) + if (ret != CKR_OK) { + p11_put_session(p, slot); return EINVAL; - } + } + if (slot->pin == NULL) { + slot->pin = strdup(pin); + if (slot->pin == NULL) { + p11_put_session(p, slot); + return EINVAL; + } + } + + } else + slot->flags |= P11_LOGIN_DONE; return 0; } @@ -667,7 +710,7 @@ p11_init(hx509_context context, free(slot_ids); - p11_get_session(p, &p->slot); + p11_get_session(p, &p->slot, lock); p11_list_keys(context, p, &p->slot, NULL, &p->slot.certs); p11_put_session(p, &p->slot); } @@ -692,6 +735,10 @@ p11_release_module(struct p11_module *p) dlclose(p->dl_handle); if (p->slot.name) free(p->slot.name); + if (p->slot.pin) { + memset(p->slot.pin, 0, strlen(p->slot.pin)); + free(p->slot.pin); + } memset(p, 0, sizeof(*p)); free(p); }