From 59c5411f01eadfd5e2a9670fd0676d83eb58e667 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 8 Nov 2010 22:38:07 -0500 Subject: [PATCH 109/150] - password-locked pkcs12 works now, though cleanup doesn't --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 56 +++++++++++++++++------- 1 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index 9188ba0..fd67b58 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -36,6 +36,7 @@ #include #include "k5-int.h" +#include "k5-utf8.h" #include "krb5.h" #include @@ -651,7 +652,7 @@ crypto_get_p12_slot(struct _pkinit_identity_crypto_context *id) if (id->id_p12_slot == NULL) { configdir = DEFAULT_CONFIGDIR; #ifdef PKCS12_HACK - while ((spec = tempnam(NULL, "p12")) != NULL) { + while ((spec = tempnam(NULL, "pk12")) != NULL) { if (spec != NULL) { if (mkdir(spec, S_IRWXU) == 0) { configdir = spec; @@ -716,9 +717,9 @@ crypto_close_p12_slot(struct _pkinit_identity_crypto_context *id) strerror(errno)); } else { while ((ent = readdir(dir)) != NULL) { - path = PORT_Alloc(strlen(ent->d_name) + + path = PORT_Alloc(strlen(id->id_p12_slot_dir) + 1 + - strlen(id->id_p12_slot_dir) + + strlen(ent->d_name) + 1); if (path != NULL) { sprintf(path, "%s/%s", @@ -2188,7 +2189,7 @@ crypto_load_pkcs12(krb5_context context, { PK11SlotInfo *slot; SEC_PKCS12DecoderContext *ctx; - unsigned char emptypwd[] = {'\0'}; + unsigned char emptypwd[] = {'\0','\0'}; SECItem tmp, password; PRBool retry; int attempt; @@ -2213,8 +2214,9 @@ crypto_load_pkcs12(krb5_context context, /* Pass in the password. */ memset(&password, 0, sizeof(password)); password.data = emptypwd; - password.len = 1; + password.len = 2; attempt = 0; + ctx = NULL; do { retry = PR_FALSE; ctx = SEC_PKCS12DecoderStart(&password, @@ -2241,7 +2243,13 @@ crypto_load_pkcs12(krb5_context context, } if (SEC_PKCS12DecoderVerify(ctx) != SECSuccess) { char *newpass; - switch (PORT_GetError()) { + krb5_ucs2 *ucs2; + unsigned char *ucs2s; + size_t i, n_ucs2s; + SECErrorCodes err; + err = PORT_GetError(); + SEC_PKCS12DecoderFinish(ctx); + switch (err) { case SEC_ERROR_BAD_PASSWORD: pkiDebug("%s: prompting for password for %s\n", __FUNCTION__, name); @@ -2249,33 +2257,43 @@ crypto_load_pkcs12(krb5_context context, id_cryptoctx); attempt++; if (newpass != NULL) { - SEC_PKCS12DecoderFinish(ctx); - password.len = strlen(newpass); - password.data = (unsigned char *) newpass; - PORT_SetError(0); - retry = PR_TRUE; - continue; + /* convert to 16-bit big-endian */ + if (krb5int_utf8s_to_ucs2les(newpass, + &ucs2s, + &n_ucs2s) == 0) { + PR_Free(newpass); + ucs2 = (krb5_ucs2 *) ucs2s; + for (i = 0; i < n_ucs2s / 2; i++) { + ucs2[i] = SWAP16(ucs2[i]); + } + password.data = (void*) ucs2s; + password.len = n_ucs2s + 2; + PORT_SetError(0); + retry = PR_TRUE; + continue; + } + PR_Free(newpass); } break; default: + SEC_PKCS12DecoderFinish(ctx); break; } pkiDebug("%s: skipping identity PKCS12 bundle \"%s\": " "error verifying data: %d\n", __FUNCTION__, name, PORT_GetError()); - SEC_PKCS12DecoderFinish(ctx); return SECFailure; } } while (retry); - if (password.data != emptypwd) { - PR_Free(password.data); - } if (SEC_PKCS12DecoderValidateBags(ctx, crypto_nickname_c_cb) != SECSuccess) { pkiDebug("%s: skipping identity PKCS12 bundle \"%s\": " "error validating bags: %d\n", __FUNCTION__, name, PORT_GetError()); SEC_PKCS12DecoderFinish(ctx); + if (password.data != emptypwd) { + free(password.data); + } return SECFailure; } if (SEC_PKCS12DecoderImportBags(ctx) != SECSuccess) { @@ -2283,10 +2301,16 @@ crypto_load_pkcs12(krb5_context context, "error importing data: %d\n", __FUNCTION__, name, PORT_GetError()); SEC_PKCS12DecoderFinish(ctx); + if (password.data != emptypwd) { + free(password.data); + } return SECFailure; } pkiDebug("%s: imported PKCS12 bundle \"%s\"\n", __FUNCTION__, name); SEC_PKCS12DecoderFinish(ctx); + if (password.data != emptypwd) { + free(password.data); + } if (cert_load_certs_with_keys_from_slot(context, id_cryptoctx, slot, NULL, NULL) == 0) { return SECSuccess; -- 1.7.6.4