From 4d1c76156afdefec29819f0a2694651c05253c0e Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Tue, 28 Jun 2011 10:26:01 -0400 Subject: [PATCH 126/150] - fix handling of pkcs12 bundles that don't have friendly names in them --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 68 ++++++++++++++++++++++-- 1 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index 1c06871..debc1e7 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -84,6 +85,10 @@ * identities. */ #define PKCS12_HACK +/* Prefix to mark the nicknames we make up for pkcs12 bundles that don't + * include a friendly name. */ +#define PKCS12_PREFIX "pkinit-pkcs12" + /* Forward declaration. */ static krb5_error_code cert_retrieve_cert_sans(krb5_context context, CERTCertificate *cert, @@ -2269,20 +2274,73 @@ crypto_get_pem_slot(struct _pkinit_identity_crypto_context *id) } /* Resolve any ambiguities from having a duplicate nickname in the PKCS12 - * bundle and in the database. */ + * bundle and in the database, or the bag not providing a nickname. Note: you + * might expect "arg" to be a wincx, but it's actually a certificate! (Mozilla + * bug #321584) */ static SECItem * crypto_nickname_c_cb(SECItem *old_nickname, PRBool *cancel, void *arg) { + CERTCertificate *leaf; + char *old_name, *new_name, *p; + SECItem *new_nickname, tmp; + int i; + + leaf = arg; if (old_nickname != NULL) { pkiDebug("%s: warning: nickname collision on \"%.*s\", " - "skipping\n", __FUNCTION__, + "generating a new nickname\n", __FUNCTION__, old_nickname->len, old_nickname->data); } else { - pkiDebug("%s: warning: nickname collision, skipping\n", + pkiDebug("%s: warning: nickname collision, generating a new " + "nickname\n", __FUNCTION__); + } + new_nickname = NULL; + if (old_nickname == NULL) { + old_name = leaf->subjectName; + new_name = PR_Malloc(strlen(PKCS12_PREFIX ": #1") + + strlen(old_name) + 1); + if (new_name != NULL) { + sprintf(new_name, PKCS12_PREFIX ": %s #1", + old_name); + tmp.data = (unsigned char *) new_name; + tmp.len = strlen(new_name) + 1; + new_nickname = SECITEM_DupItem(&tmp); + PR_Free(new_name); + } + } else { + old_name = (char *) old_nickname->data; + if (strncmp(old_name, PKCS12_PREFIX ": ", + strlen(PKCS12_PREFIX) + 2) == 0) { + p = strrchr(old_name, '#'); + i = (p ? atoi(p + 1) : 0) + 1; + old_name = leaf->subjectName; + new_name = PR_Malloc(strlen(PKCS12_PREFIX ": #") + + strlen(old_name) + + 3 * sizeof(i) + 1); + } else { + old_name = leaf->subjectName; + new_name = PR_Malloc(strlen("pkinit-pkcs12: #1") + + strlen(old_name) + 1); + i = 1; + } + if (new_name != NULL) { + sprintf(new_name, "pkinit-pkcs12: %s #%d", old_name, i); + tmp.data = (unsigned char *) new_name; + tmp.len = strlen(new_name) + 1; + new_nickname = SECITEM_DupItem(&tmp); + PR_Free(new_name); + } + } + if (new_nickname == NULL) { + pkiDebug("%s: warning: unable to generate a new nickname\n", __FUNCTION__); + *cancel = PR_TRUE; + } else { + pkiDebug("%s: generated new nickname \"%.*s\"\n", + __FUNCTION__, new_nickname->len, new_nickname->data); + *cancel = PR_FALSE; } - *cancel = PR_TRUE; - return NULL; + return new_nickname; } static SECStatus -- 1.7.6.4