summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/pk11wrap/pk11cert.c
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2020-01-02 21:06:40 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2020-01-02 21:06:40 +0100
commitf4a12fc67689a830e9da1c87fd11afe5bc09deb3 (patch)
tree211ae0cd022a6c11b0026ecc7761a550c584583c /security/nss/lib/pk11wrap/pk11cert.c
parentf7d30133221896638f7bf4f66c504255c4b14f48 (diff)
downloadUXP-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.c97
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.