diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-01-02 21:06:40 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-01-02 21:06:40 +0100 |
commit | f4a12fc67689a830e9da1c87fd11afe5bc09deb3 (patch) | |
tree | 211ae0cd022a6c11b0026ecc7761a550c584583c /security/nss/lib/pk11wrap/pk11cert.c | |
parent | f7d30133221896638f7bf4f66c504255c4b14f48 (diff) | |
download | UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.gz UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.lz UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.xz UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.zip |
Issue #1338 - Part 2: Update NSS to 3.48-RTM
Diffstat (limited to 'security/nss/lib/pk11wrap/pk11cert.c')
-rw-r--r-- | security/nss/lib/pk11wrap/pk11cert.c | 97 |
1 files changed, 95 insertions, 2 deletions
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index a880b1ab8..655c5f970 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -245,7 +245,7 @@ pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID, /* Get the cryptoki object from the handle */ token = PK11Slot_GetNSSToken(slot); - if (token->defaultSession) { + if (token && token->defaultSession) { co = nssCryptokiObject_Create(token, token->defaultSession, certID); } else { PORT_SetError(SEC_ERROR_NO_TOKEN); @@ -307,9 +307,15 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID, CERTCertificate *cert = NULL; CERTCertTrust *trust; + if (slot == NULL || certID == CK_INVALID_HANDLE) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + cert = pk11_fastCert(slot, certID, privateLabel, &nickname); - if (cert == NULL) + if (cert == NULL) { goto loser; + } if (nickname) { if (cert->nickname != NULL) { @@ -406,6 +412,93 @@ PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey) return (cert); } +CK_OBJECT_HANDLE * +PK11_FindCertHandlesForKeyHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, + int *certHandleCountOut) +{ + if (!slot || !certHandleCountOut || keyHandle == CK_INVALID_HANDLE) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + + PORTCheapArenaPool arena; + PORT_InitCheapArena(&arena, DER_DEFAULT_CHUNKSIZE); + CK_ATTRIBUTE idTemplate[] = { + { CKA_ID, NULL, 0 }, + }; + const int idAttrCount = sizeof(idTemplate) / sizeof(idTemplate[0]); + CK_RV crv = PK11_GetAttributes(&arena.arena, slot, keyHandle, idTemplate, idAttrCount); + if (crv != CKR_OK) { + PORT_DestroyCheapArena(&arena); + PORT_SetError(PK11_MapError(crv)); + return NULL; + } + + if ((idTemplate[0].ulValueLen == 0) || (idTemplate[0].ulValueLen == -1)) { + PORT_DestroyCheapArena(&arena); + PORT_SetError(SEC_ERROR_BAD_KEY); + return NULL; + } + + CK_OBJECT_CLASS searchClass = CKO_CERTIFICATE; + CK_ATTRIBUTE searchTemplate[] = { + idTemplate[0], + { CKA_CLASS, &searchClass, sizeof(searchClass) } + }; + const int searchAttrCount = sizeof(searchTemplate) / sizeof(searchTemplate[0]); + CK_OBJECT_HANDLE *ids = pk11_FindObjectsByTemplate(slot, searchTemplate, searchAttrCount, certHandleCountOut); + + PORT_DestroyCheapArena(&arena); + return ids; +} + +CERTCertList * +PK11_GetCertsMatchingPrivateKey(SECKEYPrivateKey *privKey) +{ + if (!privKey) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + CERTCertList *certs = CERT_NewCertList(); + if (!certs) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return NULL; + } + PK11SlotInfo *slot = privKey->pkcs11Slot; + CK_OBJECT_HANDLE handle = privKey->pkcs11ID; + CK_OBJECT_HANDLE certID = PK11_MatchItem(slot, handle, CKO_CERTIFICATE); + /* If we can't get a matching certID, there are no matching certificates, + * which is not an error. */ + if (certID == CK_INVALID_HANDLE) { + return certs; + } + int certHandleCount = 0; + CK_OBJECT_HANDLE *certHandles = PK11_FindCertHandlesForKeyHandle(slot, handle, &certHandleCount); + if (!certHandles) { + /* If certHandleCount is 0, there are no matching certificates, which is + * not an error. */ + if (certHandleCount == 0) { + return certs; + } + CERT_DestroyCertList(certs); + return NULL; + } + int i; + for (i = 0; i < certHandleCount; i++) { + CERTCertificate *cert = PK11_MakeCertFromHandle(slot, certHandles[i], NULL); + /* If PK11_MakeCertFromHandle fails for one handle, optimistically + assume other handles may succeed (i.e. this is best-effort). */ + if (!cert) { + continue; + } + if (CERT_AddCertToListTail(certs, cert) != SECSuccess) { + CERT_DestroyCertificate(cert); + } + } + PORT_Free(certHandles); + return certs; +} + /* * delete a cert and it's private key (if no other certs are pointing to the * private key. |