13089Swyllys /*
23089Swyllys * CDDL HEADER START
33089Swyllys *
43089Swyllys * The contents of this file are subject to the terms of the
53089Swyllys * Common Development and Distribution License (the "License").
63089Swyllys * You may not use this file except in compliance with the License.
73089Swyllys *
83089Swyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93089Swyllys * or http://www.opensolaris.org/os/licensing.
103089Swyllys * See the License for the specific language governing permissions
113089Swyllys * and limitations under the License.
123089Swyllys *
133089Swyllys * When distributing Covered Code, include this CDDL HEADER in each
143089Swyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153089Swyllys * If applicable, add the following below this CDDL HEADER, with the
163089Swyllys * fields enclosed by brackets "[]" replaced with your own identifying
173089Swyllys * information: Portions Copyright [yyyy] [name of copyright owner]
183089Swyllys *
193089Swyllys * CDDL HEADER END
203089Swyllys */
2111411SSurya.Prakki@Sun.COM
223089Swyllys /*
233089Swyllys * NSS keystore wrapper
243089Swyllys *
25*11973Swyllys.ingersoll@sun.com * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
263089Swyllys * Use is subject to license terms.
273089Swyllys */
283089Swyllys
293089Swyllys #include <sys/types.h>
303089Swyllys #include <sys/stat.h>
313089Swyllys #include <errno.h>
323089Swyllys #include <fcntl.h>
333089Swyllys #include <synch.h>
343089Swyllys
353089Swyllys #include <kmfapiP.h>
363089Swyllys #include <ber_der.h>
373089Swyllys /* NSS related headers */
383089Swyllys
393089Swyllys #include <mps/nss.h>
403089Swyllys #include <mps/cert.h>
413089Swyllys #include <mps/certdb.h>
423089Swyllys #include <mps/secoid.h>
433089Swyllys #include <mps/secder.h>
443089Swyllys #include <mps/secerr.h>
453089Swyllys #include <mps/cryptohi.h>
463089Swyllys #include <mps/keyhi.h>
473089Swyllys #include <mps/keythi.h>
483089Swyllys #include <mps/pk11func.h>
493089Swyllys #include <mps/pk11pqg.h>
503089Swyllys #include <mps/pkcs12.h>
513089Swyllys #include <mps/p12plcy.h>
523089Swyllys #include <mps/prerror.h>
533089Swyllys
543089Swyllys #define NSS_OK 0
553089Swyllys
563089Swyllys mutex_t init_lock = DEFAULTMUTEX;
573089Swyllys static int nss_initialized = 0;
583089Swyllys
593089Swyllys KMF_RETURN
605051Swyllys NSS_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
613089Swyllys
623089Swyllys KMF_RETURN
635051Swyllys NSS_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
643089Swyllys
653089Swyllys void
663089Swyllys NSS_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
673089Swyllys
683089Swyllys KMF_RETURN
695051Swyllys NSS_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
705051Swyllys
715051Swyllys KMF_RETURN
725051Swyllys NSS_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
733089Swyllys
743089Swyllys KMF_RETURN
755051Swyllys NSS_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
763089Swyllys
773089Swyllys KMF_RETURN
785051Swyllys NSS_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
793089Swyllys
803089Swyllys KMF_RETURN
815051Swyllys NSS_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
823089Swyllys
833089Swyllys KMF_RETURN
843089Swyllys NSS_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
853089Swyllys
863089Swyllys KMF_RETURN
873089Swyllys NSS_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
883089Swyllys KMF_DATA *, KMF_DATA *);
893089Swyllys
903089Swyllys KMF_RETURN
915051Swyllys NSS_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
923089Swyllys
933089Swyllys KMF_RETURN
945051Swyllys NSS_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
953089Swyllys
963089Swyllys KMF_RETURN
975051Swyllys NSS_FindCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
983089Swyllys
993089Swyllys KMF_RETURN
1005051Swyllys NSS_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1013089Swyllys
1023089Swyllys KMF_RETURN
1035051Swyllys NSS_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1043089Swyllys
1053089Swyllys KMF_RETURN
1063089Swyllys NSS_GetErrorString(KMF_HANDLE_T, char **);
1073089Swyllys
1083089Swyllys KMF_RETURN
1095051Swyllys NSS_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1103089Swyllys
1113089Swyllys KMF_RETURN
1125051Swyllys NSS_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1133089Swyllys
1143089Swyllys KMF_RETURN
1153089Swyllys NSS_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
1163089Swyllys KMF_DATA *, KMF_DATA *);
1173089Swyllys
1183089Swyllys KMF_RETURN
1195051Swyllys NSS_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1203089Swyllys
1213089Swyllys KMF_RETURN
1225051Swyllys NSS_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1233089Swyllys
1243089Swyllys KMF_RETURN
1253089Swyllys NSS_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
1263089Swyllys
1273089Swyllys KMF_RETURN
1285051Swyllys NSS_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1293089Swyllys
1303089Swyllys static
1313089Swyllys KMF_PLUGIN_FUNCLIST nss_plugin_table =
1323089Swyllys {
1333089Swyllys 1, /* Version */
1343089Swyllys NSS_ConfigureKeystore,
1353089Swyllys NSS_FindCert,
1363089Swyllys NSS_FreeKMFCert,
1373089Swyllys NSS_StoreCert,
1383089Swyllys NSS_ImportCert,
1393089Swyllys NSS_ImportCRL,
1403089Swyllys NSS_DeleteCert,
1413089Swyllys NSS_DeleteCRL,
1423089Swyllys NSS_CreateKeypair,
1433089Swyllys NSS_FindKey,
1443089Swyllys NSS_EncodePubKeyData,
1453089Swyllys NSS_SignData,
1463089Swyllys NSS_DeleteKey,
1473089Swyllys NULL /* ListCRL */,
1483089Swyllys NSS_FindCRL,
1493089Swyllys NSS_FindCertInCRL,
1503089Swyllys NSS_GetErrorString,
1515051Swyllys NSS_FindPrikeyByCert,
1523089Swyllys NSS_DecryptData,
1535051Swyllys NSS_ExportPK12,
1543089Swyllys NSS_CreateSymKey,
1553089Swyllys NSS_GetSymKeyValue,
1563089Swyllys NSS_SetTokenPin,
1575051Swyllys NSS_StoreKey,
1583089Swyllys NULL /* Finalize */
1593089Swyllys };
1603089Swyllys
1613089Swyllys /* additions for importing and exporting PKCS 12 files */
1623089Swyllys typedef struct p12uContextStr {
1633089Swyllys char *filename; /* name of file */
1643089Swyllys PRFileDesc *file; /* pointer to file */
1653089Swyllys PRBool error; /* error occurred? */
1663089Swyllys int errorValue; /* which error occurred? */
1673089Swyllys } p12uContext;
1683089Swyllys
1693089Swyllys #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_NSS; \
1703089Swyllys h->lasterr.errcode = c;
1713089Swyllys
1723089Swyllys KMF_PLUGIN_FUNCLIST *
KMF_Plugin_Initialize()1733089Swyllys KMF_Plugin_Initialize()
1743089Swyllys {
17511411SSurya.Prakki@Sun.COM (void) SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1);
17611411SSurya.Prakki@Sun.COM (void) SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1);
17711411SSurya.Prakki@Sun.COM (void) SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1);
17811411SSurya.Prakki@Sun.COM (void) SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1);
17911411SSurya.Prakki@Sun.COM (void) SEC_PKCS12EnableCipher(PKCS12_DES_56, 1);
18011411SSurya.Prakki@Sun.COM (void) SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1);
18111411SSurya.Prakki@Sun.COM (void) SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1);
1823089Swyllys
1833089Swyllys return (&nss_plugin_table);
1843089Swyllys }
1853089Swyllys
1863089Swyllys static char *
1873089Swyllys /*ARGSUSED*/
nss_getpassword(PK11SlotInfo * slot,PRBool retry,void * arg)1883089Swyllys nss_getpassword(PK11SlotInfo *slot, PRBool retry, void *arg)
1893089Swyllys {
1903089Swyllys if (retry)
1913089Swyllys return (NULL);
1923089Swyllys if (arg != NULL)
1933089Swyllys return ((char *)strdup(arg));
1943089Swyllys else
1953089Swyllys return (NULL);
1963089Swyllys }
1973089Swyllys
1983089Swyllys static KMF_RETURN
nss_authenticate(KMF_HANDLE_T handle,PK11SlotInfo * nss_slot,KMF_CREDENTIAL * cred)1993089Swyllys nss_authenticate(KMF_HANDLE_T handle,
2003089Swyllys PK11SlotInfo *nss_slot, KMF_CREDENTIAL *cred)
2013089Swyllys {
2023089Swyllys
2033089Swyllys SECStatus nssrv = SECSuccess;
2043089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2053089Swyllys
2063089Swyllys /* If a password was given, try to login to the slot */
2073089Swyllys if (cred == NULL || cred->cred == NULL || cred->credlen == 0 ||
2085051Swyllys nss_slot == NULL) {
2093089Swyllys return (KMF_ERR_BAD_PARAMETER);
2103089Swyllys }
2113089Swyllys
2123089Swyllys if (PK11_IsLoggedIn(nss_slot, NULL)) {
2133089Swyllys return (KMF_OK);
2143089Swyllys }
2153089Swyllys
2163089Swyllys PK11_SetPasswordFunc(nss_getpassword);
2175051Swyllys nssrv = PK11_Authenticate(nss_slot, PR_TRUE, (void *)cred->cred);
2183089Swyllys
2193089Swyllys if (nssrv != SECSuccess) {
2203089Swyllys SET_ERROR(kmfh, nssrv);
2213089Swyllys PK11_FreeSlot(nss_slot);
2223089Swyllys return (KMF_ERR_AUTH_FAILED);
2233089Swyllys }
2243089Swyllys
2253089Swyllys return (KMF_OK);
2263089Swyllys }
2273089Swyllys
2283089Swyllys static SECStatus
Init_NSS_DBs(const char * configdir,const char * certPrefix,const char * keyPrefix,const char * secmodName)2293089Swyllys Init_NSS_DBs(const char *configdir,
2303089Swyllys const char *certPrefix,
2313089Swyllys const char *keyPrefix,
2323089Swyllys const char *secmodName)
2333089Swyllys {
2343089Swyllys SECStatus rv = NSS_OK;
2353089Swyllys
2363089Swyllys (void) mutex_lock(&init_lock);
2373089Swyllys
2383089Swyllys /* If another thread already did it, return OK. */
2393089Swyllys if (nss_initialized) {
2403089Swyllys (void) mutex_unlock(&init_lock);
2413089Swyllys return (SECSuccess);
2423089Swyllys }
2433089Swyllys
2443089Swyllys rv = NSS_Initialize((configdir && strlen(configdir)) ?
2455051Swyllys configdir : "./", certPrefix, keyPrefix,
2465051Swyllys secmodName ? secmodName : "secmod.db", NSS_INIT_COOPERATE);
2473089Swyllys if (rv != SECSuccess) {
2483089Swyllys goto end;
2493089Swyllys }
2503089Swyllys
2513089Swyllys nss_initialized++;
2523089Swyllys end:
2533089Swyllys (void) mutex_unlock(&init_lock);
2543089Swyllys return (rv);
2553089Swyllys }
2563089Swyllys
2573089Swyllys /*
2583089Swyllys * When it is called the first time, it will intialize NSS. Once the NSS
2593089Swyllys * is initialized, this function returns KMF_KEYSTORE_ALREADY_INITIALIZED
2603089Swyllys * if it is called again.
2613089Swyllys */
2623089Swyllys KMF_RETURN
NSS_ConfigureKeystore(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2635051Swyllys NSS_ConfigureKeystore(KMF_HANDLE_T handle,
2645051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
2653089Swyllys {
2663089Swyllys KMF_RETURN rv = KMF_OK;
2673089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2685051Swyllys char *configdir;
2695051Swyllys char *certPrefix;
2705051Swyllys char *keyPrefix;
2715051Swyllys char *secModName;
2725051Swyllys
2735051Swyllys configdir = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2745051Swyllys certPrefix = kmf_get_attr_ptr(KMF_CERTPREFIX_ATTR, attrlist, numattr);
2755051Swyllys keyPrefix = kmf_get_attr_ptr(KMF_KEYPREFIX_ATTR, attrlist, numattr);
2765051Swyllys secModName = kmf_get_attr_ptr(KMF_SECMODNAME_ATTR, attrlist, numattr);
2773089Swyllys
2783089Swyllys (void) mutex_lock(&init_lock);
2793089Swyllys if (nss_initialized == 0) {
2803089Swyllys SECStatus err;
2813089Swyllys
2823089Swyllys (void) mutex_unlock(&init_lock);
2835051Swyllys err = Init_NSS_DBs(configdir, certPrefix,
2845051Swyllys keyPrefix, secModName);
2853089Swyllys if (err != SECSuccess) {
2863089Swyllys SET_ERROR(kmfh, err);
2873089Swyllys return (KMF_ERR_INTERNAL);
2883089Swyllys }
2893089Swyllys } else {
2903089Swyllys rv = KMF_KEYSTORE_ALREADY_INITIALIZED;
2913089Swyllys (void) mutex_unlock(&init_lock);
2923089Swyllys }
2933089Swyllys
2943089Swyllys return (rv);
2953089Swyllys }
2963089Swyllys
2973089Swyllys /*
2983089Swyllys * This function sets up the slot to be used for other operations.
2993089Swyllys * This function is basically called by every NSS SPI function.
3003089Swyllys * For those functions that can only be performed in the internal slot, the
3013089Swyllys * boolean "internal_slot_only" argument needs to be TRUE.
3023089Swyllys * A slot pointer will be returned when this function is executed successfully.
3033089Swyllys */
3045051Swyllys KMF_RETURN
do_nss_init(void * handle,int numattr,KMF_ATTRIBUTE * attrlist,boolean_t internal_slot_only,PK11SlotInfo ** nss_slot)3055051Swyllys do_nss_init(void *handle, int numattr,
3065051Swyllys KMF_ATTRIBUTE *attrlist,
3073089Swyllys boolean_t internal_slot_only,
3083089Swyllys PK11SlotInfo **nss_slot)
3093089Swyllys {
3105051Swyllys KMF_RETURN rv = KMF_OK;
3113089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3125051Swyllys char *slotlabel = NULL;
3133089Swyllys
3143089Swyllys if (!nss_initialized)
3153089Swyllys return (KMF_ERR_PLUGIN_INIT);
3163089Swyllys
3175051Swyllys slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
3183089Swyllys /*
3193089Swyllys * NSS Is already initialized, but we need to find
3203089Swyllys * the right slot.
3213089Swyllys */
3225051Swyllys if (slotlabel == NULL ||
3235051Swyllys strcmp(slotlabel, "internal") == 0) {
3243089Swyllys *nss_slot = PK11_GetInternalKeySlot();
3253089Swyllys } else if (internal_slot_only == TRUE) {
3265051Swyllys rv = KMF_ERR_SLOTNAME;
3275051Swyllys goto end;
3283089Swyllys } else {
3295051Swyllys *nss_slot = PK11_FindSlotByName(slotlabel);
3303089Swyllys }
3313089Swyllys
3323089Swyllys if (*nss_slot == NULL) {
3333089Swyllys SET_ERROR(kmfh, PORT_GetError());
3345051Swyllys rv = KMF_ERR_SLOTNAME;
3355051Swyllys goto end;
3363089Swyllys }
3373089Swyllys
3383089Swyllys /*
3393089Swyllys * If the token was not yet initialized, return an error.
3403089Swyllys */
3413089Swyllys if (PK11_NeedUserInit(*nss_slot)) {
3425051Swyllys rv = KMF_ERR_UNINITIALIZED_TOKEN;
3433089Swyllys }
3443089Swyllys
3455051Swyllys end:
3465051Swyllys return (rv);
3473089Swyllys }
3483089Swyllys
3493089Swyllys static KMF_RETURN
nss2kmf_cert(CERTCertificate * nss_cert,KMF_X509_DER_CERT * kmf_cert)3503089Swyllys nss2kmf_cert(CERTCertificate *nss_cert, KMF_X509_DER_CERT *kmf_cert)
3513089Swyllys {
3523089Swyllys kmf_cert->kmf_private.keystore_type = KMF_KEYSTORE_NSS;
3533089Swyllys kmf_cert->kmf_private.flags = KMF_FLAG_CERT_VALID;
3543089Swyllys
3553089Swyllys kmf_cert->certificate.Length = nss_cert->derCert.len;
3563089Swyllys
3573089Swyllys if ((kmf_cert->certificate.Data = malloc(nss_cert->derCert.len)) ==
3585051Swyllys NULL) {
3593089Swyllys kmf_cert->certificate.Length = 0;
3603089Swyllys return (KMF_ERR_MEMORY);
3613089Swyllys }
3623089Swyllys (void) memcpy(kmf_cert->certificate.Data, nss_cert->derCert.data,
3635051Swyllys nss_cert->derCert.len);
3643089Swyllys if (nss_cert->nickname != NULL)
3653089Swyllys kmf_cert->kmf_private.label =
3665051Swyllys (char *)strdup(nss_cert->nickname);
3673089Swyllys return (KMF_OK);
3683089Swyllys }
3693089Swyllys
3703089Swyllys static KMF_RETURN
nss_getcert_by_label(KMF_HANDLE * kmfh,char * name,KMF_X509_DER_CERT * kmf_cert,uint32_t * num_certs,KMF_CERT_VALIDITY find_criteria)3713089Swyllys nss_getcert_by_label(KMF_HANDLE *kmfh,
3723089Swyllys char *name, KMF_X509_DER_CERT *kmf_cert,
3733089Swyllys uint32_t *num_certs, KMF_CERT_VALIDITY find_criteria)
3743089Swyllys {
3753089Swyllys KMF_RETURN rv = KMF_OK;
3763089Swyllys CERTCertificate *nss_cert;
3773089Swyllys SECCertTimeValidity validity;
3783089Swyllys
3793089Swyllys nss_cert = PK11_FindCertFromNickname(name, NULL);
3803089Swyllys if (nss_cert == NULL) {
3813089Swyllys *num_certs = 0;
3823089Swyllys SET_ERROR(kmfh, PORT_GetError());
3833089Swyllys *num_certs = 0;
3843089Swyllys return (KMF_ERR_CERT_NOT_FOUND);
3853089Swyllys } else {
3863089Swyllys *num_certs = 1;
3873089Swyllys }
3883089Swyllys
3893089Swyllys switch (find_criteria) {
3903089Swyllys case KMF_ALL_CERTS:
3913089Swyllys break;
3923089Swyllys case KMF_NONEXPIRED_CERTS:
3933089Swyllys validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(),
3945051Swyllys PR_FALSE);
3953089Swyllys if (validity != secCertTimeValid) {
3963089Swyllys /* this is an invalid cert, reject it */
3973089Swyllys *num_certs = 0;
3983089Swyllys CERT_DestroyCertificate(nss_cert);
3993089Swyllys return (KMF_OK);
4003089Swyllys }
4013089Swyllys break;
4023089Swyllys case KMF_EXPIRED_CERTS:
4033089Swyllys validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(),
4045051Swyllys PR_FALSE);
4053089Swyllys if (validity == secCertTimeValid) {
4063089Swyllys /* this is a valid cert, reject it in this case. */
4073089Swyllys *num_certs = 0;
4083089Swyllys CERT_DestroyCertificate(nss_cert);
4093089Swyllys return (KMF_OK);
4103089Swyllys }
4113089Swyllys break;
4123089Swyllys default:
4133089Swyllys return (KMF_ERR_BAD_PARAMETER);
4143089Swyllys }
4153089Swyllys
4163089Swyllys if (kmf_cert != NULL)
4173089Swyllys rv = nss2kmf_cert(nss_cert, kmf_cert);
4183089Swyllys
4193089Swyllys /* We copied the data we need, so cleanup the internal record */
4203089Swyllys CERT_DestroyCertificate(nss_cert);
4213089Swyllys
4223089Swyllys if (rv != KMF_OK)
4233089Swyllys *num_certs = 0;
4243089Swyllys
4253089Swyllys return (rv);
4263089Swyllys }
4273089Swyllys
4283089Swyllys static KMF_RETURN
nss_find_matching_certs(PK11SlotInfo * slot,char * issuer,char * subject,KMF_BIGINT * serial,CERTCertList ** certlist,KMF_CERT_VALIDITY find_criteria)4293089Swyllys nss_find_matching_certs(PK11SlotInfo *slot,
4303089Swyllys char *issuer, char *subject, KMF_BIGINT *serial,
4313089Swyllys CERTCertList **certlist, KMF_CERT_VALIDITY find_criteria)
4323089Swyllys {
4333089Swyllys KMF_RETURN rv = KMF_OK;
4343089Swyllys SECStatus ret;
4353089Swyllys CERTCertList *list;
4363089Swyllys CERTCertListNode *node;
4373089Swyllys KMF_X509_NAME issuerDN, subjectDN;
4383089Swyllys boolean_t findIssuer = FALSE;
4393089Swyllys boolean_t findSubject = FALSE;
4403089Swyllys boolean_t findSerial = FALSE;
4413089Swyllys
4423089Swyllys if (issuer != NULL && strlen(issuer)) {
4435051Swyllys rv = kmf_dn_parser(issuer, &issuerDN);
4443089Swyllys if (rv != KMF_OK)
4453089Swyllys return (rv);
4463089Swyllys findIssuer = TRUE;
4473089Swyllys }
4483089Swyllys if (subject != NULL && strlen(subject)) {
4495051Swyllys rv = kmf_dn_parser(subject, &subjectDN);
4503089Swyllys if (rv != KMF_OK)
4513089Swyllys return (rv);
4523089Swyllys findSubject = TRUE;
4533089Swyllys }
4543089Swyllys if (serial != 0 && serial->val != NULL && serial->len > 0)
4553089Swyllys findSerial = TRUE;
4563089Swyllys
4573089Swyllys list = PK11_ListCertsInSlot(slot);
4583089Swyllys if (list) {
4593089Swyllys node = CERT_LIST_HEAD(list);
4603089Swyllys while (!CERT_LIST_END(node, list)) {
4613089Swyllys KMF_X509_NAME cmpDN;
4623089Swyllys KMF_DATA der;
4633089Swyllys boolean_t match;
4643089Swyllys CERTCertListNode *freenode;
4653089Swyllys
4663089Swyllys if (findIssuer) {
4673089Swyllys der.Data = node->cert->derIssuer.data;
4683089Swyllys der.Length = node->cert->derIssuer.len;
4693089Swyllys rv = DerDecodeName(&der, &cmpDN);
4703089Swyllys if (rv == KMF_OK) {
4713089Swyllys match = !KMF_CompareRDNs(&issuerDN,
4725051Swyllys &cmpDN);
4735051Swyllys kmf_free_dn(&cmpDN);
4743089Swyllys if (!match)
4753089Swyllys goto delete_and_cont;
4763089Swyllys } else {
4773089Swyllys goto delete_and_cont;
4783089Swyllys }
4793089Swyllys }
4803089Swyllys if (findSubject) {
4813089Swyllys der.Data = node->cert->derSubject.data;
4823089Swyllys der.Length = node->cert->derSubject.len;
4833089Swyllys rv = DerDecodeName(&der, &cmpDN);
4843089Swyllys if (rv == KMF_OK) {
4853089Swyllys match = !KMF_CompareRDNs(&subjectDN,
4865051Swyllys &cmpDN);
4875051Swyllys kmf_free_dn(&cmpDN);
4883089Swyllys if (!match)
4893089Swyllys goto delete_and_cont;
4903089Swyllys } else {
4913089Swyllys goto delete_and_cont;
4923089Swyllys }
4933089Swyllys }
4943089Swyllys if (findSerial) {
4953089Swyllys SECItem *sernum;
4963089Swyllys
4973089Swyllys sernum = &node->cert->serialNumber;
4983089Swyllys
4993089Swyllys if (serial->len != sernum->len)
5003089Swyllys goto delete_and_cont;
5013089Swyllys
5023089Swyllys if (memcmp(sernum->data, serial->val,
5035051Swyllys serial->len))
5043089Swyllys goto delete_and_cont;
5053089Swyllys }
5063089Swyllys
5073089Swyllys /* select the certs using find criteria */
5083089Swyllys switch (find_criteria) {
5093089Swyllys case KMF_ALL_CERTS:
5103089Swyllys break;
5113089Swyllys case KMF_NONEXPIRED_CERTS:
5123089Swyllys ret = CERT_CertTimesValid(node->cert);
5133089Swyllys if (ret == SECFailure) {
5143089Swyllys /* this is an invalid cert */
5153089Swyllys goto skip;
5163089Swyllys }
5173089Swyllys break;
5183089Swyllys
5193089Swyllys case KMF_EXPIRED_CERTS:
5203089Swyllys ret = CERT_CertTimesValid(node->cert);
5213089Swyllys if (ret != SECFailure) {
5223089Swyllys /* this is a valid cert */
5233089Swyllys goto skip;
5243089Swyllys }
5253089Swyllys break;
5263089Swyllys }
5273089Swyllys skip:
5283089Swyllys node = CERT_LIST_NEXT(node);
5293089Swyllys continue;
5303089Swyllys delete_and_cont:
5313089Swyllys freenode = node;
5323089Swyllys node = CERT_LIST_NEXT(node);
5333089Swyllys CERT_RemoveCertListNode(freenode);
5343089Swyllys }
5353089Swyllys }
5363089Swyllys
5373089Swyllys if (rv == KMF_OK && certlist != NULL) {
5383089Swyllys *certlist = list;
5393089Swyllys } else {
5403089Swyllys CERT_DestroyCertList(list);
5413089Swyllys }
5423089Swyllys return (rv);
5433089Swyllys }
5443089Swyllys
5453089Swyllys static KMF_RETURN
convertCertList(void * kmfhandle,CERTCertList * nsscerts,KMF_X509_DER_CERT * kmfcerts,uint32_t * numcerts)5463089Swyllys convertCertList(void *kmfhandle,
5473089Swyllys CERTCertList *nsscerts, KMF_X509_DER_CERT *kmfcerts,
5483089Swyllys uint32_t *numcerts)
5493089Swyllys {
5503089Swyllys KMF_RETURN rv = KMF_OK;
5513089Swyllys CERTCertListNode *node;
5524025Swyllys uint32_t maxcerts = *numcerts;
5533089Swyllys
5545051Swyllys maxcerts = *numcerts;
5555051Swyllys if (maxcerts == 0)
5565051Swyllys maxcerts = 0xFFFFFFFF;
5575051Swyllys
5583089Swyllys *numcerts = 0;
5593089Swyllys
5605051Swyllys /*
5615051Swyllys * Don't copy more certs than the caller wanted.
5625051Swyllys */
5633089Swyllys for (node = CERT_LIST_HEAD(nsscerts);
5645051Swyllys !CERT_LIST_END(node, nsscerts) && rv == KMF_OK &&
5655051Swyllys (*numcerts) < maxcerts;
5665051Swyllys node = CERT_LIST_NEXT(node), (*numcerts)++) {
5673089Swyllys if (kmfcerts != NULL)
5683089Swyllys rv = nss2kmf_cert(node->cert, &kmfcerts[*numcerts]);
5693089Swyllys }
5703089Swyllys
5713089Swyllys /*
5723089Swyllys * If we failed, delete any certs allocated so far.
5733089Swyllys */
5743089Swyllys if (rv != KMF_OK) {
5753089Swyllys int i;
5763089Swyllys for (i = 0; i < *numcerts; i++)
5775051Swyllys kmf_free_kmf_cert(kmfhandle, &kmfcerts[i]);
5785051Swyllys
5794025Swyllys *numcerts = 0;
5803089Swyllys }
5813089Swyllys return (rv);
5823089Swyllys }
5833089Swyllys
5843089Swyllys KMF_RETURN
NSS_FindCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)5855051Swyllys NSS_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5863089Swyllys {
5873089Swyllys KMF_RETURN rv = KMF_OK;
5883089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5893089Swyllys PK11SlotInfo *nss_slot = NULL;
5903089Swyllys CERTCertList *certlist = NULL;
5914025Swyllys uint32_t maxcerts;
5925051Swyllys uint32_t *num_certs;
5935051Swyllys KMF_X509_DER_CERT *kmfcerts = NULL;
5945051Swyllys char *certlabel = NULL;
5955051Swyllys char *issuer = NULL;
5965051Swyllys char *subject = NULL;
5975051Swyllys KMF_BIGINT *serial = NULL;
5985051Swyllys KMF_CERT_VALIDITY validity;
5995051Swyllys
6005051Swyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
6015051Swyllys return (KMF_ERR_BAD_PARAMETER);
6025051Swyllys }
6035051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
6045051Swyllys if (rv != KMF_OK)
6053089Swyllys return (rv);
6065051Swyllys
6075051Swyllys num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
6085051Swyllys if (num_certs == NULL)
6095051Swyllys return (KMF_ERR_BAD_PARAMETER);
6105051Swyllys
6115051Swyllys maxcerts = *num_certs;
6125051Swyllys if (maxcerts == 0)
6134025Swyllys maxcerts = 0xFFFFFFFF;
6143089Swyllys *num_certs = 0;
6155051Swyllys
6165051Swyllys /* Get the optional returned certificate list */
6175051Swyllys kmfcerts = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, numattr);
6185051Swyllys
6195051Swyllys /* Get optional search criteria attributes */
6205051Swyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
6215051Swyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
6225051Swyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
6235051Swyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
6245051Swyllys
6255051Swyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
6265051Swyllys &validity, NULL);
6275051Swyllys if (rv != KMF_OK) {
6285051Swyllys validity = KMF_ALL_CERTS;
6295051Swyllys rv = KMF_OK;
6305051Swyllys }
6315051Swyllys
6325051Swyllys if (certlabel != NULL) {
6334025Swyllys /* This will only find 1 certificate */
6345051Swyllys rv = nss_getcert_by_label(kmfh, certlabel, kmfcerts, num_certs,
6355051Swyllys validity);
6363089Swyllys } else {
6374025Swyllys /*
6384025Swyllys * Build a list of matching certs.
6394025Swyllys */
6405051Swyllys rv = nss_find_matching_certs(nss_slot, issuer, subject, serial,
6415051Swyllys &certlist, validity);
6423089Swyllys
6434025Swyllys /*
6444025Swyllys * If the caller supplied a pointer to storage for
6454025Swyllys * a list of certs, convert up to 'maxcerts' of the
6464025Swyllys * matching certs.
6474025Swyllys */
6483089Swyllys if (rv == KMF_OK && certlist != NULL) {
6495051Swyllys rv = convertCertList(handle, certlist, kmfcerts,
6505051Swyllys &maxcerts);
6513089Swyllys CERT_DestroyCertList(certlist);
6524025Swyllys if (rv == KMF_OK)
6534025Swyllys *num_certs = maxcerts;
6543089Swyllys }
6553089Swyllys }
6563089Swyllys
6573089Swyllys if (nss_slot != NULL) {
6583089Swyllys PK11_FreeSlot(nss_slot);
6593089Swyllys }
6603089Swyllys
6613089Swyllys if (rv == KMF_OK && *num_certs == 0)
6623089Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
6633089Swyllys
6643089Swyllys return (rv);
6653089Swyllys }
6663089Swyllys
6673089Swyllys void
6683089Swyllys /*ARGSUSED*/
NSS_FreeKMFCert(KMF_HANDLE_T handle,KMF_X509_DER_CERT * kmf_cert)6693089Swyllys NSS_FreeKMFCert(KMF_HANDLE_T handle,
6703089Swyllys KMF_X509_DER_CERT *kmf_cert)
6713089Swyllys {
6723089Swyllys if (kmf_cert != NULL) {
6733089Swyllys if (kmf_cert->certificate.Data != NULL) {
6743089Swyllys free(kmf_cert->certificate.Data);
6753089Swyllys kmf_cert->certificate.Data = NULL;
6763089Swyllys kmf_cert->certificate.Length = 0;
6773089Swyllys }
6783089Swyllys if (kmf_cert->kmf_private.label != NULL) {
6793089Swyllys free(kmf_cert->kmf_private.label);
6803089Swyllys kmf_cert->kmf_private.label = NULL;
6813089Swyllys }
6823089Swyllys }
6833089Swyllys }
6843089Swyllys
6853089Swyllys KMF_RETURN
NSS_DeleteCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)6865051Swyllys NSS_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
6873089Swyllys {
6883089Swyllys KMF_RETURN rv = KMF_OK;
6893089Swyllys int nssrv;
6903089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
6913089Swyllys CERTCertificate *cert = NULL;
6923089Swyllys PK11SlotInfo *nss_slot = NULL;
6935051Swyllys char *certlabel = NULL;
6945051Swyllys char *issuer = NULL;
6955051Swyllys char *subject = NULL;
6965051Swyllys KMF_BIGINT *serial = NULL;
6975051Swyllys KMF_CERT_VALIDITY validity;
6985051Swyllys
6995051Swyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
7003089Swyllys return (KMF_ERR_BAD_PARAMETER);
7013089Swyllys }
7025051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
7035051Swyllys if (rv != KMF_OK)
7045051Swyllys return (rv);
7055051Swyllys
7065051Swyllys /* Get the search criteria attributes. They are all optional. */
7075051Swyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
7085051Swyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
7095051Swyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
7105051Swyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
7115051Swyllys
7125051Swyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
7135051Swyllys &validity, NULL);
7143089Swyllys if (rv != KMF_OK) {
7155051Swyllys validity = KMF_ALL_CERTS;
7165051Swyllys rv = KMF_OK;
7173089Swyllys }
7183089Swyllys
7195051Swyllys /* Start finding the matched certificates and delete them. */
7205051Swyllys if (certlabel != NULL) {
7215051Swyllys cert = PK11_FindCertFromNickname(certlabel, NULL);
7223089Swyllys if (cert == NULL) {
7233089Swyllys return (KMF_ERR_CERT_NOT_FOUND);
7243089Swyllys }
7253089Swyllys
7265051Swyllys switch (validity) {
7273089Swyllys case KMF_ALL_CERTS:
7283089Swyllys break;
7293089Swyllys case KMF_NONEXPIRED_CERTS:
7303089Swyllys nssrv = CERT_CertTimesValid(cert);
7313089Swyllys if (nssrv == SECFailure) {
7323089Swyllys /* this is an invalid cert - skip it */
7333089Swyllys goto out;
7343089Swyllys }
7353089Swyllys break;
7363089Swyllys case KMF_EXPIRED_CERTS:
7373089Swyllys nssrv = CERT_CertTimesValid(cert);
7383089Swyllys if (nssrv != SECFailure) {
7393089Swyllys /* this is a valid cert - skip it */
7403089Swyllys goto out;
7413089Swyllys }
7423089Swyllys break;
7433089Swyllys }
7443089Swyllys /* delete it from database */
7453089Swyllys nssrv = SEC_DeletePermCertificate(cert);
7463089Swyllys if (nssrv) {
7473089Swyllys SET_ERROR(kmfh, nssrv);
7483089Swyllys rv = KMF_ERR_INTERNAL;
7493089Swyllys }
7503089Swyllys } else {
7513089Swyllys CERTCertListNode *node;
7523089Swyllys CERTCertList *certlist = NULL;
7533089Swyllys
7545051Swyllys rv = nss_find_matching_certs(nss_slot, issuer, subject, serial,
7555051Swyllys &certlist, validity);
7563089Swyllys
7573089Swyllys for (node = CERT_LIST_HEAD(certlist);
7585051Swyllys !CERT_LIST_END(node, certlist) && rv == KMF_OK;
7595051Swyllys node = CERT_LIST_NEXT(node)) {
7603089Swyllys
7613089Swyllys nssrv = SEC_DeletePermCertificate(node->cert);
7623089Swyllys if (nssrv) {
7633089Swyllys SET_ERROR(kmfh, nssrv);
7643089Swyllys rv = KMF_ERR_INTERNAL;
7653089Swyllys }
7663089Swyllys }
7673089Swyllys
7683089Swyllys if (rv == KMF_OK && certlist != NULL) {
7693089Swyllys CERT_DestroyCertList(certlist);
7703089Swyllys } else if (rv == KMF_OK && certlist == NULL) {
7713089Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
7723089Swyllys }
7733089Swyllys }
7743089Swyllys out:
7753089Swyllys if (nss_slot != NULL) {
7763089Swyllys PK11_FreeSlot(nss_slot);
7773089Swyllys }
7783089Swyllys
7793089Swyllys if (cert != NULL) {
7803089Swyllys CERT_DestroyCertificate(cert);
7813089Swyllys }
7823089Swyllys
7833089Swyllys return (rv);
7843089Swyllys }
7853089Swyllys
7863089Swyllys static void
InitRandom(char * filename)7873089Swyllys InitRandom(char *filename)
7883089Swyllys {
7893089Swyllys char buf[2048];
7903089Swyllys int fd;
7913089Swyllys PRInt32 count;
7923089Swyllys
7933089Swyllys fd = open(filename, O_RDONLY);
7943089Swyllys if (!fd)
7953089Swyllys return;
7963089Swyllys
7973089Swyllys count = read(fd, buf, sizeof (buf));
7983089Swyllys if (count > 0) {
79911411SSurya.Prakki@Sun.COM (void) PK11_RandomUpdate(buf, count);
8003089Swyllys }
8013089Swyllys
8023089Swyllys (void) close(fd);
8033089Swyllys }
8043089Swyllys
8053089Swyllys KMF_RETURN
NSS_CreateKeypair(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)8063089Swyllys NSS_CreateKeypair(KMF_HANDLE_T handle,
8075051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
8083089Swyllys {
8093089Swyllys KMF_RETURN rv = KMF_OK;
8103089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
8115051Swyllys PK11RSAGenParams rsaparams;
8125051Swyllys void *nssparams;
8133089Swyllys CK_MECHANISM_TYPE mechanism;
8143089Swyllys ulong_t publicExponent = 0x010001;
8153089Swyllys PK11SlotInfo *nss_slot = NULL;
8163089Swyllys SECKEYPrivateKey *NSSprivkey = NULL;
8173089Swyllys SECKEYPublicKey *NSSpubkey = NULL;
818*11973Swyllys.ingersoll@sun.com SECKEYECParams *ecparams = NULL;
8193089Swyllys PQGParams *pqgParams = NULL;
8205051Swyllys KMF_CREDENTIAL cred;
8215051Swyllys boolean_t storekey = TRUE;
8225051Swyllys uint32_t keylen = 1024, len;
8235051Swyllys uint32_t keylen_size = sizeof (uint32_t);
8245051Swyllys KMF_KEY_ALG keytype = KMF_RSA;
8255051Swyllys KMF_KEY_HANDLE *pubkey = NULL;
8265051Swyllys KMF_KEY_HANDLE *privkey = NULL;
8275051Swyllys char *keylabel = NULL;
8285051Swyllys
8295051Swyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
8303089Swyllys return (KMF_ERR_BAD_PARAMETER);
8313089Swyllys }
8325051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
8335051Swyllys if (rv != KMF_OK) {
8345051Swyllys return (rv);
8355051Swyllys }
8365051Swyllys
8375051Swyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
8385051Swyllys (void *)&cred, NULL);
8395051Swyllys if (rv != KMF_OK)
8405051Swyllys return (rv);
8415051Swyllys
8425051Swyllys rv = nss_authenticate(handle, nss_slot, &cred);
8433089Swyllys if (rv != KMF_OK) {
8443089Swyllys return (rv);
8453089Swyllys }
8463089Swyllys
8475051Swyllys /* "storekey" is optional. Default is TRUE */
8485051Swyllys (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
8495051Swyllys &storekey, NULL);
8505051Swyllys
8515051Swyllys /* keytype is optional. KMF_RSA is default */
8525051Swyllys (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
8535051Swyllys (void *)&keytype, NULL);
8545051Swyllys
8555051Swyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
8565051Swyllys &keylen, &keylen_size);
8575051Swyllys if (rv == KMF_ERR_ATTR_NOT_FOUND)
8585051Swyllys /* Default keylen = 1024 */
8595051Swyllys rv = KMF_OK;
8605051Swyllys else if (rv != KMF_OK)
8615051Swyllys return (KMF_ERR_BAD_PARAMETER);
8625051Swyllys
8635051Swyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
8645051Swyllys privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
8655051Swyllys if (pubkey == NULL || privkey == NULL)
8665051Swyllys return (KMF_ERR_BAD_PARAMETER);
8675051Swyllys
8685051Swyllys (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
8695051Swyllys (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
8705051Swyllys
8715051Swyllys rv = kmf_get_attr(KMF_KEYLABEL_ATTR, attrlist, numattr, NULL, &len);
8725051Swyllys if (rv == KMF_OK && len > 0) {
8735051Swyllys keylabel = malloc(len + 1);
8745051Swyllys if (keylabel == NULL)
8755051Swyllys return (KMF_ERR_MEMORY);
8765051Swyllys /* Now fill in the label value */
8775051Swyllys (void) memset(keylabel, 0, len + 1);
8785051Swyllys rv = kmf_get_attr(KMF_KEYLABEL_ATTR, attrlist, numattr,
8795051Swyllys keylabel, NULL);
8805051Swyllys if (rv != KMF_OK) {
8815051Swyllys free(keylabel);
8825051Swyllys goto cleanup;
8835051Swyllys }
8843089Swyllys }
8853089Swyllys
8863089Swyllys /* Get some random bits */
8873089Swyllys InitRandom("/dev/urandom");
8885051Swyllys if (keytype == KMF_RSA) {
8895051Swyllys KMF_BIGINT rsaexp;
8905051Swyllys
8915051Swyllys rsaparams.keySizeInBits = keylen;
8923089Swyllys /*
8933089Swyllys * NSS only allows for a 4 byte exponent.
8943089Swyllys * Ignore the exponent parameter if it is too big.
8953089Swyllys */
8965051Swyllys if ((rv = kmf_get_attr(KMF_RSAEXP_ATTR, attrlist, numattr,
8975051Swyllys &rsaexp, NULL)) == KMF_OK) {
8985051Swyllys if (rsaexp.len > 0 &&
8995051Swyllys rsaexp.len <= sizeof (publicExponent) &&
9005051Swyllys rsaexp.val != NULL) {
9015051Swyllys (void) memcpy(&publicExponent, rsaexp.val,
9025051Swyllys rsaexp.len);
9035051Swyllys }
9043089Swyllys }
9053089Swyllys rsaparams.pe = publicExponent;
9063089Swyllys mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
9073089Swyllys nssparams = &rsaparams;
9085051Swyllys } else if (keytype == KMF_DSA) {
9093089Swyllys PQGVerify *pqgVerify = NULL;
9103089Swyllys int ks;
9113089Swyllys SECStatus nssrv, passed;
9123089Swyllys
9133089Swyllys mechanism = CKM_DSA_KEY_PAIR_GEN;
9143089Swyllys
9155051Swyllys ks = PQG_PBITS_TO_INDEX(keylen);
9163089Swyllys nssrv = PK11_PQG_ParamGen(ks, &pqgParams, &pqgVerify);
9173089Swyllys if (nssrv != SECSuccess) {
9183089Swyllys SET_ERROR(kmfh, rv);
9193089Swyllys PK11_PQG_DestroyVerify(pqgVerify);
9203089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
9213089Swyllys goto cleanup;
9223089Swyllys }
9233089Swyllys
9243089Swyllys nssrv = PK11_PQG_VerifyParams(pqgParams, pqgVerify, &passed);
9253089Swyllys if (nssrv != SECSuccess || passed != SECSuccess) {
9263089Swyllys SET_ERROR(kmfh, rv);
9273089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
9283089Swyllys }
9293089Swyllys
9303089Swyllys PK11_PQG_DestroyVerify(pqgVerify);
9313089Swyllys
9323089Swyllys if (rv != KMF_OK) {
9333089Swyllys SET_ERROR(kmfh, PORT_GetError());
9343089Swyllys goto cleanup;
9353089Swyllys }
9363089Swyllys
9373089Swyllys nssparams = pqgParams;
938*11973Swyllys.ingersoll@sun.com } else if (keytype == KMF_ECDSA) {
939*11973Swyllys.ingersoll@sun.com KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
940*11973Swyllys.ingersoll@sun.com attrlist, numattr);
941*11973Swyllys.ingersoll@sun.com if (eccoid == NULL)
942*11973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_PARAMETER);
943*11973Swyllys.ingersoll@sun.com
944*11973Swyllys.ingersoll@sun.com ecparams = SECITEM_AllocItem(NULL, NULL, (eccoid->Length));
945*11973Swyllys.ingersoll@sun.com if (!ecparams)
946*11973Swyllys.ingersoll@sun.com return (KMF_ERR_MEMORY);
947*11973Swyllys.ingersoll@sun.com
948*11973Swyllys.ingersoll@sun.com (void) memcpy(ecparams->data, eccoid->Data, eccoid->Length);
949*11973Swyllys.ingersoll@sun.com
950*11973Swyllys.ingersoll@sun.com mechanism = CKM_EC_KEY_PAIR_GEN;
951*11973Swyllys.ingersoll@sun.com nssparams = ecparams;
9523089Swyllys } else {
9533089Swyllys rv = KMF_ERR_BAD_PARAMETER;
9543089Swyllys goto cleanup;
9553089Swyllys }
9563089Swyllys
9575051Swyllys NSSprivkey = PK11_GenerateKeyPair(nss_slot, mechanism, nssparams,
9585051Swyllys &NSSpubkey,
9595051Swyllys storekey, /* isPermanent */
9605051Swyllys PR_TRUE, /* isSensitive */
9615051Swyllys (void *)cred.cred);
9623089Swyllys
9633089Swyllys if (NSSprivkey == NULL || NSSpubkey == NULL) {
9643089Swyllys SET_ERROR(kmfh, PORT_GetError());
9653089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
9663089Swyllys } else {
9675051Swyllys if (keylabel != NULL && strlen(keylabel)) {
9683089Swyllys (void) PK11_SetPrivateKeyNickname(NSSprivkey,
9695051Swyllys keylabel);
9705051Swyllys (void) PK11_SetPublicKeyNickname(NSSpubkey, keylabel);
9713089Swyllys }
9723089Swyllys /* Now, convert it to a KMF_KEY object for the framework */
9735051Swyllys privkey->kstype = KMF_KEYSTORE_NSS;
9745051Swyllys privkey->keyalg = keytype;
9755051Swyllys privkey->keyclass = KMF_ASYM_PRI;
9765051Swyllys privkey->keylabel = PK11_GetPrivateKeyNickname(NSSprivkey);
9775051Swyllys privkey->keyp = (void *)NSSprivkey;
9785051Swyllys
9795051Swyllys pubkey->kstype = KMF_KEYSTORE_NSS;
9805051Swyllys pubkey->keyalg = keytype;
9815051Swyllys pubkey->keyp = (void *)NSSpubkey;
9825051Swyllys pubkey->keyclass = KMF_ASYM_PUB;
9835051Swyllys pubkey->keylabel = PK11_GetPublicKeyNickname(NSSpubkey);
9845051Swyllys
9853089Swyllys rv = KMF_OK;
9863089Swyllys }
9873089Swyllys cleanup:
9883089Swyllys if (rv != KMF_OK) {
9893089Swyllys if (NSSpubkey)
99011411SSurya.Prakki@Sun.COM (void) PK11_DeleteTokenPublicKey(NSSpubkey);
9913089Swyllys if (NSSprivkey)
99211411SSurya.Prakki@Sun.COM (void) PK11_DeleteTokenPrivateKey(NSSprivkey, PR_TRUE);
9933089Swyllys
9943089Swyllys privkey->keyp = NULL;
9953089Swyllys pubkey->keyp = NULL;
9963089Swyllys }
9973089Swyllys
9985051Swyllys if (keylabel)
9995051Swyllys free(keylabel);
10005051Swyllys
10013089Swyllys if (pqgParams != NULL)
10023089Swyllys PK11_PQG_DestroyParams(pqgParams);
10033089Swyllys
1004*11973Swyllys.ingersoll@sun.com if (ecparams != NULL)
1005*11973Swyllys.ingersoll@sun.com SECITEM_FreeItem(ecparams, PR_TRUE);
1006*11973Swyllys.ingersoll@sun.com
10073089Swyllys if (nss_slot != NULL)
10083089Swyllys PK11_FreeSlot(nss_slot);
10093089Swyllys
10103089Swyllys return (rv);
10113089Swyllys }
10123089Swyllys
10133089Swyllys KMF_RETURN
NSS_SignData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * AlgOID,KMF_DATA * tobesigned,KMF_DATA * output)10143089Swyllys NSS_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
10155051Swyllys KMF_OID *AlgOID, KMF_DATA *tobesigned,
10165051Swyllys KMF_DATA *output)
10173089Swyllys {
10183089Swyllys KMF_RETURN ret = KMF_OK;
10195051Swyllys KMF_ALGORITHM_INDEX AlgId;
10203089Swyllys SECOidTag signAlgTag;
10213089Swyllys SECKEYPrivateKey *NSSprivkey = NULL;
10223089Swyllys SECStatus rv;
10233089Swyllys SECItem signed_data;
10243089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
10253089Swyllys
10263089Swyllys signed_data.data = 0;
10273089Swyllys if (key == NULL || AlgOID == NULL ||
10283089Swyllys tobesigned == NULL || output == NULL ||
10293089Swyllys tobesigned->Data == NULL ||
10303089Swyllys output->Data == NULL)
10313089Swyllys return (KMF_ERR_BAD_PARAMETER);
10323089Swyllys
10333089Swyllys /* Map the OID to a NSS algorithm */
10345051Swyllys AlgId = x509_algoid_to_algid(AlgOID);
10353089Swyllys if (AlgId == KMF_ALGID_NONE)
10363089Swyllys return (KMF_ERR_BAD_PARAMETER);
10373089Swyllys
10383089Swyllys NSSprivkey = (SECKEYPrivateKey *)key->keyp;
10393089Swyllys
10403089Swyllys if (AlgId == KMF_ALGID_MD5WithRSA)
10413089Swyllys signAlgTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
10423089Swyllys else if (AlgId == KMF_ALGID_MD2WithRSA)
10433089Swyllys signAlgTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
10443089Swyllys else if (AlgId == KMF_ALGID_SHA1WithRSA)
10453089Swyllys signAlgTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
1046*11973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA256WithRSA)
1047*11973Swyllys.ingersoll@sun.com signAlgTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
1048*11973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA384WithRSA)
1049*11973Swyllys.ingersoll@sun.com signAlgTag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
1050*11973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA512WithRSA)
1051*11973Swyllys.ingersoll@sun.com signAlgTag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
10523089Swyllys else if (AlgId == KMF_ALGID_SHA1WithDSA)
10533089Swyllys signAlgTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
1054*11973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA1WithECDSA || AlgId == KMF_ALGID_ECDSA)
1055*11973Swyllys.ingersoll@sun.com signAlgTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
1056*11973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA256WithECDSA)
1057*11973Swyllys.ingersoll@sun.com signAlgTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE;
1058*11973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA384WithECDSA)
1059*11973Swyllys.ingersoll@sun.com signAlgTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE;
1060*11973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA512WithECDSA)
1061*11973Swyllys.ingersoll@sun.com signAlgTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE;
1062*11973Swyllys.ingersoll@sun.com else /* NSS does not support DSA with SHA2 hashes (FIPS 186-3) */
10633089Swyllys return (KMF_ERR_BAD_PARAMETER);
10643089Swyllys
10653089Swyllys rv = SEC_SignData(&signed_data, tobesigned->Data,
10663089Swyllys tobesigned->Length, NSSprivkey, signAlgTag);
10673089Swyllys
10683089Swyllys if (rv != 0) {
10693089Swyllys SET_ERROR(kmfh, rv);
10703089Swyllys return (KMF_ERR_INTERNAL);
10713089Swyllys }
10723089Swyllys
10733089Swyllys if (signed_data.len <= output->Length) {
10743089Swyllys (void) memcpy(output->Data, signed_data.data, signed_data.len);
10753089Swyllys output->Length = signed_data.len;
10763089Swyllys } else {
10773089Swyllys output->Length = 0;
10783089Swyllys ret = KMF_ERR_BAD_PARAMETER;
10793089Swyllys }
10803089Swyllys free(signed_data.data);
10813089Swyllys
10823089Swyllys return (ret);
10833089Swyllys }
10843089Swyllys
10853089Swyllys KMF_RETURN
NSS_EncodePubKeyData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * keyp,KMF_DATA * encoded)10863089Swyllys NSS_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp,
10873089Swyllys KMF_DATA *encoded)
10883089Swyllys {
10893089Swyllys KMF_RETURN ret = KMF_OK;
10903089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
10913089Swyllys SECItem *rvitem;
10923089Swyllys CERTSubjectPublicKeyInfo *spki = NULL;
10933089Swyllys
10943089Swyllys if (keyp == NULL || encoded == NULL || keyp->keyp == NULL)
10953089Swyllys return (KMF_ERR_BAD_PARAMETER);
10963089Swyllys
10973089Swyllys spki = SECKEY_CreateSubjectPublicKeyInfo(keyp->keyp);
10983089Swyllys if (spki == NULL) {
10993089Swyllys SET_ERROR(kmfh, PORT_GetError());
11003089Swyllys return (KMF_ERR_MEMORY);
11013089Swyllys }
11023089Swyllys
11033089Swyllys rvitem = SEC_ASN1EncodeItem(NULL, NULL, spki,
11045051Swyllys CERT_SubjectPublicKeyInfoTemplate);
11053089Swyllys if (rvitem != NULL) {
11063089Swyllys encoded->Data = malloc(rvitem->len);
11073089Swyllys if (encoded->Data == NULL) {
11083089Swyllys ret = KMF_ERR_MEMORY;
11093089Swyllys } else {
11103089Swyllys (void) memcpy(encoded->Data, rvitem->data, rvitem->len);
11113089Swyllys encoded->Length = rvitem->len;
11123089Swyllys }
11133089Swyllys SECITEM_FreeItem(rvitem, TRUE);
11143089Swyllys } else {
11153089Swyllys SET_ERROR(kmfh, PORT_GetError());
11163089Swyllys encoded->Data = NULL;
11173089Swyllys encoded->Length = 0;
11183089Swyllys ret = KMF_ERR_ENCODING;
11193089Swyllys }
11203089Swyllys SECKEY_DestroySubjectPublicKeyInfo(spki);
11213089Swyllys
11223089Swyllys return (ret);
11233089Swyllys }
11243089Swyllys
11253089Swyllys KMF_RETURN
NSS_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)11265051Swyllys NSS_DeleteKey(KMF_HANDLE_T handle,
11275051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
11283089Swyllys {
11293089Swyllys KMF_RETURN rv = KMF_OK;
11303089Swyllys PK11SlotInfo *nss_slot = NULL;
11315051Swyllys KMF_KEY_HANDLE *key;
11325051Swyllys KMF_CREDENTIAL cred;
11335051Swyllys boolean_t delete_token = B_TRUE;
11345051Swyllys
11355051Swyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
11365051Swyllys return (KMF_ERR_BAD_PARAMETER);
11375051Swyllys }
11383089Swyllys /*
11393089Swyllys * "delete_token" means to clear it from the token storage as well
11403089Swyllys * as from memory.
11413089Swyllys */
11425051Swyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
11433089Swyllys if (key == NULL || key->keyp == NULL)
11443089Swyllys return (KMF_ERR_BAD_PARAMETER);
11453089Swyllys
11465051Swyllys rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
11475051Swyllys (void *)&delete_token, NULL);
11485051Swyllys if (rv != KMF_OK)
11495051Swyllys /* "delete_token" is optional. Default is TRUE */
11505051Swyllys rv = KMF_OK;
11515051Swyllys
11523089Swyllys if (delete_token) {
11533089Swyllys SECStatus nssrv = SECSuccess;
11543089Swyllys if (key->keyclass != KMF_ASYM_PUB &&
11555051Swyllys key->keyclass != KMF_ASYM_PRI &&
11565051Swyllys key->keyclass != KMF_SYMMETRIC)
11573089Swyllys return (KMF_ERR_BAD_KEY_CLASS);
11583089Swyllys
11595051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
11603089Swyllys if (rv != KMF_OK) {
11613089Swyllys return (rv);
11623089Swyllys }
11635051Swyllys
11645051Swyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
11655051Swyllys (void *)&cred, NULL);
11665051Swyllys if (rv != KMF_OK)
11675051Swyllys return (KMF_ERR_BAD_PARAMETER);
11685051Swyllys
11695051Swyllys rv = nss_authenticate(handle, nss_slot, &cred);
11703089Swyllys if (rv != KMF_OK) {
11713089Swyllys return (rv);
11723089Swyllys }
11733089Swyllys
11743089Swyllys if (key->keyclass == KMF_ASYM_PUB) {
11753089Swyllys nssrv = PK11_DeleteTokenPublicKey(
11765051Swyllys (SECKEYPublicKey *)key->keyp);
11773089Swyllys } else if (key->keyclass == KMF_ASYM_PRI) {
11783089Swyllys nssrv = PK11_DeleteTokenPrivateKey(
11795051Swyllys (SECKEYPrivateKey *)key->keyp, PR_TRUE);
11803089Swyllys } else if (key->keyclass == KMF_SYMMETRIC) {
11813089Swyllys nssrv = PK11_DeleteTokenSymKey(
11825051Swyllys (PK11SymKey *) key->keyp);
11833089Swyllys if (nssrv == SECSuccess)
11845051Swyllys PK11_FreeSymKey((PK11SymKey *) key->keyp);
11853089Swyllys }
11863089Swyllys if (nssrv != SECSuccess) {
11873089Swyllys SET_ERROR(handle, PORT_GetError());
11883089Swyllys rv = KMF_ERR_INTERNAL;
11893089Swyllys }
11903089Swyllys } else {
11913089Swyllys if (key->keyclass == KMF_ASYM_PUB) {
11923089Swyllys SECKEY_DestroyPublicKey((SECKEYPublicKey *)key->keyp);
11933089Swyllys } else if (key->keyclass == KMF_ASYM_PRI) {
11943089Swyllys SECKEY_DestroyPrivateKey((SECKEYPrivateKey *)key->keyp);
11953089Swyllys } else if (key->keyclass == KMF_SYMMETRIC) {
11963089Swyllys PK11_FreeSymKey((PK11SymKey *) key->keyp);
11973089Swyllys } else {
11983089Swyllys return (KMF_ERR_BAD_KEY_CLASS);
11993089Swyllys }
12003089Swyllys }
12013089Swyllys key->keyp = NULL;
12023089Swyllys
12033089Swyllys return (rv);
12043089Swyllys }
12053089Swyllys
12063089Swyllys KMF_RETURN
NSS_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)12073089Swyllys NSS_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
12083089Swyllys {
12093089Swyllys KMF_RETURN ret = KMF_OK;
12103089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
12113089Swyllys char *str;
12123089Swyllys
12133089Swyllys /* Get the error string in the default language */
12143089Swyllys str = (char *)PR_ErrorToName((PRErrorCode)kmfh->lasterr.errcode);
12153089Swyllys
12163089Swyllys if (str != NULL) {
12173089Swyllys *msgstr = (char *)strdup(str);
12183089Swyllys if ((*msgstr) == NULL)
12193089Swyllys ret = KMF_ERR_MEMORY;
12203089Swyllys } else {
12213089Swyllys *msgstr = NULL;
12223089Swyllys }
12233089Swyllys
12243089Swyllys return (ret);
12253089Swyllys }
12263089Swyllys
12273089Swyllys KMF_RETURN
NSS_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)12285051Swyllys NSS_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
12293089Swyllys {
12303089Swyllys KMF_RETURN rv = KMF_OK;
12313089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
12325051Swyllys PK11SlotInfo *nss_slot = NULL;
12335051Swyllys KMF_CREDENTIAL cred;
12345051Swyllys KMF_KEY_HANDLE *key = NULL;
12355051Swyllys KMF_DATA *cert = NULL;
12365051Swyllys CERTCertificate *nss_cert = NULL;
12375051Swyllys SECKEYPrivateKey* privkey = NULL;
12385051Swyllys
12395051Swyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
12405051Swyllys return (KMF_ERR_BAD_PARAMETER);
12413089Swyllys }
12423089Swyllys
12435051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
12445051Swyllys if (rv != KMF_OK)
12455051Swyllys return (rv);
12465051Swyllys
12475051Swyllys /* Get the credential */
12485051Swyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
12495051Swyllys (void *)&cred, NULL);
12505051Swyllys if (rv != KMF_OK)
12515051Swyllys return (KMF_ERR_BAD_PARAMETER);
12525051Swyllys rv = nss_authenticate(handle, nss_slot, &cred);
12535051Swyllys if (rv != KMF_OK)
12543089Swyllys return (rv);
12555051Swyllys
12565051Swyllys /* Get the key handle */
12575051Swyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
12585051Swyllys if (key == NULL)
12595051Swyllys return (KMF_ERR_BAD_PARAMETER);
12605051Swyllys
12615051Swyllys /* Get the cert data and decode it */
12625051Swyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
12635051Swyllys if (cert == NULL || cert->Data == NULL)
12645051Swyllys return (KMF_ERR_BAD_PARAMETER);
12655051Swyllys
12665051Swyllys nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data,
12675051Swyllys cert->Length);
12683089Swyllys if (nss_cert == NULL) {
12693089Swyllys SET_ERROR(kmfh, PORT_GetError());
12703089Swyllys return (KMF_ERR_BAD_CERT_FORMAT);
12713089Swyllys }
12723089Swyllys
12733089Swyllys privkey = PK11_FindPrivateKeyFromCert(nss_slot, nss_cert, NULL);
12743089Swyllys if (privkey == NULL) {
12753089Swyllys SET_ERROR(kmfh, PORT_GetError());
12763089Swyllys return (KMF_ERR_KEY_NOT_FOUND);
12773089Swyllys }
12783089Swyllys
12793089Swyllys key->kstype = KMF_KEYSTORE_NSS;
12803089Swyllys key->keyclass = KMF_ASYM_PRI;
12813089Swyllys key->keyp = (void *)privkey;
12823089Swyllys key->keylabel = PK11_GetPrivateKeyNickname(privkey);
12833089Swyllys
12843089Swyllys CERT_DestroyCertificate(nss_cert);
12853089Swyllys
12863089Swyllys return (KMF_OK);
12873089Swyllys }
12883089Swyllys
12895051Swyllys
12903089Swyllys KMF_RETURN
NSS_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * AlgOID,KMF_DATA * ciphertext,KMF_DATA * output)12913089Swyllys NSS_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
12923089Swyllys KMF_OID *AlgOID, KMF_DATA *ciphertext,
12933089Swyllys KMF_DATA *output)
12943089Swyllys {
12953089Swyllys KMF_RETURN ret = KMF_OK;
12963089Swyllys SECKEYPrivateKey *NSSprivkey = NULL;
12973089Swyllys SECStatus rv;
12983089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
12993089Swyllys unsigned int in_len = 0, out_len = 0;
13003089Swyllys unsigned int total_decrypted = 0, modulus_len = 0;
13013089Swyllys uint8_t *in_data, *out_data;
13023089Swyllys int i, blocks;
13033089Swyllys
13043089Swyllys if (key == NULL || AlgOID == NULL ||
13053089Swyllys ciphertext == NULL || output == NULL ||
13063089Swyllys ciphertext->Data == NULL ||
13073089Swyllys output->Data == NULL)
13083089Swyllys return (KMF_ERR_BAD_PARAMETER);
13093089Swyllys
13103089Swyllys NSSprivkey = (SECKEYPrivateKey *)key->keyp;
13113089Swyllys modulus_len = PK11_GetPrivateModulusLen(NSSprivkey);
13123089Swyllys
13133089Swyllys blocks = ciphertext->Length/modulus_len;
13143089Swyllys out_data = output->Data;
13153089Swyllys in_data = ciphertext->Data;
13163089Swyllys out_len = modulus_len - 11;
13173089Swyllys in_len = modulus_len;
13183089Swyllys
13193089Swyllys for (i = 0; i < blocks; i++) {
13203089Swyllys rv = PK11_PrivDecryptPKCS1(NSSprivkey, out_data,
13213089Swyllys &out_len, ciphertext->Length, in_data, in_len);
13223089Swyllys
13233089Swyllys if (rv != 0) {
13243089Swyllys SET_ERROR(kmfh, rv);
13253089Swyllys return (KMF_ERR_INTERNAL);
13263089Swyllys }
13273089Swyllys
13283089Swyllys out_data += out_len;
13293089Swyllys total_decrypted += out_len;
13303089Swyllys in_data += in_len;
13313089Swyllys }
13323089Swyllys
13333089Swyllys output->Length = total_decrypted;
13343089Swyllys
13353089Swyllys return (ret);
13363089Swyllys }
13373089Swyllys
13383089Swyllys static KMF_KEY_ALG
pk11keytype2kmf(CK_KEY_TYPE type)13393089Swyllys pk11keytype2kmf(CK_KEY_TYPE type)
13403089Swyllys {
13413089Swyllys switch (type) {
13423089Swyllys case CKK_RSA:
13433089Swyllys return (KMF_RSA);
13443089Swyllys case CKK_DSA:
13453089Swyllys return (KMF_RSA);
13463089Swyllys case CKK_AES:
13473089Swyllys return (KMF_AES);
13483089Swyllys case CKK_RC4:
13493089Swyllys return (KMF_RC4);
13503089Swyllys case CKK_DES:
13513089Swyllys return (KMF_DES);
13523089Swyllys case CKK_DES3:
13533089Swyllys return (KMF_DES3);
1354*11973Swyllys.ingersoll@sun.com case CKK_EC:
1355*11973Swyllys.ingersoll@sun.com return (KMF_ECDSA);
13563089Swyllys default:
13573089Swyllys /* not supported */
13583089Swyllys return (KMF_KEYALG_NONE);
13593089Swyllys }
13603089Swyllys }
13613089Swyllys
13623089Swyllys KMF_RETURN
NSS_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)13635051Swyllys NSS_FindKey(KMF_HANDLE_T handle,
13645051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
13653089Swyllys {
13663089Swyllys KMF_RETURN rv;
13673089Swyllys SECKEYPrivateKeyList *prilist;
13683089Swyllys SECKEYPrivateKeyListNode *prinode;
13693089Swyllys SECKEYPublicKeyList *publist;
13703089Swyllys SECKEYPublicKeyListNode *pubnode;
13713089Swyllys PK11SlotInfo *nss_slot = NULL;
13724025Swyllys PK11SymKey *symlist = NULL;
13733089Swyllys int count;
13744025Swyllys uint32_t maxkeys;
13755051Swyllys KMF_KEY_HANDLE *keys;
13765051Swyllys uint32_t *numkeys;
13775221Swyllys KMF_CREDENTIAL *cred = NULL;
13785051Swyllys KMF_KEY_CLASS keyclass;
13795051Swyllys char *findLabel;
13805221Swyllys char *nick;
13815221Swyllys int match = 0;
13825051Swyllys KMF_KEY_ALG keytype = KMF_KEYALG_NONE;
13835051Swyllys
13845051Swyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
13855051Swyllys return (KMF_ERR_BAD_PARAMETER);
13865051Swyllys }
13875051Swyllys
13885051Swyllys numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
13895051Swyllys if (numkeys == NULL)
13905051Swyllys return (KMF_ERR_BAD_PARAMETER);
13915051Swyllys
13925051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
13933089Swyllys if (rv != KMF_OK) {
13943089Swyllys return (rv);
13953089Swyllys }
13963089Swyllys
13975221Swyllys /* It is OK if this is NULL, we dont need a cred to find public keys */
13985221Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
13995221Swyllys
14005221Swyllys if (cred != NULL) {
14015221Swyllys rv = nss_authenticate(handle, nss_slot, cred);
14025221Swyllys if (rv != KMF_OK) {
14035221Swyllys return (rv);
14045221Swyllys }
14053089Swyllys }
14063089Swyllys
14074025Swyllys maxkeys = *numkeys;
14084025Swyllys if (maxkeys == 0)
14094025Swyllys maxkeys = 0xFFFFFFFF;
14103089Swyllys *numkeys = 0;
14115051Swyllys
14125051Swyllys rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
14135051Swyllys (void *)&keyclass, NULL);
14145051Swyllys if (rv != KMF_OK)
14155051Swyllys return (KMF_ERR_BAD_PARAMETER);
14165051Swyllys
14175051Swyllys findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
14185051Swyllys
14195051Swyllys if (keyclass == KMF_ASYM_PUB) {
14205051Swyllys publist = PK11_ListPublicKeysInSlot(nss_slot, findLabel);
14213089Swyllys if (publist == NULL) {
14223089Swyllys rv = KMF_ERR_KEY_NOT_FOUND;
14233089Swyllys goto cleanup;
14243089Swyllys }
14255051Swyllys } else if (keyclass == KMF_ASYM_PRI) {
14265051Swyllys prilist = PK11_ListPrivKeysInSlot(nss_slot, findLabel, NULL);
14273089Swyllys if (prilist == NULL) {
14283089Swyllys rv = KMF_ERR_KEY_NOT_FOUND;
14293089Swyllys goto cleanup;
14303089Swyllys }
14315051Swyllys } else if (keyclass == KMF_SYMMETRIC) {
14325051Swyllys symlist = PK11_ListFixedKeysInSlot(nss_slot, findLabel, NULL);
14333089Swyllys if (symlist == NULL) {
14343089Swyllys rv = KMF_ERR_KEY_NOT_FOUND;
14353089Swyllys goto cleanup;
14363089Swyllys }
14373089Swyllys } else {
14383089Swyllys rv = KMF_ERR_BAD_KEY_CLASS;
14393089Swyllys goto cleanup;
14403089Swyllys }
14413089Swyllys
14425051Swyllys keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
14435051Swyllys /* it is okay to have "keys" contains NULL */
14445051Swyllys
14455051Swyllys if (keyclass == KMF_ASYM_PUB) {
14463089Swyllys for (count = 0, pubnode = PUBKEY_LIST_HEAD(publist);
14475051Swyllys !PUBKEY_LIST_END(pubnode, publist) && count < maxkeys;
14485221Swyllys pubnode = PUBKEY_LIST_NEXT(pubnode)) {
14495221Swyllys match = 0;
14505221Swyllys /*
14515221Swyllys * Due to bug in NSS, we have to manually match
14525221Swyllys * the labels to be sure we have a match.
14535221Swyllys */
14545221Swyllys nick = PK11_GetPublicKeyNickname(pubnode->key);
14555221Swyllys if (findLabel) {
14565221Swyllys match = (nick &&
14575221Swyllys (strcmp(nick, findLabel) == 0));
14585221Swyllys } else {
14595221Swyllys /* always match if findLabel is NULL */
14605221Swyllys match = 1;
14615221Swyllys }
14625221Swyllys if (keys != NULL && match) {
14633089Swyllys keys[count].kstype = KMF_KEYSTORE_NSS;
14643089Swyllys keys[count].keyclass = KMF_ASYM_PUB;
14653089Swyllys keys[count].keyp = (void *)pubnode->key;
14665221Swyllys keys[count].keylabel = nick;
14673089Swyllys
14683089Swyllys if (pubnode->key->keyType == rsaKey)
14693089Swyllys keys[count].keyalg = KMF_RSA;
14703089Swyllys else if (pubnode->key->keyType == dsaKey)
14713089Swyllys keys[count].keyalg = KMF_DSA;
1472*11973Swyllys.ingersoll@sun.com else if (pubnode->key->keyType == ecKey)
1473*11973Swyllys.ingersoll@sun.com keys[count].keyalg = KMF_ECDSA;
14743089Swyllys }
14755221Swyllys if (match)
14765221Swyllys count++;
14773089Swyllys }
14783089Swyllys *numkeys = count;
14795051Swyllys } else if (keyclass == KMF_ASYM_PRI) {
14803089Swyllys for (count = 0, prinode = PRIVKEY_LIST_HEAD(prilist);
14815051Swyllys !PRIVKEY_LIST_END(prinode, prilist) && count < maxkeys;
14825221Swyllys prinode = PRIVKEY_LIST_NEXT(prinode)) {
14835221Swyllys match = 0;
14845221Swyllys /*
14855221Swyllys * Due to bug in NSS, we have to manually match
14865221Swyllys * the labels to be sure we have a match.
14875221Swyllys */
14885221Swyllys nick = PK11_GetPrivateKeyNickname(prinode->key);
14895221Swyllys if (findLabel) {
14905221Swyllys match = (nick &&
14915221Swyllys (strcmp(nick, findLabel) == 0));
14925221Swyllys } else {
14935221Swyllys /* always match if findLabel is NULL */
14945221Swyllys match = 1;
14955221Swyllys }
14965221Swyllys if (keys != NULL && match) {
14973089Swyllys keys[count].kstype = KMF_KEYSTORE_NSS;
14983089Swyllys keys[count].keyclass = KMF_ASYM_PRI;
14993089Swyllys keys[count].keyp = (void *)prinode->key;
15005221Swyllys keys[count].keylabel = nick;
15013089Swyllys
15023089Swyllys if (prinode->key->keyType == rsaKey)
15033089Swyllys keys[count].keyalg = KMF_RSA;
15043089Swyllys else if (prinode->key->keyType == dsaKey)
15053089Swyllys keys[count].keyalg = KMF_DSA;
1506*11973Swyllys.ingersoll@sun.com else if (prinode->key->keyType == ecKey)
1507*11973Swyllys.ingersoll@sun.com keys[count].keyalg = KMF_ECDSA;
15083089Swyllys }
15095221Swyllys if (match)
15105221Swyllys count++;
15113089Swyllys }
15123089Swyllys *numkeys = count;
15135051Swyllys } else if (keyclass == KMF_SYMMETRIC) {
15143089Swyllys count = 0;
15155051Swyllys rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
15165051Swyllys (void *)&keytype, NULL);
15175051Swyllys if (rv != KMF_OK)
15185051Swyllys rv = KMF_OK;
15194025Swyllys while (symlist && count < maxkeys) {
15203089Swyllys PK11SymKey *symkey = symlist;
15213089Swyllys CK_KEY_TYPE type;
15223089Swyllys KMF_KEY_ALG keyalg;
15233089Swyllys
15245221Swyllys match = 0;
15253089Swyllys type = PK11_GetSymKeyType(symkey);
15263089Swyllys keyalg = pk11keytype2kmf(type);
15273089Swyllys
15285051Swyllys symlist = PK11_GetNextSymKey(symkey);
15295051Swyllys
15303089Swyllys /*
15313089Swyllys * If keytype is specified in the searching parameter,
15323089Swyllys * check the keytype and skip the key if its keytype
15333089Swyllys * doesn't match.
15343089Swyllys */
15355051Swyllys if (keytype != KMF_KEYALG_NONE && keytype != keyalg) {
15365051Swyllys /* free that key since we arent using it */
15374025Swyllys PK11_FreeSymKey(symkey);
15383089Swyllys continue;
15393089Swyllys }
15405221Swyllys /*
15415221Swyllys * Due to bug in NSS, we have to manually match
15425221Swyllys * the labels to be sure we have a match.
15435221Swyllys */
15445221Swyllys nick = PK11_GetSymKeyNickname(symkey);
15455221Swyllys if (findLabel) {
15465221Swyllys match = (nick &&
15475221Swyllys (strcmp(nick, findLabel) == 0));
15485221Swyllys } else {
15495221Swyllys /* always match if findLabel is NULL */
15505221Swyllys match = 1;
15515221Swyllys }
15525221Swyllys
15535221Swyllys if (keys != NULL && match) {
15543089Swyllys keys[count].kstype = KMF_KEYSTORE_NSS;
15553089Swyllys keys[count].keyclass = KMF_SYMMETRIC;
15563089Swyllys keys[count].keyp = (void *) symkey;
15575221Swyllys keys[count].keylabel = nick;
15583089Swyllys keys[count].keyalg = keyalg;
15593089Swyllys } else {
15603089Swyllys PK11_FreeSymKey(symkey);
15613089Swyllys }
15625221Swyllys if (match)
15635221Swyllys count++;
15643089Swyllys }
15654025Swyllys /*
15664025Swyllys * Cleanup memory for unused keys.
15674025Swyllys */
15684025Swyllys while (symlist != NULL) {
15694025Swyllys PK11SymKey *symkey = symlist;
15705051Swyllys
15714025Swyllys PK11_FreeSymKey(symkey);
15724025Swyllys symlist = PK11_GetNextSymKey(symkey);
15734025Swyllys }
15745051Swyllys *numkeys = count;
15753089Swyllys }
15763089Swyllys
15773089Swyllys cleanup:
15783089Swyllys if (nss_slot != NULL) {
15793089Swyllys PK11_FreeSlot(nss_slot);
15803089Swyllys }
15813089Swyllys
15823089Swyllys return (rv);
15833089Swyllys }
15843089Swyllys
15853089Swyllys static SECStatus
p12u_SwapUnicodeBytes(SECItem * uniItem)15863089Swyllys p12u_SwapUnicodeBytes(SECItem *uniItem)
15873089Swyllys {
15883089Swyllys unsigned int i;
15893089Swyllys unsigned char a;
15903089Swyllys if ((uniItem == NULL) || (uniItem->len % 2)) {
15913089Swyllys return (SECFailure);
15923089Swyllys }
15933089Swyllys for (i = 0; i < uniItem->len; i += 2) {
15943089Swyllys a = uniItem->data[i];
15953089Swyllys uniItem->data[i] = uniItem->data[i+1];
15963089Swyllys uniItem->data[i+1] = a;
15973089Swyllys }
15983089Swyllys return (SECSuccess);
15993089Swyllys }
16003089Swyllys
16013089Swyllys static PRBool
p12u_ucs2_ascii_conversion_function(PRBool toUnicode,unsigned char * inBuf,unsigned int inBufLen,unsigned char * outBuf,unsigned int maxOutBufLen,unsigned int * outBufLen,PRBool swapBytes)16023089Swyllys p12u_ucs2_ascii_conversion_function(
16033089Swyllys PRBool toUnicode,
16043089Swyllys unsigned char *inBuf,
16053089Swyllys unsigned int inBufLen,
16063089Swyllys unsigned char *outBuf,
16073089Swyllys unsigned int maxOutBufLen,
16083089Swyllys unsigned int *outBufLen,
16093089Swyllys PRBool swapBytes)
16103089Swyllys {
16113089Swyllys SECItem it = { 0 };
16123089Swyllys SECItem *dup = NULL;
16133089Swyllys PRBool ret;
16143089Swyllys
16153089Swyllys it.data = inBuf;
16163089Swyllys it.len = inBufLen;
16173089Swyllys dup = SECITEM_DupItem(&it);
16183089Swyllys /*
16193089Swyllys * If converting Unicode to ASCII, swap bytes before conversion
16203089Swyllys * as neccessary.
16213089Swyllys */
16223089Swyllys if (!toUnicode && swapBytes) {
16233089Swyllys if (p12u_SwapUnicodeBytes(dup) != SECSuccess) {
16243089Swyllys SECITEM_ZfreeItem(dup, PR_TRUE);
16253089Swyllys return (PR_FALSE);
16263089Swyllys }
16273089Swyllys }
16283089Swyllys /* Perform the conversion. */
16293089Swyllys ret = PORT_UCS2_UTF8Conversion(toUnicode, dup->data, dup->len,
16305051Swyllys outBuf, maxOutBufLen, outBufLen);
16313089Swyllys if (dup)
16323089Swyllys SECITEM_ZfreeItem(dup, PR_TRUE);
16333089Swyllys
16343089Swyllys return (ret);
16353089Swyllys }
16363089Swyllys
16373089Swyllys static PRBool
p12u_OpenFile(p12uContext * p12ctx,PRBool fileRead)16383089Swyllys p12u_OpenFile(p12uContext *p12ctx, PRBool fileRead)
16393089Swyllys {
16403089Swyllys if (!p12ctx || !p12ctx->filename) {
16413089Swyllys return (PR_FALSE);
16423089Swyllys }
16433089Swyllys
16443089Swyllys if (fileRead) {
16455051Swyllys p12ctx->file = PR_Open(p12ctx->filename, PR_RDONLY, 0400);
16463089Swyllys } else {
16473089Swyllys p12ctx->file = PR_Open(p12ctx->filename,
16485051Swyllys PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 0600);
16493089Swyllys }
16503089Swyllys
16513089Swyllys if (!p12ctx->file) {
16523089Swyllys p12ctx->error = PR_TRUE;
16533089Swyllys return (PR_FALSE);
16543089Swyllys }
16553089Swyllys
16563089Swyllys return (PR_TRUE);
16573089Swyllys }
16583089Swyllys
16593089Swyllys static void
p12u_DestroyContext(p12uContext ** ppCtx,PRBool removeFile)16603089Swyllys p12u_DestroyContext(p12uContext **ppCtx, PRBool removeFile)
16613089Swyllys {
16623089Swyllys if (!ppCtx || !(*ppCtx)) {
16633089Swyllys return;
16643089Swyllys }
16653089Swyllys
16663089Swyllys if ((*ppCtx)->file != NULL) {
166711411SSurya.Prakki@Sun.COM (void) PR_Close((*ppCtx)->file);
16683089Swyllys }
16693089Swyllys
16703089Swyllys if ((*ppCtx)->filename != NULL) {
16713089Swyllys if (removeFile) {
167211411SSurya.Prakki@Sun.COM (void) PR_Delete((*ppCtx)->filename);
16733089Swyllys }
16743089Swyllys free((*ppCtx)->filename);
16753089Swyllys }
16763089Swyllys
16773089Swyllys free(*ppCtx);
16783089Swyllys *ppCtx = NULL;
16793089Swyllys }
16803089Swyllys
16813089Swyllys static p12uContext *
p12u_InitContext(PRBool fileImport,char * filename)16823089Swyllys p12u_InitContext(PRBool fileImport, char *filename)
16833089Swyllys {
16843089Swyllys p12uContext *p12ctx;
16853089Swyllys
16863089Swyllys p12ctx = PORT_ZNew(p12uContext);
16873089Swyllys if (!p12ctx) {
16883089Swyllys return (NULL);
16893089Swyllys }
16903089Swyllys
16913089Swyllys p12ctx->error = PR_FALSE;
16923089Swyllys p12ctx->errorValue = 0;
16933089Swyllys p12ctx->filename = strdup(filename);
16943089Swyllys
16953089Swyllys if (!p12u_OpenFile(p12ctx, fileImport)) {
16963089Swyllys p12u_DestroyContext(&p12ctx, PR_FALSE);
16973089Swyllys return (NULL);
16983089Swyllys }
16993089Swyllys
17003089Swyllys return (p12ctx);
17013089Swyllys }
17023089Swyllys
17033089Swyllys static void
p12u_WriteToExportFile(void * arg,const char * buf,unsigned long len)17043089Swyllys p12u_WriteToExportFile(void *arg, const char *buf, unsigned long len)
17053089Swyllys {
17063089Swyllys p12uContext *p12cxt = arg;
17073089Swyllys int writeLen;
17083089Swyllys
17093089Swyllys if (!p12cxt || (p12cxt->error == PR_TRUE)) {
17103089Swyllys return;
17113089Swyllys }
17123089Swyllys
17133089Swyllys if (p12cxt->file == NULL) {
17143089Swyllys p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE;
17153089Swyllys p12cxt->error = PR_TRUE;
17163089Swyllys return;
17173089Swyllys }
17183089Swyllys
17193089Swyllys writeLen = PR_Write(p12cxt->file, (unsigned char *)buf, (int32)len);
17203089Swyllys
17213089Swyllys if (writeLen != (int)len) {
172211411SSurya.Prakki@Sun.COM (void) PR_Close(p12cxt->file);
17233089Swyllys free(p12cxt->filename);
17243089Swyllys p12cxt->filename = NULL;
17253089Swyllys p12cxt->file = NULL;
17263089Swyllys p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE;
17273089Swyllys p12cxt->error = PR_TRUE;
17283089Swyllys }
17293089Swyllys }
17303089Swyllys
17313089Swyllys #define HANDLE_NSS_ERROR(r) {\
17323089Swyllys SET_ERROR(kmfh, PORT_GetError()); \
17333089Swyllys rv = r; \
17343089Swyllys goto out; }
17353089Swyllys
17363089Swyllys static KMF_RETURN
add_cert_to_bag(SEC_PKCS12ExportContext * p12ecx,CERTCertificate * cert,SECItem * pwitem)17373089Swyllys add_cert_to_bag(SEC_PKCS12ExportContext *p12ecx,
17383089Swyllys CERTCertificate *cert, SECItem *pwitem)
17393089Swyllys {
17403089Swyllys KMF_RETURN rv = KMF_OK;
17413089Swyllys SEC_PKCS12SafeInfo *keySafe = NULL, *certSafe = NULL;
17423089Swyllys
17433089Swyllys keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx);
17443089Swyllys if (PK11_IsFIPS()) {
17453089Swyllys certSafe = keySafe;
17463089Swyllys } else {
17473089Swyllys certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem,
17485051Swyllys SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);
17493089Swyllys }
17503089Swyllys
17513089Swyllys if (!certSafe || !keySafe) {
17523089Swyllys rv = KMF_ERR_INTERNAL;
17533089Swyllys goto out;
17543089Swyllys }
17553089Swyllys
17563089Swyllys if (SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert,
17575051Swyllys CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem,
17585051Swyllys SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC)
17595051Swyllys != SECSuccess) {
17603089Swyllys rv = KMF_ERR_INTERNAL;
17613089Swyllys }
17623089Swyllys out:
17633089Swyllys return (rv);
17643089Swyllys }
17653089Swyllys
17663089Swyllys KMF_RETURN
NSS_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)17675051Swyllys NSS_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
17683089Swyllys {
17693089Swyllys KMF_RETURN rv;
17703089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
17713089Swyllys SEC_PKCS12ExportContext *p12ecx = NULL;
17723089Swyllys p12uContext *p12ctx = NULL;
17733089Swyllys CERTCertList *certlist = NULL;
17743089Swyllys CERTCertificate *nsscert = NULL;
17753089Swyllys CERTCertListNode* node = NULL;
17763089Swyllys PK11SlotInfo *slot = NULL;
17773089Swyllys SECItem pwitem = {NULL, 0};
17785051Swyllys KMF_CREDENTIAL *cred = NULL;
17795051Swyllys KMF_CREDENTIAL *p12cred = NULL;
17805051Swyllys char *certlabel = NULL;
17815051Swyllys char *issuer = NULL;
17825051Swyllys char *subject = NULL;
17835051Swyllys KMF_BIGINT *serial = NULL;
17845051Swyllys char *filename = NULL;
17855051Swyllys
17865051Swyllys if (kmfh == NULL || attrlist == NULL || numattr == 0) {
17875051Swyllys return (KMF_ERR_BAD_PARAMETER);
17883089Swyllys }
17893089Swyllys
17905051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &slot);
17915051Swyllys if (rv != KMF_OK)
17925051Swyllys return (rv);
17935051Swyllys
17945051Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
17955051Swyllys if (cred == NULL)
17965051Swyllys return (KMF_ERR_BAD_PARAMETER);
17975051Swyllys
17985051Swyllys rv = nss_authenticate(handle, slot, cred);
17995051Swyllys if (rv != KMF_OK)
18003089Swyllys return (rv);
18015051Swyllys
18025051Swyllys p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
18035051Swyllys if (p12cred == NULL)
18045051Swyllys return (KMF_ERR_BAD_PARAMETER);
18055051Swyllys
18065051Swyllys filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
18075051Swyllys numattr);
18085051Swyllys if (filename == NULL)
18095051Swyllys return (KMF_ERR_BAD_PARAMETER);
18105051Swyllys
18115051Swyllys /* Get optional search criteria attributes */
18125051Swyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
18135051Swyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
18145051Swyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
18155051Swyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
18163089Swyllys
18173089Swyllys /*
18183089Swyllys * Find the certificate(s) first.
18193089Swyllys */
18205051Swyllys if (certlabel != NULL) {
18215051Swyllys nsscert = PK11_FindCertFromNickname(certlabel, NULL);
18223089Swyllys if (nsscert == NULL) {
18233089Swyllys HANDLE_NSS_ERROR(KMF_ERR_CERT_NOT_FOUND)
18243089Swyllys }
18253089Swyllys } else {
18265051Swyllys rv = nss_find_matching_certs(slot, issuer, subject, serial,
18275051Swyllys &certlist, 0);
18283089Swyllys
18293089Swyllys if (rv == KMF_OK && certlist == NULL) {
18303089Swyllys return (KMF_ERR_CERT_NOT_FOUND);
18313089Swyllys }
18323089Swyllys if (rv != KMF_OK)
18333089Swyllys return (rv);
18343089Swyllys }
18353089Swyllys
18363089Swyllys /*
18373089Swyllys * The KMF_CREDENTIAL holds the password to use for
18383089Swyllys * encrypting the PKCS12 key information.
18393089Swyllys */
18405051Swyllys pwitem.data = (uchar_t *)p12cred->cred;
18415051Swyllys pwitem.len = p12cred->credlen;
18423089Swyllys
18433089Swyllys p12ctx = p12u_InitContext(PR_FALSE, filename);
18443089Swyllys if (!p12ctx) {
18453089Swyllys HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE)
18463089Swyllys }
18473089Swyllys
18483089Swyllys PORT_SetUCS2_ASCIIConversionFunction(
18495051Swyllys p12u_ucs2_ascii_conversion_function);
18505051Swyllys
18515051Swyllys p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, slot, NULL);
18523089Swyllys if (!p12ecx) {
18533089Swyllys HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE)
18543089Swyllys }
18553089Swyllys
18563089Swyllys if (SEC_PKCS12AddPasswordIntegrity(p12ecx, &pwitem, SEC_OID_SHA1)
18575051Swyllys != SECSuccess) {
18583089Swyllys HANDLE_NSS_ERROR(KMF_ERR_INTERNAL)
18593089Swyllys }
18603089Swyllys
18613089Swyllys /*
18623089Swyllys * NSS actually supports storing a list of keys and certs
18633089Swyllys * in the PKCS#12 PDU. Nice feature.
18643089Swyllys */
18653089Swyllys if (certlist != NULL) {
18663089Swyllys for (node = CERT_LIST_HEAD(certlist);
18675051Swyllys !CERT_LIST_END(node, certlist) && rv == KMF_OK;
18685051Swyllys node = CERT_LIST_NEXT(node)) {
18693089Swyllys rv = add_cert_to_bag(p12ecx, node->cert, &pwitem);
18703089Swyllys }
18713089Swyllys } else if (nsscert != NULL) {
18723089Swyllys rv = add_cert_to_bag(p12ecx, nsscert, &pwitem);
18733089Swyllys }
18743089Swyllys
18753089Swyllys if (SEC_PKCS12Encode(p12ecx, p12u_WriteToExportFile, p12ctx)
18765051Swyllys != SECSuccess) {
18773089Swyllys HANDLE_NSS_ERROR(KMF_ERR_ENCODING)
18783089Swyllys }
18793089Swyllys out:
18803089Swyllys if (nsscert)
18813089Swyllys CERT_DestroyCertificate(nsscert);
18823089Swyllys
18833089Swyllys if (certlist)
18843089Swyllys CERT_DestroyCertList(certlist);
18853089Swyllys
18863089Swyllys if (p12ctx)
18873089Swyllys p12u_DestroyContext(&p12ctx, PR_FALSE);
18883089Swyllys
18893089Swyllys if (p12ecx)
18903089Swyllys SEC_PKCS12DestroyExportContext(p12ecx);
18913089Swyllys
18923089Swyllys return (rv);
18933089Swyllys }
18943089Swyllys
18953089Swyllys #define SETATTR(t, n, atype, value, size) \
18963089Swyllys t[n].type = atype; \
18973089Swyllys t[n].pValue = (CK_BYTE *)value; \
18983089Swyllys t[n].ulValueLen = (CK_ULONG)size;
18993089Swyllys
19003089Swyllys KMF_RETURN
NSS_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)19013089Swyllys NSS_CreateSymKey(KMF_HANDLE_T handle,
19025051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
19033089Swyllys {
19043089Swyllys KMF_RETURN rv = KMF_OK;
19053089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
19063089Swyllys PK11SlotInfo *nss_slot = NULL;
19073089Swyllys PK11SymKey *nsskey = NULL;
19083089Swyllys CK_MECHANISM_TYPE keyType;
19093089Swyllys SECStatus nssrv;
19103089Swyllys int keySize;
19115051Swyllys KMF_KEY_HANDLE *symkey;
19125051Swyllys KMF_CREDENTIAL cred;
19135051Swyllys uint32_t keylen;
19145051Swyllys uint32_t keylen_size = sizeof (uint32_t);
19155051Swyllys KMF_KEY_ALG keytype;
19165051Swyllys char *keylabel = NULL;
19175051Swyllys
19185051Swyllys if (kmfh == NULL || attrlist == NULL || numattr == 0) {
19193089Swyllys return (KMF_ERR_BAD_PARAMETER);
19203089Swyllys }
19213089Swyllys
19225051Swyllys symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
19235051Swyllys if (symkey == NULL)
19245051Swyllys return (KMF_ERR_BAD_PARAMETER);
19255051Swyllys
19265051Swyllys rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, (void *)&keytype,
19275051Swyllys NULL);
19285051Swyllys if (rv != KMF_OK)
19295051Swyllys return (KMF_ERR_BAD_PARAMETER);
19305051Swyllys
19315051Swyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, &keylen,
19325051Swyllys &keylen_size);
19335051Swyllys if (rv == KMF_ERR_ATTR_NOT_FOUND &&
19345051Swyllys (keytype == KMF_DES || keytype == KMF_DES3))
19355051Swyllys /* keylength is not required for DES and 3DES */
19365051Swyllys rv = KMF_OK;
19375051Swyllys if (rv != KMF_OK)
19385051Swyllys return (KMF_ERR_BAD_PARAMETER);
19395051Swyllys
19405051Swyllys keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
19415051Swyllys if (keylabel == NULL)
19425051Swyllys return (KMF_ERR_BAD_PARAMETER);
19435051Swyllys
19445051Swyllys switch (keytype) {
19453089Swyllys case KMF_AES:
19463089Swyllys keyType = CKM_AES_KEY_GEN;
19475051Swyllys keySize = keylen;
19483089Swyllys if (keySize == 0 || (keySize % 8) != 0)
19493089Swyllys return (KMF_ERR_BAD_KEY_SIZE);
19503089Swyllys break;
19513089Swyllys case KMF_RC4:
19523089Swyllys keyType = CKM_RC4_KEY_GEN;
19535051Swyllys keySize = keylen;
19543089Swyllys if (keySize == 0 || (keySize % 8) != 0)
19553089Swyllys return (KMF_ERR_BAD_KEY_SIZE);
19563089Swyllys break;
19573089Swyllys case KMF_DES:
19583089Swyllys keyType = CKM_DES_KEY_GEN;
19593089Swyllys keySize = 0; /* required by PK11_TokenKeyGen() */
19603089Swyllys break;
19613089Swyllys case KMF_DES3:
19623089Swyllys keyType = CKM_DES3_KEY_GEN;
19633089Swyllys keySize = 0; /* required by PK11_TokenKeyGen() */
19643089Swyllys break;
19653812Shylee case KMF_GENERIC_SECRET:
19663812Shylee keyType = CKM_GENERIC_SECRET_KEY_GEN;
19675051Swyllys keySize = keylen;
19683812Shylee if (keySize == 0 || (keySize % 8) != 0)
19693812Shylee return (KMF_ERR_BAD_KEY_SIZE);
19703812Shylee break;
19713089Swyllys default:
19723089Swyllys rv = KMF_ERR_BAD_KEY_TYPE;
19733089Swyllys goto out;
19743089Swyllys }
19753089Swyllys
19765051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
19773089Swyllys if (rv != KMF_OK) {
19783089Swyllys return (rv);
19793089Swyllys }
19803089Swyllys
19815051Swyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
19825051Swyllys (void *)&cred, NULL);
19835051Swyllys if (rv != KMF_OK)
19845051Swyllys return (KMF_ERR_BAD_PARAMETER);
19855051Swyllys
19865051Swyllys rv = nss_authenticate(handle, nss_slot, &cred);
19873089Swyllys if (rv != KMF_OK) {
19883089Swyllys return (rv);
19893089Swyllys }
19903089Swyllys
199110442Swyllys.ingersoll@sun.com /* convert key length to bytes */
199210442Swyllys.ingersoll@sun.com nsskey = PK11_TokenKeyGen(nss_slot, keyType, NULL, keySize / 8, NULL,
19935051Swyllys PR_TRUE, (void *)cred.cred);
19943089Swyllys if (nsskey == NULL) {
19953089Swyllys SET_ERROR(kmfh, PORT_GetError());
19963089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
19973089Swyllys goto out;
19983089Swyllys }
19993089Swyllys
20005051Swyllys nssrv = PK11_SetSymKeyNickname(nsskey, keylabel);
20013089Swyllys if (nssrv != SECSuccess) {
20023089Swyllys SET_ERROR(kmfh, PORT_GetError());
20033089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
20043089Swyllys goto out;
20053089Swyllys }
20063089Swyllys
20073089Swyllys symkey->kstype = KMF_KEYSTORE_NSS;
20085051Swyllys symkey->keyalg = keytype;
20093089Swyllys symkey->keyclass = KMF_SYMMETRIC;
20103089Swyllys symkey->israw = FALSE;
20113089Swyllys symkey->keyp = (void *)nsskey;
20123089Swyllys
20133089Swyllys out:
20143089Swyllys if (nss_slot != NULL)
20153089Swyllys PK11_FreeSlot(nss_slot);
20163089Swyllys
20173089Swyllys if (rv != KMF_OK && nsskey != NULL) {
201811411SSurya.Prakki@Sun.COM (void) PK11_DeleteTokenSymKey(nsskey);
20193089Swyllys PK11_FreeSymKey(nsskey);
20203089Swyllys }
20213089Swyllys return (rv);
20223089Swyllys }
20233089Swyllys
20243089Swyllys KMF_RETURN
NSS_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)20253089Swyllys NSS_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
20263089Swyllys KMF_RAW_SYM_KEY *rkey)
20273089Swyllys {
20283089Swyllys KMF_RETURN rv = KMF_OK;
20293089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
20303089Swyllys SECItem *value = NULL;
20313089Swyllys PK11SymKey *nsskey;
20323089Swyllys SECStatus nss_rv;
20333089Swyllys
20343089Swyllys if (kmfh == NULL)
20353089Swyllys return (KMF_ERR_UNINITIALIZED);
20363089Swyllys
20373089Swyllys if (symkey == NULL || rkey == NULL)
20383089Swyllys return (KMF_ERR_BAD_PARAMETER);
20393089Swyllys else if (symkey->keyclass != KMF_SYMMETRIC)
20403089Swyllys return (KMF_ERR_BAD_KEY_CLASS);
20413089Swyllys
20423089Swyllys if (symkey->israw) {
20433089Swyllys KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
20443089Swyllys
20453089Swyllys if (rawkey == NULL ||
20463089Swyllys rawkey->rawdata.sym.keydata.val == NULL ||
20473089Swyllys rawkey->rawdata.sym.keydata.len == 0)
20483089Swyllys return (KMF_ERR_BAD_KEYHANDLE);
20493089Swyllys
20503089Swyllys rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
20513089Swyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
20523089Swyllys return (KMF_ERR_MEMORY);
20533089Swyllys (void) memcpy(rkey->keydata.val,
20545051Swyllys rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
20553089Swyllys } else {
20563089Swyllys nsskey = (PK11SymKey *)(symkey->keyp);
20573089Swyllys if (nsskey == NULL)
20583089Swyllys return (KMF_ERR_BAD_KEYHANDLE);
20593089Swyllys
20603089Swyllys nss_rv = PK11_ExtractKeyValue(nsskey);
20613089Swyllys if (nss_rv != SECSuccess) {
20623089Swyllys SET_ERROR(kmfh, PORT_GetError());
20633089Swyllys rv = KMF_ERR_GETKEYVALUE_FAILED;
20643089Swyllys goto out;
20653089Swyllys }
20663089Swyllys
20673089Swyllys value = PK11_GetKeyData(nsskey);
20683089Swyllys if (value == NULL) {
20693089Swyllys SET_ERROR(kmfh, PORT_GetError());
20703089Swyllys rv = KMF_ERR_GETKEYVALUE_FAILED;
20713089Swyllys goto out;
20723089Swyllys }
20733089Swyllys
20743089Swyllys if (value->len == 0 || value->data == NULL) {
20753089Swyllys rv = KMF_ERR_GETKEYVALUE_FAILED;
20763089Swyllys goto out;
20773089Swyllys }
20783089Swyllys
20793089Swyllys rkey->keydata.val = malloc(value->len);
20803089Swyllys if (rkey->keydata.val == NULL) {
20813089Swyllys rv = KMF_ERR_MEMORY;
20823089Swyllys goto out;
20833089Swyllys }
20843089Swyllys (void) memcpy(rkey->keydata.val, value->data, value->len);
20853089Swyllys rkey->keydata.len = value->len;
20863089Swyllys (void) memset(value->data, 0, value->len);
20873089Swyllys }
20883089Swyllys out:
20893089Swyllys if (value != NULL)
20903089Swyllys SECITEM_FreeItem(value, PR_TRUE);
20913089Swyllys return (rv);
20923089Swyllys }
20933089Swyllys
20943089Swyllys KMF_RETURN
NSS_SetTokenPin(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)20955051Swyllys NSS_SetTokenPin(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
20963089Swyllys {
20973089Swyllys KMF_RETURN ret = KMF_OK;
20983089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
20993089Swyllys int rv;
21003089Swyllys PK11SlotInfo *nss_slot = NULL;
21015051Swyllys KMF_CREDENTIAL oldcred, newcred;
21025051Swyllys
21035051Swyllys if (handle == NULL || attrlist == NULL || numattr == 0)
21043089Swyllys return (KMF_ERR_BAD_PARAMETER);
21055051Swyllys
21065051Swyllys ret = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
21075051Swyllys (void *)&oldcred, NULL);
21085051Swyllys if (ret != KMF_OK)
21095051Swyllys return (KMF_ERR_BAD_PARAMETER);
21105051Swyllys ret = kmf_get_attr(KMF_NEWPIN_ATTR, attrlist, numattr,
21115051Swyllys (void *)&newcred, NULL);
21125051Swyllys if (ret != KMF_OK)
21135051Swyllys return (KMF_ERR_BAD_PARAMETER);
21145051Swyllys
21155051Swyllys ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
21163089Swyllys /* If it was uninitialized, set it */
21173089Swyllys if (ret == KMF_ERR_UNINITIALIZED_TOKEN) {
21185051Swyllys rv = PK11_InitPin(nss_slot, NULL, newcred.cred);
21193089Swyllys if (rv != SECSuccess) {
21203089Swyllys SET_ERROR(kmfh, PORT_GetError());
21213089Swyllys ret = KMF_ERR_AUTH_FAILED;
21223089Swyllys } else {
21233089Swyllys ret = KMF_OK;
21243089Swyllys }
21253089Swyllys } else if (ret == KMF_OK) {
21265051Swyllys ret = nss_authenticate(handle, nss_slot, &oldcred);
21273089Swyllys if (ret != KMF_OK) {
21283089Swyllys return (ret);
21293089Swyllys }
21305051Swyllys rv = PK11_ChangePW(nss_slot, oldcred.cred, newcred.cred);
21313089Swyllys if (rv != SECSuccess) {
21323089Swyllys SET_ERROR(kmfh, PORT_GetError());
21333089Swyllys ret = KMF_ERR_AUTH_FAILED;
21343089Swyllys }
21353089Swyllys }
21363089Swyllys
21373089Swyllys return (ret);
21383089Swyllys }
21395051Swyllys
21405051Swyllys KMF_RETURN
NSS_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)21415051Swyllys NSS_StoreKey(KMF_HANDLE_T handle,
21425051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
21435051Swyllys {
21445051Swyllys KMF_RETURN rv = KMF_OK;
21455051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
21465051Swyllys PK11SlotInfo *nss_slot = NULL;
21475051Swyllys KMF_CREDENTIAL cred = {NULL, 0};
21485051Swyllys KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
21495051Swyllys KMF_RAW_KEY_DATA *rawkey = NULL;
21505051Swyllys char *keylabel = NULL;
21515051Swyllys SECStatus ckrv = SECSuccess;
21525051Swyllys SECItem nickname = {NULL, 0};
21535051Swyllys CERTCertificate *nss_cert = NULL;
21545051Swyllys
21555051Swyllys if (kmfh == NULL || attrlist == NULL || numattr == 0) {
21565051Swyllys return (KMF_ERR_BAD_PARAMETER);
21575051Swyllys }
21585051Swyllys
21595051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
21605051Swyllys if (rv != KMF_OK) {
21615051Swyllys return (rv);
21625051Swyllys }
21635051Swyllys
21645051Swyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
21655051Swyllys (void *)&cred, NULL);
21665051Swyllys if (rv != KMF_OK)
21675051Swyllys return (KMF_ERR_BAD_PARAMETER);
21685051Swyllys
21695051Swyllys rv = nss_authenticate(handle, nss_slot, &cred);
21705051Swyllys if (rv != KMF_OK) {
21715051Swyllys return (rv);
21725051Swyllys }
21735051Swyllys
21745051Swyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
21755051Swyllys if (pubkey == NULL) {
21765051Swyllys /* look for private key */
21775051Swyllys prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist,
21785051Swyllys numattr);
21795051Swyllys if (prikey == NULL)
21805051Swyllys /* look for raw key */
21815051Swyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR,
21825051Swyllys attrlist, numattr);
21835051Swyllys }
21845051Swyllys
21855051Swyllys /* If no keys were found, return error */
21865051Swyllys if (pubkey == NULL && prikey == NULL && rawkey == NULL)
21875051Swyllys return (KMF_ERR_ATTR_NOT_FOUND);
21885051Swyllys
21895051Swyllys keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
21905051Swyllys if (keylabel != NULL) {
21915051Swyllys nickname.data = (uchar_t *)keylabel;
21925051Swyllys nickname.len = strlen(keylabel);
21935051Swyllys }
21945051Swyllys
21955051Swyllys if (rawkey != NULL) {
21965051Swyllys uchar_t ver = 0;
21975051Swyllys SECKEYPrivateKeyInfo rpk;
21985051Swyllys KMF_DATA derkey = {NULL, 0};
21995051Swyllys KMF_DATA *cert;
22005051Swyllys
22015051Swyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
22025051Swyllys if (cert == NULL)
22035051Swyllys return (rv);
22045051Swyllys /*
22055051Swyllys * Decode the cert into an NSS CERT object so we can access the
22065051Swyllys * SPKI and KeyUsage data later.
22075051Swyllys */
22085051Swyllys nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data,
22095051Swyllys cert->Length);
22105051Swyllys
22115051Swyllys if (nss_cert == NULL) {
22125051Swyllys SET_ERROR(kmfh, PORT_GetError());
22135051Swyllys rv = KMF_ERR_BAD_CERT_FORMAT;
22145051Swyllys goto cleanup;
22155051Swyllys }
22165051Swyllys
22175051Swyllys (void) memset(&rpk, 0, sizeof (rpk));
22185051Swyllys rpk.arena = NULL;
22195051Swyllys rpk.version.type = siUnsignedInteger;
22205051Swyllys rpk.version.data = &ver;
22215051Swyllys rpk.version.len = 1;
22225051Swyllys if (rawkey->keytype == KMF_RSA) {
22235051Swyllys rv = DerEncodeRSAPrivateKey(&derkey,
22245051Swyllys &rawkey->rawdata.rsa);
22255051Swyllys if (rv != KMF_OK)
22265051Swyllys goto cleanup;
22275051Swyllys } else if (rawkey->keytype == KMF_DSA) {
22285051Swyllys rv = DerEncodeDSAPrivateKey(&derkey,
22295051Swyllys &rawkey->rawdata.dsa);
22305051Swyllys if (rv != KMF_OK)
22315051Swyllys goto cleanup;
2232*11973Swyllys.ingersoll@sun.com } else if (rawkey->keytype == KMF_ECDSA) {
2233*11973Swyllys.ingersoll@sun.com rv = DerEncodeECPrivateKey(&derkey,
2234*11973Swyllys.ingersoll@sun.com &rawkey->rawdata.ec);
2235*11973Swyllys.ingersoll@sun.com if (rv != KMF_OK)
2236*11973Swyllys.ingersoll@sun.com goto cleanup;
22375051Swyllys }
22385051Swyllys rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm;
22395051Swyllys rpk.privateKey.data = derkey.Data;
22405051Swyllys rpk.privateKey.len = derkey.Length;
22415051Swyllys rpk.attributes = NULL;
22425051Swyllys
22435051Swyllys ckrv = PK11_ImportPrivateKeyInfo(nss_slot, &rpk, &nickname,
22445051Swyllys &nss_cert->subjectPublicKeyInfo.subjectPublicKey, TRUE,
22455051Swyllys TRUE, nss_cert->keyUsage, NULL);
22465051Swyllys if (ckrv != CKR_OK) {
22475051Swyllys SET_ERROR(kmfh, PORT_GetError());
22485051Swyllys rv = KMF_ERR_INTERNAL;
22495051Swyllys }
22505051Swyllys kmf_free_data(&derkey);
22515051Swyllys } else if (pubkey != NULL && pubkey->kstype == KMF_KEYSTORE_NSS) {
22525051Swyllys CK_OBJECT_HANDLE pk;
22535051Swyllys SECKEYPublicKey *publicKey = (SECKEYPublicKey *) pubkey->keyp;
22545051Swyllys
22555051Swyllys pk = PK11_ImportPublicKey(nss_slot, publicKey, PR_TRUE);
22565051Swyllys if (pk == CK_INVALID_HANDLE) {
22575051Swyllys SET_ERROR(kmfh, PORT_GetError());
22585051Swyllys rv = KMF_ERR_INTERNAL;
22595051Swyllys }
22605051Swyllys } else if (prikey != NULL && prikey->kstype == KMF_KEYSTORE_NSS) {
22615051Swyllys SECKEYPrivateKey *pk;
22625051Swyllys SECKEYPrivateKey *privKey = (SECKEYPrivateKey *) prikey->keyp;
22635051Swyllys
22645051Swyllys pk = PK11_LoadPrivKey(nss_slot, privKey, NULL, PR_TRUE,
22655051Swyllys PR_TRUE);
22665051Swyllys if (pk == CK_INVALID_HANDLE) {
22675051Swyllys SET_ERROR(kmfh, PORT_GetError());
22685051Swyllys rv = KMF_ERR_INTERNAL;
22695051Swyllys }
22705051Swyllys /* We stored it, but don't need the handle anymore */
22715051Swyllys SECKEY_DestroyPrivateKey(pk);
22725051Swyllys }
22735051Swyllys
22745051Swyllys cleanup:
22755051Swyllys if (nss_cert != NULL)
22765051Swyllys CERT_DestroyCertificate(nss_cert);
22775051Swyllys PK11_FreeSlot(nss_slot);
22785051Swyllys return (rv);
22795051Swyllys }
22805051Swyllys
22815051Swyllys /*
22825051Swyllys * This function is called by NSS_StoreCert() and NSS_ImportCert().
22835051Swyllys * The "label" and "trust_flag" arguments can be NULL.
22845051Swyllys */
22855051Swyllys static KMF_RETURN
store_cert(KMF_HANDLE_T handle,PK11SlotInfo * nss_slot,KMF_DATA * cert,char * label,char * trust_flag)22865051Swyllys store_cert(KMF_HANDLE_T handle, PK11SlotInfo *nss_slot, KMF_DATA *cert,
22875051Swyllys char *label, char *trust_flag)
22885051Swyllys {
22895051Swyllys KMF_RETURN ret = KMF_OK;
22905051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
22915051Swyllys SECStatus nss_rv;
22925051Swyllys CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
22935051Swyllys CERTCertificate *nss_cert = NULL;
22945051Swyllys CERTCertTrust *nss_trust = NULL;
22955051Swyllys
22965051Swyllys if (nss_slot == NULL || cert == NULL)
22975051Swyllys return (KMF_ERR_BAD_PARAMETER);
22985051Swyllys
22995051Swyllys nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data,
23005051Swyllys cert->Length);
23015051Swyllys if (nss_cert == NULL) {
23025051Swyllys SET_ERROR(kmfh, PORT_GetError());
23035051Swyllys ret = KMF_ERR_BAD_CERT_FORMAT;
23045051Swyllys goto out;
23055051Swyllys }
23065051Swyllys
23075051Swyllys /* Store the cert into the NSS database */
23085051Swyllys nss_rv = PK11_ImportCert(nss_slot, nss_cert, CK_INVALID_HANDLE,
23095051Swyllys label, 0);
23105051Swyllys if (nss_rv) {
23115051Swyllys SET_ERROR(kmfh, nss_rv);
23125051Swyllys ret = KMF_ERR_BAD_CERT_FORMAT;
23135051Swyllys goto out;
23145051Swyllys }
23155051Swyllys
23165051Swyllys /* If trust_flag is NULL, then we are done */
23175051Swyllys if (trust_flag == NULL)
23185051Swyllys goto out;
23195051Swyllys
23205051Swyllys nss_trust = (CERTCertTrust *) malloc(sizeof (CERTCertTrust));
23215051Swyllys if (nss_trust == NULL) {
23225051Swyllys ret = KMF_ERR_MEMORY;
23235051Swyllys goto out;
23245051Swyllys }
23255051Swyllys
23265051Swyllys nss_rv = CERT_DecodeTrustString(nss_trust, trust_flag);
23275051Swyllys if (nss_rv) {
23285051Swyllys SET_ERROR(kmfh, nss_rv);
23295051Swyllys ret = KMF_ERR_BAD_PARAMETER;
23305051Swyllys goto out;
23315051Swyllys }
23325051Swyllys
23335051Swyllys nss_rv = CERT_ChangeCertTrust(certHandle, nss_cert, nss_trust);
23345051Swyllys if (nss_rv) {
23355051Swyllys SET_ERROR(kmfh, nss_rv);
23365051Swyllys ret = KMF_ERR_BAD_PARAMETER;
23375051Swyllys }
23385051Swyllys
23395051Swyllys out:
23405051Swyllys if (nss_cert != NULL) {
23415051Swyllys CERT_DestroyCertificate(nss_cert);
23425051Swyllys }
23435051Swyllys
23445051Swyllys if (nss_trust != NULL) {
23455051Swyllys free(nss_trust);
23465051Swyllys }
23475051Swyllys
23485051Swyllys return (ret);
23495051Swyllys }
23505051Swyllys
23515051Swyllys
23525051Swyllys KMF_RETURN
NSS_StoreCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)23535051Swyllys NSS_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
23545051Swyllys {
23555051Swyllys KMF_RETURN ret = KMF_OK;
23565051Swyllys PK11SlotInfo *nss_slot = NULL;
23575051Swyllys KMF_DATA *cert = NULL;
23585051Swyllys char *label = NULL;
23595051Swyllys char *trust_flag = NULL;
23605051Swyllys
23615051Swyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
23625051Swyllys return (KMF_ERR_BAD_PARAMETER);
23635051Swyllys }
23645051Swyllys
23655051Swyllys ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
23665051Swyllys if (ret != KMF_OK)
23675051Swyllys return (ret);
23685051Swyllys
23695051Swyllys /* Get the cert data */
23705051Swyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
23715051Swyllys if (cert == NULL || cert->Data == NULL)
23725051Swyllys return (KMF_ERR_BAD_PARAMETER);
23735051Swyllys
23745051Swyllys /* The label attribute is optional */
23755051Swyllys label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
23765051Swyllys
23775051Swyllys /* The trustflag attriburte is optional */
23785051Swyllys trust_flag = kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR, attrlist, numattr);
23795051Swyllys
23805051Swyllys ret = store_cert(handle, nss_slot, cert, label, trust_flag);
23815051Swyllys
23825051Swyllys out:
23835051Swyllys if (nss_slot != NULL) {
23845051Swyllys PK11_FreeSlot(nss_slot);
23855051Swyllys }
23865051Swyllys
23875051Swyllys return (ret);
23885051Swyllys }
23895051Swyllys
23905051Swyllys
23915051Swyllys KMF_RETURN
NSS_ImportCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)23925051Swyllys NSS_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
23935051Swyllys {
23945051Swyllys KMF_RETURN ret = KMF_OK;
23955051Swyllys PK11SlotInfo *nss_slot = NULL;
23965051Swyllys KMF_DATA cert = {NULL, 0};
23975051Swyllys KMF_DATA cert_der = {NULL, 0};
23985051Swyllys KMF_DATA *cptr = NULL;
23995051Swyllys KMF_ENCODE_FORMAT format;
24005051Swyllys char *label = NULL;
24015051Swyllys char *trust_flag = NULL;
24025051Swyllys char *certfile = NULL;
24035051Swyllys
24045051Swyllys if (handle == NULL || attrlist == NULL || numattr == 0) {
24055051Swyllys return (KMF_ERR_BAD_PARAMETER);
24065051Swyllys }
24075051Swyllys
24085051Swyllys ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
24095051Swyllys if (ret != KMF_OK)
24105051Swyllys return (ret);
24115051Swyllys
24125051Swyllys /* Get the input cert filename attribute */
24135051Swyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
24145051Swyllys if (certfile == NULL)
24155051Swyllys return (KMF_ERR_BAD_PARAMETER);
24165051Swyllys
24175051Swyllys /* Check the cert file and auto-detect the file format of it. */
24185051Swyllys ret = kmf_is_cert_file(handle, certfile, &format);
24195051Swyllys if (ret != KMF_OK)
24205051Swyllys return (ret);
24215051Swyllys
24225051Swyllys ret = kmf_read_input_file(handle, certfile, &cert);
24235051Swyllys if (ret != KMF_OK) {
24245051Swyllys return (ret);
24255051Swyllys }
24265051Swyllys
24275051Swyllys /*
24285051Swyllys * If the imported cert is in PEM format, convert it to
24295051Swyllys * DER format in order to store it in NSS token.
24305051Swyllys */
24315051Swyllys if (format == KMF_FORMAT_PEM) {
24325051Swyllys int derlen;
24335051Swyllys ret = kmf_pem_to_der(cert.Data, cert.Length,
24345051Swyllys &cert_der.Data, &derlen);
24355051Swyllys if (ret != KMF_OK) {
24365051Swyllys goto cleanup;
24375051Swyllys }
24385051Swyllys cert_der.Length = (size_t)derlen;
24395051Swyllys cptr = &cert_der;
24405051Swyllys } else {
24415051Swyllys cptr = &cert;
24425051Swyllys }
24435051Swyllys
24445051Swyllys label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
24455051Swyllys trust_flag = kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR, attrlist, numattr);
24465051Swyllys ret = store_cert(handle, nss_slot, cptr, label, trust_flag);
24475051Swyllys
24485051Swyllys cleanup:
24495051Swyllys if (format == KMF_FORMAT_PEM) {
24505051Swyllys kmf_free_data(&cert_der);
24515051Swyllys }
24525051Swyllys
24535051Swyllys kmf_free_data(&cert);
24545051Swyllys
24555051Swyllys return (ret);
24565051Swyllys }
24575051Swyllys
24585051Swyllys
24595051Swyllys KMF_RETURN
NSS_ImportCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)24605051Swyllys NSS_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
24615051Swyllys {
24625051Swyllys KMF_RETURN ret = KMF_OK;
24635051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
24645051Swyllys PK11SlotInfo *nss_slot = NULL;
24655051Swyllys CERTSignedCrl *nss_crl = NULL;
24665051Swyllys KMF_ENCODE_FORMAT format;
24675051Swyllys int importOptions;
24685051Swyllys SECItem crlDER;
24695051Swyllys KMF_DATA crl1;
24705051Swyllys KMF_DATA crl2;
24715051Swyllys char *crlfilename;
24725051Swyllys boolean_t crlcheck = FALSE;
24735051Swyllys
24745051Swyllys if (attrlist == NULL || numattr == 0) {
24755051Swyllys return (KMF_ERR_BAD_PARAMETER);
24765051Swyllys }
24775051Swyllys
24785051Swyllys ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
24795051Swyllys if (ret != KMF_OK) {
24805051Swyllys return (ret);
24815051Swyllys }
24825051Swyllys
24835051Swyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist,
24845051Swyllys numattr);
24855051Swyllys if (crlfilename == NULL)
24865051Swyllys return (KMF_ERR_BAD_CRLFILE);
24875051Swyllys
24885051Swyllys /*
24895051Swyllys * Check if the input CRL file is a valid CRL file and auto-detect
24905051Swyllys * the encoded format of the file.
24915051Swyllys */
24925051Swyllys ret = kmf_is_crl_file(handle, crlfilename, &format);
24935051Swyllys if (ret != KMF_OK)
24945051Swyllys return (ret);
24955051Swyllys
24965051Swyllys ret = kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
24975051Swyllys &crlcheck, NULL);
24985051Swyllys if (ret != KMF_OK)
24995051Swyllys ret = KMF_OK; /* CRL_CHECK is optional */
25005051Swyllys
25015051Swyllys /* set importOptions */
25025051Swyllys if (crlcheck == B_FALSE) {
25035051Swyllys importOptions = CRL_IMPORT_DEFAULT_OPTIONS |
25045051Swyllys CRL_IMPORT_BYPASS_CHECKS;
25055051Swyllys } else {
25065051Swyllys importOptions = CRL_IMPORT_DEFAULT_OPTIONS;
25075051Swyllys }
25085051Swyllys
25095051Swyllys
25105051Swyllys /* Read in the CRL file */
25115051Swyllys crl1.Data = NULL;
25125051Swyllys crl2.Data = NULL;
25135051Swyllys ret = kmf_read_input_file(handle, crlfilename, &crl1);
25145051Swyllys if (ret != KMF_OK) {
25155051Swyllys return (ret);
25165051Swyllys }
25175051Swyllys
25185051Swyllys /* If the input CRL is in PEM format, convert it to DER first. */
25195051Swyllys if (format == KMF_FORMAT_PEM) {
25205051Swyllys int len;
25215051Swyllys ret = kmf_pem_to_der(crl1.Data, crl1.Length,
25225051Swyllys &crl2.Data, &len);
25235051Swyllys if (ret != KMF_OK) {
25245051Swyllys goto out;
25255051Swyllys }
25265051Swyllys crl2.Length = (size_t)len;
25275051Swyllys }
25285051Swyllys
25295051Swyllys crlDER.data = format == KMF_FORMAT_ASN1 ? crl1.Data : crl2.Data;
25305051Swyllys crlDER.len = format == KMF_FORMAT_ASN1 ? crl1.Length : crl2.Length;
25315051Swyllys
25325051Swyllys nss_crl = PK11_ImportCRL(nss_slot, &crlDER, NULL, SEC_CRL_TYPE,
25335051Swyllys NULL, importOptions, NULL, CRL_DECODE_DEFAULT_OPTIONS);
25345051Swyllys
25355051Swyllys if (nss_crl == NULL) {
25365051Swyllys SET_ERROR(kmfh, PORT_GetError());
25375051Swyllys ret = KMF_ERR_BAD_CRLFILE;
25385051Swyllys goto out;
25395051Swyllys }
25405051Swyllys
25415051Swyllys out:
25425051Swyllys if (nss_slot != NULL) {
25435051Swyllys PK11_FreeSlot(nss_slot);
25445051Swyllys }
25455051Swyllys
25465051Swyllys if (crl1.Data != NULL) {
25475051Swyllys free(crl1.Data);
25485051Swyllys }
25495051Swyllys
25505051Swyllys if (crl2.Data != NULL) {
25515051Swyllys free(crl2.Data);
25525051Swyllys }
25535051Swyllys
25545051Swyllys if (nss_crl != NULL) {
255511411SSurya.Prakki@Sun.COM (void) SEC_DestroyCrl(nss_crl);
25565051Swyllys }
25575051Swyllys
25585051Swyllys return (ret);
25595051Swyllys }
25605051Swyllys
25615051Swyllys KMF_RETURN
NSS_DeleteCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)25625051Swyllys NSS_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
25635051Swyllys {
25645051Swyllys KMF_RETURN rv = KMF_OK;
25655051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
25665051Swyllys CERTSignedCrl *crl = NULL;
25675051Swyllys CERTCertificate *cert = NULL;
25685051Swyllys PK11SlotInfo *nss_slot = NULL;
25695051Swyllys CERTCrlHeadNode *crlList = NULL;
25705051Swyllys CERTCrlNode *crlNode = NULL;
25715051Swyllys PRArenaPool *arena = NULL;
25725051Swyllys CERTName *name = NULL;
25735051Swyllys CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
25745051Swyllys char *issuername, *subjectname;
25755051Swyllys
25765051Swyllys /* check params */
25775051Swyllys if (numattr == 0 || attrlist == NULL) {
25785051Swyllys return (KMF_ERR_BAD_PARAMETER);
25795051Swyllys }
25805051Swyllys
25815051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
25825051Swyllys if (rv != KMF_OK) {
25835051Swyllys return (rv);
25845051Swyllys }
25855051Swyllys
25865051Swyllys issuername = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist,
25875051Swyllys numattr);
25885051Swyllys subjectname = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist,
25895051Swyllys numattr);
25905051Swyllys
25915051Swyllys /* Caller must specify issuer or subject but not both */
25925051Swyllys if ((issuername == NULL && subjectname == NULL) ||
25935051Swyllys (issuername != NULL && subjectname != NULL))
25945051Swyllys return (KMF_ERR_BAD_PARAMETER);
25955051Swyllys
25965051Swyllys /* Find the CRL based on the deletion criteria. */
25975051Swyllys if (issuername != NULL) {
25985051Swyllys /*
25995051Swyllys * If the deletion is based on the issuer's certificate
26005051Swyllys * nickname, we will get the issuer's cert first, then
26015051Swyllys * get the CRL from the cert.
26025051Swyllys */
26035051Swyllys cert = CERT_FindCertByNicknameOrEmailAddr(certHandle,
26045051Swyllys issuername);
26055051Swyllys if (!cert) {
26065051Swyllys SET_ERROR(kmfh, PORT_GetError());
26075051Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
26085051Swyllys goto out;
26095051Swyllys }
26105051Swyllys
26115051Swyllys crl = SEC_FindCrlByName(certHandle, &cert->derSubject,
26125051Swyllys SEC_CRL_TYPE);
26135051Swyllys if (crl == NULL) {
26145051Swyllys SET_ERROR(kmfh, PORT_GetError());
26155051Swyllys rv = KMF_ERR_CRL_NOT_FOUND;
26165051Swyllys goto out;
26175051Swyllys }
26185051Swyllys } else {
26195051Swyllys /*
26205051Swyllys * If the deletion is based on the CRL's subject name, we will
26215051Swyllys * get all the CRLs from the internal database and search
26225051Swyllys * for the CRL with the same subject name.
26235051Swyllys */
26245051Swyllys boolean_t found = B_FALSE;
26255051Swyllys int nssrv;
26265051Swyllys
26275051Swyllys nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE);
26285051Swyllys if (nssrv) {
26295051Swyllys SET_ERROR(kmfh, nssrv);
26305051Swyllys rv = KMF_ERR_CRL_NOT_FOUND;
26315051Swyllys goto out;
26325051Swyllys }
26335051Swyllys
26345051Swyllys if (crlList == NULL) {
26355051Swyllys SET_ERROR(kmfh, PORT_GetError());
26365051Swyllys rv = KMF_ERR_CRL_NOT_FOUND;
26375051Swyllys goto out;
26385051Swyllys }
26395051Swyllys
26405051Swyllys /* Allocate space for name */
26415051Swyllys arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
26425051Swyllys if (arena == NULL) {
26435051Swyllys rv = KMF_ERR_MEMORY;
26445051Swyllys goto out;
26455051Swyllys }
26465051Swyllys
26475051Swyllys name = PORT_ArenaZAlloc(arena, sizeof (*name));
26485051Swyllys if (name == NULL) {
26495051Swyllys rv = KMF_ERR_MEMORY;
26505051Swyllys goto out;
26515051Swyllys }
26525051Swyllys name->arena = arena;
26535051Swyllys
26545051Swyllys crlNode = crlList->first;
26555051Swyllys while (crlNode && !found) {
26565051Swyllys char *asciiname = NULL;
26575051Swyllys SECItem* issuer;
26585051Swyllys
26595051Swyllys name = &crlNode->crl->crl.name;
26605051Swyllys if (!name) {
26615051Swyllys SET_ERROR(kmfh, PORT_GetError());
26625051Swyllys rv = KMF_ERR_CRL_NOT_FOUND;
26635051Swyllys break;
26645051Swyllys }
26655051Swyllys
26665051Swyllys asciiname = CERT_NameToAscii(name);
26675051Swyllys if (asciiname == NULL) {
26685051Swyllys SET_ERROR(kmfh, PORT_GetError());
26695051Swyllys rv = KMF_ERR_CRL_NOT_FOUND;
26705051Swyllys break;
26715051Swyllys }
26725051Swyllys
26735051Swyllys if (strcmp(subjectname, asciiname) == 0) {
26745051Swyllys found = B_TRUE;
26755051Swyllys issuer = &crlNode->crl->crl.derName;
26765051Swyllys crl = SEC_FindCrlByName(certHandle, issuer,
26775051Swyllys SEC_CRL_TYPE);
26785051Swyllys if (crl == NULL) {
26795051Swyllys /* We found a cert but no CRL */
26805051Swyllys SET_ERROR(kmfh, PORT_GetError());
26815051Swyllys rv = KMF_ERR_CRL_NOT_FOUND;
26825051Swyllys }
26835051Swyllys }
26845051Swyllys PORT_Free(asciiname);
26855051Swyllys crlNode = crlNode->next;
26865051Swyllys }
26875051Swyllys
26885051Swyllys if (rv) {
26895051Swyllys goto out;
26905051Swyllys }
26915051Swyllys }
26925051Swyllys
26935051Swyllys if (crl) {
26945051Swyllys (void) SEC_DeletePermCRL(crl);
26955051Swyllys }
26965051Swyllys
26975051Swyllys out:
26985051Swyllys if (nss_slot != NULL) {
26995051Swyllys PK11_FreeSlot(nss_slot);
27005051Swyllys }
27015051Swyllys
27025051Swyllys if (crlList != NULL) {
27035051Swyllys PORT_FreeArena(crlList->arena, PR_FALSE);
27045051Swyllys }
27055051Swyllys
27065051Swyllys if (arena != NULL) {
27075051Swyllys PORT_FreeArena(arena, PR_FALSE);
27085051Swyllys }
27095051Swyllys
27105051Swyllys if (cert != NULL) {
27115051Swyllys CERT_DestroyCertificate(cert);
27125051Swyllys }
27135051Swyllys
27145051Swyllys if (crl != NULL) {
271511411SSurya.Prakki@Sun.COM (void) SEC_DestroyCrl(crl);
27165051Swyllys }
27175051Swyllys
27185051Swyllys return (rv);
27195051Swyllys }
27205051Swyllys
27215051Swyllys KMF_RETURN
NSS_FindCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)27225051Swyllys NSS_FindCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
27235051Swyllys {
27245051Swyllys KMF_RETURN rv = KMF_OK;
27255051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
27265051Swyllys PK11SlotInfo *nss_slot = NULL;
27275051Swyllys CERTCrlHeadNode *crlList = NULL;
27285051Swyllys CERTCrlNode *crlNode = NULL;
27295051Swyllys PRArenaPool *arena = NULL;
27305051Swyllys CERTName *name = NULL;
27315051Swyllys SECStatus nssrv;
27325051Swyllys char *asciiname = NULL;
27335051Swyllys int crl_num;
27345051Swyllys int i, *CRLCount;
27355051Swyllys CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
27365051Swyllys char **CRLNameList;
27375051Swyllys
27385051Swyllys if (numattr == 0 || attrlist == NULL) {
27395051Swyllys return (KMF_ERR_BAD_PARAMETER);
27405051Swyllys }
27415051Swyllys
27425051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
27435051Swyllys if (rv != KMF_OK) {
27445051Swyllys return (rv);
27455051Swyllys }
27465051Swyllys
27475051Swyllys CRLCount = kmf_get_attr_ptr(KMF_CRL_COUNT_ATTR, attrlist, numattr);
27485051Swyllys if (CRLCount == NULL)
27495051Swyllys return (KMF_ERR_BAD_PARAMETER);
27505051Swyllys
27515051Swyllys CRLNameList = (char **)kmf_get_attr_ptr(KMF_CRL_NAMELIST_ATTR,
27525051Swyllys attrlist, numattr);
27535051Swyllys
27545051Swyllys /* Look up Crls */
27555051Swyllys nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE);
27565051Swyllys if (nssrv) {
27575051Swyllys SET_ERROR(kmfh, rv);
27585051Swyllys rv = KMF_ERR_CRL_NOT_FOUND;
27595051Swyllys goto out;
27605051Swyllys }
27615051Swyllys
27625051Swyllys /* Allocate space for name first */
27635051Swyllys arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
27645051Swyllys if (arena == NULL) {
27655051Swyllys rv = KMF_ERR_MEMORY;
27665051Swyllys goto out;
27675051Swyllys }
27685051Swyllys
27695051Swyllys name = PORT_ArenaZAlloc(arena, sizeof (*name));
27705051Swyllys if (name == NULL) {
27715051Swyllys rv = KMF_ERR_MEMORY;
27725051Swyllys goto out;
27735051Swyllys }
27745051Swyllys name->arena = arena;
27755051Swyllys
27765051Swyllys /*
27775051Swyllys * Loop thru the crlList and create a crl list with CRL's subject name.
27785051Swyllys */
27795051Swyllys crlNode = crlList->first;
27805051Swyllys crl_num = 0;
27815051Swyllys while (crlNode) {
27825051Swyllys char *subj_name;
27835051Swyllys
27845051Swyllys /* Get the CRL subject name */
27855051Swyllys name = &crlNode->crl->crl.name;
27865051Swyllys if (!name) {
27875051Swyllys SET_ERROR(kmfh, PORT_GetError());
27885051Swyllys rv = KMF_ERR_CRL_NOT_FOUND;
27895051Swyllys break;
27905051Swyllys }
27915051Swyllys
27925051Swyllys
27935051Swyllys if (CRLNameList != NULL) {
27945051Swyllys asciiname = CERT_NameToAscii(name);
27955051Swyllys if (asciiname == NULL) {
27965051Swyllys SET_ERROR(kmfh, PORT_GetError());
27975051Swyllys rv = KMF_ERR_CRL_NOT_FOUND;
27985051Swyllys break;
27995051Swyllys }
28005051Swyllys subj_name = strdup(asciiname);
28015051Swyllys PORT_Free(asciiname);
28025051Swyllys if (subj_name == NULL) {
28035051Swyllys rv = KMF_ERR_MEMORY;
28045051Swyllys break;
28055051Swyllys }
28065051Swyllys CRLNameList[crl_num] = subj_name;
28075051Swyllys }
28085051Swyllys
28095051Swyllys crl_num++;
28105051Swyllys crlNode = crlNode->next;
28115051Swyllys }
28125051Swyllys
28135051Swyllys if (rv == KMF_OK) {
28145051Swyllys /* success */
28155051Swyllys *CRLCount = crl_num;
28165051Swyllys }
28175051Swyllys
28185051Swyllys out:
28195051Swyllys if (nss_slot != NULL) {
28205051Swyllys PK11_FreeSlot(nss_slot);
28215051Swyllys }
28225051Swyllys
28235051Swyllys if (crlList != NULL) {
28245051Swyllys PORT_FreeArena(crlList->arena, PR_FALSE);
28255051Swyllys }
28265051Swyllys
28275051Swyllys if (arena != NULL) {
28285051Swyllys PORT_FreeArena(arena, PR_FALSE);
28295051Swyllys }
28305051Swyllys
28315051Swyllys /* If failed, free memory allocated for the returning rlist */
28325051Swyllys if (rv && (CRLNameList != NULL)) {
28335051Swyllys for (i = 0; i < crl_num; i++) {
28345051Swyllys free(CRLNameList[i]);
28355051Swyllys }
28365051Swyllys }
28375051Swyllys
28385051Swyllys return (rv);
28395051Swyllys }
28405051Swyllys
28415051Swyllys KMF_RETURN
NSS_FindCertInCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)28425051Swyllys NSS_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
28435051Swyllys {
28445051Swyllys KMF_RETURN rv = KMF_OK;
28455051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
28465051Swyllys PK11SlotInfo *nss_slot = NULL;
28475051Swyllys CERTCertificate *cert = NULL;
28485051Swyllys CERTSignedCrl *crl = NULL;
28495051Swyllys CERTCrlEntry *entry;
28505051Swyllys boolean_t match = B_FALSE;
28515051Swyllys int i;
28525051Swyllys CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
28535051Swyllys char *certlabel;
28545051Swyllys KMF_DATA *certdata;
28555051Swyllys
28565051Swyllys /* check params */
28575051Swyllys if (numattr == 0 || attrlist == NULL) {
28585051Swyllys return (KMF_ERR_BAD_PARAMETER);
28595051Swyllys }
28605051Swyllys
28615051Swyllys rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
28625051Swyllys if (rv != KMF_OK) {
28635051Swyllys return (rv);
28645051Swyllys }
28655051Swyllys
28665051Swyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
28675051Swyllys
28685051Swyllys /* Find the certificate first */
28695051Swyllys if (certlabel != NULL) {
28705051Swyllys cert = CERT_FindCertByNicknameOrEmailAddr(certHandle,
28715051Swyllys certlabel);
28725051Swyllys } else {
28735051Swyllys SECItem derCert = { NULL, 0};
28745051Swyllys
28755051Swyllys certdata = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR,
28765051Swyllys attrlist, numattr);
28775051Swyllys
28785051Swyllys if (certdata == NULL)
28795051Swyllys return (KMF_ERR_BAD_PARAMETER);
28805051Swyllys
28815051Swyllys derCert.data = certdata->Data;
28825051Swyllys derCert.len = certdata->Length;
28835051Swyllys
28845051Swyllys cert = CERT_FindCertByDERCert(certHandle, &derCert);
28855051Swyllys }
28865051Swyllys
28875051Swyllys if (cert == NULL) {
28885051Swyllys SET_ERROR(kmfh, PORT_GetError());
28895051Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
28905051Swyllys goto out;
28915051Swyllys }
28925051Swyllys
28935051Swyllys /* Find the CRL with the same issuer as the given certificate. */
28945051Swyllys crl = SEC_FindCrlByName(certHandle, &cert->derIssuer, SEC_CRL_TYPE);
28955051Swyllys if (crl == NULL) {
28965051Swyllys /*
28975051Swyllys * Could not find the CRL issued by the same issuer. This
28985051Swyllys * usually means that the CRL is not installed in the DB.
28995051Swyllys */
29005051Swyllys SET_ERROR(kmfh, PORT_GetError());
29015051Swyllys rv = KMF_ERR_CRL_NOT_FOUND;
29025051Swyllys goto out;
29035051Swyllys
29045051Swyllys }
29055051Swyllys
29065051Swyllys /* Check if the certificate's serialNumber is revoked in the CRL */
29075051Swyllys i = 0;
29085051Swyllys while ((entry = (crl->crl).entries[i++]) != NULL) {
29095051Swyllys if (SECITEM_CompareItem(&(cert->serialNumber),
29105051Swyllys &(entry->serialNumber)) == SECEqual) {
29115051Swyllys match = B_TRUE;
29125051Swyllys break;
29135051Swyllys }
29145051Swyllys }
29155051Swyllys
29165051Swyllys if (!match) {
29175051Swyllys rv = KMF_ERR_NOT_REVOKED;
29185051Swyllys }
29195051Swyllys
29205051Swyllys out:
29215051Swyllys if (nss_slot != NULL) {
29225051Swyllys PK11_FreeSlot(nss_slot);
29235051Swyllys }
29245051Swyllys
29255051Swyllys if (cert != NULL) {
29265051Swyllys CERT_DestroyCertificate(cert);
29275051Swyllys }
29285051Swyllys
29295051Swyllys if (crl != NULL) {
293011411SSurya.Prakki@Sun.COM (void) SEC_DestroyCrl(crl);
29315051Swyllys }
29325051Swyllys
29335051Swyllys return (rv);
29345051Swyllys }
2935