From b51fae389736609e37d9a939d92718c4b336b628 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Wed, 27 Oct 2010 14:20:19 -0400 Subject: [PATCH 076/150] - load pkcs11 modules correctly - add files and certs to the pem module correctly --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 119 ++++++++++++++++++++---- 1 files changed, 100 insertions(+), 19 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index 191c249..a4745a2 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -630,14 +630,13 @@ pkinit_init_identity_crypto(pkinit_identity_crypto_context *id_cryptoctx) (id->id_keys != NULL) && (id->ca_certs != NULL) && (id->other_certs != NULL)) { - id->pem_module = SECMOD_CreateModule("libnsspem.so", - "PEM Reader", - NULL, - NULL); + id->pem_module = SECMOD_LoadUserModule("library=libnsspem.so", + NULL, PR_FALSE); if (id->pem_module == NULL) { pkiDebug("%s: error loading libnsspem.so\n", __FUNCTION__); } + SECMOD_UpdateSlotList(id->pem_module); *id_cryptoctx = id; return 0; } @@ -1696,7 +1695,7 @@ static SECStatus crypto_load_pkcs11(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, pkinit_req_crypto_context req_cryptoctx, - const char *spec, + const char *name, pkinit_identity_crypto_context id_cryptoctx) { SECMODModule **id_modules, *module; @@ -1705,18 +1704,12 @@ crypto_load_pkcs11(krb5_context context, CERTCertificate *cert; CERTCertList *certs; CERTCertListNode *node; - char *name; + char *spec; int i, j; - if (spec == NULL) { - return SECFailure; - } - - name = PORT_Alloc(strlen(spec) + strlen("pkinit:") + 1); if (name == NULL) { return SECFailure; } - sprintf(name, "pkinit:%s", spec); certdb = CERT_GetDefaultCertDB(); /* Count the number of modules we've already loaded. */ @@ -1734,8 +1727,22 @@ crypto_load_pkcs11(krb5_context context, id_modules[j] = id_cryptoctx->id_modules[i]; } /* Actually load the module. */ - module = SECMOD_CreateModule(spec, name, NULL, NULL); - PORT_Free(name); + spec = PORT_Alloc(strlen("library=\"\" ") + strlen(name) * 2); + if (spec == NULL) { + return SECFailure; + } + strcpy(spec, "library=\""); + j = strlen(spec); + for (i = 0; name[i] != '\0'; i++) { + if (name[i] == '\"') { + spec[j++] = '\\'; + } + spec[j++] = name[i]; + } + spec[j++] = '\0'; + strcat(spec, "\""); + module = SECMOD_LoadUserModule(spec, NULL, PR_FALSE); + PORT_Free(spec); if (module == NULL) { pkiDebug("%s: error loading PKCS11 module \"%s\"", __FUNCTION__, spec); @@ -1747,8 +1754,8 @@ crypto_load_pkcs11(krb5_context context, id_modules[j] = NULL; id_cryptoctx->id_modules = id_modules; /* Walk the list of slots in the module. */ - for (i = 0; - (slot = SECMOD_LookupSlot(module->moduleID, i)) != NULL; + for (i = module->slotCount; + (slot = module->slots[i]) != NULL; i++) { /* If we have to log in to the token, give it a shot. */ if (!PK11_IsLoggedIn(slot, @@ -1760,6 +1767,7 @@ crypto_load_pkcs11(krb5_context context, pkiDebug("%s: error logging into \"%s\":\"%s\", " "skipping\n", __FUNCTION__, spec, PK11_GetTokenName(slot)); + PK11_FreeSlot(slot); continue; } certs = PK11_ListCertsInSlot(slot); @@ -1776,10 +1784,23 @@ crypto_load_pkcs11(krb5_context context, __FUNCTION__, cert->subjectName, spec); } CERT_DestroyCertList(certs); + PK11_FreeSlot(slot); } return SECSuccess; } +static void +crypto_set_attributes(CK_ATTRIBUTE *attr, + CK_ATTRIBUTE_TYPE type, + void *pValue, + CK_ULONG ulValueLen) +{ + memset(attr, 0, sizeof(*attr)); + attr->type = type; + attr->pValue = pValue; + attr->ulValueLen = ulValueLen; +} + static SECStatus crypto_load_files(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -1790,6 +1811,15 @@ crypto_load_files(krb5_context context, PRBool cert_self, PRBool cert_mark_trusted, pkinit_identity_crypto_context id_cryptoctx) { + PK11SlotInfo *slot; + PK11GenericObject *obj; + PRBool permanent; + CK_ATTRIBUTE attrs[4]; + CK_BBOOL cktrue = CK_TRUE, cktrust; + CK_OBJECT_CLASS keyclass = CKO_PRIVATE_KEY, certclass = CKO_CERTIFICATE; + SECStatus status; + int n_attrs; + if (id_cryptoctx->pem_module == NULL) { if (certfile != NULL) { pkiDebug("%s: nsspem module not loaded, " @@ -1811,7 +1841,50 @@ crypto_load_files(krb5_context context, if ((certfile == NULL) && (crlfile == NULL)) { return SECFailure; } - /* FIXME */ + if ((id_cryptoctx->pem_module->slotCount == 0) || + ((slot = id_cryptoctx->pem_module->slots[0]) == NULL)) { + pkiDebug("%s: unable to find first slot\n", __FUNCTION__); + return SECFailure; + } + status = SECSuccess; + if (certfile != NULL) { + n_attrs = 0; + crypto_set_attributes(&attrs[n_attrs++], CKA_CLASS, + &certclass, sizeof(certclass)); + crypto_set_attributes(&attrs[n_attrs++], CKA_TOKEN, + &cktrue, sizeof(cktrue)); + crypto_set_attributes(&attrs[n_attrs++], CKA_LABEL, + (char *) certfile, strlen(certfile) + 1); + cktrust = cert_mark_trusted ? CK_TRUE : CK_FALSE; + crypto_set_attributes(&attrs[n_attrs++], CKA_TRUST, + &cktrust, sizeof(cktrust)); + permanent = PR_FALSE; + obj = PK11_CreateGenericObject(slot, attrs, n_attrs, permanent); + if (obj != NULL) { + pkiDebug("%s: loaded %scertificate \"%s\"\n", + __FUNCTION__, + cert_mark_trusted ? "CA " : "", + certfile); + status = SECFailure; + } + } + if (keyfile != NULL) { + n_attrs = 0; + crypto_set_attributes(&attrs[n_attrs++], CKA_CLASS, + &keyclass, sizeof(keyclass)); + crypto_set_attributes(&attrs[n_attrs++], CKA_TOKEN, + &cktrue, sizeof(cktrue)); + crypto_set_attributes(&attrs[n_attrs++], CKA_LABEL, + (char *) keyfile, strlen(keyfile) + 1); + permanent = PR_FALSE; + obj = PK11_CreateGenericObject(slot, attrs, n_attrs, permanent); + if (obj != NULL) { + pkiDebug("%s: loaded key \"%s\"\n", + __FUNCTION__, keyfile); + status = SECFailure; + } + } + PK11_FreeSlot(slot); return SECSuccess; } @@ -1956,6 +2029,9 @@ crypto_load_certs(krb5_context context, return 0; break; case IDTYPE_PKCS12: + pkiDebug("%s: skipping identity PKCS12 bundle \"%s\"\n", + __FUNCTION__, idopts->cert_filename); + return 0; /* FIXME */ return ENOSYS; break; default: @@ -2481,7 +2557,7 @@ crypto_load_cas_and_crls(krb5_context context, id_cryptoctx); if (status != SECSuccess) { pkiDebug("%s: error loading CA file \"%s\"\n", - __FUNCTION__, idopts->cert_filename); + __FUNCTION__, id); return ENOMEM; } return 0; @@ -2495,11 +2571,16 @@ crypto_load_cas_and_crls(krb5_context context, id_cryptoctx); if (status != SECSuccess) { pkiDebug("%s: error loading CA directory \"%s\"\n", - __FUNCTION__, idopts->cert_filename); + __FUNCTION__, id); return ENOMEM; } return 0; break; + case IDTYPE_PKCS12: + pkiDebug("%s: skipping CA PKCS12 bundle \"%s\"\n", + __FUNCTION__, id); + return 0; /* FIXME */ + return ENOSYS; default: return EINVAL; break; -- 1.7.6.4