diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/lib/libkmf/libkmf/common/keyop.c | 3 | ||||
-rw-r--r-- | usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c | 54 | ||||
-rw-r--r-- | usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c | 76 |
3 files changed, 94 insertions, 39 deletions
diff --git a/usr/src/lib/libkmf/libkmf/common/keyop.c b/usr/src/lib/libkmf/libkmf/common/keyop.c index 42781ecf52..7182dbedb7 100644 --- a/usr/src/lib/libkmf/libkmf/common/keyop.c +++ b/usr/src/lib/libkmf/libkmf/common/keyop.c @@ -290,6 +290,9 @@ KMF_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, if (parms == NULL || numkeys == NULL) return (KMF_ERR_BAD_PARAMETER); + if (keys != NULL && *numkeys == 0) + return (KMF_ERR_BAD_PARAMETER); + plugin = FindPlugin(handle, parms->kstype); if (plugin != NULL && plugin->funclist->FindKey != NULL) { diff --git a/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c b/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c index a7f4788498..2ef9aa0fee 100644 --- a/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c @@ -557,11 +557,13 @@ convertCertList(void *kmfhandle, { KMF_RETURN rv = KMF_OK; CERTCertListNode *node; + uint32_t maxcerts = *numcerts; *numcerts = 0; for (node = CERT_LIST_HEAD(nsscerts); - !CERT_LIST_END(node, nsscerts) && rv == KMF_OK; + !CERT_LIST_END(node, nsscerts) && rv == KMF_OK && + (*numcerts) < maxcerts; node = CERT_LIST_NEXT(node), (*numcerts)++) { if (kmfcerts != NULL) rv = nss2kmf_cert(node->cert, &kmfcerts[*numcerts]); @@ -574,6 +576,7 @@ convertCertList(void *kmfhandle, int i; for (i = 0; i < *numcerts; i++) KMF_FreeKMFCert(kmfhandle, &kmfcerts[i]); + *numcerts = 0; } return (rv); } @@ -587,6 +590,7 @@ NSS_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; PK11SlotInfo *nss_slot = NULL; CERTCertList *certlist = NULL; + uint32_t maxcerts; rv = Do_NSS_Init(handle, params->ks_opt_u.nss_opts, FALSE, &nss_slot); @@ -594,20 +598,36 @@ NSS_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, return (rv); } + if (*num_certs == 0) + maxcerts = 0xFFFFFFFF; + else + maxcerts = *num_certs; + *num_certs = 0; if (params->certLabel) { + /* This will only find 1 certificate */ rv = nss_getcert_by_label(kmfh, params->certLabel, kmfcerts, num_certs, params->find_cert_validity); } else { + /* + * Build a list of matching certs. + */ rv = nss_find_matching_certs(nss_slot, params->issuer, params->subject, params->serial, &certlist, params->find_cert_validity); + /* + * If the caller supplied a pointer to storage for + * a list of certs, convert up to 'maxcerts' of the + * matching certs. + */ if (rv == KMF_OK && certlist != NULL) { rv = convertCertList(handle, - certlist, kmfcerts, num_certs); + certlist, kmfcerts, &maxcerts); CERT_DestroyCertList(certlist); + if (rv == KMF_OK) + *num_certs = maxcerts; } } @@ -1801,11 +1821,9 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, SECKEYPublicKeyList *publist; SECKEYPublicKeyListNode *pubnode; PK11SlotInfo *nss_slot = NULL; - PK11SymKey *symlist; + PK11SymKey *symlist = NULL; int count; - - if (handle == NULL || parms == NULL || numkeys == NULL) - return (KMF_ERR_BAD_PARAMETER); + uint32_t maxkeys; rv = Do_NSS_Init(handle, parms->ks_opt_u.nss_opts, FALSE, &nss_slot); @@ -1818,6 +1836,10 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, return (rv); } + maxkeys = *numkeys; + if (maxkeys == 0) + maxkeys = 0xFFFFFFFF; + *numkeys = 0; if (parms->keyclass == KMF_ASYM_PUB) { publist = PK11_ListPublicKeysInSlot(nss_slot, parms->findLabel); @@ -1846,7 +1868,8 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, if (parms->keyclass == KMF_ASYM_PUB) { for (count = 0, pubnode = PUBKEY_LIST_HEAD(publist); - !PUBKEY_LIST_END(pubnode, publist); + !PUBKEY_LIST_END(pubnode, publist) && + count < maxkeys; pubnode = PUBKEY_LIST_NEXT(pubnode), count++) { if (keys != NULL) { keys[count].kstype = KMF_KEYSTORE_NSS; @@ -1865,7 +1888,8 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, *numkeys = count; } else if (parms->keyclass == KMF_ASYM_PRI) { for (count = 0, prinode = PRIVKEY_LIST_HEAD(prilist); - !PRIVKEY_LIST_END(prinode, prilist); + !PRIVKEY_LIST_END(prinode, prilist) && + count < maxkeys; prinode = PRIVKEY_LIST_NEXT(prinode), count++) { if (keys != NULL) { keys[count].kstype = KMF_KEYSTORE_NSS; @@ -1884,7 +1908,7 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, *numkeys = count; } else if (parms->keyclass == KMF_SYMMETRIC) { count = 0; - while (symlist) { + while (symlist && count < maxkeys) { PK11SymKey *symkey = symlist; CK_KEY_TYPE type; KMF_KEY_ALG keyalg; @@ -1900,6 +1924,8 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, symlist = PK11_GetNextSymKey(symkey); if (parms->keytype != KMF_KEYALG_NONE && parms->keytype != keyalg) { + /* free that key since we aren't using it */ + PK11_FreeSymKey(symkey); continue; } @@ -1915,9 +1941,17 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, } count++; } - *numkeys = count; + /* + * Cleanup memory for unused keys. + */ + while (symlist != NULL) { + PK11SymKey *symkey = symlist; + PK11_FreeSymKey(symkey); + symlist = PK11_GetNextSymKey(symkey); + } } + *numkeys = count; cleanup: if (nss_slot != NULL) { PK11_FreeSlot(nss_slot); diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c index 6cd2f87966..694c1cb2ba 100644 --- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c @@ -997,11 +997,15 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; char *fullpath; - int i; + int i, n; + uint32_t maxcerts = 0; if (num_certs == NULL || params == NULL) return (KMF_ERR_BAD_PARAMETER); + maxcerts = *num_certs; + if (maxcerts == 0) + maxcerts = 0xFFFFFFFF; *num_certs = 0; fullpath = get_fullpath(params->sslparms.dirpath, @@ -1013,8 +1017,8 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, if (isdir(fullpath)) { DIR *dirp; struct dirent *dp; - int n = 0; + n = 0; /* open all files in the directory and attempt to read them */ if ((dirp = opendir(fullpath)) == NULL) { return (KMF_ERR_BAD_PARAMETER); @@ -1022,7 +1026,7 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, while ((dp = readdir(dirp)) != NULL) { char *fname; KMF_DATA *certlist = NULL; - uint32_t numcerts = 0; + uint32_t loaded_certs = 0; if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) @@ -1032,12 +1036,12 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, (char *)&dp->d_name); rv = load_certs(kmfh, params, fname, &certlist, - &numcerts); + &loaded_certs); if (rv != KMF_OK) { free(fname); if (certlist != NULL) { - for (i = 0; i < numcerts; i++) + for (i = 0; i < loaded_certs; i++) KMF_FreeData(&certlist[i]); free(certlist); } @@ -1046,7 +1050,8 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, /* If load succeeds, add certdata to the list */ if (kmf_cert != NULL) { - for (i = 0; i < numcerts; i++) { + for (i = 0; i < loaded_certs && + i < maxcerts; i++) { kmf_cert[n].certificate.Data = certlist[i].Data; kmf_cert[n].certificate.Length = @@ -1060,54 +1065,62 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, strdup(fname); n++; } - free(certlist); + /* If maxcerts < loaded_certs, clean up */ + for (; i < loaded_certs; i++) + KMF_FreeData(&certlist[i]); } else { - for (i = 0; i < numcerts; i++) + for (i = 0; i < loaded_certs; i++) KMF_FreeData(&certlist[i]); - free(certlist); - n += numcerts; + n += loaded_certs; } + free(certlist); free(fname); } (*num_certs) = n; if (*num_certs == 0) rv = KMF_ERR_CERT_NOT_FOUND; - if (*num_certs > 0) + else rv = KMF_OK; exit: (void) closedir(dirp); } else { KMF_DATA *certlist = NULL; - uint32_t numcerts = 0; + uint32_t loaded_certs = 0; - rv = load_certs(kmfh, params, fullpath, &certlist, &numcerts); + rv = load_certs(kmfh, params, fullpath, + &certlist, &loaded_certs); if (rv != KMF_OK) { free(fullpath); return (rv); } + n = 0; if (kmf_cert != NULL && certlist != NULL) { - for (i = 0; i < numcerts; i++) { - kmf_cert[i].certificate.Data = + for (i = 0; i < loaded_certs && i < maxcerts; i++) { + kmf_cert[n].certificate.Data = certlist[i].Data; - kmf_cert[i].certificate.Length = + kmf_cert[n].certificate.Length = certlist[i].Length; - kmf_cert[i].kmf_private.keystore_type = + kmf_cert[n].kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL; - kmf_cert[i].kmf_private.flags = + kmf_cert[n].kmf_private.flags = KMF_FLAG_CERT_VALID; - kmf_cert[i].kmf_private.label = + kmf_cert[n].kmf_private.label = strdup(fullpath); + n++; } - free(certlist); - } else { - if (certlist != NULL) { - for (i = 0; i < numcerts; i++) - KMF_FreeData(&certlist[i]); - free(certlist); - } + /* If maxcerts < loaded_certs, clean up */ + for (; i < loaded_certs; i++) + KMF_FreeData(&certlist[i]); + } else if (certlist != NULL) { + for (i = 0; i < loaded_certs; i++) + KMF_FreeData(&certlist[i]); + n = loaded_certs; } - *num_certs = numcerts; + if (certlist) + free(certlist); + + *num_certs = n; } free(fullpath); @@ -3078,6 +3091,7 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, { KMF_RETURN rv = KMF_OK; char *fullpath = NULL; + uint32_t maxkeys; if (handle == NULL || params == NULL || numkeys == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -3093,6 +3107,10 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); + maxkeys = *numkeys; + if (maxkeys == 0) + maxkeys = 0xFFFFFFFF; + *numkeys = 0; if (isdir(fullpath)) { @@ -3105,7 +3123,7 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, return (KMF_ERR_BAD_PARAMETER); } rewinddir(dirp); - while ((dp = readdir(dirp)) != NULL) { + while ((dp = readdir(dirp)) != NULL && n < maxkeys) { if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) { char *fname; @@ -3136,7 +3154,7 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, free(fullpath); } - if ((*numkeys) == 0) + if (rv == KMF_OK && (*numkeys) == 0) rv = KMF_ERR_KEY_NOT_FOUND; return (rv); |