summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@dahyabhai.net>2013-04-24 15:29:27 -0400
committerGreg Hudson <ghudson@mit.edu>2013-05-13 01:59:35 -0400
commitf190b7abe307a005b9f58a634c53d06a3a3381ee (patch)
tree55c1f46ad3a7205c48c5850fda8650ee53414b6e
parent9d429bb8a78060334d2a533723fe549c72cba68e (diff)
In PKINIT NSS crypto, support encrypted PEM keys
When the PEM module is given an encrypted key, it changes its token flags to indicate that a password is required (by setting needs-login) to signal the application that we need to supply a password to decrypt it. Attempts to load any other items will fail until the flag is cleared. If we detect that the flag is set after we've attempted to load a private key, attempt to "log in" to the "token" using a password. Even if we fail, the token will reset its needs-login flag, which is necessary before we can import anything else.
-rw-r--r--src/plugins/preauth/pkinit/pkinit_crypto_nss.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
index 0c798b50d..d5b49e7a1 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
@@ -2642,6 +2642,32 @@ crypto_load_files(krb5_context context,
}
}
+ /* "Log in" (provide an encryption password) if the PEM slot now
+ * requires it. */
+ PK11_TokenRefresh(slot);
+
+ /*
+ * Unlike most tokens, this one won't self-destruct if we throw wrong
+ * passwords at it, but it will cause the module to clear the
+ * needs-login flag so that we can continue importing PEM items.
+ */
+ if (!PK11_IsLoggedIn(slot, crypto_pwcb_prep(id_cryptoctx,
+ context)) &&
+ PK11_NeedLogin(slot)) {
+ pkiDebug("%s: logging in to token \"%s\"\n",
+ __FUNCTION__, PK11_GetTokenName(slot));
+ if (PK11_Authenticate(slot, PR_TRUE,
+ crypto_pwcb_prep(id_cryptoctx,
+ context)) != SECSuccess) {
+ pkiDebug("%s: error logging into \"%s\": %s, skipping\n",
+ __FUNCTION__, PK11_GetTokenName(slot),
+ PORT_ErrorToName(PORT_GetError()));
+ status = SECFailure;
+ PK11_DestroyGenericObject(kobj->obj);
+ kobj->obj = NULL;
+ }
+ }
+
/* If we loaded a key and a certificate, see if they match. */
if (cobj != NULL && cobj->cert != NULL && kobj->obj != NULL) {
key = PK11_FindPrivateKeyFromCert(slot, cobj->cert,