99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER START
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The contents of this file are subject to the terms of the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Common Development and Distribution License (the "License").
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You may not use this file except in compliance with the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * or http://www.opensolaris.org/os/licensing.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * See the License for the specific language governing permissions
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and limitations under the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * When distributing Covered Code, include this CDDL HEADER in each
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If applicable, add the following below this CDDL HEADER, with the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * fields enclosed by brackets "[]" replaced with your own identifying
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * information: Portions Copyright [yyyy] [name of copyright owner]
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER END
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * NSS keystore wrapper
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Use is subject to license terms.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/types.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/stat.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <errno.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <fcntl.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <synch.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <kmfapiP.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <ber_der.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/* NSS related headers */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/nss.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/cert.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/certdb.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/secoid.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/secder.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/secerr.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/cryptohi.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/keyhi.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/keythi.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/pk11func.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/pk11pqg.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/pkcs12.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/p12plcy.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <mps/prerror.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define NSS_OK 0
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysmutex_t init_lock = DEFAULTMUTEX;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic int nss_initialized = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysvoid
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysNSS_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysNSS_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysNSS_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *, KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_FindCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysNSS_GetErrorString(KMF_HANDLE_T, char **);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysNSS_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *, KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysNSS_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_PLUGIN_FUNCLIST nss_plugin_table =
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 1, /* Version */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_ConfigureKeystore,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_FindCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_FreeKMFCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_StoreCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_ImportCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_ImportCRL,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_DeleteCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_DeleteCRL,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_CreateKeypair,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_FindKey,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_EncodePubKeyData,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_SignData,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_DeleteKey,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NULL /* ListCRL */,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_FindCRL,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_FindCertInCRL,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_GetErrorString,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NSS_FindPrikeyByCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_DecryptData,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NSS_ExportPK12,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_CreateSymKey,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_GetSymKeyValue,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSS_SetTokenPin,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NSS_StoreKey,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NULL /* Finalize */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys};
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/* additions for importing and exporting PKCS 12 files */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllystypedef struct p12uContextStr {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *filename; /* name of file */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PRFileDesc *file; /* pointer to file */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PRBool error; /* error occurred? */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int errorValue; /* which error occurred? */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys} p12uContext;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_NSS; \
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys h->lasterr.errcode = c;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_PLUGIN_FUNCLIST *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_Plugin_Initialize()
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1);
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1);
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1);
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1);
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) SEC_PKCS12EnableCipher(PKCS12_DES_56, 1);
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1);
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (&nss_plugin_table);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic char *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysnss_getpassword(PK11SlotInfo *slot, PRBool retry, void *arg)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (retry)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (arg != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return ((char *)strdup(arg));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys else
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysnss_authenticate(KMF_HANDLE_T handle,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11SlotInfo *nss_slot, KMF_CREDENTIAL *cred)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECStatus nssrv = SECSuccess;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If a password was given, try to login to the slot */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (cred == NULL || cred->cred == NULL || cred->credlen == 0 ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_slot == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (PK11_IsLoggedIn(nss_slot, NULL)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_SetPasswordFunc(nss_getpassword);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nssrv = PK11_Authenticate(nss_slot, PR_TRUE, (void *)cred->cred);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nssrv != SECSuccess) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, nssrv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_FreeSlot(nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_AUTH_FAILED);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic SECStatus
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysInit_NSS_DBs(const char *configdir,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const char *certPrefix,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const char *keyPrefix,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const char *secmodName)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECStatus rv = NSS_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_lock(&init_lock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If another thread already did it, return OK. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nss_initialized) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_unlock(&init_lock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (SECSuccess);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = NSS_Initialize((configdir && strlen(configdir)) ?
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys configdir : "./", certPrefix, keyPrefix,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys secmodName ? secmodName : "secmod.db", NSS_INIT_COOPERATE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != SECSuccess) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nss_initialized++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysend:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_unlock(&init_lock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * When it is called the first time, it will intialize NSS. Once the NSS
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * is initialized, this function returns KMF_KEYSTORE_ALREADY_INITIALIZED
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * if it is called again.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_ConfigureKeystore(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *configdir;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *certPrefix;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *keyPrefix;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *secModName;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys configdir = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certPrefix = kmf_get_attr_ptr(KMF_CERTPREFIX_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyPrefix = kmf_get_attr_ptr(KMF_KEYPREFIX_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys secModName = kmf_get_attr_ptr(KMF_SECMODNAME_ATTR, attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_lock(&init_lock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nss_initialized == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECStatus err;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_unlock(&init_lock);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys err = Init_NSS_DBs(configdir, certPrefix,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyPrefix, secModName);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (err != SECSuccess) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, err);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_INTERNAL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_KEYSTORE_ALREADY_INITIALIZED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_unlock(&init_lock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function sets up the slot to be used for other operations.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function is basically called by every NSS SPI function.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * For those functions that can only be performed in the internal slot, the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * boolean "internal_slot_only" argument needs to be TRUE.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * A slot pointer will be returned when this function is executed successfully.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysdo_nss_init(void *handle, int numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *attrlist,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t internal_slot_only,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11SlotInfo **nss_slot)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *slotlabel = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!nss_initialized)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_PLUGIN_INIT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * NSS Is already initialized, but we need to find
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the right slot.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (slotlabel == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys strcmp(slotlabel, "internal") == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *nss_slot = PK11_GetInternalKeySlot();
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (internal_slot_only == TRUE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_SLOTNAME;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *nss_slot = PK11_FindSlotByName(slotlabel);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (*nss_slot == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_SLOTNAME;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If the token was not yet initialized, return an error.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (PK11_NeedUserInit(*nss_slot)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_UNINITIALIZED_TOKEN;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysnss2kmf_cert(CERTCertificate *nss_cert, KMF_X509_DER_CERT *kmf_cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmf_cert->kmf_private.keystore_type = KMF_KEYSTORE_NSS;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmf_cert->kmf_private.flags = KMF_FLAG_CERT_VALID;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmf_cert->certificate.Length = nss_cert->derCert.len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((kmf_cert->certificate.Data = malloc(nss_cert->derCert.len)) ==
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmf_cert->certificate.Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(kmf_cert->certificate.Data, nss_cert->derCert.data,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_cert->derCert.len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nss_cert->nickname != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmf_cert->kmf_private.label =
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (char *)strdup(nss_cert->nickname);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysnss_getcert_by_label(KMF_HANDLE *kmfh,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *name, KMF_X509_DER_CERT *kmf_cert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uint32_t *num_certs, KMF_CERT_VALIDITY find_criteria)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertificate *nss_cert;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECCertTimeValidity validity;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nss_cert = PK11_FindCertFromNickname(name, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nss_cert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *num_certs = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, PORT_GetError());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *num_certs = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_CERT_NOT_FOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *num_certs = 1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys switch (find_criteria) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_ALL_CERTS:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_NONEXPIRED_CERTS:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PR_FALSE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (validity != secCertTimeValid) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* this is an invalid cert, reject it */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *num_certs = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERT_DestroyCertificate(nss_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_EXPIRED_CERTS:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PR_FALSE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (validity == secCertTimeValid) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* this is a valid cert, reject it in this case. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *num_certs = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERT_DestroyCertificate(nss_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys default:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmf_cert != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = nss2kmf_cert(nss_cert, kmf_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* We copied the data we need, so cleanup the internal record */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERT_DestroyCertificate(nss_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *num_certs = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysnss_find_matching_certs(PK11SlotInfo *slot,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *issuer, char *subject, KMF_BIGINT *serial,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertList **certlist, KMF_CERT_VALIDITY find_criteria)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECStatus ret;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertList *list;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertListNode *node;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_NAME issuerDN, subjectDN;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t findIssuer = FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t findSubject = FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t findSerial = FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (issuer != NULL && strlen(issuer)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_dn_parser(issuer, &issuerDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys findIssuer = TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (subject != NULL && strlen(subject)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_dn_parser(subject, &subjectDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys findSubject = TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (serial != 0 && serial->val != NULL && serial->len > 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys findSerial = TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys list = PK11_ListCertsInSlot(slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (list) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys node = CERT_LIST_HEAD(list);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys while (!CERT_LIST_END(node, list)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_NAME cmpDN;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA der;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t match;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertListNode *freenode;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (findIssuer) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys der.Data = node->cert->derIssuer.data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys der.Length = node->cert->derIssuer.len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = DerDecodeName(&der, &cmpDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys match = !KMF_CompareRDNs(&issuerDN,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &cmpDN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_dn(&cmpDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!match)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto delete_and_cont;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto delete_and_cont;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (findSubject) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys der.Data = node->cert->derSubject.data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys der.Length = node->cert->derSubject.len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = DerDecodeName(&der, &cmpDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys match = !KMF_CompareRDNs(&subjectDN,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &cmpDN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_dn(&cmpDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!match)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto delete_and_cont;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto delete_and_cont;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (findSerial) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECItem *sernum;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sernum = &node->cert->serialNumber;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (serial->len != sernum->len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto delete_and_cont;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (memcmp(sernum->data, serial->val,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys serial->len))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto delete_and_cont;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* select the certs using find criteria */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys switch (find_criteria) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_ALL_CERTS:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_NONEXPIRED_CERTS:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = CERT_CertTimesValid(node->cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret == SECFailure) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* this is an invalid cert */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto skip;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_EXPIRED_CERTS:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = CERT_CertTimesValid(node->cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != SECFailure) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* this is a valid cert */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto skip;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysskip:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys node = CERT_LIST_NEXT(node);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys continue;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysdelete_and_cont:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys freenode = node;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys node = CERT_LIST_NEXT(node);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERT_RemoveCertListNode(freenode);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_OK && certlist != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *certlist = list;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERT_DestroyCertList(list);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysconvertCertList(void *kmfhandle,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertList *nsscerts, KMF_X509_DER_CERT *kmfcerts,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uint32_t *numcerts)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertListNode *node;
f482c776bc557f0256e776932c7842b9db390de1wyllys uint32_t maxcerts = *numcerts;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys maxcerts = *numcerts;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (maxcerts == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys maxcerts = 0xFFFFFFFF;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *numcerts = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Don't copy more certs than the caller wanted.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (node = CERT_LIST_HEAD(nsscerts);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys !CERT_LIST_END(node, nsscerts) && rv == KMF_OK &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (*numcerts) < maxcerts;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys node = CERT_LIST_NEXT(node), (*numcerts)++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfcerts != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = nss2kmf_cert(node->cert, &kmfcerts[*numcerts]);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If we failed, delete any certs allocated so far.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int i;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < *numcerts; i++)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_kmf_cert(kmfhandle, &kmfcerts[i]);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
f482c776bc557f0256e776932c7842b9db390de1wyllys *numcerts = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11SlotInfo *nss_slot = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertList *certlist = NULL;
f482c776bc557f0256e776932c7842b9db390de1wyllys uint32_t maxcerts;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t *num_certs;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_DER_CERT *kmfcerts = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *certlabel = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *issuer = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *subject = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_BIGINT *serial = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_VALIDITY validity;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (num_certs == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
f482c776bc557f0256e776932c7842b9db390de1wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys maxcerts = *num_certs;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (maxcerts == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys maxcerts = 0xFFFFFFFF;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *num_certs = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the optional returned certificate list */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmfcerts = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get optional search criteria attributes */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &validity, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys validity = KMF_ALL_CERTS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certlabel != NULL) {
f482c776bc557f0256e776932c7842b9db390de1wyllys /* This will only find 1 certificate */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = nss_getcert_by_label(kmfh, certlabel, kmfcerts, num_certs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys validity);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
f482c776bc557f0256e776932c7842b9db390de1wyllys /*
f482c776bc557f0256e776932c7842b9db390de1wyllys * Build a list of matching certs.
f482c776bc557f0256e776932c7842b9db390de1wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = nss_find_matching_certs(nss_slot, issuer, subject, serial,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &certlist, validity);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
f482c776bc557f0256e776932c7842b9db390de1wyllys /*
f482c776bc557f0256e776932c7842b9db390de1wyllys * If the caller supplied a pointer to storage for
f482c776bc557f0256e776932c7842b9db390de1wyllys * a list of certs, convert up to 'maxcerts' of the
f482c776bc557f0256e776932c7842b9db390de1wyllys * matching certs.
f482c776bc557f0256e776932c7842b9db390de1wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_OK && certlist != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = convertCertList(handle, certlist, kmfcerts,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &maxcerts);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERT_DestroyCertList(certlist);
f482c776bc557f0256e776932c7842b9db390de1wyllys if (rv == KMF_OK)
f482c776bc557f0256e776932c7842b9db390de1wyllys *num_certs = maxcerts;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nss_slot != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_FreeSlot(nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_OK && *num_certs == 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_CERT_NOT_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysvoid
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysNSS_FreeKMFCert(KMF_HANDLE_T handle,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_DER_CERT *kmf_cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmf_cert != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmf_cert->certificate.Data != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(kmf_cert->certificate.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmf_cert->certificate.Data = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmf_cert->certificate.Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmf_cert->kmf_private.label != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(kmf_cert->kmf_private.label);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmf_cert->kmf_private.label = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int nssrv;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertificate *cert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *certlabel = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *issuer = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *subject = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_BIGINT *serial = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_VALIDITY validity;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the search criteria attributes. They are all optional. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &validity, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys validity = KMF_ALL_CERTS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Start finding the matched certificates and delete them. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certlabel != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = PK11_FindCertFromNickname(certlabel, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (cert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_CERT_NOT_FOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (validity) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_ALL_CERTS:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_NONEXPIRED_CERTS:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssrv = CERT_CertTimesValid(cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nssrv == SECFailure) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* this is an invalid cert - skip it */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_EXPIRED_CERTS:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssrv = CERT_CertTimesValid(cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nssrv != SECFailure) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* this is a valid cert - skip it */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* delete it from database */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssrv = SEC_DeletePermCertificate(cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nssrv) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, nssrv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertListNode *node;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTCertList *certlist = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = nss_find_matching_certs(nss_slot, issuer, subject, serial,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &certlist, validity);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (node = CERT_LIST_HEAD(certlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys !CERT_LIST_END(node, certlist) && rv == KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys node = CERT_LIST_NEXT(node)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssrv = SEC_DeletePermCertificate(node->cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nssrv) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, nssrv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_OK && certlist != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERT_DestroyCertList(certlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (rv == KMF_OK && certlist == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_CERT_NOT_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nss_slot != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_FreeSlot(nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (cert != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERT_DestroyCertificate(cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic void
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysInitRandom(char *filename)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char buf[2048];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int fd;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PRInt32 count;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys fd = open(filename, O_RDONLY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!fd)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys count = read(fd, buf, sizeof (buf));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (count > 0) {
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) PK11_RandomUpdate(buf, count);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(fd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysNSS_CreateKeypair(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11RSAGenParams rsaparams;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys void *nssparams;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CK_MECHANISM_TYPE mechanism;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ulong_t publicExponent = 0x010001;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11SlotInfo *nss_slot = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECKEYPrivateKey *NSSprivkey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECKEYPublicKey *NSSpubkey = NULL;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll SECKEYECParams *ecparams = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PQGParams *pqgParams = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL cred;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t storekey = TRUE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t keylen = 1024, len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t keylen_size = sizeof (uint32_t);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_ALG keytype = KMF_RSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *pubkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *privkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *keylabel = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&cred, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = nss_authenticate(handle, nss_slot, &cred);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* "storekey" is optional. Default is TRUE */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &storekey, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* keytype is optional. KMF_RSA is default */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&keytype, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &keylen, &keylen_size);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_ERR_ATTR_NOT_FOUND)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Default keylen = 1024 */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pubkey == NULL || privkey == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_KEYLABEL_ATTR, attrlist, numattr, NULL, &len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK && len > 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keylabel = malloc(len + 1);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keylabel == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Now fill in the label value */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(keylabel, 0, len + 1);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_KEYLABEL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keylabel, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(keylabel);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Get some random bits */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys InitRandom("/dev/urandom");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keytype == KMF_RSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_BIGINT rsaexp;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsaparams.keySizeInBits = keylen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * NSS only allows for a 4 byte exponent.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Ignore the exponent parameter if it is too big.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = kmf_get_attr(KMF_RSAEXP_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &rsaexp, NULL)) == KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsaexp.len > 0 &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsaexp.len <= sizeof (publicExponent) &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsaexp.val != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy(&publicExponent, rsaexp.val,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsaexp.len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rsaparams.pe = publicExponent;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssparams = &rsaparams;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (keytype == KMF_DSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PQGVerify *pqgVerify = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int ks;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECStatus nssrv, passed;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys mechanism = CKM_DSA_KEY_PAIR_GEN;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ks = PQG_PBITS_TO_INDEX(keylen);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssrv = PK11_PQG_ParamGen(ks, &pqgParams, &pqgVerify);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nssrv != SECSuccess) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_PQG_DestroyVerify(pqgVerify);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssrv = PK11_PQG_VerifyParams(pqgParams, pqgVerify, &passed);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nssrv != SECSuccess || passed != SECSuccess) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_PQG_DestroyVerify(pqgVerify);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, PORT_GetError());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssparams = pqgParams;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll } else if (keytype == KMF_ECDSA) {
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll attrlist, numattr);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (eccoid == NULL)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll return (KMF_ERR_BAD_PARAMETER);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ecparams = SECITEM_AllocItem(NULL, NULL, (eccoid->Length));
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (!ecparams)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll return (KMF_ERR_MEMORY);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll (void) memcpy(ecparams->data, eccoid->Data, eccoid->Length);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll mechanism = CKM_EC_KEY_PAIR_GEN;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll nssparams = ecparams;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_PARAMETER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NSSprivkey = PK11_GenerateKeyPair(nss_slot, mechanism, nssparams,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &NSSpubkey,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys storekey, /* isPermanent */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PR_TRUE, /* isSensitive */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)cred.cred);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (NSSprivkey == NULL || NSSpubkey == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, PORT_GetError());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keylabel != NULL && strlen(keylabel)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) PK11_SetPrivateKeyNickname(NSSprivkey,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keylabel);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) PK11_SetPublicKeyNickname(NSSpubkey, keylabel);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Now, convert it to a KMF_KEY object for the framework */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->kstype = KMF_KEYSTORE_NSS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->keyalg = keytype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->keyclass = KMF_ASYM_PRI;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->keylabel = PK11_GetPrivateKeyNickname(NSSprivkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->keyp = (void *)NSSprivkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->kstype = KMF_KEYSTORE_NSS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keyalg = keytype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keyp = (void *)NSSpubkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keyclass = KMF_ASYM_PUB;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keylabel = PK11_GetPublicKeyNickname(NSSpubkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (NSSpubkey)
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) PK11_DeleteTokenPublicKey(NSSpubkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (NSSprivkey)
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) PK11_DeleteTokenPrivateKey(NSSprivkey, PR_TRUE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys privkey->keyp = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pubkey->keyp = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keylabel)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(keylabel);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (pqgParams != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_PQG_DestroyParams(pqgParams);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (ecparams != NULL)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll SECITEM_FreeItem(ecparams, PR_TRUE);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nss_slot != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_FreeSlot(nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysNSS_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OID *AlgOID, KMF_DATA *tobesigned,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *output)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ALGORITHM_INDEX AlgId;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECOidTag signAlgTag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECKEYPrivateKey *NSSprivkey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECStatus rv;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECItem signed_data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signed_data.data = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key == NULL || AlgOID == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tobesigned == NULL || output == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tobesigned->Data == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys output->Data == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Map the OID to a NSS algorithm */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys AlgId = x509_algoid_to_algid(AlgOID);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (AlgId == KMF_ALGID_NONE)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NSSprivkey = (SECKEYPrivateKey *)key->keyp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (AlgId == KMF_ALGID_MD5WithRSA)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signAlgTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys else if (AlgId == KMF_ALGID_MD2WithRSA)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signAlgTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys else if (AlgId == KMF_ALGID_SHA1WithRSA)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signAlgTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll else if (AlgId == KMF_ALGID_SHA256WithRSA)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll signAlgTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll else if (AlgId == KMF_ALGID_SHA384WithRSA)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll signAlgTag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll else if (AlgId == KMF_ALGID_SHA512WithRSA)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll signAlgTag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys else if (AlgId == KMF_ALGID_SHA1WithDSA)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signAlgTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll else if (AlgId == KMF_ALGID_SHA1WithECDSA || AlgId == KMF_ALGID_ECDSA)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll signAlgTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll else if (AlgId == KMF_ALGID_SHA256WithECDSA)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll signAlgTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll else if (AlgId == KMF_ALGID_SHA384WithECDSA)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll signAlgTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll else if (AlgId == KMF_ALGID_SHA512WithECDSA)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll signAlgTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll else /* NSS does not support DSA with SHA2 hashes (FIPS 186-3) */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = SEC_SignData(&signed_data, tobesigned->Data,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tobesigned->Length, NSSprivkey, signAlgTag);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_INTERNAL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (signed_data.len <= output->Length) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(output->Data, signed_data.data, signed_data.len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys output->Length = signed_data.len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys output->Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_PARAMETER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(signed_data.data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysNSS_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *encoded)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECItem *rvitem;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CERTSubjectPublicKeyInfo *spki = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (keyp == NULL || encoded == NULL || keyp->keyp == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys spki = SECKEY_CreateSubjectPublicKeyInfo(keyp->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (spki == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, PORT_GetError());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rvitem = SEC_ASN1EncodeItem(NULL, NULL, spki,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERT_SubjectPublicKeyInfoTemplate);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rvitem != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys encoded->Data = malloc(rvitem->len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (encoded->Data == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(encoded->Data, rvitem->data, rvitem->len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys encoded->Length = rvitem->len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECITEM_FreeItem(rvitem, TRUE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, PORT_GetError());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys encoded->Data = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys encoded->Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_ENCODING;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECKEY_DestroySubjectPublicKeyInfo(spki);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_DeleteKey(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *key;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL cred;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t delete_token = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * "delete_token" means to clear it from the token storage as well
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * as from memory.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key == NULL || key->keyp == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&delete_token, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* "delete_token" is optional. Default is TRUE */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (delete_token) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECStatus nssrv = SECSuccess;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key->keyclass != KMF_ASYM_PUB &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyclass != KMF_ASYM_PRI &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyclass != KMF_SYMMETRIC)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_KEY_CLASS);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&cred, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = nss_authenticate(handle, nss_slot, &cred);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key->keyclass == KMF_ASYM_PUB) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssrv = PK11_DeleteTokenPublicKey(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (SECKEYPublicKey *)key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (key->keyclass == KMF_ASYM_PRI) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssrv = PK11_DeleteTokenPrivateKey(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (SECKEYPrivateKey *)key->keyp, PR_TRUE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (key->keyclass == KMF_SYMMETRIC) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nssrv = PK11_DeleteTokenSymKey(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (PK11SymKey *) key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nssrv == SECSuccess)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSymKey((PK11SymKey *) key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nssrv != SECSuccess) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(handle, PORT_GetError());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key->keyclass == KMF_ASYM_PUB) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECKEY_DestroyPublicKey((SECKEYPublicKey *)key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (key->keyclass == KMF_ASYM_PRI) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SECKEY_DestroyPrivateKey((SECKEYPrivateKey *)key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (key->keyclass == KMF_SYMMETRIC) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_FreeSymKey((PK11SymKey *) key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_KEY_CLASS);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys key->keyp = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *str;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the error string in the default language */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys str = (char *)PR_ErrorToName((PRErrorCode)kmfh->lasterr.errcode);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (str != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *msgstr = (char *)strdup(str);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((*msgstr) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *msgstr = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL cred;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *key = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertificate *nss_cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEYPrivateKey* privkey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the credential */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&cred, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = nss_authenticate(handle, nss_slot, &cred);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the key handle */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the cert data and decode it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL || cert->Data == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert->Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_cert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CERT_FORMAT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey = PK11_FindPrivateKeyFromCert(nss_slot, nss_cert, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (privkey == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_KEY_NOT_FOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->kstype = KMF_KEYSTORE_NSS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyclass = KMF_ASYM_PRI;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyp = (void *)privkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keylabel = PK11_GetPrivateKeyNickname(privkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERT_DestroyCertificate(nss_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_OK);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OID *AlgOID, KMF_DATA *ciphertext,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *output)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEYPrivateKey *NSSprivkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECStatus rv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned int in_len = 0, out_len = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned int total_decrypted = 0, modulus_len = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint8_t *in_data, *out_data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i, blocks;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key == NULL || AlgOID == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ciphertext == NULL || output == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ciphertext->Data == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys output->Data == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NSSprivkey = (SECKEYPrivateKey *)key->keyp;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys modulus_len = PK11_GetPrivateModulusLen(NSSprivkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys blocks = ciphertext->Length/modulus_len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out_data = output->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in_data = ciphertext->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out_len = modulus_len - 11;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in_len = modulus_len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; i < blocks; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = PK11_PrivDecryptPKCS1(NSSprivkey, out_data,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &out_len, ciphertext->Length, in_data, in_len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_INTERNAL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out_data += out_len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys total_decrypted += out_len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in_data += in_len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys output->Length = total_decrypted;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_KEY_ALG
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyspk11keytype2kmf(CK_KEY_TYPE type)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (type) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case CKK_RSA:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_RSA);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case CKK_DSA:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_RSA);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case CKK_AES:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_AES);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case CKK_RC4:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_RC4);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case CKK_DES:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_DES);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case CKK_DES3:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_DES3);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll case CKK_EC:
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll return (KMF_ECDSA);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys default:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* not supported */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_KEYALG_NONE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_FindKey(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEYPrivateKeyList *prilist;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEYPrivateKeyListNode *prinode;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEYPublicKeyList *publist;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEYPublicKeyListNode *pubnode;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SymKey *symlist = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int count;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t maxkeys;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *keys;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t *numkeys;
2cbed7292737821015ab481353eb10e8346b2c05wyllys KMF_CREDENTIAL *cred = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_CLASS keyclass;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *findLabel;
2cbed7292737821015ab481353eb10e8346b2c05wyllys char *nick;
2cbed7292737821015ab481353eb10e8346b2c05wyllys int match = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_ALG keytype = KMF_KEYALG_NONE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numkeys == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
2cbed7292737821015ab481353eb10e8346b2c05wyllys /* It is OK if this is NULL, we dont need a cred to find public keys */
2cbed7292737821015ab481353eb10e8346b2c05wyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (cred != NULL) {
2cbed7292737821015ab481353eb10e8346b2c05wyllys rv = nss_authenticate(handle, nss_slot, cred);
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (rv != KMF_OK) {
2cbed7292737821015ab481353eb10e8346b2c05wyllys return (rv);
2cbed7292737821015ab481353eb10e8346b2c05wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys maxkeys = *numkeys;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (maxkeys == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys maxkeys = 0xFFFFFFFF;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *numkeys = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&keyclass, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyclass == KMF_ASYM_PUB) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys publist = PK11_ListPublicKeysInSlot(nss_slot, findLabel);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (publist == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_KEY_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (keyclass == KMF_ASYM_PRI) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys prilist = PK11_ListPrivKeysInSlot(nss_slot, findLabel, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (prilist == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_KEY_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (keyclass == KMF_SYMMETRIC) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symlist = PK11_ListFixedKeysInSlot(nss_slot, findLabel, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (symlist == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_KEY_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_BAD_KEY_CLASS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* it is okay to have "keys" contains NULL */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyclass == KMF_ASYM_PUB) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (count = 0, pubnode = PUBKEY_LIST_HEAD(publist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys !PUBKEY_LIST_END(pubnode, publist) && count < maxkeys;
2cbed7292737821015ab481353eb10e8346b2c05wyllys pubnode = PUBKEY_LIST_NEXT(pubnode)) {
2cbed7292737821015ab481353eb10e8346b2c05wyllys match = 0;
2cbed7292737821015ab481353eb10e8346b2c05wyllys /*
2cbed7292737821015ab481353eb10e8346b2c05wyllys * Due to bug in NSS, we have to manually match
2cbed7292737821015ab481353eb10e8346b2c05wyllys * the labels to be sure we have a match.
2cbed7292737821015ab481353eb10e8346b2c05wyllys */
2cbed7292737821015ab481353eb10e8346b2c05wyllys nick = PK11_GetPublicKeyNickname(pubnode->key);
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (findLabel) {
2cbed7292737821015ab481353eb10e8346b2c05wyllys match = (nick &&
2cbed7292737821015ab481353eb10e8346b2c05wyllys (strcmp(nick, findLabel) == 0));
2cbed7292737821015ab481353eb10e8346b2c05wyllys } else {
2cbed7292737821015ab481353eb10e8346b2c05wyllys /* always match if findLabel is NULL */
2cbed7292737821015ab481353eb10e8346b2c05wyllys match = 1;
2cbed7292737821015ab481353eb10e8346b2c05wyllys }
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (keys != NULL && match) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].kstype = KMF_KEYSTORE_NSS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyclass = KMF_ASYM_PUB;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyp = (void *)pubnode->key;
2cbed7292737821015ab481353eb10e8346b2c05wyllys keys[count].keylabel = nick;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pubnode->key->keyType == rsaKey)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyalg = KMF_RSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else if (pubnode->key->keyType == dsaKey)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyalg = KMF_DSA;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll else if (pubnode->key->keyType == ecKey)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll keys[count].keyalg = KMF_ECDSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (match)
2cbed7292737821015ab481353eb10e8346b2c05wyllys count++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *numkeys = count;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (keyclass == KMF_ASYM_PRI) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (count = 0, prinode = PRIVKEY_LIST_HEAD(prilist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys !PRIVKEY_LIST_END(prinode, prilist) && count < maxkeys;
2cbed7292737821015ab481353eb10e8346b2c05wyllys prinode = PRIVKEY_LIST_NEXT(prinode)) {
2cbed7292737821015ab481353eb10e8346b2c05wyllys match = 0;
2cbed7292737821015ab481353eb10e8346b2c05wyllys /*
2cbed7292737821015ab481353eb10e8346b2c05wyllys * Due to bug in NSS, we have to manually match
2cbed7292737821015ab481353eb10e8346b2c05wyllys * the labels to be sure we have a match.
2cbed7292737821015ab481353eb10e8346b2c05wyllys */
2cbed7292737821015ab481353eb10e8346b2c05wyllys nick = PK11_GetPrivateKeyNickname(prinode->key);
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (findLabel) {
2cbed7292737821015ab481353eb10e8346b2c05wyllys match = (nick &&
2cbed7292737821015ab481353eb10e8346b2c05wyllys (strcmp(nick, findLabel) == 0));
2cbed7292737821015ab481353eb10e8346b2c05wyllys } else {
2cbed7292737821015ab481353eb10e8346b2c05wyllys /* always match if findLabel is NULL */
2cbed7292737821015ab481353eb10e8346b2c05wyllys match = 1;
2cbed7292737821015ab481353eb10e8346b2c05wyllys }
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (keys != NULL && match) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].kstype = KMF_KEYSTORE_NSS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyclass = KMF_ASYM_PRI;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyp = (void *)prinode->key;
2cbed7292737821015ab481353eb10e8346b2c05wyllys keys[count].keylabel = nick;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (prinode->key->keyType == rsaKey)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyalg = KMF_RSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else if (prinode->key->keyType == dsaKey)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyalg = KMF_DSA;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll else if (prinode->key->keyType == ecKey)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll keys[count].keyalg = KMF_ECDSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (match)
2cbed7292737821015ab481353eb10e8346b2c05wyllys count++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *numkeys = count;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (keyclass == KMF_SYMMETRIC) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys count = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&keytype, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys while (symlist && count < maxkeys) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SymKey *symkey = symlist;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CK_KEY_TYPE type;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_ALG keyalg;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
2cbed7292737821015ab481353eb10e8346b2c05wyllys match = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys type = PK11_GetSymKeyType(symkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyalg = pk11keytype2kmf(type);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symlist = PK11_GetNextSymKey(symkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If keytype is specified in the searching parameter,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * check the keytype and skip the key if its keytype
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * doesn't match.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keytype != KMF_KEYALG_NONE && keytype != keyalg) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* free that key since we arent using it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSymKey(symkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys continue;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
2cbed7292737821015ab481353eb10e8346b2c05wyllys /*
2cbed7292737821015ab481353eb10e8346b2c05wyllys * Due to bug in NSS, we have to manually match
2cbed7292737821015ab481353eb10e8346b2c05wyllys * the labels to be sure we have a match.
2cbed7292737821015ab481353eb10e8346b2c05wyllys */
2cbed7292737821015ab481353eb10e8346b2c05wyllys nick = PK11_GetSymKeyNickname(symkey);
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (findLabel) {
2cbed7292737821015ab481353eb10e8346b2c05wyllys match = (nick &&
2cbed7292737821015ab481353eb10e8346b2c05wyllys (strcmp(nick, findLabel) == 0));
2cbed7292737821015ab481353eb10e8346b2c05wyllys } else {
2cbed7292737821015ab481353eb10e8346b2c05wyllys /* always match if findLabel is NULL */
2cbed7292737821015ab481353eb10e8346b2c05wyllys match = 1;
2cbed7292737821015ab481353eb10e8346b2c05wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (keys != NULL && match) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].kstype = KMF_KEYSTORE_NSS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyclass = KMF_SYMMETRIC;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyp = (void *) symkey;
2cbed7292737821015ab481353eb10e8346b2c05wyllys keys[count].keylabel = nick;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys[count].keyalg = keyalg;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSymKey(symkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
2cbed7292737821015ab481353eb10e8346b2c05wyllys if (match)
2cbed7292737821015ab481353eb10e8346b2c05wyllys count++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Cleanup memory for unused keys.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys while (symlist != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SymKey *symkey = symlist;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSymKey(symkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symlist = PK11_GetNextSymKey(symkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *numkeys = count;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (nss_slot != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_FreeSlot(nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic SECStatus
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysp12u_SwapUnicodeBytes(SECItem *uniItem)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned int i;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char a;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((uniItem == NULL) || (uniItem->len % 2)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (SECFailure);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; i < uniItem->len; i += 2) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys a = uniItem->data[i];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uniItem->data[i] = uniItem->data[i+1];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uniItem->data[i+1] = a;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (SECSuccess);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic PRBool
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysp12u_ucs2_ascii_conversion_function(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PRBool toUnicode,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char *inBuf,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned int inBufLen,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char *outBuf,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned int maxOutBufLen,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned int *outBufLen,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PRBool swapBytes)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO SECItem it = { siBuffer, NULL, 0 };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECItem *dup = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PRBool ret;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys it.data = inBuf;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys it.len = inBufLen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dup = SECITEM_DupItem(&it);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If converting Unicode to ASCII, swap bytes before conversion
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * as neccessary.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!toUnicode && swapBytes) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (p12u_SwapUnicodeBytes(dup) != SECSuccess) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECITEM_ZfreeItem(dup, PR_TRUE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (PR_FALSE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Perform the conversion. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = PORT_UCS2_UTF8Conversion(toUnicode, dup->data, dup->len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys outBuf, maxOutBufLen, outBufLen);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (dup)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECITEM_ZfreeItem(dup, PR_TRUE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic PRBool
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysp12u_OpenFile(p12uContext *p12ctx, PRBool fileRead)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!p12ctx || !p12ctx->filename) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (PR_FALSE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fileRead) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12ctx->file = PR_Open(p12ctx->filename, PR_RDONLY, 0400);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12ctx->file = PR_Open(p12ctx->filename,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 0600);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!p12ctx->file) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12ctx->error = PR_TRUE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (PR_FALSE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (PR_TRUE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic void
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysp12u_DestroyContext(p12uContext **ppCtx, PRBool removeFile)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!ppCtx || !(*ppCtx)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((*ppCtx)->file != NULL) {
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) PR_Close((*ppCtx)->file);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((*ppCtx)->filename != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (removeFile) {
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) PR_Delete((*ppCtx)->filename);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free((*ppCtx)->filename);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(*ppCtx);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *ppCtx = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic p12uContext *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysp12u_InitContext(PRBool fileImport, char *filename)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12uContext *p12ctx;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12ctx = PORT_ZNew(p12uContext);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!p12ctx) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12ctx->error = PR_FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12ctx->errorValue = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12ctx->filename = strdup(filename);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!p12u_OpenFile(p12ctx, fileImport)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12u_DestroyContext(&p12ctx, PR_FALSE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (p12ctx);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic void
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysp12u_WriteToExportFile(void *arg, const char *buf, unsigned long len)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12uContext *p12cxt = arg;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int writeLen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!p12cxt || (p12cxt->error == PR_TRUE)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (p12cxt->file == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12cxt->error = PR_TRUE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys writeLen = PR_Write(p12cxt->file, (unsigned char *)buf, (int32)len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (writeLen != (int)len) {
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) PR_Close(p12cxt->file);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(p12cxt->filename);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12cxt->filename = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12cxt->file = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12cxt->error = PR_TRUE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#define HANDLE_NSS_ERROR(r) {\
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError()); \
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = r; \
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out; }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysadd_cert_to_bag(SEC_PKCS12ExportContext *p12ecx,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertificate *cert, SECItem *pwitem)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SEC_PKCS12SafeInfo *keySafe = NULL, *certSafe = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (PK11_IsFIPS()) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certSafe = keySafe;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!certSafe || !keySafe) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys != SECSuccess) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_INTERNAL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SEC_PKCS12ExportContext *p12ecx = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12uContext *p12ctx = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertList *certlist = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertificate *nsscert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertListNode* node = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SlotInfo *slot = NULL;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO SECItem pwitem = { siBuffer, NULL, 0 };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL *cred = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL *p12cred = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *certlabel = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *issuer = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *subject = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_BIGINT *serial = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *filename = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmfh == NULL || attrlist == NULL || numattr == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cred == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = nss_authenticate(handle, slot, cred);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (p12cred == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (filename == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get optional search criteria attributes */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Find the certificate(s) first.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certlabel != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nsscert = PK11_FindCertFromNickname(certlabel, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nsscert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_NSS_ERROR(KMF_ERR_CERT_NOT_FOUND)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = nss_find_matching_certs(slot, issuer, subject, serial,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &certlist, 0);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK && certlist == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_CERT_NOT_FOUND);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The KMF_CREDENTIAL holds the password to use for
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * encrypting the PKCS12 key information.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pwitem.data = (uchar_t *)p12cred->cred;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pwitem.len = p12cred->credlen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12ctx = p12u_InitContext(PR_FALSE, filename);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!p12ctx) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PORT_SetUCS2_ASCIIConversionFunction(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12u_ucs2_ascii_conversion_function);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, slot, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!p12ecx) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (SEC_PKCS12AddPasswordIntegrity(p12ecx, &pwitem, SEC_OID_SHA1)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys != SECSuccess) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_NSS_ERROR(KMF_ERR_INTERNAL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * NSS actually supports storing a list of keys and certs
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * in the PKCS#12 PDU. Nice feature.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certlist != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (node = CERT_LIST_HEAD(certlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys !CERT_LIST_END(node, certlist) && rv == KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys node = CERT_LIST_NEXT(node)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = add_cert_to_bag(p12ecx, node->cert, &pwitem);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (nsscert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = add_cert_to_bag(p12ecx, nsscert, &pwitem);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (SEC_PKCS12Encode(p12ecx, p12u_WriteToExportFile, p12ctx)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys != SECSuccess) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_NSS_ERROR(KMF_ERR_ENCODING)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nsscert)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERT_DestroyCertificate(nsscert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERT_DestroyCertList(certlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (p12ctx)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12u_DestroyContext(&p12ctx, PR_FALSE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (p12ecx)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SEC_PKCS12DestroyExportContext(p12ecx);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#define SETATTR(t, n, atype, value, size) \
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys t[n].type = atype; \
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys t[n].pValue = (CK_BYTE *)value; \
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys t[n].ulValueLen = (CK_ULONG)size;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_CreateSymKey(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SymKey *nsskey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CK_MECHANISM_TYPE keyType;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECStatus nssrv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int keySize;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *symkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL cred;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t keylen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t keylen_size = sizeof (uint32_t);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_ALG keytype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *keylabel = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmfh == NULL || attrlist == NULL || numattr == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (symkey == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, (void *)&keytype,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, &keylen,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &keylen_size);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_ERR_ATTR_NOT_FOUND &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (keytype == KMF_DES || keytype == KMF_DES3))
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* keylength is not required for DES and 3DES */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keylabel == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (keytype) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_AES:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyType = CKM_AES_KEY_GEN;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keySize = keylen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keySize == 0 || (keySize % 8) != 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_KEY_SIZE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_RC4:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyType = CKM_RC4_KEY_GEN;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keySize = keylen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keySize == 0 || (keySize % 8) != 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_KEY_SIZE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_DES:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyType = CKM_DES_KEY_GEN;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keySize = 0; /* required by PK11_TokenKeyGen() */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_DES3:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyType = CKM_DES3_KEY_GEN;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keySize = 0; /* required by PK11_TokenKeyGen() */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_GENERIC_SECRET:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyType = CKM_GENERIC_SECRET_KEY_GEN;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keySize = keylen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keySize == 0 || (keySize % 8) != 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_KEY_SIZE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys default:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_BAD_KEY_TYPE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&cred, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
5363b1129db4ee42d2c9736898eab4670580bec7hylee
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = nss_authenticate(handle, nss_slot, &cred);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
5363b1129db4ee42d2c9736898eab4670580bec7hylee }
5363b1129db4ee42d2c9736898eab4670580bec7hylee
ab8b4e5c888370036603c72719799620ea5c6b77Wyllys Ingersoll /* convert key length to bytes */
ab8b4e5c888370036603c72719799620ea5c6b77Wyllys Ingersoll nsskey = PK11_TokenKeyGen(nss_slot, keyType, NULL, keySize / 8, NULL,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PR_TRUE, (void *)cred.cred);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nsskey == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nssrv = PK11_SetSymKeyNickname(nsskey, keylabel);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nssrv != SECSuccess) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->kstype = KMF_KEYSTORE_NSS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keyalg = keytype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keyclass = KMF_SYMMETRIC;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->israw = FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keyp = (void *)nsskey;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_slot != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11_FreeSlot(nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK && nsskey != NULL) {
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) PK11_DeleteTokenSymKey(nsskey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSymKey(nsskey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_SYM_KEY *rkey)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECItem *value = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SymKey *nsskey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECStatus nss_rv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmfh == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_UNINITIALIZED);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (symkey == NULL || rkey == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else if (symkey->keyclass != KMF_SYMMETRIC)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_KEY_CLASS);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (symkey->israw) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rawkey == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rawkey->rawdata.sym.keydata.val == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rawkey->rawdata.sym.keydata.len == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_KEYHANDLE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy(rkey->keydata.val,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nsskey = (PK11SymKey *)(symkey->keyp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nsskey == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_KEYHANDLE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_rv = PK11_ExtractKeyValue(nsskey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_rv != SECSuccess) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_GETKEYVALUE_FAILED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys value = PK11_GetKeyData(nsskey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (value == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_GETKEYVALUE_FAILED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (value->len == 0 || value->data == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_GETKEYVALUE_FAILED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.val = malloc(value->len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rkey->keydata.val == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy(rkey->keydata.val, value->data, value->len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.len = value->len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(value->data, 0, value->len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (value != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECITEM_FreeItem(value, PR_TRUE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_SetTokenPin(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int rv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL oldcred, newcred;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || attrlist == NULL || numattr == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&oldcred, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_NEWPIN_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&newcred, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If it was uninitialized, set it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret == KMF_ERR_UNINITIALIZED_TOKEN) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = PK11_InitPin(nss_slot, NULL, newcred.cred);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != SECSuccess) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_AUTH_FAILED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (ret == KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = nss_authenticate(handle, nss_slot, &oldcred);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = PK11_ChangePW(nss_slot, oldcred.cred, newcred.cred);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != SECSuccess) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_AUTH_FAILED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_StoreKey(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SlotInfo *nss_slot = NULL;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_CREDENTIAL cred = { NULL, 0 };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_KEY_DATA *rawkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *keylabel = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECStatus ckrv = SECSuccess;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO SECItem nickname = { siBuffer, NULL, 0 };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertificate *nss_cert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmfh == NULL || attrlist == NULL || numattr == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&cred, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = nss_authenticate(handle, nss_slot, &cred);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pubkey == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* look for private key */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (prikey == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* look for raw key */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If no keys were found, return error */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pubkey == NULL && prikey == NULL && rawkey == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_ATTR_NOT_FOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keylabel != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nickname.data = (uchar_t *)keylabel;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nickname.len = strlen(keylabel);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rawkey != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uchar_t ver = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEYPrivateKeyInfo rpk;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA derkey = { 0, NULL };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *cert;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Decode the cert into an NSS CERT object so we can access the
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * SPKI and KeyUsage data later.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert->Length);
f482c776bc557f0256e776932c7842b9db390de1wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_cert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_BAD_CERT_FORMAT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(&rpk, 0, sizeof (rpk));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rpk.arena = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rpk.version.type = siUnsignedInteger;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rpk.version.data = &ver;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rpk.version.len = 1;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rawkey->keytype == KMF_RSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = DerEncodeRSAPrivateKey(&derkey,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &rawkey->rawdata.rsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (rawkey->keytype == KMF_DSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = DerEncodeDSAPrivateKey(&derkey,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &rawkey->rawdata.dsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll } else if (rawkey->keytype == KMF_ECDSA) {
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll rv = DerEncodeECPrivateKey(&derkey,
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll &rawkey->rawdata.ec);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (rv != KMF_OK)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rpk.privateKey.data = derkey.Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rpk.privateKey.len = derkey.Length;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rpk.attributes = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ckrv = PK11_ImportPrivateKeyInfo(nss_slot, &rpk, &nickname,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &nss_cert->subjectPublicKeyInfo.subjectPublicKey, TRUE,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys TRUE, nss_cert->keyUsage, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ckrv != CKR_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&derkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (pubkey != NULL && pubkey->kstype == KMF_KEYSTORE_NSS) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CK_OBJECT_HANDLE pk;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEYPublicKey *publicKey = (SECKEYPublicKey *) pubkey->keyp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pk = PK11_ImportPublicKey(nss_slot, publicKey, PR_TRUE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pk == CK_INVALID_HANDLE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (prikey != NULL && prikey->kstype == KMF_KEYSTORE_NSS) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEYPrivateKey *pk;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEYPrivateKey *privKey = (SECKEYPrivateKey *) prikey->keyp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pk = PK11_LoadPrivKey(nss_slot, privKey, NULL, PR_TRUE,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PR_TRUE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pk == CK_INVALID_HANDLE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_INTERNAL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* We stored it, but don't need the handle anymore */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECKEY_DestroyPrivateKey(pk);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscleanup:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_cert != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERT_DestroyCertificate(nss_cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSlot(nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * This function is called by NSS_StoreCert() and NSS_ImportCert().
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The "label" and "trust_flag" arguments can be NULL.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstore_cert(KMF_HANDLE_T handle, PK11SlotInfo *nss_slot, KMF_DATA *cert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *label, char *trust_flag)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECStatus nss_rv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertificate *nss_cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertTrust *nss_trust = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_slot == NULL || cert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert->Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_cert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERT_FORMAT;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Store the cert into the NSS database */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_rv = PK11_ImportCert(nss_slot, nss_cert, CK_INVALID_HANDLE,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys label, 0);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_rv) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, nss_rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERT_FORMAT;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If trust_flag is NULL, then we are done */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (trust_flag == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_trust = (CERTCertTrust *) malloc(sizeof (CERTCertTrust));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_trust == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_rv = CERT_DecodeTrustString(nss_trust, trust_flag);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_rv) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, nss_rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_rv = CERT_ChangeCertTrust(certHandle, nss_cert, nss_trust);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_rv) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, nss_rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_cert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERT_DestroyCertificate(nss_cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_trust != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(nss_trust);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *label = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *trust_flag = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the cert data */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL || cert->Data == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* The label attribute is optional */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* The trustflag attriburte is optional */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys trust_flag = kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = store_cert(handle, nss_slot, cert, label, trust_flag);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_slot != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSlot(nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SlotInfo *nss_slot = NULL;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA cert = { 0, NULL };
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA cert_der = { 0, NULL };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *cptr = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *label = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *trust_flag = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *certfile = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the input cert filename attribute */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Check the cert file and auto-detect the file format of it. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_is_cert_file(handle, certfile, &format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_read_input_file(handle, certfile, &cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If the imported cert is in PEM format, convert it to
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * DER format in order to store it in NSS token.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (format == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int derlen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_pem_to_der(cert.Data, cert.Length,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &cert_der.Data, &derlen);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert_der.Length = (size_t)derlen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cptr = &cert_der;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cptr = &cert;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys trust_flag = kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = store_cert(handle, nss_slot, cptr, label, trust_flag);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscleanup:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (format == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&cert_der);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTSignedCrl *nss_crl = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int importOptions;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECItem crlDER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA crl1;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA crl2;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *crlfilename;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t crlcheck = FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (attrlist == NULL || numattr == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlfilename == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Check if the input CRL file is a valid CRL file and auto-detect
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * the encoded format of the file.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_is_crl_file(handle, crlfilename, &format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &crlcheck, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK; /* CRL_CHECK is optional */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* set importOptions */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlcheck == B_FALSE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys importOptions = CRL_IMPORT_DEFAULT_OPTIONS |
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CRL_IMPORT_BYPASS_CHECKS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys importOptions = CRL_IMPORT_DEFAULT_OPTIONS;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Read in the CRL file */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crl1.Data = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crl2.Data = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_read_input_file(handle, crlfilename, &crl1);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If the input CRL is in PEM format, convert it to DER first. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (format == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_pem_to_der(crl1.Data, crl1.Length,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &crl2.Data, &len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crl2.Length = (size_t)len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlDER.data = format == KMF_FORMAT_ASN1 ? crl1.Data : crl2.Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlDER.len = format == KMF_FORMAT_ASN1 ? crl1.Length : crl2.Length;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nss_crl = PK11_ImportCRL(nss_slot, &crlDER, NULL, SEC_CRL_TYPE,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NULL, importOptions, NULL, CRL_DECODE_DEFAULT_OPTIONS);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_crl == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CRLFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_slot != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSlot(nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crl1.Data != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(crl1.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crl2.Data != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(crl2.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_crl != NULL) {
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) SEC_DestroyCrl(nss_crl);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTSignedCrl *crl = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertificate *cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCrlHeadNode *crlList = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCrlNode *crlNode = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PRArenaPool *arena = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTName *name = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *issuername, *subjectname;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* check params */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numattr == 0 || attrlist == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuername = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys subjectname = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Caller must specify issuer or subject but not both */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((issuername == NULL && subjectname == NULL) ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (issuername != NULL && subjectname != NULL))
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Find the CRL based on the deletion criteria. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (issuername != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If the deletion is based on the issuer's certificate
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * nickname, we will get the issuer's cert first, then
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * get the CRL from the cert.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = CERT_FindCertByNicknameOrEmailAddr(certHandle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuername);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!cert) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CERT_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crl = SEC_FindCrlByName(certHandle, &cert->derSubject,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SEC_CRL_TYPE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crl == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CRL_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If the deletion is based on the CRL's subject name, we will
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * get all the CRLs from the internal database and search
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * for the CRL with the same subject name.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t found = B_FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int nssrv;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nssrv) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, nssrv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CRL_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlList == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CRL_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Allocate space for name */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (arena == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys name = PORT_ArenaZAlloc(arena, sizeof (*name));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (name == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys name->arena = arena;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlNode = crlList->first;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys while (crlNode && !found) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *asciiname = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECItem* issuer;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys name = &crlNode->crl->crl.name;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!name) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CRL_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys asciiname = CERT_NameToAscii(name);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (asciiname == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CRL_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (strcmp(subjectname, asciiname) == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys found = B_TRUE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer = &crlNode->crl->crl.derName;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crl = SEC_FindCrlByName(certHandle, issuer,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SEC_CRL_TYPE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crl == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* We found a cert but no CRL */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CRL_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PORT_Free(asciiname);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlNode = crlNode->next;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crl) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) SEC_DeletePermCRL(crl);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_slot != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSlot(nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlList != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PORT_FreeArena(crlList->arena, PR_FALSE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (arena != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PORT_FreeArena(arena, PR_FALSE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERT_DestroyCertificate(cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crl != NULL) {
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) SEC_DestroyCrl(crl);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_FindCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCrlHeadNode *crlList = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCrlNode *crlNode = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PRArenaPool *arena = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTName *name = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SECStatus nssrv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *asciiname = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int crl_num;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i, *CRLCount;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char **CRLNameList;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numattr == 0 || attrlist == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CRLCount = kmf_get_attr_ptr(KMF_CRL_COUNT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (CRLCount == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CRLNameList = (char **)kmf_get_attr_ptr(KMF_CRL_NAMELIST_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Look up Crls */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nssrv) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CRL_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Allocate space for name first */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (arena == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys name = PORT_ArenaZAlloc(arena, sizeof (*name));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (name == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys name->arena = arena;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Loop thru the crlList and create a crl list with CRL's subject name.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlNode = crlList->first;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crl_num = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys while (crlNode) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *subj_name;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the CRL subject name */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys name = &crlNode->crl->crl.name;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!name) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CRL_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (CRLNameList != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys asciiname = CERT_NameToAscii(name);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (asciiname == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CRL_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys subj_name = strdup(asciiname);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PORT_Free(asciiname);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (subj_name == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CRLNameList[crl_num] = subj_name;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crl_num++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlNode = crlNode->next;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* success */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *CRLCount = crl_num;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_slot != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSlot(nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlList != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PORT_FreeArena(crlList->arena, PR_FALSE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (arena != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PORT_FreeArena(arena, PR_FALSE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If failed, free memory allocated for the returning rlist */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv && (CRLNameList != NULL)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; i < crl_num; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(CRLNameList[i]);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysNSS_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PK11SlotInfo *nss_slot = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertificate *cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTSignedCrl *crl = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCrlEntry *entry;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t match = B_FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *certlabel;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *certdata;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* check params */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numattr == 0 || attrlist == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Find the certificate first */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certlabel != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = CERT_FindCertByNicknameOrEmailAddr(certHandle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certlabel);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO SECItem derCert = { siBuffer, NULL, 0 };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certdata = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certdata == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys derCert.data = certdata->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys derCert.len = certdata->Length;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = CERT_FindCertByDERCert(certHandle, &derCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CERT_NOT_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Find the CRL with the same issuer as the given certificate. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crl = SEC_FindCrlByName(certHandle, &cert->derIssuer, SEC_CRL_TYPE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crl == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Could not find the CRL issued by the same issuer. This
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * usually means that the CRL is not installed in the DB.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, PORT_GetError());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CRL_NOT_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Check if the certificate's serialNumber is revoked in the CRL */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys while ((entry = (crl->crl).entries[i++]) != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (SECITEM_CompareItem(&(cert->serialNumber),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &(entry->serialNumber)) == SECEqual) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys match = B_TRUE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!match) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_NOT_REVOKED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nss_slot != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PK11_FreeSlot(nss_slot);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CERT_DestroyCertificate(cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crl != NULL) {
5ad42b1b1469908fabc0099764182e9ecbc04ddaSurya Prakki (void) SEC_DestroyCrl(crl);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}