From: Nalin Dahyabhai Date: Wed, 24 Apr 2013 19:29:27 +0000 (-0400) Subject: In PKINIT NSS crypto, support encrypted PEM keys X-Git-Tag: krb5-1.12-alpha1~169 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f190b7abe307a005b9f58a634c53d06a3a3381ee;p=thirdparty%2Fkrb5.git 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. --- diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index 0c798b50d3..d5b49e7a19 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,