diff options
| author | wyllys <none@none> | 2007-09-14 12:13:39 -0700 |
|---|---|---|
| committer | wyllys <none@none> | 2007-09-14 12:13:39 -0700 |
| commit | 30a5e8fa1253cb33980ee4514743cf683f584b4e (patch) | |
| tree | 210cd7ded596d35a49c4935177abf7b72b4b241d /usr/src/lib/libkmf/plugins | |
| parent | 1b300de97c3a03432cd287d7e82a800782dcd236 (diff) | |
| download | illumos-gate-30a5e8fa1253cb33980ee4514743cf683f584b4e.tar.gz | |
PSARC 2007/426 KMFAPI Interface Taxonomy Change
PSARC 2007/465 pktool symmetric key enhancements
6546405 KMF Interfaces need to be extensible
6547894 pktool should be more detailed
6590232 pktool should import and export generic keys
Diffstat (limited to 'usr/src/lib/libkmf/plugins')
7 files changed, 4142 insertions, 2826 deletions
diff --git a/usr/src/lib/libkmf/plugins/kmf_nss/common/mapfile-vers b/usr/src/lib/libkmf/plugins/kmf_nss/common/mapfile-vers index ed84774842..86cd5655a4 100644 --- a/usr/src/lib/libkmf/plugins/kmf_nss/common/mapfile-vers +++ b/usr/src/lib/libkmf/plugins/kmf_nss/common/mapfile-vers @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -28,29 +28,28 @@ SUNWprivate_1.1 { global: KMF_Plugin_Initialize; - NSS_FindCert; - NSS_FreeKMFCert; - NSS_StoreCert; - NSS_ImportCert; - NSS_ImportCRL; - NSS_DeleteCert; - NSS_DeleteCRL; - NSS_CreateKeypair; - NSS_FindKey; - NSS_EncodePubKeyData; - NSS_SignData; - NSS_DeleteKey; - NSS_FindCRL; - NSS_FindCertInCRL; - NSS_GetErrorString; - NSS_GetPrikeyByCert; - NSS_DecryptData; - NSS_ExportP12; - NSS_StorePrivateKey; - NSS_CreateSymKey; - NSS_GetSymKeyValue; - NSS_SetTokenPin; - + NSS_CreateKeypair; + NSS_CreateSymKey; + NSS_DecryptData; + NSS_DeleteCRL; + NSS_DeleteCert; + NSS_DeleteKey; + NSS_EncodePubKeyData; + NSS_ExportPK12; + NSS_FindCRL; + NSS_FindCert; + NSS_FindCertInCRL; + NSS_FindKey; + NSS_FindPrikeyByCert; + NSS_FreeKMFCert; + NSS_GetErrorString; + NSS_GetSymKeyValue; + NSS_ImportCRL; + NSS_ImportCert; + NSS_SetTokenPin; + NSS_SignData; + NSS_StoreCert; + NSS_StoreKey; local: *; }; diff --git a/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c b/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c index 2ef9aa0fee..010bc547b9 100644 --- a/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c @@ -58,30 +58,28 @@ mutex_t init_lock = DEFAULTMUTEX; static int nss_initialized = 0; KMF_RETURN -NSS_ConfigureKeystore(KMF_HANDLE_T, KMF_CONFIG_PARAMS *); +NSS_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_FindCert(KMF_HANDLE_T, - KMF_FINDCERT_PARAMS *params, - KMF_X509_DER_CERT *kmf_cert, - uint32_t *num_certs); +NSS_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); void NSS_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); KMF_RETURN -NSS_StoreCert(KMF_HANDLE_T, KMF_STORECERT_PARAMS *params, - KMF_DATA * pcert); +NSS_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_ImportCert(KMF_HANDLE_T, KMF_IMPORTCERT_PARAMS *params); +NSS_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_DeleteCert(KMF_HANDLE_T, KMF_DELETECERT_PARAMS *params); +NSS_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, - KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); +NSS_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); + +KMF_RETURN +NSS_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN NSS_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); @@ -91,55 +89,44 @@ NSS_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, KMF_DATA *, KMF_DATA *); KMF_RETURN -NSS_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *params); +NSS_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *params); +NSS_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_FindCRL(KMF_HANDLE_T, KMF_FINDCRL_PARAMS *params, - char **CRLNameList, int *CRLCount); +NSS_FindCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, - KMF_KEY_HANDLE *, uint32_t *); +NSS_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *params); +NSS_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN NSS_GetErrorString(KMF_HANDLE_T, char **); KMF_RETURN -NSS_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, - KMF_KEY_HANDLE *, boolean_t); +NSS_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, - KMF_KEY_HANDLE *, KMF_KEY_ALG); +NSS_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN NSS_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, KMF_DATA *, KMF_DATA *); KMF_RETURN -NSS_ExportP12(KMF_HANDLE_T, - KMF_EXPORTP12_PARAMS *, - int, KMF_X509_DER_CERT *, - int, KMF_KEY_HANDLE *, - char *); - -KMF_RETURN -NSS_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, KMF_RAW_KEY_DATA *); +NSS_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -NSS_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, KMF_KEY_HANDLE *); +NSS_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN NSS_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); KMF_RETURN -NSS_SetTokenPin(KMF_HANDLE_T, KMF_SETPIN_PARAMS *, KMF_CREDENTIAL *); +NSS_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); static KMF_PLUGIN_FUNCLIST nss_plugin_table = @@ -162,14 +149,14 @@ KMF_PLUGIN_FUNCLIST nss_plugin_table = NSS_FindCRL, NSS_FindCertInCRL, NSS_GetErrorString, - NSS_GetPrikeyByCert, + NSS_FindPrikeyByCert, NSS_DecryptData, - NSS_ExportP12, - NSS_StorePrivateKey, + NSS_ExportPK12, NSS_CreateSymKey, NSS_GetSymKeyValue, NSS_SetTokenPin, NULL, /* VerifyData */ + NSS_StoreKey, NULL /* Finalize */ }; @@ -220,7 +207,7 @@ nss_authenticate(KMF_HANDLE_T handle, /* If a password was given, try to login to the slot */ if (cred == NULL || cred->cred == NULL || cred->credlen == 0 || - nss_slot == NULL) { + nss_slot == NULL) { return (KMF_ERR_BAD_PARAMETER); } @@ -229,8 +216,7 @@ nss_authenticate(KMF_HANDLE_T handle, } PK11_SetPasswordFunc(nss_getpassword); - nssrv = PK11_Authenticate(nss_slot, PR_TRUE, - (void *)cred->cred); + nssrv = PK11_Authenticate(nss_slot, PR_TRUE, (void *)cred->cred); if (nssrv != SECSuccess) { SET_ERROR(kmfh, nssrv); @@ -258,9 +244,8 @@ Init_NSS_DBs(const char *configdir, } rv = NSS_Initialize((configdir && strlen(configdir)) ? - configdir : "./", certPrefix, - keyPrefix, secmodName ? secmodName : "secmod.db", - NSS_INIT_COOPERATE); + configdir : "./", certPrefix, keyPrefix, + secmodName ? secmodName : "secmod.db", NSS_INIT_COOPERATE); if (rv != SECSuccess) { goto end; } @@ -277,23 +262,28 @@ end: * if it is called again. */ KMF_RETURN -NSS_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) +NSS_ConfigureKeystore(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + char *configdir; + char *certPrefix; + char *keyPrefix; + char *secModName; - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); + configdir = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + certPrefix = kmf_get_attr_ptr(KMF_CERTPREFIX_ATTR, attrlist, numattr); + keyPrefix = kmf_get_attr_ptr(KMF_KEYPREFIX_ATTR, attrlist, numattr); + secModName = kmf_get_attr_ptr(KMF_SECMODNAME_ATTR, attrlist, numattr); (void) mutex_lock(&init_lock); if (nss_initialized == 0) { SECStatus err; (void) mutex_unlock(&init_lock); - err = Init_NSS_DBs(params->nssconfig.configdir, - params->nssconfig.certPrefix, - params->nssconfig.keyPrefix, - params->nssconfig.secModName); + err = Init_NSS_DBs(configdir, certPrefix, + keyPrefix, secModName); if (err != SECSuccess) { SET_ERROR(kmfh, err); return (KMF_ERR_INTERNAL); @@ -306,7 +296,6 @@ NSS_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) return (rv); } - /* * This function sets up the slot to be used for other operations. * This function is basically called by every NSS SPI function. @@ -314,44 +303,49 @@ NSS_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) * boolean "internal_slot_only" argument needs to be TRUE. * A slot pointer will be returned when this function is executed successfully. */ -static KMF_RETURN -Do_NSS_Init( - void *handle, - KMF_NSS_PARAMS nss_opts, +KMF_RETURN +do_nss_init(void *handle, int numattr, + KMF_ATTRIBUTE *attrlist, boolean_t internal_slot_only, PK11SlotInfo **nss_slot) { + KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + char *slotlabel = NULL; if (!nss_initialized) return (KMF_ERR_PLUGIN_INIT); + slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr); /* * NSS Is already initialized, but we need to find * the right slot. */ - if (nss_opts.slotlabel == NULL || - strcmp(nss_opts.slotlabel, "internal") == 0) { + if (slotlabel == NULL || + strcmp(slotlabel, "internal") == 0) { *nss_slot = PK11_GetInternalKeySlot(); } else if (internal_slot_only == TRUE) { - return (KMF_ERR_SLOTNAME); + rv = KMF_ERR_SLOTNAME; + goto end; } else { - *nss_slot = PK11_FindSlotByName(nss_opts.slotlabel); + *nss_slot = PK11_FindSlotByName(slotlabel); } if (*nss_slot == NULL) { SET_ERROR(kmfh, PORT_GetError()); - return (KMF_ERR_SLOTNAME); + rv = KMF_ERR_SLOTNAME; + goto end; } /* * If the token was not yet initialized, return an error. */ if (PK11_NeedUserInit(*nss_slot)) { - return (KMF_ERR_UNINITIALIZED_TOKEN); + rv = KMF_ERR_UNINITIALIZED_TOKEN; } - return (KMF_OK); +end: + return (rv); } static KMF_RETURN @@ -363,15 +357,15 @@ nss2kmf_cert(CERTCertificate *nss_cert, KMF_X509_DER_CERT *kmf_cert) kmf_cert->certificate.Length = nss_cert->derCert.len; if ((kmf_cert->certificate.Data = malloc(nss_cert->derCert.len)) == - NULL) { + NULL) { kmf_cert->certificate.Length = 0; return (KMF_ERR_MEMORY); } (void) memcpy(kmf_cert->certificate.Data, nss_cert->derCert.data, - nss_cert->derCert.len); + nss_cert->derCert.len); if (nss_cert->nickname != NULL) kmf_cert->kmf_private.label = - (char *)strdup(nss_cert->nickname); + (char *)strdup(nss_cert->nickname); return (KMF_OK); } @@ -399,7 +393,7 @@ nss_getcert_by_label(KMF_HANDLE *kmfh, break; case KMF_NONEXPIRED_CERTS: validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(), - PR_FALSE); + PR_FALSE); if (validity != secCertTimeValid) { /* this is an invalid cert, reject it */ *num_certs = 0; @@ -409,7 +403,7 @@ nss_getcert_by_label(KMF_HANDLE *kmfh, break; case KMF_EXPIRED_CERTS: validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(), - PR_FALSE); + PR_FALSE); if (validity == secCertTimeValid) { /* this is a valid cert, reject it in this case. */ *num_certs = 0; @@ -448,13 +442,13 @@ nss_find_matching_certs(PK11SlotInfo *slot, boolean_t findSerial = FALSE; if (issuer != NULL && strlen(issuer)) { - rv = KMF_DNParser(issuer, &issuerDN); + rv = kmf_dn_parser(issuer, &issuerDN); if (rv != KMF_OK) return (rv); findIssuer = TRUE; } if (subject != NULL && strlen(subject)) { - rv = KMF_DNParser(subject, &subjectDN); + rv = kmf_dn_parser(subject, &subjectDN); if (rv != KMF_OK) return (rv); findSubject = TRUE; @@ -477,8 +471,8 @@ nss_find_matching_certs(PK11SlotInfo *slot, rv = DerDecodeName(&der, &cmpDN); if (rv == KMF_OK) { match = !KMF_CompareRDNs(&issuerDN, - &cmpDN); - KMF_FreeDN(&cmpDN); + &cmpDN); + kmf_free_dn(&cmpDN); if (!match) goto delete_and_cont; } else { @@ -491,8 +485,8 @@ nss_find_matching_certs(PK11SlotInfo *slot, rv = DerDecodeName(&der, &cmpDN); if (rv == KMF_OK) { match = !KMF_CompareRDNs(&subjectDN, - &cmpDN); - KMF_FreeDN(&cmpDN); + &cmpDN); + kmf_free_dn(&cmpDN); if (!match) goto delete_and_cont; } else { @@ -508,7 +502,7 @@ nss_find_matching_certs(PK11SlotInfo *slot, goto delete_and_cont; if (memcmp(sernum->data, serial->val, - serial->len)) + serial->len)) goto delete_and_cont; } @@ -559,12 +553,19 @@ convertCertList(void *kmfhandle, CERTCertListNode *node; uint32_t maxcerts = *numcerts; + maxcerts = *numcerts; + if (maxcerts == 0) + maxcerts = 0xFFFFFFFF; + *numcerts = 0; + /* + * Don't copy more certs than the caller wanted. + */ for (node = CERT_LIST_HEAD(nsscerts); - !CERT_LIST_END(node, nsscerts) && rv == KMF_OK && - (*numcerts) < maxcerts; - node = CERT_LIST_NEXT(node), (*numcerts)++) { + !CERT_LIST_END(node, nsscerts) && rv == KMF_OK && + (*numcerts) < maxcerts; + node = CERT_LIST_NEXT(node), (*numcerts)++) { if (kmfcerts != NULL) rv = nss2kmf_cert(node->cert, &kmfcerts[*numcerts]); } @@ -575,47 +576,71 @@ convertCertList(void *kmfhandle, if (rv != KMF_OK) { int i; for (i = 0; i < *numcerts; i++) - KMF_FreeKMFCert(kmfhandle, &kmfcerts[i]); + kmf_free_kmf_cert(kmfhandle, &kmfcerts[i]); + *numcerts = 0; } return (rv); } KMF_RETURN -NSS_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, - KMF_X509_DER_CERT *kmfcerts, - uint32_t *num_certs) +NSS_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; PK11SlotInfo *nss_slot = NULL; CERTCertList *certlist = NULL; uint32_t maxcerts; - - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, FALSE, &nss_slot); - if (rv != KMF_OK) { - return (rv); + uint32_t *num_certs; + KMF_X509_DER_CERT *kmfcerts = NULL; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; + + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); } + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) + return (rv); - if (*num_certs == 0) - maxcerts = 0xFFFFFFFF; - else - maxcerts = *num_certs; + num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (num_certs == NULL) + return (KMF_ERR_BAD_PARAMETER); + maxcerts = *num_certs; + if (maxcerts == 0) + maxcerts = 0xFFFFFFFF; *num_certs = 0; - if (params->certLabel) { + + /* Get the optional returned certificate list */ + kmfcerts = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, numattr); + + /* Get optional search criteria attributes */ + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); + if (rv != KMF_OK) { + validity = KMF_ALL_CERTS; + rv = KMF_OK; + } + + if (certlabel != NULL) { /* This will only find 1 certificate */ - rv = nss_getcert_by_label(kmfh, - params->certLabel, - kmfcerts, num_certs, params->find_cert_validity); + rv = nss_getcert_by_label(kmfh, certlabel, kmfcerts, num_certs, + validity); } else { /* * Build a list of matching certs. */ - rv = nss_find_matching_certs(nss_slot, - params->issuer, params->subject, params->serial, - &certlist, params->find_cert_validity); + rv = nss_find_matching_certs(nss_slot, issuer, subject, serial, + &certlist, validity); /* * If the caller supplied a pointer to storage for @@ -623,8 +648,8 @@ NSS_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, * matching certs. */ if (rv == KMF_OK && certlist != NULL) { - rv = convertCertList(handle, - certlist, kmfcerts, &maxcerts); + rv = convertCertList(handle, certlist, kmfcerts, + &maxcerts); CERT_DestroyCertList(certlist); if (rv == KMF_OK) *num_certs = maxcerts; @@ -659,177 +684,49 @@ NSS_FreeKMFCert(KMF_HANDLE_T handle, } } -KMF_RETURN -NSS_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, - KMF_DATA *pcert) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - SECStatus nss_rv; - CERTCertificate *nss_cert = NULL; - CERTCertTrust *nss_trust = NULL; - PK11SlotInfo *nss_slot = NULL; - CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); - - if (pcert == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - /* NSS only support DER format */ - if (params == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - ret = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, FALSE, &nss_slot); - if (ret != KMF_OK) { - return (ret); - } - - nss_cert = CERT_DecodeCertFromPackage((char *)pcert->Data, - pcert->Length); - if (nss_cert == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - ret = KMF_ERR_BAD_CERT_FORMAT; - goto out; - } - - nss_rv = PK11_ImportCert(nss_slot, nss_cert, CK_INVALID_HANDLE, - params->certLabel, 0); - if (nss_rv) { - SET_ERROR(kmfh, nss_rv); - ret = KMF_ERR_BAD_CERT_FORMAT; - goto out; - } - - if (params->ks_opt_u.nss_opts.trustflag != NULL && - strlen(params->ks_opt_u.nss_opts.trustflag)) { - nss_trust = (CERTCertTrust *) malloc(sizeof (CERTCertTrust)); - if (nss_trust == NULL) { - ret = KMF_ERR_MEMORY; - goto out; - } - nss_rv = CERT_DecodeTrustString(nss_trust, - params->ks_opt_u.nss_opts.trustflag); - if (nss_rv) { - SET_ERROR(kmfh, nss_rv); - ret = KMF_ERR_BAD_PARAMETER; - goto out; - } - - nss_rv = CERT_ChangeCertTrust(certHandle, nss_cert, nss_trust); - if (nss_rv) { - SET_ERROR(kmfh, nss_rv); - ret = KMF_ERR_BAD_PARAMETER; - } - } - -out: - if (nss_trust != NULL) { - free(nss_trust); - } - - if (nss_cert != NULL) { - CERT_DestroyCertificate(nss_cert); - } - - if (nss_slot != NULL) { - PK11_FreeSlot(nss_slot); - } - - return (ret); -} - KMF_RETURN -NSS_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_STORECERT_PARAMS scparams; - KMF_DATA cert = {NULL, 0}; - KMF_DATA cert_der = {NULL, 0}; - KMF_DATA *cptr = NULL; - KMF_ENCODE_FORMAT format; - - if (params == NULL || params->certfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - /* - * Check if the input cert file is a valid certificate and - * auto-detect the file format of it. - */ - ret = KMF_IsCertFile(handle, params->certfile, &format); - if (ret != KMF_OK) - return (ret); - - ret = KMF_ReadInputFile(handle, params->certfile, &cert); - if (ret != KMF_OK) { - return (ret); - } - - /* - * If the imported cert is in PEM format, convert it to - * DER format in order to store it in NSS token. - */ - if (format == KMF_FORMAT_PEM) { - int derlen; - ret = KMF_Pem2Der(cert.Data, cert.Length, - &cert_der.Data, &derlen); - if (ret != KMF_OK) { - goto cleanup; - } - cert_der.Length = (size_t)derlen; - cptr = &cert_der; - } else { - cptr = &cert; - } - - (void) memset(&scparams, 0, sizeof (scparams)); - scparams.kstype = params->kstype; - scparams.certLabel = params->certLabel; - scparams.nssparms = params->nssparms; - - ret = NSS_StoreCert(handle, &scparams, cptr); - - if (format == KMF_FORMAT_PEM) { - KMF_FreeData(&cert_der); - } - -cleanup: - KMF_FreeData(&cert); - - return (ret); -} - -KMF_RETURN -NSS_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) +NSS_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; int nssrv; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; CERTCertificate *cert = NULL; PK11SlotInfo *nss_slot = NULL; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; - /* check params */ - if (params == NULL) { + if (handle == NULL || attrlist == NULL || numattr == 0) { return (KMF_ERR_BAD_PARAMETER); } + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) + return (rv); + + /* Get the search criteria attributes. They are all optional. */ + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, - FALSE, &nss_slot); + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); if (rv != KMF_OK) { - return (rv); + validity = KMF_ALL_CERTS; + rv = KMF_OK; } - if (params->certLabel) { - cert = PK11_FindCertFromNickname(params->certLabel, NULL); + /* Start finding the matched certificates and delete them. */ + if (certlabel != NULL) { + cert = PK11_FindCertFromNickname(certlabel, NULL); if (cert == NULL) { return (KMF_ERR_CERT_NOT_FOUND); } - switch (params->find_cert_validity) { + switch (validity) { case KMF_ALL_CERTS: break; case KMF_NONEXPIRED_CERTS: @@ -857,13 +754,12 @@ NSS_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) CERTCertListNode *node; CERTCertList *certlist = NULL; - rv = nss_find_matching_certs(nss_slot, - params->issuer, params->subject, params->serial, - &certlist, params->find_cert_validity); + rv = nss_find_matching_certs(nss_slot, issuer, subject, serial, + &certlist, validity); for (node = CERT_LIST_HEAD(certlist); - !CERT_LIST_END(node, certlist) && rv == KMF_OK; - node = CERT_LIST_NEXT(node)) { + !CERT_LIST_END(node, certlist) && rv == KMF_OK; + node = CERT_LIST_NEXT(node)) { nssrv = SEC_DeletePermCertificate(node->cert); if (nssrv) { @@ -911,63 +807,114 @@ InitRandom(char *filename) KMF_RETURN NSS_CreateKeypair(KMF_HANDLE_T handle, - KMF_CREATEKEYPAIR_PARAMS *params, - KMF_KEY_HANDLE *privkey, - KMF_KEY_HANDLE *pubkey) + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - PK11RSAGenParams rsaparams; - void *nssparams; + PK11RSAGenParams rsaparams; + void *nssparams; CK_MECHANISM_TYPE mechanism; ulong_t publicExponent = 0x010001; PK11SlotInfo *nss_slot = NULL; SECKEYPrivateKey *NSSprivkey = NULL; SECKEYPublicKey *NSSpubkey = NULL; PQGParams *pqgParams = NULL; - - - if (params == NULL) { + KMF_CREDENTIAL cred; + boolean_t storekey = TRUE; + uint32_t keylen = 1024, len; + uint32_t keylen_size = sizeof (uint32_t); + KMF_KEY_ALG keytype = KMF_RSA; + KMF_KEY_HANDLE *pubkey = NULL; + KMF_KEY_HANDLE *privkey = NULL; + char *keylabel = NULL; + + if (handle == NULL || attrlist == NULL || numattr == 0) { return (KMF_ERR_BAD_PARAMETER); } - - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, FALSE, &nss_slot); + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); if (rv != KMF_OK) { return (rv); } - rv = nss_authenticate(handle, nss_slot, ¶ms->cred); + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (rv); + + rv = nss_authenticate(handle, nss_slot, &cred); if (rv != KMF_OK) { return (rv); } + /* "storekey" is optional. Default is TRUE */ + (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr, + &storekey, NULL); + + /* keytype is optional. KMF_RSA is default */ + (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); + + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, + &keylen, &keylen_size); + if (rv == KMF_ERR_ATTR_NOT_FOUND) + /* Default keylen = 1024 */ + rv = KMF_OK; + else if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); + privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); + if (pubkey == NULL || privkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); + (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); + + rv = kmf_get_attr(KMF_KEYLABEL_ATTR, attrlist, numattr, NULL, &len); + if (rv == KMF_OK && len > 0) { + keylabel = malloc(len + 1); + if (keylabel == NULL) + return (KMF_ERR_MEMORY); + /* Now fill in the label value */ + (void) memset(keylabel, 0, len + 1); + rv = kmf_get_attr(KMF_KEYLABEL_ATTR, attrlist, numattr, + keylabel, NULL); + if (rv != KMF_OK) { + free(keylabel); + goto cleanup; + } + } + /* Get some random bits */ InitRandom("/dev/urandom"); - if (params->keytype == KMF_RSA) { - rsaparams.keySizeInBits = params->keylength; + if (keytype == KMF_RSA) { + KMF_BIGINT rsaexp; + + rsaparams.keySizeInBits = keylen; /* * NSS only allows for a 4 byte exponent. * Ignore the exponent parameter if it is too big. */ - if (params->rsa_exponent.len > 0 && - params->rsa_exponent.len <= sizeof (publicExponent) && - params->rsa_exponent.val != NULL) { - (void) memcpy(&publicExponent, - params->rsa_exponent.val, - params->rsa_exponent.len); + if ((rv = kmf_get_attr(KMF_RSAEXP_ATTR, attrlist, numattr, + &rsaexp, NULL)) == KMF_OK) { + if (rsaexp.len > 0 && + rsaexp.len <= sizeof (publicExponent) && + rsaexp.val != NULL) { + (void) memcpy(&publicExponent, rsaexp.val, + rsaexp.len); + } } rsaparams.pe = publicExponent; mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; nssparams = &rsaparams; - } else if (params->keytype == KMF_DSA) { + } else if (keytype == KMF_DSA) { PQGVerify *pqgVerify = NULL; int ks; SECStatus nssrv, passed; mechanism = CKM_DSA_KEY_PAIR_GEN; - ks = PQG_PBITS_TO_INDEX(params->keylength); + ks = PQG_PBITS_TO_INDEX(keylen); nssrv = PK11_PQG_ParamGen(ks, &pqgParams, &pqgVerify); if (nssrv != SECSuccess) { SET_ERROR(kmfh, rv); @@ -995,40 +942,34 @@ NSS_CreateKeypair(KMF_HANDLE_T handle, goto cleanup; } - NSSprivkey = PK11_GenerateKeyPair(nss_slot, - mechanism, nssparams, &NSSpubkey, - PR_TRUE, /* isPermanent */ - PR_TRUE, /* isSensitive */ - (void *)params->cred.cred); + NSSprivkey = PK11_GenerateKeyPair(nss_slot, mechanism, nssparams, + &NSSpubkey, + storekey, /* isPermanent */ + PR_TRUE, /* isSensitive */ + (void *)cred.cred); if (NSSprivkey == NULL || NSSpubkey == NULL) { SET_ERROR(kmfh, PORT_GetError()); rv = KMF_ERR_KEYGEN_FAILED; } else { - if (params->keylabel != NULL && - strlen(params->keylabel)) { + if (keylabel != NULL && strlen(keylabel)) { (void) PK11_SetPrivateKeyNickname(NSSprivkey, - params->keylabel); - (void) PK11_SetPublicKeyNickname(NSSpubkey, - params->keylabel); + keylabel); + (void) PK11_SetPublicKeyNickname(NSSpubkey, keylabel); } /* Now, convert it to a KMF_KEY object for the framework */ - if (privkey != NULL) { - privkey->kstype = KMF_KEYSTORE_NSS; - privkey->keyalg = params->keytype; - privkey->keyclass = KMF_ASYM_PRI; - privkey->keylabel = - PK11_GetPrivateKeyNickname(NSSprivkey); - privkey->keyp = (void *)NSSprivkey; - } - if (pubkey != NULL) { - pubkey->kstype = KMF_KEYSTORE_NSS; - pubkey->keyalg = params->keytype; - pubkey->keyp = (void *)NSSpubkey; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->keylabel = - PK11_GetPublicKeyNickname(NSSpubkey); - } + privkey->kstype = KMF_KEYSTORE_NSS; + privkey->keyalg = keytype; + privkey->keyclass = KMF_ASYM_PRI; + privkey->keylabel = PK11_GetPrivateKeyNickname(NSSprivkey); + privkey->keyp = (void *)NSSprivkey; + + pubkey->kstype = KMF_KEYSTORE_NSS; + pubkey->keyalg = keytype; + pubkey->keyp = (void *)NSSpubkey; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->keylabel = PK11_GetPublicKeyNickname(NSSpubkey); + rv = KMF_OK; } cleanup: @@ -1042,10 +983,12 @@ cleanup: pubkey->keyp = NULL; } + if (keylabel) + free(keylabel); + if (pqgParams != NULL) PK11_PQG_DestroyParams(pqgParams); - if (nss_slot != NULL) PK11_FreeSlot(nss_slot); @@ -1054,11 +997,11 @@ cleanup: KMF_RETURN NSS_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, - KMF_OID *AlgOID, KMF_DATA *tobesigned, - KMF_DATA *output) + KMF_OID *AlgOID, KMF_DATA *tobesigned, + KMF_DATA *output) { KMF_RETURN ret = KMF_OK; - KMF_ALGORITHM_INDEX AlgId; + KMF_ALGORITHM_INDEX AlgId; SECOidTag signAlgTag; SECKEYPrivateKey *NSSprivkey = NULL; SECStatus rv; @@ -1073,7 +1016,7 @@ NSS_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, return (KMF_ERR_BAD_PARAMETER); /* Map the OID to a NSS algorithm */ - AlgId = X509_AlgorithmOidToAlgId(AlgOID); + AlgId = x509_algoid_to_algid(AlgOID); if (AlgId == KMF_ALGID_NONE) return (KMF_ERR_BAD_PARAMETER); @@ -1129,8 +1072,7 @@ NSS_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, } rvitem = SEC_ASN1EncodeItem(NULL, NULL, spki, - CERT_SubjectPublicKeyInfoTemplate); - + CERT_SubjectPublicKeyInfoTemplate); if (rvitem != NULL) { encoded->Data = malloc(rvitem->len); if (encoded->Data == NULL) { @@ -1152,50 +1094,65 @@ NSS_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, } KMF_RETURN -NSS_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, - KMF_KEY_HANDLE *key, boolean_t delete_token) +NSS_DeleteKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; PK11SlotInfo *nss_slot = NULL; + KMF_KEY_HANDLE *key; + KMF_CREDENTIAL cred; + boolean_t delete_token = B_TRUE; + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } /* * "delete_token" means to clear it from the token storage as well * as from memory. */ + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); if (key == NULL || key->keyp == NULL) return (KMF_ERR_BAD_PARAMETER); + rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, + (void *)&delete_token, NULL); + if (rv != KMF_OK) + /* "delete_token" is optional. Default is TRUE */ + rv = KMF_OK; + if (delete_token) { SECStatus nssrv = SECSuccess; if (key->keyclass != KMF_ASYM_PUB && - key->keyclass != KMF_ASYM_PRI && - key->keyclass != KMF_SYMMETRIC) + key->keyclass != KMF_ASYM_PRI && + key->keyclass != KMF_SYMMETRIC) return (KMF_ERR_BAD_KEY_CLASS); - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, FALSE, &nss_slot); + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); if (rv != KMF_OK) { return (rv); } - rv = nss_authenticate(handle, nss_slot, ¶ms->cred); + + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = nss_authenticate(handle, nss_slot, &cred); if (rv != KMF_OK) { return (rv); } if (key->keyclass == KMF_ASYM_PUB) { nssrv = PK11_DeleteTokenPublicKey( - (SECKEYPublicKey *)key->keyp); + (SECKEYPublicKey *)key->keyp); } else if (key->keyclass == KMF_ASYM_PRI) { nssrv = PK11_DeleteTokenPrivateKey( - (SECKEYPrivateKey *)key->keyp, PR_TRUE); + (SECKEYPrivateKey *)key->keyp, PR_TRUE); } else if (key->keyclass == KMF_SYMMETRIC) { nssrv = PK11_DeleteTokenSymKey( - (PK11SymKey *) key->keyp); + (PK11SymKey *) key->keyp); if (nssrv == SECSuccess) - PK11_FreeSymKey( - (PK11SymKey *) key->keyp); + PK11_FreeSymKey((PK11SymKey *) key->keyp); } if (nssrv != SECSuccess) { SET_ERROR(handle, PORT_GetError()); @@ -1218,460 +1175,6 @@ NSS_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, } KMF_RETURN -NSS_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - PK11SlotInfo *nss_slot = NULL; - CERTSignedCrl *nss_crl = NULL; - KMF_ENCODE_FORMAT format; - int importOptions; - SECItem crlDER; - KMF_DATA crl1; - KMF_DATA crl2; - - if (params == NULL || params->ks_opt_u.nss_opts.crlfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - /* - * Check if the input CRL file is a valid CRL file and auto-detect - * the encoded format of the file. - */ - ret = KMF_IsCRLFile(handle, params->ks_opt_u.nss_opts.crlfile, - &format); - if (ret != KMF_OK) - return (ret); - - ret = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, TRUE, &nss_slot); - if (ret != KMF_OK) { - return (ret); - } - - /* set importOptions */ - if (params->ks_opt_u.nss_opts.crl_check == B_FALSE) { - importOptions = CRL_IMPORT_DEFAULT_OPTIONS | - CRL_IMPORT_BYPASS_CHECKS; - } else { - importOptions = CRL_IMPORT_DEFAULT_OPTIONS; - } - - - /* Read in the CRL file */ - crl1.Data = NULL; - crl2.Data = NULL; - ret = KMF_ReadInputFile(handle, params->ks_opt_u.nss_opts.crlfile, - &crl1); - if (ret != KMF_OK) { - return (ret); - } - - /* If the input CRL is in PEM format, convert it to DER first. */ - if (format == KMF_FORMAT_PEM) { - int len; - ret = KMF_Pem2Der(crl1.Data, crl1.Length, - &crl2.Data, &len); - if (ret != KMF_OK) { - goto out; - } - crl2.Length = (size_t)len; - } - - crlDER.data = format == KMF_FORMAT_ASN1 ? crl1.Data : crl2.Data; - crlDER.len = format == KMF_FORMAT_ASN1 ? crl1.Length : crl2.Length; - - nss_crl = PK11_ImportCRL(nss_slot, &crlDER, NULL, SEC_CRL_TYPE, - NULL, importOptions, NULL, CRL_DECODE_DEFAULT_OPTIONS); - - if (nss_crl == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - ret = KMF_ERR_BAD_CRLFILE; - goto out; - } - -out: - if (nss_slot != NULL) { - PK11_FreeSlot(nss_slot); - } - - if (crl1.Data != NULL) { - free(crl1.Data); - } - - if (crl2.Data != NULL) { - free(crl2.Data); - } - - if (nss_crl != NULL) { - SEC_DestroyCrl(nss_crl); - } - - return (ret); -} - -KMF_RETURN -NSS_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) -{ - KMF_RETURN rv = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - CERTSignedCrl *crl = NULL; - CERTCertificate *cert = NULL; - PK11SlotInfo *nss_slot = NULL; - CERTCrlHeadNode *crlList = NULL; - CERTCrlNode *crlNode = NULL; - PRArenaPool *arena = NULL; - CERTName *name = NULL; - CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); - - /* check params */ - if (params == NULL || - (params->ks_opt_u.nss_opts.crl_issuerName == NULL && - params->ks_opt_u.nss_opts.crl_subjName == NULL) || - (params->ks_opt_u.nss_opts.crl_issuerName != NULL && - params->ks_opt_u.nss_opts.crl_subjName != NULL)) { - return (KMF_ERR_BAD_PARAMETER); - } - - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, TRUE, - &nss_slot); - if (rv != KMF_OK) { - return (rv); - } - - /* Find the CRL based on the deletion criteria. */ - if (params->ks_opt_u.nss_opts.crl_issuerName != NULL) { - /* - * If the deletion is based on the issuer's certificate - * nickname, we will get the issuer's cert first, then - * get the CRL from the cert. - */ - cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, - params->ks_opt_u.nss_opts.crl_issuerName); - if (!cert) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CERT_NOT_FOUND; - goto out; - } - - crl = SEC_FindCrlByName(certHandle, &cert->derSubject, - SEC_CRL_TYPE); - if (crl == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - goto out; - } - } else { - /* - * If the deletion is based on the CRL's subject name, we will - * get all the CRLs from the internal database and search - * for the CRL with the same subject name. - */ - boolean_t found = B_FALSE; - int nssrv; - - nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); - if (nssrv) { - SET_ERROR(kmfh, nssrv); - rv = KMF_ERR_CRL_NOT_FOUND; - goto out; - } - - if (crlList == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - goto out; - } - - /* Allocate space for name */ - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if (arena == NULL) { - rv = KMF_ERR_MEMORY; - goto out; - } - - name = PORT_ArenaZAlloc(arena, sizeof (*name)); - if (name == NULL) { - rv = KMF_ERR_MEMORY; - goto out; - } - name->arena = arena; - - crlNode = crlList->first; - while (crlNode && !found) { - char *asciiname = NULL; - SECItem* issuer; - - name = &crlNode->crl->crl.name; - if (!name) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - break; - } - - asciiname = CERT_NameToAscii(name); - if (asciiname == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - break; - } - - if (strcmp(params->ks_opt_u.nss_opts.crl_subjName, - asciiname) == 0) { - found = B_TRUE; - issuer = &crlNode->crl->crl.derName; - crl = SEC_FindCrlByName(certHandle, issuer, - SEC_CRL_TYPE); - if (crl == NULL) { - /* We found a cert but no CRL */ - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - } - } - PORT_Free(asciiname); - crlNode = crlNode->next; - } - - if (rv) { - goto out; - } - } - - if (crl) { - (void) SEC_DeletePermCRL(crl); - } - -out: - if (nss_slot != NULL) { - PK11_FreeSlot(nss_slot); - } - - if (crlList != NULL) { - PORT_FreeArena(crlList->arena, PR_FALSE); - } - - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - - if (cert != NULL) { - CERT_DestroyCertificate(cert); - } - - if (crl != NULL) { - SEC_DestroyCrl(crl); - } - - return (rv); -} - - -KMF_RETURN -NSS_FindCRL(KMF_HANDLE_T handle, KMF_FINDCRL_PARAMS *params, - char **CRLNameList, int *CRLCount) -{ - KMF_RETURN rv = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - PK11SlotInfo *nss_slot = NULL; - CERTCrlHeadNode *crlList = NULL; - CERTCrlNode *crlNode = NULL; - PRArenaPool *arena = NULL; - CERTName *name = NULL; - SECStatus nssrv; - char *asciiname = NULL; - int crl_num; - int i; - CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); - - if (CRLCount == NULL || params == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - *CRLCount = 0; - - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, TRUE, &nss_slot); - if (rv != KMF_OK) { - return (rv); - } - - /* Look up Crls */ - nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); - if (nssrv) { - SET_ERROR(kmfh, rv); - rv = KMF_ERR_CRL_NOT_FOUND; - goto out; - } - - /* Allocate space for name first */ - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if (arena == NULL) { - rv = KMF_ERR_MEMORY; - goto out; - } - - name = PORT_ArenaZAlloc(arena, sizeof (*name)); - if (name == NULL) { - rv = KMF_ERR_MEMORY; - goto out; - } - name->arena = arena; - - /* - * Loop thru the crlList and create a crl list with CRL's subject name. - */ - crlNode = crlList->first; - crl_num = 0; - while (crlNode) { - char *subj_name; - - /* Get the CRL subject name */ - name = &crlNode->crl->crl.name; - if (!name) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - break; - } - - - if (CRLNameList != NULL) { - asciiname = CERT_NameToAscii(name); - if (asciiname == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - break; - } - subj_name = strdup(asciiname); - PORT_Free(asciiname); - if (subj_name == NULL) { - rv = KMF_ERR_MEMORY; - break; - } - CRLNameList[crl_num] = subj_name; - } - - crl_num++; - crlNode = crlNode->next; - } - - if (rv == KMF_OK) { - /* success */ - *CRLCount = crl_num; - } - -out: - if (nss_slot != NULL) { - PK11_FreeSlot(nss_slot); - } - - if (crlList != NULL) { - PORT_FreeArena(crlList->arena, PR_FALSE); - } - - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - - /* If failed, free memory allocated for the returning rlist */ - if (rv && (CRLNameList != NULL)) { - for (i = 0; i < crl_num; i++) { - free(CRLNameList[i]); - } - } - - return (rv); -} - - -KMF_RETURN -NSS_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) -{ - KMF_RETURN rv = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - PK11SlotInfo *nss_slot = NULL; - CERTCertificate *cert = NULL; - CERTSignedCrl *crl = NULL; - CERTCrlEntry *entry; - boolean_t match = B_FALSE; - int i; - CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); - - /* check params */ - if (params == NULL || - (params->ks_opt_u.nss_opts.certLabel == NULL && - params->ks_opt_u.nss_opts.certificate == NULL)) { - return (KMF_ERR_BAD_PARAMETER); - } - - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, TRUE, &nss_slot); - if (rv != KMF_OK) { - return (rv); - } - - /* Find the certificate first */ - if (params->ks_opt_u.nss_opts.certLabel != NULL) { - cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, - params->ks_opt_u.nss_opts.certLabel); - } else { - SECItem derCert = { NULL, 0}; - - derCert.data = params->ks_opt_u.nss_opts.certificate->Data; - derCert.len = params->ks_opt_u.nss_opts.certificate->Length; - cert = CERT_FindCertByDERCert(certHandle, &derCert); - } - - if (!cert) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CERT_NOT_FOUND; - goto out; - } - - /* Find the CRL with the same issuer as the given certificate. */ - crl = SEC_FindCrlByName(certHandle, &cert->derIssuer, SEC_CRL_TYPE); - if (crl == NULL) { - /* - * Could not find the CRL issued by the same issuer. This - * usually means that the CRL is not installed in the DB. - */ - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_CRL_NOT_FOUND; - goto out; - - } - - /* Check if the certificate's serialNumber is revoked in the CRL */ - i = 0; - while ((entry = (crl->crl).entries[i++]) != NULL) { - if (SECITEM_CompareItem(&(cert->serialNumber), - &(entry->serialNumber)) == SECEqual) { - match = B_TRUE; - break; - } - } - - if (!match) { - rv = KMF_ERR_NOT_REVOKED; - } - -out: - if (nss_slot != NULL) { - PK11_FreeSlot(nss_slot); - } - - if (cert != NULL) { - CERT_DestroyCertificate(cert); - } - - if (crl != NULL) { - SEC_DestroyCrl(crl); - } - - return (rv); -} - -KMF_RETURN NSS_GetErrorString(KMF_HANDLE_T handle, char **msgstr) { KMF_RETURN ret = KMF_OK; @@ -1693,30 +1196,46 @@ NSS_GetErrorString(KMF_HANDLE_T handle, char **msgstr) } KMF_RETURN -NSS_GetPrikeyByCert(KMF_HANDLE_T handle, KMF_CRYPTOWITHCERT_PARAMS *params, - KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, - KMF_KEY_ALG keytype) +NSS_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { - CERTCertificate *nss_cert = NULL; - SECKEYPrivateKey* privkey = NULL; - PK11SlotInfo *nss_slot = NULL; KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + PK11SlotInfo *nss_slot = NULL; + KMF_CREDENTIAL cred; + KMF_KEY_HANDLE *key = NULL; + KMF_DATA *cert = NULL; + CERTCertificate *nss_cert = NULL; + SECKEYPrivateKey* privkey = NULL; - rv = Do_NSS_Init(handle, - params->nssparms, FALSE, &nss_slot); - if (rv != KMF_OK) { - return (rv); + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); } - rv = nss_authenticate(handle, nss_slot, ¶ms->cred); - if (rv != KMF_OK) { + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) return (rv); - } - nss_cert = CERT_DecodeCertFromPackage((char *)SignerCertData->Data, - SignerCertData->Length); + /* Get the credential */ + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + rv = nss_authenticate(handle, nss_slot, &cred); + if (rv != KMF_OK) + return (rv); + + /* Get the key handle */ + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (key == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* Get the cert data and decode it */ + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL || cert->Data == NULL) + return (KMF_ERR_BAD_PARAMETER); + nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data, + cert->Length); if (nss_cert == NULL) { SET_ERROR(kmfh, PORT_GetError()); return (KMF_ERR_BAD_CERT_FORMAT); @@ -1730,16 +1249,15 @@ NSS_GetPrikeyByCert(KMF_HANDLE_T handle, KMF_CRYPTOWITHCERT_PARAMS *params, key->kstype = KMF_KEYSTORE_NSS; key->keyclass = KMF_ASYM_PRI; - key->keyalg = keytype; key->keyp = (void *)privkey; key->keylabel = PK11_GetPrivateKeyNickname(privkey); CERT_DestroyCertificate(nss_cert); return (KMF_OK); - } + KMF_RETURN NSS_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, KMF_OID *AlgOID, KMF_DATA *ciphertext, @@ -1754,7 +1272,6 @@ NSS_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, uint8_t *in_data, *out_data; int i, blocks; - if (key == NULL || AlgOID == NULL || ciphertext == NULL || output == NULL || ciphertext->Data == NULL || @@ -1812,8 +1329,8 @@ pk11keytype2kmf(CK_KEY_TYPE type) } KMF_RETURN -NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, - KMF_KEY_HANDLE *keys, uint32_t *numkeys) +NSS_FindKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv; SECKEYPrivateKeyList *prilist; @@ -1824,14 +1341,32 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, PK11SymKey *symlist = NULL; int count; uint32_t maxkeys; + KMF_KEY_HANDLE *keys; + uint32_t *numkeys; + KMF_CREDENTIAL cred; + KMF_KEY_CLASS keyclass; + char *findLabel; + KMF_KEY_ALG keytype = KMF_KEYALG_NONE; + + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } + + numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (numkeys == NULL) + return (KMF_ERR_BAD_PARAMETER); - rv = Do_NSS_Init(handle, - parms->ks_opt_u.nss_opts, FALSE, &nss_slot); + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); if (rv != KMF_OK) { return (rv); } - rv = nss_authenticate(handle, nss_slot, &parms->cred); + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = nss_authenticate(handle, nss_slot, &cred); if (rv != KMF_OK) { return (rv); } @@ -1839,24 +1374,29 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, maxkeys = *numkeys; if (maxkeys == 0) maxkeys = 0xFFFFFFFF; - *numkeys = 0; - if (parms->keyclass == KMF_ASYM_PUB) { - publist = PK11_ListPublicKeysInSlot(nss_slot, parms->findLabel); + + rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, + (void *)&keyclass, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + + if (keyclass == KMF_ASYM_PUB) { + publist = PK11_ListPublicKeysInSlot(nss_slot, findLabel); if (publist == NULL) { rv = KMF_ERR_KEY_NOT_FOUND; goto cleanup; } - } else if (parms->keyclass == KMF_ASYM_PRI) { - prilist = PK11_ListPrivKeysInSlot(nss_slot, - parms->findLabel, NULL); + } else if (keyclass == KMF_ASYM_PRI) { + prilist = PK11_ListPrivKeysInSlot(nss_slot, findLabel, NULL); if (prilist == NULL) { rv = KMF_ERR_KEY_NOT_FOUND; goto cleanup; } - } else if (parms->keyclass == KMF_SYMMETRIC) { - symlist = PK11_ListFixedKeysInSlot(nss_slot, parms->findLabel, - NULL); + } else if (keyclass == KMF_SYMMETRIC) { + symlist = PK11_ListFixedKeysInSlot(nss_slot, findLabel, NULL); if (symlist == NULL) { rv = KMF_ERR_KEY_NOT_FOUND; goto cleanup; @@ -1866,18 +1406,19 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, goto cleanup; } - if (parms->keyclass == KMF_ASYM_PUB) { + keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + /* it is okay to have "keys" contains NULL */ + + if (keyclass == KMF_ASYM_PUB) { for (count = 0, pubnode = PUBKEY_LIST_HEAD(publist); - !PUBKEY_LIST_END(pubnode, publist) && - count < maxkeys; - pubnode = PUBKEY_LIST_NEXT(pubnode), count++) { + !PUBKEY_LIST_END(pubnode, publist) && count < maxkeys; + pubnode = PUBKEY_LIST_NEXT(pubnode), count++) { if (keys != NULL) { keys[count].kstype = KMF_KEYSTORE_NSS; keys[count].keyclass = KMF_ASYM_PUB; keys[count].keyp = (void *)pubnode->key; keys[count].keylabel = - PK11_GetPublicKeyNickname( - pubnode->key); + PK11_GetPublicKeyNickname(pubnode->key); if (pubnode->key->keyType == rsaKey) keys[count].keyalg = KMF_RSA; @@ -1886,18 +1427,16 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, } } *numkeys = count; - } else if (parms->keyclass == KMF_ASYM_PRI) { + } else if (keyclass == KMF_ASYM_PRI) { for (count = 0, prinode = PRIVKEY_LIST_HEAD(prilist); - !PRIVKEY_LIST_END(prinode, prilist) && - count < maxkeys; - prinode = PRIVKEY_LIST_NEXT(prinode), count++) { + !PRIVKEY_LIST_END(prinode, prilist) && count < maxkeys; + prinode = PRIVKEY_LIST_NEXT(prinode), count++) { if (keys != NULL) { keys[count].kstype = KMF_KEYSTORE_NSS; keys[count].keyclass = KMF_ASYM_PRI; keys[count].keyp = (void *)prinode->key; keys[count].keylabel = - PK11_GetPrivateKeyNickname( - prinode->key); + PK11_GetPrivateKeyNickname(prinode->key); if (prinode->key->keyType == rsaKey) keys[count].keyalg = KMF_RSA; @@ -1906,8 +1445,12 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, } } *numkeys = count; - } else if (parms->keyclass == KMF_SYMMETRIC) { + } else if (keyclass == KMF_SYMMETRIC) { count = 0; + rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); + if (rv != KMF_OK) + rv = KMF_OK; while (symlist && count < maxkeys) { PK11SymKey *symkey = symlist; CK_KEY_TYPE type; @@ -1916,15 +1459,15 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, type = PK11_GetSymKeyType(symkey); keyalg = pk11keytype2kmf(type); + symlist = PK11_GetNextSymKey(symkey); + /* * If keytype is specified in the searching parameter, * check the keytype and skip the key if its keytype * doesn't match. */ - symlist = PK11_GetNextSymKey(symkey); - if (parms->keytype != KMF_KEYALG_NONE && - parms->keytype != keyalg) { - /* free that key since we aren't using it */ + if (keytype != KMF_KEYALG_NONE && keytype != keyalg) { + /* free that key since we arent using it */ PK11_FreeSymKey(symkey); continue; } @@ -1946,12 +1489,13 @@ NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, */ while (symlist != NULL) { PK11SymKey *symkey = symlist; + PK11_FreeSymKey(symkey); symlist = PK11_GetNextSymKey(symkey); } + *numkeys = count; } - *numkeys = count; cleanup: if (nss_slot != NULL) { PK11_FreeSlot(nss_slot); @@ -2005,7 +1549,7 @@ p12u_ucs2_ascii_conversion_function( } /* Perform the conversion. */ ret = PORT_UCS2_UTF8Conversion(toUnicode, dup->data, dup->len, - outBuf, maxOutBufLen, outBufLen); + outBuf, maxOutBufLen, outBufLen); if (dup) SECITEM_ZfreeItem(dup, PR_TRUE); @@ -2020,11 +1564,10 @@ p12u_OpenFile(p12uContext *p12ctx, PRBool fileRead) } if (fileRead) { - p12ctx->file = PR_Open(p12ctx->filename, - PR_RDONLY, 0400); + p12ctx->file = PR_Open(p12ctx->filename, PR_RDONLY, 0400); } else { p12ctx->file = PR_Open(p12ctx->filename, - PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 0600); + PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 0600); } if (!p12ctx->file) { @@ -2124,7 +1667,7 @@ add_cert_to_bag(SEC_PKCS12ExportContext *p12ecx, certSafe = keySafe; } else { certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem, - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC); + SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC); } if (!certSafe || !keySafe) { @@ -2133,22 +1676,17 @@ add_cert_to_bag(SEC_PKCS12ExportContext *p12ecx, } if (SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert, - CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem, - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC) - != SECSuccess) { + CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem, + SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC) + != SECSuccess) { rv = KMF_ERR_INTERNAL; } out: return (rv); } -/*ARGSUSED*/ KMF_RETURN -NSS_ExportP12(KMF_HANDLE_T handle, - KMF_EXPORTP12_PARAMS *params, - int numcerts, KMF_X509_DER_CERT *certs, - int numkeys, KMF_KEY_HANDLE *keylist, - char *filename) +NSS_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -2159,33 +1697,56 @@ NSS_ExportP12(KMF_HANDLE_T handle, CERTCertListNode* node = NULL; PK11SlotInfo *slot = NULL; SECItem pwitem = {NULL, 0}; + KMF_CREDENTIAL *cred = NULL; + KMF_CREDENTIAL *p12cred = NULL; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + char *filename = NULL; + + if (kmfh == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } - rv = Do_NSS_Init(handle, - params->nssparms, FALSE, &slot); - if (rv != KMF_OK) { + rv = do_nss_init(handle, numattr, attrlist, FALSE, &slot); + if (rv != KMF_OK) return (rv); - } - rv = nss_authenticate(handle, slot, ¶ms->cred); - if (rv != KMF_OK) { + cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); + if (cred == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = nss_authenticate(handle, slot, cred); + if (rv != KMF_OK) return (rv); - } + + p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); + if (p12cred == NULL) + return (KMF_ERR_BAD_PARAMETER); + + filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, + numattr); + if (filename == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* Get optional search criteria attributes */ + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); /* * Find the certificate(s) first. */ - if (params->certLabel) { - nsscert = PK11_FindCertFromNickname(params->certLabel, - NULL); + if (certlabel != NULL) { + nsscert = PK11_FindCertFromNickname(certlabel, NULL); if (nsscert == NULL) { HANDLE_NSS_ERROR(KMF_ERR_CERT_NOT_FOUND) } } else { - rv = nss_find_matching_certs(slot, - params->issuer, - params->subject, - params->serial, - &certlist, 0); + rv = nss_find_matching_certs(slot, issuer, subject, serial, + &certlist, 0); if (rv == KMF_OK && certlist == NULL) { return (KMF_ERR_CERT_NOT_FOUND); @@ -2198,8 +1759,8 @@ NSS_ExportP12(KMF_HANDLE_T handle, * The KMF_CREDENTIAL holds the password to use for * encrypting the PKCS12 key information. */ - pwitem.data = (uchar_t *)params->p12cred.cred; - pwitem.len = params->p12cred.credlen; + pwitem.data = (uchar_t *)p12cred->cred; + pwitem.len = p12cred->credlen; p12ctx = p12u_InitContext(PR_FALSE, filename); if (!p12ctx) { @@ -2207,16 +1768,15 @@ NSS_ExportP12(KMF_HANDLE_T handle, } PORT_SetUCS2_ASCIIConversionFunction( - p12u_ucs2_ascii_conversion_function); + p12u_ucs2_ascii_conversion_function); - p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, - slot, NULL); + p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, slot, NULL); if (!p12ecx) { HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE) } if (SEC_PKCS12AddPasswordIntegrity(p12ecx, &pwitem, SEC_OID_SHA1) - != SECSuccess) { + != SECSuccess) { HANDLE_NSS_ERROR(KMF_ERR_INTERNAL) } @@ -2226,9 +1786,8 @@ NSS_ExportP12(KMF_HANDLE_T handle, */ if (certlist != NULL) { for (node = CERT_LIST_HEAD(certlist); - !CERT_LIST_END(node, certlist) && rv == KMF_OK; - node = CERT_LIST_NEXT(node)) { - + !CERT_LIST_END(node, certlist) && rv == KMF_OK; + node = CERT_LIST_NEXT(node)) { rv = add_cert_to_bag(p12ecx, node->cert, &pwitem); } } else if (nsscert != NULL) { @@ -2236,7 +1795,7 @@ NSS_ExportP12(KMF_HANDLE_T handle, } if (SEC_PKCS12Encode(p12ecx, p12u_WriteToExportFile, p12ctx) - != SECSuccess) { + != SECSuccess) { HANDLE_NSS_ERROR(KMF_ERR_ENCODING) } out: @@ -2261,105 +1820,8 @@ out: t[n].ulValueLen = (CK_ULONG)size; KMF_RETURN -NSS_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, - KMF_RAW_KEY_DATA *rawkey) -{ - KMF_RETURN rv = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - SECStatus ckrv = SECSuccess; - PK11SlotInfo *slot = NULL; - CERTCertificate *nss_cert = NULL; - SECKEYPrivateKeyInfo rpk; - SECItem nickname; - KMF_DATA derkey = { NULL, 0 }; - uchar_t ver = 0; - - if (!kmfh) - return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ - - if (params == NULL || params->certificate == NULL || rawkey == NULL) - return (KMF_ERR_BAD_PARAMETER); - - rv = Do_NSS_Init(handle, - params->nssparms, FALSE, &slot); - - if (rv != KMF_OK) - return (rv); - - rv = nss_authenticate(handle, slot, ¶ms->cred); - if (rv != KMF_OK) { - return (rv); - } - - /* - * Decode the cert into an NSS CERT object so we can access the - * SPKI and KeyUsage data later. - */ - nss_cert = CERT_DecodeCertFromPackage((char *)params->certificate->Data, - params->certificate->Length); - - if (nss_cert == NULL) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_BAD_CERT_FORMAT; - goto cleanup; - } - - (void) memset(&rpk, 0, sizeof (rpk)); - - rpk.arena = NULL; - rpk.version.type = siUnsignedInteger; - rpk.version.data = &ver; - rpk.version.len = 1; - if (rawkey->keytype == KMF_RSA) { - - rv = DerEncodeRSAPrivateKey(&derkey, &rawkey->rawdata.rsa); - if (rv != KMF_OK) - goto cleanup; - - rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm; - rpk.privateKey.data = derkey.Data; - rpk.privateKey.len = derkey.Length; - rpk.attributes = NULL; - - - } else if (rawkey->keytype == KMF_DSA) { - rv = DerEncodeDSAPrivateKey(&derkey, &rawkey->rawdata.dsa); - if (rv != KMF_OK) - goto cleanup; - - rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm; - rpk.privateKey.data = derkey.Data; - rpk.privateKey.len = derkey.Length; - rpk.attributes = NULL; - - } else { - return (KMF_ERR_BAD_PARAMETER); - } - - nickname.data = (uchar_t *)params->label; - nickname.len = (params->label ? strlen(params->label) : 0); - - ckrv = PK11_ImportPrivateKeyInfo(slot, &rpk, - &nickname, &nss_cert->subjectPublicKeyInfo.subjectPublicKey, - TRUE, TRUE, nss_cert->keyUsage, NULL); - - if (ckrv != CKR_OK) { - SET_ERROR(kmfh, PORT_GetError()); - rv = KMF_ERR_INTERNAL; - } - -cleanup: - if (nss_cert != NULL) { - CERT_DestroyCertificate(nss_cert); - } - KMF_FreeData(&derkey); - return (rv); -} - -KMF_RETURN NSS_CreateSymKey(KMF_HANDLE_T handle, - KMF_CREATESYMKEY_PARAMS *params, - KMF_KEY_HANDLE *symkey) + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -2368,21 +1830,49 @@ NSS_CreateSymKey(KMF_HANDLE_T handle, CK_MECHANISM_TYPE keyType; SECStatus nssrv; int keySize; - - if (params == NULL || symkey == NULL) { + KMF_KEY_HANDLE *symkey; + KMF_CREDENTIAL cred; + uint32_t keylen; + uint32_t keylen_size = sizeof (uint32_t); + KMF_KEY_ALG keytype; + char *keylabel = NULL; + + if (kmfh == NULL || attrlist == NULL || numattr == 0) { return (KMF_ERR_BAD_PARAMETER); } - switch (params->keytype) { + symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (symkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, (void *)&keytype, + NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, &keylen, + &keylen_size); + if (rv == KMF_ERR_ATTR_NOT_FOUND && + (keytype == KMF_DES || keytype == KMF_DES3)) + /* keylength is not required for DES and 3DES */ + rv = KMF_OK; + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + if (keylabel == NULL) + return (KMF_ERR_BAD_PARAMETER); + + switch (keytype) { case KMF_AES: keyType = CKM_AES_KEY_GEN; - keySize = params->keylength; + keySize = keylen; if (keySize == 0 || (keySize % 8) != 0) return (KMF_ERR_BAD_KEY_SIZE); break; case KMF_RC4: keyType = CKM_RC4_KEY_GEN; - keySize = params->keylength; + keySize = keylen; if (keySize == 0 || (keySize % 8) != 0) return (KMF_ERR_BAD_KEY_SIZE); break; @@ -2396,7 +1886,7 @@ NSS_CreateSymKey(KMF_HANDLE_T handle, break; case KMF_GENERIC_SECRET: keyType = CKM_GENERIC_SECRET_KEY_GEN; - keySize = params->keylength; + keySize = keylen; if (keySize == 0 || (keySize % 8) != 0) return (KMF_ERR_BAD_KEY_SIZE); break; @@ -2405,26 +1895,30 @@ NSS_CreateSymKey(KMF_HANDLE_T handle, goto out; } - rv = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, FALSE, &nss_slot); + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); if (rv != KMF_OK) { return (rv); } - rv = nss_authenticate(handle, nss_slot, ¶ms->cred); + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = nss_authenticate(handle, nss_slot, &cred); if (rv != KMF_OK) { return (rv); } nsskey = PK11_TokenKeyGen(nss_slot, keyType, NULL, keySize, NULL, - PR_TRUE, (void *)params->cred.cred); + PR_TRUE, (void *)cred.cred); if (nsskey == NULL) { SET_ERROR(kmfh, PORT_GetError()); rv = KMF_ERR_KEYGEN_FAILED; goto out; } - nssrv = PK11_SetSymKeyNickname(nsskey, params->keylabel); + nssrv = PK11_SetSymKeyNickname(nsskey, keylabel); if (nssrv != SECSuccess) { SET_ERROR(kmfh, PORT_GetError()); rv = KMF_ERR_KEYGEN_FAILED; @@ -2432,7 +1926,7 @@ NSS_CreateSymKey(KMF_HANDLE_T handle, } symkey->kstype = KMF_KEYSTORE_NSS; - symkey->keyalg = params->keytype; + symkey->keyalg = keytype; symkey->keyclass = KMF_SYMMETRIC; symkey->israw = FALSE; symkey->keyp = (void *)nsskey; @@ -2478,7 +1972,7 @@ NSS_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) return (KMF_ERR_MEMORY); (void) memcpy(rkey->keydata.val, - rawkey->rawdata.sym.keydata.val, rkey->keydata.len); + rawkey->rawdata.sym.keydata.val, rkey->keydata.len); } else { nsskey = (PK11SymKey *)(symkey->keyp); if (nsskey == NULL) @@ -2519,24 +2013,30 @@ out: } KMF_RETURN -NSS_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, - KMF_CREDENTIAL *newpin) +NSS_SetTokenPin(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; int rv; PK11SlotInfo *nss_slot = NULL; + KMF_CREDENTIAL oldcred, newcred; - if (handle == NULL || params == NULL || newpin == NULL) { + if (handle == NULL || attrlist == NULL || numattr == 0) + return (KMF_ERR_BAD_PARAMETER); + + ret = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&oldcred, NULL); + if (ret != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + ret = kmf_get_attr(KMF_NEWPIN_ATTR, attrlist, numattr, + (void *)&newcred, NULL); + if (ret != KMF_OK) return (KMF_ERR_BAD_PARAMETER); - } - ret = Do_NSS_Init(handle, - params->ks_opt_u.nss_opts, - FALSE, &nss_slot); + ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); /* If it was uninitialized, set it */ if (ret == KMF_ERR_UNINITIALIZED_TOKEN) { - rv = PK11_InitPin(nss_slot, NULL, newpin->cred); + rv = PK11_InitPin(nss_slot, NULL, newcred.cred); if (rv != SECSuccess) { SET_ERROR(kmfh, PORT_GetError()); ret = KMF_ERR_AUTH_FAILED; @@ -2544,12 +2044,11 @@ NSS_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, ret = KMF_OK; } } else if (ret == KMF_OK) { - ret = nss_authenticate(handle, nss_slot, ¶ms->cred); + ret = nss_authenticate(handle, nss_slot, &oldcred); if (ret != KMF_OK) { return (ret); } - rv = PK11_ChangePW(nss_slot, - params->cred.cred, newpin->cred); + rv = PK11_ChangePW(nss_slot, oldcred.cred, newcred.cred); if (rv != SECSuccess) { SET_ERROR(kmfh, PORT_GetError()); ret = KMF_ERR_AUTH_FAILED; @@ -2558,3 +2057,795 @@ NSS_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, return (ret); } + +KMF_RETURN +NSS_StoreKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + PK11SlotInfo *nss_slot = NULL; + KMF_CREDENTIAL cred = {NULL, 0}; + KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL; + KMF_RAW_KEY_DATA *rawkey = NULL; + char *keylabel = NULL; + SECStatus ckrv = SECSuccess; + SECItem nickname = {NULL, 0}; + CERTCertificate *nss_cert = NULL; + + if (kmfh == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } + + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) { + return (rv); + } + + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = nss_authenticate(handle, nss_slot, &cred); + if (rv != KMF_OK) { + return (rv); + } + + pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); + if (pubkey == NULL) { + /* look for private key */ + prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, + numattr); + if (prikey == NULL) + /* look for raw key */ + rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, + attrlist, numattr); + } + + /* If no keys were found, return error */ + if (pubkey == NULL && prikey == NULL && rawkey == NULL) + return (KMF_ERR_ATTR_NOT_FOUND); + + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + if (keylabel != NULL) { + nickname.data = (uchar_t *)keylabel; + nickname.len = strlen(keylabel); + } + + if (rawkey != NULL) { + uchar_t ver = 0; + SECKEYPrivateKeyInfo rpk; + KMF_DATA derkey = {NULL, 0}; + KMF_DATA *cert; + + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL) + return (rv); + /* + * Decode the cert into an NSS CERT object so we can access the + * SPKI and KeyUsage data later. + */ + nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data, + cert->Length); + + if (nss_cert == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_BAD_CERT_FORMAT; + goto cleanup; + } + + (void) memset(&rpk, 0, sizeof (rpk)); + rpk.arena = NULL; + rpk.version.type = siUnsignedInteger; + rpk.version.data = &ver; + rpk.version.len = 1; + if (rawkey->keytype == KMF_RSA) { + rv = DerEncodeRSAPrivateKey(&derkey, + &rawkey->rawdata.rsa); + if (rv != KMF_OK) + goto cleanup; + + } else if (rawkey->keytype == KMF_DSA) { + rv = DerEncodeDSAPrivateKey(&derkey, + &rawkey->rawdata.dsa); + if (rv != KMF_OK) + goto cleanup; + } + rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm; + rpk.privateKey.data = derkey.Data; + rpk.privateKey.len = derkey.Length; + rpk.attributes = NULL; + + ckrv = PK11_ImportPrivateKeyInfo(nss_slot, &rpk, &nickname, + &nss_cert->subjectPublicKeyInfo.subjectPublicKey, TRUE, + TRUE, nss_cert->keyUsage, NULL); + if (ckrv != CKR_OK) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_INTERNAL; + } + kmf_free_data(&derkey); + } else if (pubkey != NULL && pubkey->kstype == KMF_KEYSTORE_NSS) { + CK_OBJECT_HANDLE pk; + SECKEYPublicKey *publicKey = (SECKEYPublicKey *) pubkey->keyp; + + pk = PK11_ImportPublicKey(nss_slot, publicKey, PR_TRUE); + if (pk == CK_INVALID_HANDLE) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_INTERNAL; + } + } else if (prikey != NULL && prikey->kstype == KMF_KEYSTORE_NSS) { + SECKEYPrivateKey *pk; + SECKEYPrivateKey *privKey = (SECKEYPrivateKey *) prikey->keyp; + + pk = PK11_LoadPrivKey(nss_slot, privKey, NULL, PR_TRUE, + PR_TRUE); + if (pk == CK_INVALID_HANDLE) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_INTERNAL; + } + /* We stored it, but don't need the handle anymore */ + SECKEY_DestroyPrivateKey(pk); + } + +cleanup: + if (nss_cert != NULL) + CERT_DestroyCertificate(nss_cert); + PK11_FreeSlot(nss_slot); + return (rv); +} + +/* + * This function is called by NSS_StoreCert() and NSS_ImportCert(). + * The "label" and "trust_flag" arguments can be NULL. + */ +static KMF_RETURN +store_cert(KMF_HANDLE_T handle, PK11SlotInfo *nss_slot, KMF_DATA *cert, + char *label, char *trust_flag) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + SECStatus nss_rv; + CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); + CERTCertificate *nss_cert = NULL; + CERTCertTrust *nss_trust = NULL; + + if (nss_slot == NULL || cert == NULL) + return (KMF_ERR_BAD_PARAMETER); + + nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data, + cert->Length); + if (nss_cert == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + ret = KMF_ERR_BAD_CERT_FORMAT; + goto out; + } + + /* Store the cert into the NSS database */ + nss_rv = PK11_ImportCert(nss_slot, nss_cert, CK_INVALID_HANDLE, + label, 0); + if (nss_rv) { + SET_ERROR(kmfh, nss_rv); + ret = KMF_ERR_BAD_CERT_FORMAT; + goto out; + } + + /* If trust_flag is NULL, then we are done */ + if (trust_flag == NULL) + goto out; + + nss_trust = (CERTCertTrust *) malloc(sizeof (CERTCertTrust)); + if (nss_trust == NULL) { + ret = KMF_ERR_MEMORY; + goto out; + } + + nss_rv = CERT_DecodeTrustString(nss_trust, trust_flag); + if (nss_rv) { + SET_ERROR(kmfh, nss_rv); + ret = KMF_ERR_BAD_PARAMETER; + goto out; + } + + nss_rv = CERT_ChangeCertTrust(certHandle, nss_cert, nss_trust); + if (nss_rv) { + SET_ERROR(kmfh, nss_rv); + ret = KMF_ERR_BAD_PARAMETER; + } + +out: + if (nss_cert != NULL) { + CERT_DestroyCertificate(nss_cert); + } + + if (nss_trust != NULL) { + free(nss_trust); + } + + return (ret); +} + + +KMF_RETURN +NSS_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + PK11SlotInfo *nss_slot = NULL; + KMF_DATA *cert = NULL; + char *label = NULL; + char *trust_flag = NULL; + + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (ret != KMF_OK) + return (ret); + + /* Get the cert data */ + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL || cert->Data == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* The label attribute is optional */ + label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + + /* The trustflag attriburte is optional */ + trust_flag = kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR, attrlist, numattr); + + ret = store_cert(handle, nss_slot, cert, label, trust_flag); + +out: + if (nss_slot != NULL) { + PK11_FreeSlot(nss_slot); + } + + return (ret); +} + + +KMF_RETURN +NSS_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + PK11SlotInfo *nss_slot = NULL; + KMF_DATA cert = {NULL, 0}; + KMF_DATA cert_der = {NULL, 0}; + KMF_DATA *cptr = NULL; + KMF_ENCODE_FORMAT format; + char *label = NULL; + char *trust_flag = NULL; + char *certfile = NULL; + + if (handle == NULL || attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (ret != KMF_OK) + return (ret); + + /* Get the input cert filename attribute */ + certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); + if (certfile == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* Check the cert file and auto-detect the file format of it. */ + ret = kmf_is_cert_file(handle, certfile, &format); + if (ret != KMF_OK) + return (ret); + + ret = kmf_read_input_file(handle, certfile, &cert); + if (ret != KMF_OK) { + return (ret); + } + + /* + * If the imported cert is in PEM format, convert it to + * DER format in order to store it in NSS token. + */ + if (format == KMF_FORMAT_PEM) { + int derlen; + ret = kmf_pem_to_der(cert.Data, cert.Length, + &cert_der.Data, &derlen); + if (ret != KMF_OK) { + goto cleanup; + } + cert_der.Length = (size_t)derlen; + cptr = &cert_der; + } else { + cptr = &cert; + } + + label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + trust_flag = kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR, attrlist, numattr); + ret = store_cert(handle, nss_slot, cptr, label, trust_flag); + +cleanup: + if (format == KMF_FORMAT_PEM) { + kmf_free_data(&cert_der); + } + + kmf_free_data(&cert); + + return (ret); +} + + +KMF_RETURN +NSS_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + PK11SlotInfo *nss_slot = NULL; + CERTSignedCrl *nss_crl = NULL; + KMF_ENCODE_FORMAT format; + int importOptions; + SECItem crlDER; + KMF_DATA crl1; + KMF_DATA crl2; + char *crlfilename; + boolean_t crlcheck = FALSE; + + if (attrlist == NULL || numattr == 0) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (ret != KMF_OK) { + return (ret); + } + + crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, + numattr); + if (crlfilename == NULL) + return (KMF_ERR_BAD_CRLFILE); + + /* + * Check if the input CRL file is a valid CRL file and auto-detect + * the encoded format of the file. + */ + ret = kmf_is_crl_file(handle, crlfilename, &format); + if (ret != KMF_OK) + return (ret); + + ret = kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr, + &crlcheck, NULL); + if (ret != KMF_OK) + ret = KMF_OK; /* CRL_CHECK is optional */ + + /* set importOptions */ + if (crlcheck == B_FALSE) { + importOptions = CRL_IMPORT_DEFAULT_OPTIONS | + CRL_IMPORT_BYPASS_CHECKS; + } else { + importOptions = CRL_IMPORT_DEFAULT_OPTIONS; + } + + + /* Read in the CRL file */ + crl1.Data = NULL; + crl2.Data = NULL; + ret = kmf_read_input_file(handle, crlfilename, &crl1); + if (ret != KMF_OK) { + return (ret); + } + + /* If the input CRL is in PEM format, convert it to DER first. */ + if (format == KMF_FORMAT_PEM) { + int len; + ret = kmf_pem_to_der(crl1.Data, crl1.Length, + &crl2.Data, &len); + if (ret != KMF_OK) { + goto out; + } + crl2.Length = (size_t)len; + } + + crlDER.data = format == KMF_FORMAT_ASN1 ? crl1.Data : crl2.Data; + crlDER.len = format == KMF_FORMAT_ASN1 ? crl1.Length : crl2.Length; + + nss_crl = PK11_ImportCRL(nss_slot, &crlDER, NULL, SEC_CRL_TYPE, + NULL, importOptions, NULL, CRL_DECODE_DEFAULT_OPTIONS); + + if (nss_crl == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + ret = KMF_ERR_BAD_CRLFILE; + goto out; + } + +out: + if (nss_slot != NULL) { + PK11_FreeSlot(nss_slot); + } + + if (crl1.Data != NULL) { + free(crl1.Data); + } + + if (crl2.Data != NULL) { + free(crl2.Data); + } + + if (nss_crl != NULL) { + SEC_DestroyCrl(nss_crl); + } + + return (ret); +} + +KMF_RETURN +NSS_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + CERTSignedCrl *crl = NULL; + CERTCertificate *cert = NULL; + PK11SlotInfo *nss_slot = NULL; + CERTCrlHeadNode *crlList = NULL; + CERTCrlNode *crlNode = NULL; + PRArenaPool *arena = NULL; + CERTName *name = NULL; + CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); + char *issuername, *subjectname; + + /* check params */ + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) { + return (rv); + } + + issuername = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, + numattr); + subjectname = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, + numattr); + + /* Caller must specify issuer or subject but not both */ + if ((issuername == NULL && subjectname == NULL) || + (issuername != NULL && subjectname != NULL)) + return (KMF_ERR_BAD_PARAMETER); + + /* Find the CRL based on the deletion criteria. */ + if (issuername != NULL) { + /* + * If the deletion is based on the issuer's certificate + * nickname, we will get the issuer's cert first, then + * get the CRL from the cert. + */ + cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, + issuername); + if (!cert) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CERT_NOT_FOUND; + goto out; + } + + crl = SEC_FindCrlByName(certHandle, &cert->derSubject, + SEC_CRL_TYPE); + if (crl == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + goto out; + } + } else { + /* + * If the deletion is based on the CRL's subject name, we will + * get all the CRLs from the internal database and search + * for the CRL with the same subject name. + */ + boolean_t found = B_FALSE; + int nssrv; + + nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); + if (nssrv) { + SET_ERROR(kmfh, nssrv); + rv = KMF_ERR_CRL_NOT_FOUND; + goto out; + } + + if (crlList == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + goto out; + } + + /* Allocate space for name */ + arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); + if (arena == NULL) { + rv = KMF_ERR_MEMORY; + goto out; + } + + name = PORT_ArenaZAlloc(arena, sizeof (*name)); + if (name == NULL) { + rv = KMF_ERR_MEMORY; + goto out; + } + name->arena = arena; + + crlNode = crlList->first; + while (crlNode && !found) { + char *asciiname = NULL; + SECItem* issuer; + + name = &crlNode->crl->crl.name; + if (!name) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + break; + } + + asciiname = CERT_NameToAscii(name); + if (asciiname == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + break; + } + + if (strcmp(subjectname, asciiname) == 0) { + found = B_TRUE; + issuer = &crlNode->crl->crl.derName; + crl = SEC_FindCrlByName(certHandle, issuer, + SEC_CRL_TYPE); + if (crl == NULL) { + /* We found a cert but no CRL */ + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + } + } + PORT_Free(asciiname); + crlNode = crlNode->next; + } + + if (rv) { + goto out; + } + } + + if (crl) { + (void) SEC_DeletePermCRL(crl); + } + +out: + if (nss_slot != NULL) { + PK11_FreeSlot(nss_slot); + } + + if (crlList != NULL) { + PORT_FreeArena(crlList->arena, PR_FALSE); + } + + if (arena != NULL) { + PORT_FreeArena(arena, PR_FALSE); + } + + if (cert != NULL) { + CERT_DestroyCertificate(cert); + } + + if (crl != NULL) { + SEC_DestroyCrl(crl); + } + + return (rv); +} + +KMF_RETURN +NSS_FindCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + PK11SlotInfo *nss_slot = NULL; + CERTCrlHeadNode *crlList = NULL; + CERTCrlNode *crlNode = NULL; + PRArenaPool *arena = NULL; + CERTName *name = NULL; + SECStatus nssrv; + char *asciiname = NULL; + int crl_num; + int i, *CRLCount; + CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); + char **CRLNameList; + + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) { + return (rv); + } + + CRLCount = kmf_get_attr_ptr(KMF_CRL_COUNT_ATTR, attrlist, numattr); + if (CRLCount == NULL) + return (KMF_ERR_BAD_PARAMETER); + + CRLNameList = (char **)kmf_get_attr_ptr(KMF_CRL_NAMELIST_ATTR, + attrlist, numattr); + + /* Look up Crls */ + nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); + if (nssrv) { + SET_ERROR(kmfh, rv); + rv = KMF_ERR_CRL_NOT_FOUND; + goto out; + } + + /* Allocate space for name first */ + arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); + if (arena == NULL) { + rv = KMF_ERR_MEMORY; + goto out; + } + + name = PORT_ArenaZAlloc(arena, sizeof (*name)); + if (name == NULL) { + rv = KMF_ERR_MEMORY; + goto out; + } + name->arena = arena; + + /* + * Loop thru the crlList and create a crl list with CRL's subject name. + */ + crlNode = crlList->first; + crl_num = 0; + while (crlNode) { + char *subj_name; + + /* Get the CRL subject name */ + name = &crlNode->crl->crl.name; + if (!name) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + break; + } + + + if (CRLNameList != NULL) { + asciiname = CERT_NameToAscii(name); + if (asciiname == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + break; + } + subj_name = strdup(asciiname); + PORT_Free(asciiname); + if (subj_name == NULL) { + rv = KMF_ERR_MEMORY; + break; + } + CRLNameList[crl_num] = subj_name; + } + + crl_num++; + crlNode = crlNode->next; + } + + if (rv == KMF_OK) { + /* success */ + *CRLCount = crl_num; + } + +out: + if (nss_slot != NULL) { + PK11_FreeSlot(nss_slot); + } + + if (crlList != NULL) { + PORT_FreeArena(crlList->arena, PR_FALSE); + } + + if (arena != NULL) { + PORT_FreeArena(arena, PR_FALSE); + } + + /* If failed, free memory allocated for the returning rlist */ + if (rv && (CRLNameList != NULL)) { + for (i = 0; i < crl_num; i++) { + free(CRLNameList[i]); + } + } + + return (rv); +} + +KMF_RETURN +NSS_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + PK11SlotInfo *nss_slot = NULL; + CERTCertificate *cert = NULL; + CERTSignedCrl *crl = NULL; + CERTCrlEntry *entry; + boolean_t match = B_FALSE; + int i; + CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); + char *certlabel; + KMF_DATA *certdata; + + /* check params */ + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot); + if (rv != KMF_OK) { + return (rv); + } + + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + + /* Find the certificate first */ + if (certlabel != NULL) { + cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, + certlabel); + } else { + SECItem derCert = { NULL, 0}; + + certdata = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, + attrlist, numattr); + + if (certdata == NULL) + return (KMF_ERR_BAD_PARAMETER); + + derCert.data = certdata->Data; + derCert.len = certdata->Length; + + cert = CERT_FindCertByDERCert(certHandle, &derCert); + } + + if (cert == NULL) { + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CERT_NOT_FOUND; + goto out; + } + + /* Find the CRL with the same issuer as the given certificate. */ + crl = SEC_FindCrlByName(certHandle, &cert->derIssuer, SEC_CRL_TYPE); + if (crl == NULL) { + /* + * Could not find the CRL issued by the same issuer. This + * usually means that the CRL is not installed in the DB. + */ + SET_ERROR(kmfh, PORT_GetError()); + rv = KMF_ERR_CRL_NOT_FOUND; + goto out; + + } + + /* Check if the certificate's serialNumber is revoked in the CRL */ + i = 0; + while ((entry = (crl->crl).entries[i++]) != NULL) { + if (SECITEM_CompareItem(&(cert->serialNumber), + &(entry->serialNumber)) == SECEqual) { + match = B_TRUE; + break; + } + } + + if (!match) { + rv = KMF_ERR_NOT_REVOKED; + } + +out: + if (nss_slot != NULL) { + PK11_FreeSlot(nss_slot); + } + + if (cert != NULL) { + CERT_DestroyCertificate(cert); + } + + if (crl != NULL) { + SEC_DestroyCrl(crl); + } + + return (rv); +} diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers b/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers index ae025ddd8f..08ad0b561f 100644 --- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers @@ -37,14 +37,14 @@ SUNWprivate_1.1 { OpenSSL_DeleteCert; OpenSSL_DeleteKey; OpenSSL_EncodePubKeyData; - OpenSSL_ExportP12; + OpenSSL_ExportPK12; OpenSSL_FindCert; OpenSSL_FindCertInCRL; OpenSSL_FindKey; + OpenSSL_FindPrikeyByCert; OpenSSL_FreeKMFCert; OpenSSL_GetErrorString; OpenSSL_GetOCSPStatusForCert; - OpenSSL_GetPrikeyByCert; OpenSSL_GetSymKeyValue; OpenSSL_ImportCRL; OpenSSL_IsCRLFile; @@ -52,10 +52,10 @@ SUNWprivate_1.1 { OpenSSL_ListCRL; OpenSSL_SignData; OpenSSL_StoreCert; - OpenSSL_StorePrivateKey; + OpenSSL_StoreKey; OpenSSL_VerifyCRLFile; - openssl_read_pkcs12; - openssl_import_keypair; + openssl_import_objects; + openssl_build_pk12; local: *; }; diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c index 2e88fee0ae..88ff83dbea 100644 --- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c @@ -103,7 +103,6 @@ KMF_X509_EXT_SUBJ_KEY_ID |\ KMF_X509_EXT_POLICY_MAPPING) -static BIO *bio_err = NULL; static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, @@ -135,13 +134,22 @@ static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, mutex_t init_lock = DEFAULTMUTEX; static int ssl_initialized = 0; +static BIO *bio_err = NULL; + +static int +test_for_file(char *, mode_t); static KMF_RETURN -extract_objects(KMF_HANDLE *, KMF_FINDCERT_PARAMS *, char *, - CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *); +extract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *, + CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *); static KMF_RETURN -kmf_load_cert(KMF_HANDLE *, KMF_FINDCERT_PARAMS *, char *, KMF_DATA *); +kmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, + char *, KMF_DATA *); + +static KMF_RETURN +load_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, + char *, KMF_DATA **, uint32_t *); static KMF_RETURN sslBN2KMFBN(BIGNUM *, KMF_BIGINT *); @@ -149,24 +157,26 @@ sslBN2KMFBN(BIGNUM *, KMF_BIGINT *); static EVP_PKEY * ImportRawRSAKey(KMF_RAW_RSA_KEY *); +static KMF_RETURN +convertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *); + KMF_RETURN -OpenSSL_FindCert(KMF_HANDLE_T, - KMF_FINDCERT_PARAMS *, - KMF_X509_DER_CERT *, - uint32_t *); +OpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); void OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); KMF_RETURN -OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *, KMF_DATA *); +OpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); + +KMF_RETURN +OpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *); +OpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, - KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); +OpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); @@ -176,20 +186,19 @@ OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, KMF_DATA *, KMF_DATA *); KMF_RETURN -OpenSSL_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, - KMF_KEY_HANDLE *, boolean_t); +OpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *); +OpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *); +OpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_ListCRL(KMF_HANDLE_T, KMF_LISTCRL_PARAMS *, char **); +OpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *); +OpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *, @@ -199,48 +208,35 @@ KMF_RETURN OpenSSL_GetErrorString(KMF_HANDLE_T, char **); KMF_RETURN -OpenSSL_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, - KMF_KEY_HANDLE *, KMF_KEY_ALG); +OpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, KMF_DATA *, KMF_DATA *); KMF_RETURN -OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, KMF_OCSPREQUEST_PARAMS *, - char *reqfile); +OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, KMF_OCSPRESPONSE_PARAMS_INPUT *, - KMF_OCSPRESPONSE_PARAMS_OUTPUT *); +OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, - KMF_KEY_HANDLE *, uint32_t *); +OpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_ExportP12(KMF_HANDLE_T, - KMF_EXPORTP12_PARAMS *, - int, KMF_X509_DER_CERT *, - int, KMF_KEY_HANDLE *, - char *); +OpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -OpenSSL_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, - KMF_RAW_KEY_DATA *); - -KMF_RETURN -OpenSSL_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, - KMF_KEY_HANDLE *); +OpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); KMF_RETURN -OpenSSL_VerifyCRLFile(KMF_HANDLE_T, KMF_VERIFYCRL_PARAMS *); +OpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *); KMF_RETURN -OpenSSL_CheckCRLDate(KMF_HANDLE_T, KMF_CHECKCRLDATE_PARAMS *); +OpenSSL_CheckCRLDate(KMF_HANDLE_T, char *); KMF_RETURN OpenSSL_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, @@ -267,14 +263,14 @@ KMF_PLUGIN_FUNCLIST openssl_plugin_table = NULL, /* FindCRL */ OpenSSL_FindCertInCRL, OpenSSL_GetErrorString, - OpenSSL_GetPrikeyByCert, + OpenSSL_FindPrikeyByCert, OpenSSL_DecryptData, - OpenSSL_ExportP12, - OpenSSL_StorePrivateKey, + OpenSSL_ExportPK12, OpenSSL_CreateSymKey, OpenSSL_GetSymKeyValue, NULL, /* SetTokenPin */ OpenSSL_VerifyDataWithCert, + OpenSSL_StoreKey, NULL /* Finalize */ }; @@ -382,7 +378,7 @@ get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN) return (rv); } -static int +int isdir(char *path) { struct stat s; @@ -390,7 +386,7 @@ isdir(char *path) if (stat(path, &s) == -1) return (0); - return (s.st_mode & S_IFDIR); + return ((s.st_mode & S_IFMT) == S_IFDIR); } static KMF_RETURN @@ -441,8 +437,10 @@ cleanup: return (rv); } + static KMF_RETURN -check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) +check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial, + boolean_t *match) { KMF_RETURN rv = KMF_OK; boolean_t findIssuer = FALSE; @@ -461,21 +459,21 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME)); (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME)); - if (params->issuer != NULL && strlen(params->issuer)) { - rv = KMF_DNParser(params->issuer, &issuerDN); + if (issuer != NULL && strlen(issuer)) { + rv = kmf_dn_parser(issuer, &issuerDN); if (rv != KMF_OK) return (KMF_ERR_BAD_PARAMETER); rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); if (rv != KMF_OK) { - KMF_FreeDN(&issuerDN); + kmf_free_dn(&issuerDN); return (KMF_ERR_BAD_PARAMETER); } findIssuer = TRUE; } - if (params->subject != NULL && strlen(params->subject)) { - rv = KMF_DNParser(params->subject, &subjectDN); + if (subject != NULL && strlen(subject)) { + rv = kmf_dn_parser(subject, &subjectDN); if (rv != KMF_OK) { rv = KMF_ERR_BAD_PARAMETER; goto cleanup; @@ -488,7 +486,7 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) } findSubject = TRUE; } - if (params->serial != NULL && params->serial->val != NULL) + if (serial != NULL && serial->val != NULL) findSerial = TRUE; if (findSerial) { @@ -499,7 +497,7 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) if (bn != NULL) { int bnlen = BN_num_bytes(bn); - if (bnlen == params->serial->len) { + if (bnlen == serial->len) { uchar_t *a = malloc(bnlen); if (a == NULL) { rv = KMF_ERR_MEMORY; @@ -507,9 +505,8 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) goto cleanup; } bnlen = BN_bn2bin(bn, a); - *match = !memcmp(a, - params->serial->val, - params->serial->len); + *match = (memcmp(a, serial->val, serial->len) == + 0); rv = KMF_OK; free(a); } @@ -522,15 +519,17 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) } } if (findIssuer) { - *match = !KMF_CompareRDNs(&issuerDN, &certIssuerDN); - if (!(*match)) { + *match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0); + if ((*match) == B_FALSE) { + /* stop checking and bail */ rv = KMF_OK; goto cleanup; } } if (findSubject) { - *match = !KMF_CompareRDNs(&subjectDN, &certSubjectDN); - if (!(*match)) { + *match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0); + if ((*match) == B_FALSE) { + /* stop checking and bail */ rv = KMF_OK; goto cleanup; } @@ -539,22 +538,27 @@ check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) *match = TRUE; cleanup: if (findIssuer) { - KMF_FreeDN(&issuerDN); - KMF_FreeDN(&certIssuerDN); + kmf_free_dn(&issuerDN); + kmf_free_dn(&certIssuerDN); } if (findSubject) { - KMF_FreeDN(&subjectDN); - KMF_FreeDN(&certSubjectDN); + kmf_free_dn(&subjectDN); + kmf_free_dn(&certSubjectDN); } return (rv); } + +/* + * This function loads a certificate file into an X509 data structure, and + * checks if its issuer, subject or the serial number matches with those + * values. If it matches, then return the X509 data structure. + */ static KMF_RETURN load_X509cert(KMF_HANDLE *kmfh, - KMF_FINDCERT_PARAMS *params, - char *pathname, - X509 **outcert) + char *issuer, char *subject, KMF_BIGINT *serial, + char *pathname, X509 **outcert) { KMF_RETURN rv = KMF_OK; X509 *xcert = NULL; @@ -566,7 +570,7 @@ load_X509cert(KMF_HANDLE *kmfh, * auto-detect the file format, regardless of what * the 'format' parameters in the params say. */ - rv = KMF_GetFileFormat(pathname, &format); + rv = kmf_get_file_format(pathname, &format); if (rv != KMF_OK) { if (rv == KMF_ERR_OPEN_FILE) rv = KMF_ERR_CERT_NOT_FOUND; @@ -605,7 +609,8 @@ load_X509cert(KMF_HANDLE *kmfh, goto cleanup; } - if (check_cert(xcert, params, &match) != KMF_OK || match == FALSE) { + if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK || + match == FALSE) { rv = KMF_ERR_CERT_NOT_FOUND; goto cleanup; } @@ -635,8 +640,9 @@ datacmp(const void *a, const void *b) } static KMF_RETURN -load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, - KMF_DATA **certlist, uint32_t *numcerts) +load_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial, + KMF_CERT_VALIDITY validity, char *pathname, + KMF_DATA **certlist, uint32_t *numcerts) { KMF_RETURN rv = KMF_OK; int i; @@ -645,7 +651,7 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, int hits = 0; KMF_ENCODE_FORMAT format; - rv = KMF_GetFileFormat(pathname, &format); + rv = kmf_get_file_format(pathname, &format); if (rv != KMF_OK) { if (rv == KMF_ERR_OPEN_FILE) rv = KMF_ERR_CERT_NOT_FOUND; @@ -658,7 +664,8 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, return (KMF_ERR_MEMORY); certs->Data = NULL; certs->Length = 0; - rv = kmf_load_cert(kmfh, params, pathname, certs); + rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, + pathname, certs); if (rv == KMF_OK) { *certlist = certs; *numcerts = 1; @@ -671,7 +678,7 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, format != KMF_FORMAT_PEM_KEYPAIR) { /* This function only works on PEM files */ - rv = extract_objects(kmfh, params, pathname, + rv = extract_pem(kmfh, issuer, subject, serial, pathname, (uchar_t *)NULL, 0, NULL, &certs, &nc); } else { return (KMF_ERR_ENCODING); @@ -681,10 +688,10 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, return (rv); for (i = 0; i < nc; i++) { - if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) { - rv = KMF_CheckCertDate(kmfh, &certs[i]); - } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) { - rv = KMF_CheckCertDate(kmfh, &certs[i]); + if (validity == KMF_NONEXPIRED_CERTS) { + rv = kmf_check_cert_date(kmfh, &certs[i]); + } else if (validity == KMF_EXPIRED_CERTS) { + rv = kmf_check_cert_date(kmfh, &certs[i]); if (rv == KMF_OK) rv = KMF_ERR_CERT_NOT_FOUND; if (rv == KMF_ERR_VALIDITY_PERIOD) @@ -692,7 +699,7 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, } if (rv != KMF_OK) { /* Remove this cert from the list by clearing it. */ - KMF_FreeData(&certs[i]); + kmf_free_data(&certs[i]); } else { hits++; /* count valid certs found */ } @@ -714,25 +721,27 @@ load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, return (rv); } + static KMF_RETURN kmf_load_cert(KMF_HANDLE *kmfh, - KMF_FINDCERT_PARAMS *params, - char *pathname, - KMF_DATA *cert) + char *issuer, char *subject, KMF_BIGINT *serial, + KMF_CERT_VALIDITY validity, + char *pathname, + KMF_DATA *cert) { KMF_RETURN rv = KMF_OK; X509 *x509cert = NULL; - rv = load_X509cert(kmfh, params, pathname, &x509cert); + rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert); if (rv == KMF_OK && x509cert != NULL && cert != NULL) { rv = ssl_cert2KMFDATA(kmfh, x509cert, cert); if (rv != KMF_OK) { goto cleanup; } - if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) { - rv = KMF_CheckCertDate(kmfh, cert); - } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) { - rv = KMF_CheckCertDate(kmfh, cert); + if (validity == KMF_NONEXPIRED_CERTS) { + rv = kmf_check_cert_date(kmfh, cert); + } else if (validity == KMF_EXPIRED_CERTS) { + rv = kmf_check_cert_date(kmfh, cert); if (rv == KMF_OK) { /* * This is a valid cert so skip it. @@ -926,7 +935,7 @@ openssl_load_key(KMF_HANDLE_T handle, const char *file) return (NULL); } - if (KMF_GetFileFormat((char *)file, &format) != KMF_OK) + if (kmf_get_file_format((char *)file, &format) != KMF_OK) return (NULL); keyfile = BIO_new_file(file, "rb"); @@ -941,12 +950,12 @@ openssl_load_key(KMF_HANDLE_T handle, const char *file) (void) BIO_free(keyfile); keyfile = NULL; /* Try odd ASN.1 variations */ - rv = KMF_ReadInputFile(kmfh, (char *)file, + rv = kmf_read_input_file(kmfh, (char *)file, &filedata); if (rv == KMF_OK) { (void) readAltFormatPrivateKey(&filedata, &pkey); - KMF_FreeData(&filedata); + kmf_free_data(&filedata); } } } else if (format == KMF_FORMAT_PEM || @@ -958,12 +967,12 @@ openssl_load_key(KMF_HANDLE_T handle, const char *file) * Check if this is the alt. format * RSA private key file. */ - rv = KMF_ReadInputFile(kmfh, (char *)file, + rv = kmf_read_input_file(kmfh, (char *)file, &filedata); if (rv == KMF_OK) { uchar_t *d = NULL; int len; - rv = KMF_Pem2Der(filedata.Data, + rv = kmf_pem_to_der(filedata.Data, filedata.Length, &d, &len); if (rv == KMF_OK && d != NULL) { derdata.Data = d; @@ -972,7 +981,7 @@ openssl_load_key(KMF_HANDLE_T handle, const char *file) &derdata, &pkey); free(d); } - KMF_FreeData(&filedata); + kmf_free_data(&filedata); } } } @@ -988,31 +997,59 @@ end: } KMF_RETURN -OpenSSL_FindCert(KMF_HANDLE_T handle, - KMF_FINDCERT_PARAMS *params, - KMF_X509_DER_CERT *kmf_cert, - uint32_t *num_certs) +OpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - char *fullpath; int i, n; uint32_t maxcerts = 0; + uint32_t *num_certs; + KMF_X509_DER_CERT *kmf_cert = NULL; + char *dirpath = NULL; + char *filename = NULL; + char *fullpath = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; - if (num_certs == NULL || params == NULL) + num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (num_certs == NULL) return (KMF_ERR_BAD_PARAMETER); + /* num_certs should reference the size of kmf_cert */ maxcerts = *num_certs; if (maxcerts == 0) maxcerts = 0xFFFFFFFF; *num_certs = 0; - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.certfile); + /* Get the optional returned certificate list */ + kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, + numattr); + /* + * The dirpath attribute and the filename attribute can not be NULL + * at the same time. + */ + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, + numattr); + + fullpath = get_fullpath(dirpath, filename); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); + /* Get optional search criteria attributes */ + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); + if (rv != KMF_OK) { + validity = KMF_ALL_CERTS; + rv = KMF_OK; + } + if (isdir(fullpath)) { DIR *dirp; struct dirent *dp; @@ -1033,14 +1070,14 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, fname = get_fullpath(fullpath, (char *)&dp->d_name); - rv = load_certs(kmfh, params, fname, &certlist, - &loaded_certs); + rv = load_certs(kmfh, issuer, subject, serial, + validity, fname, &certlist, &loaded_certs); if (rv != KMF_OK) { free(fname); if (certlist != NULL) { for (i = 0; i < loaded_certs; i++) - KMF_FreeData(&certlist[i]); + kmf_free_data(&certlist[i]); free(certlist); } continue; @@ -1068,10 +1105,10 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, * certs that were not used. */ for (; i < loaded_certs; i++) - KMF_FreeData(&certlist[i]); + kmf_free_data(&certlist[i]); } else { for (i = 0; i < loaded_certs; i++) - KMF_FreeData(&certlist[i]); + kmf_free_data(&certlist[i]); n += loaded_certs; } free(certlist); @@ -1080,7 +1117,7 @@ OpenSSL_FindCert(KMF_HANDLE_T handle, (*num_certs) = n; if (*num_certs == 0) rv = KMF_ERR_CERT_NOT_FOUND; - else + if (*num_certs > 0) rv = KMF_OK; exit: (void) closedir(dirp); @@ -1088,8 +1125,8 @@ exit: KMF_DATA *certlist = NULL; uint32_t loaded_certs = 0; - rv = load_certs(kmfh, params, fullpath, - &certlist, &loaded_certs); + rv = load_certs(kmfh, issuer, subject, serial, validity, + fullpath, &certlist, &loaded_certs); if (rv != KMF_OK) { free(fullpath); return (rv); @@ -1112,15 +1149,14 @@ exit: } /* If maxcerts < loaded_certs, clean up */ for (; i < loaded_certs; i++) - KMF_FreeData(&certlist[i]); + kmf_free_data(&certlist[i]); } else if (certlist != NULL) { for (i = 0; i < loaded_certs; i++) - KMF_FreeData(&certlist[i]); + kmf_free_data(&certlist[i]); n = loaded_certs; } - if (certlist) + if (certlist != NULL) free(certlist); - *num_certs = n; } @@ -1145,133 +1181,92 @@ OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, } } +/*ARGSUSED*/ KMF_RETURN -OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, - KMF_DATA * pcert) +OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - X509 *xcert = NULL; - FILE *fp; - unsigned char *outbuf; - unsigned char *outbuf_p; - char *fullpath; - int outbuflen; - int len; + KMF_DATA *cert = NULL; + char *outfilename = NULL; + char *dirpath = NULL; + char *fullpath = NULL; KMF_ENCODE_FORMAT format; - if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - /* - * check if the cert output format is supported by OPENSSL. - * however, since the keystore for OPENSSL is just a file, we have - * no way to store the format along with the file. - */ - format = params->sslparms.format; - if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) - return (KMF_ERR_BAD_CERT_FORMAT); - - - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.certfile); - if (fullpath == NULL) + /* Get the cert data */ + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL || cert->Data == NULL) return (KMF_ERR_BAD_PARAMETER); - /* - * When storing a certificate, you must specify a filename. - */ - if (isdir(fullpath)) { - free(fullpath); + /* Check the output filename and directory attributes. */ + outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, + numattr); + if (outfilename == NULL) return (KMF_ERR_BAD_PARAMETER); - } - - /* copy cert data to outbuf */ - outbuflen = pcert->Length; - outbuf = malloc(outbuflen); - if (outbuf == NULL) { - free(fullpath); - return (KMF_ERR_MEMORY); - } - (void) memcpy(outbuf, pcert->Data, pcert->Length); - if ((fp = fopen(fullpath, "w")) == NULL) { - SET_SYS_ERROR(kmfh, errno); - ret = KMF_ERR_INTERNAL; - goto out; - } - - if (format == KMF_FORMAT_ASN1) { - len = fwrite(outbuf, 1, outbuflen, fp); - if (len != outbuflen) { - SET_SYS_ERROR(kmfh, errno); - ret = KMF_ERR_WRITE_FILE; - } else { - ret = KMF_OK; - } - goto out; - } + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + fullpath = get_fullpath(dirpath, outfilename); + if (fullpath == NULL) + return (KMF_ERR_BAD_CERTFILE); - /* - * The output format is not KMF_FORMAT_ASN1, so we will - * Convert the cert data to OpenSSL internal X509 first. - */ - outbuf_p = outbuf; /* use a temp pointer; required by openssl */ - xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen); - if (xcert == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_ENCODING; + /* Check the optional format attribute */ + ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, + &format, NULL); + if (ret != KMF_OK) { + /* If there is no format attribute, then default to PEM */ + format = KMF_FORMAT_PEM; + ret = KMF_OK; + } else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) { + ret = KMF_ERR_BAD_CERT_FORMAT; goto out; } - if (format == KMF_FORMAT_PEM) { - /* Convert to the PEM format and write it out */ - if (!PEM_write_X509(fp, xcert)) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_ENCODING; - } else { - ret = KMF_OK; - } - goto out; - } + /* Store the certificate in the file with the specified format */ + ret = kmf_create_cert_file(cert, format, fullpath); out: if (fullpath != NULL) free(fullpath); - if (outbuf != NULL) { - free(outbuf); - } - if (fp != NULL) { - (void) fclose(fp); - } - - if (xcert != NULL) { - X509_free(xcert); - } - return (ret); } + KMF_RETURN -OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) +OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - char *fullpath = NULL; KMF_DATA certdata = {NULL, 0}; + char *dirpath = NULL; + char *filename = NULL; + char *fullpath = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; - if (params == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.certfile); - + /* + * Get the DIRPATH and CERT_FILENAME attributes. They can not be + * NULL at the same time. + */ + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, + numattr); + fullpath = get_fullpath(dirpath, filename); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); + /* Get optional search criteria attributes */ + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); + if (rv != KMF_OK) { + validity = KMF_ALL_CERTS; + rv = KMF_OK; + } + if (isdir(fullpath)) { DIR *dirp; struct dirent *dp; @@ -1294,8 +1289,8 @@ OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) break; } - rv = kmf_load_cert(kmfh, params, fname, - &certdata); + rv = kmf_load_cert(kmfh, issuer, subject, + serial, validity, fname, &certdata); if (rv == KMF_ERR_CERT_NOT_FOUND) { free(fname); @@ -1322,7 +1317,8 @@ OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) (void) closedir(dirp); } else { /* Just try to load a single certificate */ - rv = kmf_load_cert(kmfh, params, fullpath, &certdata); + rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, + fullpath, &certdata); if (rv == KMF_OK) { if (unlink(fullpath) != 0) { SET_SYS_ERROR(kmfh, errno); @@ -1386,8 +1382,8 @@ cleanup: } static KMF_RETURN -ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, - KMF_CREDENTIAL *cred, EVP_PKEY *pkey) +ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, + KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private) { int rv = 0; RSA *rsa; @@ -1397,7 +1393,10 @@ ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, case KMF_FORMAT_ASN1: if (pkey->type == EVP_PKEY_RSA) { rsa = EVP_PKEY_get1_RSA(pkey); - rv = i2d_RSAPrivateKey_bio(out, rsa); + if (private) + rv = i2d_RSAPrivateKey_bio(out, rsa); + else + rv = i2d_RSAPublicKey_bio(out, rsa); RSA_free(rsa); } else if (pkey->type == EVP_PKEY_DSA) { dsa = EVP_PKEY_get1_DSA(pkey); @@ -1413,15 +1412,19 @@ ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, case KMF_FORMAT_PEM: if (pkey->type == EVP_PKEY_RSA) { rsa = EVP_PKEY_get1_RSA(pkey); - rv = PEM_write_bio_RSAPrivateKey(out, - rsa, NULL /* encryption type */, - NULL, 0, NULL, cred->cred); + if (private) + rv = PEM_write_bio_RSAPrivateKey(out, + rsa, NULL, NULL, 0, NULL, + (cred != NULL ? cred->cred : NULL)); + else + rv = PEM_write_bio_RSAPublicKey(out, + rsa); RSA_free(rsa); } else if (pkey->type == EVP_PKEY_DSA) { dsa = EVP_PKEY_get1_DSA(pkey); rv = PEM_write_bio_DSAPrivateKey(out, - dsa, NULL /* encryption type */, - NULL, 0, NULL, cred->cred); + dsa, NULL, NULL, 0, NULL, + (cred != NULL ? cred->cred : NULL)); DSA_free(dsa); } @@ -1440,35 +1443,46 @@ ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, } KMF_RETURN -OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, - KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) +OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - int format; uint32_t eValue = 0x010001; RSA *sslPrivKey = NULL; DSA *sslDSAKey = NULL; EVP_PKEY *eprikey = NULL; EVP_PKEY *epubkey = NULL; BIO *out = NULL; - char *fullpath = NULL; - - if (params == NULL || params->sslparms.keyfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); + KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL; + uint32_t keylen = 1024; + uint32_t keylen_size = sizeof (uint32_t); + boolean_t storekey = TRUE; + KMF_KEY_ALG keytype = KMF_RSA; + + rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr, + &storekey, NULL); + if (rv != KMF_OK) { + /* "storekey" is optional. Default is TRUE */ + rv = KMF_OK; } - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.keyfile); + rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); + if (rv != KMF_OK) + /* keytype is optional. KMF_RSA is default */ + rv = KMF_OK; - if (fullpath == NULL) + pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); + if (pubkey == NULL) return (KMF_ERR_BAD_PARAMETER); - /* If the requested file exists, return an error */ - if (access(fullpath, F_OK) == 0) { - free(fullpath); - return (KMF_ERR_DUPLICATE_KEYFILE); - } + privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); + if (privkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); + (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); eprikey = EVP_PKEY_new(); if (eprikey == NULL) { @@ -1482,40 +1496,57 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, rv = KMF_ERR_KEYGEN_FAILED; goto cleanup; } - if (params->keytype == KMF_RSA) { - if (params->rsa_exponent.len > 0 && - params->rsa_exponent.len <= sizeof (eValue) && - params->rsa_exponent.val != NULL) - /*LINTED*/ - eValue = *(uint32_t *)params->rsa_exponent.val; + if (keytype == KMF_RSA) { + KMF_BIGINT *rsaexp = NULL; - sslPrivKey = RSA_generate_key(params->keylength, eValue, - NULL, NULL); + rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr); + if (rsaexp != NULL) { + if (rsaexp->len > 0 && + rsaexp->len <= sizeof (eValue) && + rsaexp->val != NULL) { + /*LINTED*/ + eValue = *(uint32_t *)rsaexp->val; + } else { + rv = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } + } else { + /* RSA Exponent is optional. Default is 0x10001 */ + rv = KMF_OK; + } + + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, + &keylen, &keylen_size); + if (rv == KMF_ERR_ATTR_NOT_FOUND) + /* keylen is optional, default is 1024 */ + rv = KMF_OK; + if (rv != KMF_OK) { + rv = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } + + sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL); if (sslPrivKey == NULL) { SET_ERROR(kmfh, ERR_get_error()); rv = KMF_ERR_KEYGEN_FAILED; } else { - if (privkey != NULL && - EVP_PKEY_set1_RSA(eprikey, sslPrivKey)) { - privkey->kstype = KMF_KEYSTORE_OPENSSL; - privkey->keyalg = KMF_RSA; - privkey->keyclass = KMF_ASYM_PRI; - privkey->israw = FALSE; - privkey->keylabel = (char *)strdup(fullpath); - privkey->keyp = (void *)eprikey; - } + (void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey); + privkey->kstype = KMF_KEYSTORE_OPENSSL; + privkey->keyalg = KMF_RSA; + privkey->keyclass = KMF_ASYM_PRI; + privkey->israw = FALSE; + privkey->keyp = (void *)eprikey; + /* OpenSSL derives the public key from the private */ - if (pubkey != NULL && - EVP_PKEY_set1_RSA(epubkey, sslPrivKey)) { - pubkey->kstype = KMF_KEYSTORE_OPENSSL; - pubkey->keyalg = KMF_RSA; - pubkey->israw = FALSE; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->keylabel = (char *)strdup(fullpath); - pubkey->keyp = (void *)epubkey; - } + (void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey); + pubkey->kstype = KMF_KEYSTORE_OPENSSL; + pubkey->keyalg = KMF_RSA; + pubkey->israw = FALSE; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->keyp = (void *)epubkey; } - } else if (params->keytype == KMF_DSA) { + } else if (keytype == KMF_DSA) { + DSA *dp; sslDSAKey = DSA_new(); if (sslDSAKey == NULL) { SET_ERROR(kmfh, ERR_get_error()); @@ -1547,89 +1578,116 @@ OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, goto cleanup; } - if (privkey != NULL) { - privkey->kstype = KMF_KEYSTORE_OPENSSL; - privkey->keyalg = KMF_DSA; - privkey->keyclass = KMF_ASYM_PRI; - privkey->israw = FALSE; - privkey->keylabel = (char *)strdup(fullpath); - if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { - privkey->keyp = (void *)eprikey; + privkey->kstype = KMF_KEYSTORE_OPENSSL; + privkey->keyalg = KMF_DSA; + privkey->keyclass = KMF_ASYM_PRI; + privkey->israw = FALSE; + if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { + privkey->keyp = (void *)eprikey; + } else { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_KEYGEN_FAILED; + goto cleanup; + } + dp = DSA_new(); + /* Make a copy for the public key */ + if (dp != NULL) { + if ((dp->p = BN_new()) == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_MEMORY; + DSA_free(dp); + goto cleanup; + } + if ((dp->q = BN_new()) == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_MEMORY; + BN_free(dp->p); + DSA_free(dp); + goto cleanup; + } + if ((dp->g = BN_new()) == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_MEMORY; + BN_free(dp->q); + BN_free(dp->p); + DSA_free(dp); + goto cleanup; + } + if ((dp->pub_key = BN_new()) == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_MEMORY; + BN_free(dp->q); + BN_free(dp->p); + BN_free(dp->g); + DSA_free(dp); + goto cleanup; + } + (void) BN_copy(dp->p, sslDSAKey->p); + (void) BN_copy(dp->q, sslDSAKey->q); + (void) BN_copy(dp->g, sslDSAKey->g); + (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); + + pubkey->kstype = KMF_KEYSTORE_OPENSSL; + pubkey->keyalg = KMF_DSA; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->israw = FALSE; + + if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { + pubkey->keyp = (void *)epubkey; } else { SET_ERROR(kmfh, ERR_get_error()); rv = KMF_ERR_KEYGEN_FAILED; goto cleanup; } } - if (pubkey != NULL) { - DSA *dp = DSA_new(); - /* Make a copy for the public key */ - if (dp != NULL) { - if ((dp->p = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - DSA_free(dp); - goto cleanup; - } - if ((dp->q = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - BN_free(dp->p); - DSA_free(dp); - goto cleanup; - } - if ((dp->g = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - BN_free(dp->q); - BN_free(dp->p); - DSA_free(dp); - goto cleanup; - } - if ((dp->pub_key = BN_new()) == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_MEMORY; - BN_free(dp->q); - BN_free(dp->p); - BN_free(dp->g); - DSA_free(dp); - goto cleanup; - } - (void) BN_copy(dp->p, sslDSAKey->p); - (void) BN_copy(dp->q, sslDSAKey->q); - (void) BN_copy(dp->g, sslDSAKey->g); - (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); - - pubkey->kstype = KMF_KEYSTORE_OPENSSL; - pubkey->keyalg = KMF_DSA; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->israw = FALSE; - pubkey->keylabel = (char *)strdup(fullpath); - - if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { - pubkey->keyp = (void *)epubkey; - } else { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_KEYGEN_FAILED; - goto cleanup; - } - } - } } if (rv != KMF_OK) { goto cleanup; } - /* Store the private key to the keyfile */ - format = params->sslparms.format; - out = BIO_new_file(fullpath, "wb"); - if (out == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_OPEN_FILE; - goto cleanup; + if (storekey) { + KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */ + int i = 0; + char *keyfile = NULL, *dirpath = NULL; + KMF_ENCODE_FORMAT format; + /* + * Construct a new attribute arrray and call openssl_store_key + */ + kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR, + privkey, sizeof (privkey)); + i++; + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + if (dirpath != NULL) { + storeattrs[i].type = KMF_DIRPATH_ATTR; + storeattrs[i].pValue = dirpath; + storeattrs[i].valueLen = strlen(dirpath); + i++; + } else { + rv = KMF_OK; /* DIRPATH is optional */ + } + keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, + attrlist, numattr); + if (keyfile != NULL) { + storeattrs[i].type = KMF_KEY_FILENAME_ATTR; + storeattrs[i].pValue = keyfile; + storeattrs[i].valueLen = strlen(keyfile); + i++; + } else { + goto cleanup; /* KEYFILE is required */ + } + rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, + (void *)&format, NULL); + if (rv == KMF_OK) { + storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR; + storeattrs[i].pValue = &format; + storeattrs[i].valueLen = sizeof (format); + i++; + } + + rv = OpenSSL_StoreKey(handle, i, storeattrs); } - rv = ssl_write_private_key(kmfh, format, out, ¶ms->cred, eprikey); cleanup: if (rv != KMF_OK) { @@ -1659,17 +1717,9 @@ cleanup: if (sslDSAKey) DSA_free(sslDSAKey); - if (out != NULL) (void) BIO_free(out); - if (fullpath) - free(fullpath); - - /* Protect the file by making it read-only */ - if (rv == KMF_OK) { - (void) chmod(fullpath, 0400); - } return (rv); } @@ -1690,7 +1740,7 @@ OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, return (KMF_ERR_BAD_PARAMETER); /* Map the OID to an OpenSSL algorithm */ - AlgId = X509_AlgorithmOidToAlgId(AlgOID); + AlgId = x509_algoid_to_algid(AlgOID); if (AlgId == KMF_ALGID_NONE) return (KMF_ERR_BAD_PARAMETER); @@ -1777,20 +1827,31 @@ cleanup: KMF_RETURN /*ARGSUSED*/ -OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, - KMF_KEY_HANDLE *key, boolean_t destroy) +OpenSSL_DeleteKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; + KMF_KEY_HANDLE *key; + boolean_t destroy = B_TRUE; + + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); if (key == NULL || key->keyp == NULL) return (KMF_ERR_BAD_PARAMETER); + rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, + (void *)&destroy, NULL); + if (rv != KMF_OK) { + /* "destroy" is optional. Default is TRUE */ + rv = KMF_OK; + } + if (key->keyclass != KMF_ASYM_PUB && key->keyclass != KMF_ASYM_PRI && key->keyclass != KMF_SYMMETRIC) return (KMF_ERR_BAD_KEY_CLASS); if (key->keyclass == KMF_SYMMETRIC) { - KMF_FreeRawSymKey((KMF_RAW_SYM_KEY *)key->keyp); + kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp); key->keyp = NULL; } else { if (key->keyp != NULL) { @@ -1826,409 +1887,6 @@ OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, } KMF_RETURN -OpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - X509_CRL *xcrl = NULL; - X509 *xcert = NULL; - EVP_PKEY *pkey; - KMF_ENCODE_FORMAT format; - BIO *in = NULL, *out = NULL; - int openssl_ret = 0; - char *outcrlfile = NULL; - KMF_ENCODE_FORMAT outformat; - - if (params == NULL || params->sslparms.crlfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - if (params->sslparms.crl_check == B_TRUE && - params->sslparms.certfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - outcrlfile = get_fullpath(params->sslparms.dirpath, - params->sslparms.outcrlfile); - - if (outcrlfile == NULL) - return (KMF_ERR_BAD_PARAMETER); - - if (isdir(outcrlfile)) { - free(outcrlfile); - return (KMF_ERR_BAD_PARAMETER); - } - - ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); - if (ret != KMF_OK) { - free(outcrlfile); - return (ret); - } - - in = BIO_new_file(params->sslparms.crlfile, "rb"); - if (in == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (format == KMF_FORMAT_ASN1) { - xcrl = d2i_X509_CRL_bio(in, NULL); - } else if (format == KMF_FORMAT_PEM) { - xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - } - - if (xcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CRLFILE; - goto end; - } - - /* If bypasscheck is specified, no need to verify. */ - if (params->sslparms.crl_check == B_FALSE) { - goto output; - } - - ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); - if (ret != KMF_OK) - goto end; - - /* Read in the CA cert file and convert to X509 */ - if (BIO_read_filename(in, params->sslparms.certfile) <= 0) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (format == KMF_FORMAT_ASN1) { - xcert = d2i_X509_bio(in, NULL); - } else if (format == KMF_FORMAT_PEM) { - xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); - } else { - ret = KMF_ERR_BAD_CERT_FORMAT; - goto end; - } - - if (xcert == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CERT_FORMAT; - goto end; - } - /* Now get the public key from the CA cert */ - pkey = X509_get_pubkey(xcert); - if (!pkey) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CERTFILE; - goto end; - } - - /* Verify the CRL with the CA's public key */ - openssl_ret = X509_CRL_verify(xcrl, pkey); - EVP_PKEY_free(pkey); - if (openssl_ret > 0) { - ret = KMF_OK; /* verify succeed */ - } else { - SET_ERROR(kmfh, openssl_ret); - ret = KMF_ERR_BAD_CRLFILE; - } - -output: - outformat = params->sslparms.format; - - out = BIO_new_file(outcrlfile, "wb"); - if (out == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (outformat == KMF_FORMAT_ASN1) { - openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); - } else if (outformat == KMF_FORMAT_PEM) { - openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); - } else { - ret = KMF_ERR_BAD_PARAMETER; - goto end; - } - - if (openssl_ret <= 0) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_WRITE_FILE; - } else { - ret = KMF_OK; - } - -end: - if (xcrl != NULL) - X509_CRL_free(xcrl); - - if (xcert != NULL) - X509_free(xcert); - - if (in != NULL) - (void) BIO_free(in); - - if (out != NULL) - (void) BIO_free(out); - - if (outcrlfile != NULL) - free(outcrlfile); - - return (ret); -} - -KMF_RETURN -OpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, - char **crldata) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - X509_CRL *x = NULL; - KMF_ENCODE_FORMAT format; - char *crlfile = NULL; - BIO *in = NULL; - BIO *mem = NULL; - long len; - char *memptr; - char *data = NULL; - - if (params == NULL || params->sslparms.crlfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - crlfile = get_fullpath(params->sslparms.dirpath, - params->sslparms.crlfile); - - if (crlfile == NULL) - return (KMF_ERR_BAD_PARAMETER); - - if (isdir(crlfile)) { - free(crlfile); - return (KMF_ERR_BAD_PARAMETER); - } - - ret = KMF_IsCRLFile(handle, crlfile, &format); - if (ret != KMF_OK) { - free(crlfile); - return (ret); - } - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - in = BIO_new_file(crlfile, "rb"); - if (in == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (format == KMF_FORMAT_ASN1) { - x = d2i_X509_CRL_bio(in, NULL); - } else if (format == KMF_FORMAT_PEM) { - x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - } - - if (x == NULL) { /* should not happen */ - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - mem = BIO_new(BIO_s_mem()); - if (mem == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_MEMORY; - goto end; - } - - (void) X509_CRL_print(mem, x); - len = BIO_get_mem_data(mem, &memptr); - if (len <= 0) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_MEMORY; - goto end; - } - - data = malloc(len + 1); - if (data == NULL) { - ret = KMF_ERR_MEMORY; - goto end; - } - - (void) memcpy(data, memptr, len); - data[len] = '\0'; - *crldata = data; - -end: - if (x != NULL) - X509_CRL_free(x); - - if (crlfile != NULL) - free(crlfile); - - if (in != NULL) - (void) BIO_free(in); - - if (mem != NULL) - (void) BIO_free(mem); - - return (ret); -} - -KMF_RETURN -OpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - KMF_ENCODE_FORMAT format; - char *crlfile = NULL; - BIO *in = NULL; - - if (params == NULL || params->sslparms.crlfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - crlfile = get_fullpath(params->sslparms.dirpath, - params->sslparms.crlfile); - - if (crlfile == NULL) - return (KMF_ERR_BAD_PARAMETER); - - if (isdir(crlfile)) { - ret = KMF_ERR_BAD_PARAMETER; - goto end; - } - - ret = KMF_IsCRLFile(handle, crlfile, &format); - if (ret != KMF_OK) - goto end; - - if (unlink(crlfile) != 0) { - SET_SYS_ERROR(kmfh, errno); - ret = KMF_ERR_INTERNAL; - goto end; - } - -end: - if (in != NULL) - (void) BIO_free(in); - if (crlfile != NULL) - free(crlfile); - - return (ret); -} - - -KMF_RETURN -OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - KMF_ENCODE_FORMAT format; - BIO *in = NULL; - X509 *xcert = NULL; - X509_CRL *xcrl = NULL; - STACK_OF(X509_REVOKED) *revoke_stack = NULL; - X509_REVOKED *revoke; - int i; - - if (params == NULL || params->sslparms.crlfile == NULL || - params->sslparms.certfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); - if (ret != KMF_OK) - return (ret); - - /* Read the CRL file and load it into a X509_CRL structure */ - in = BIO_new_file(params->sslparms.crlfile, "rb"); - if (in == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (format == KMF_FORMAT_ASN1) { - xcrl = d2i_X509_CRL_bio(in, NULL); - } else if (format == KMF_FORMAT_PEM) { - xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - } - - if (xcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CRLFILE; - goto end; - } - (void) BIO_free(in); - - /* Read the Certificate file and load it into a X509 structure */ - ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); - if (ret != KMF_OK) - goto end; - - in = BIO_new_file(params->sslparms.certfile, "rb"); - if (in == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto end; - } - - if (format == KMF_FORMAT_ASN1) { - xcert = d2i_X509_bio(in, NULL); - } else if (format == KMF_FORMAT_PEM) { - xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); - } - - if (xcert == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CERTFILE; - goto end; - } - - /* Check if the certificate and the CRL have same issuer */ - if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { - ret = KMF_ERR_ISSUER; - goto end; - } - - /* Check to see if the certificate serial number is revoked */ - revoke_stack = X509_CRL_get_REVOKED(xcrl); - if (sk_X509_REVOKED_num(revoke_stack) <= 0) { - /* No revoked certificates in the CRL file */ - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_EMPTY_CRL; - goto end; - } - - for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { - /*LINTED*/ - revoke = sk_X509_REVOKED_value(revoke_stack, i); - if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, - revoke->serialNumber) == 0) { - break; - } - } - - if (i < sk_X509_REVOKED_num(revoke_stack)) { - ret = KMF_OK; - } else { - ret = KMF_ERR_NOT_REVOKED; - } - -end: - if (in != NULL) - (void) BIO_free(in); - if (xcrl != NULL) - X509_CRL_free(xcrl); - if (xcert != NULL) - X509_free(xcert); - - return (ret); -} - -KMF_RETURN OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) { KMF_RETURN ret = KMF_OK; @@ -2452,8 +2110,7 @@ OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); if (BIO_printf(mem, ": %s\n", - X509_EXTENSION_get_critical(ex) ? "critical" : "") <= - 0) { + X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) { SET_ERROR(kmfh, ERR_get_error()); ret = KMF_ERR_ENCODING; goto out; @@ -2489,33 +2146,64 @@ out: return (ret); } + KMF_RETURN /*ARGSUSED*/ -OpenSSL_GetPrikeyByCert(KMF_HANDLE_T handle, - KMF_CRYPTOWITHCERT_PARAMS *params, - KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, - KMF_KEY_ALG keytype) +OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; - KMF_FINDKEY_PARAMS fkparms; - uint32_t numkeys = 0; - - if (params == NULL || params->sslparms.keyfile == NULL) - return (KMF_ERR_BAD_PARAMETER); + KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; + KMF_KEY_CLASS keyclass = KMF_ASYM_PRI; + KMF_KEY_HANDLE *key = NULL; + uint32_t numkeys = 1; /* 1 key only */ + char *dirpath = NULL; + char *keyfile = NULL; + KMF_ATTRIBUTE new_attrlist[16]; + int i = 0; /* * This is really just a FindKey operation, reuse the * FindKey function. */ - (void *)memset(&fkparms, 0, sizeof (fkparms)); - fkparms.kstype = KMF_KEYSTORE_OPENSSL; - fkparms.keyclass = KMF_ASYM_PRI; - fkparms.keytype = keytype; - fkparms.format = params->format; - fkparms.sslparms = params->sslparms; + kmf_set_attr_at_index(new_attrlist, i, + KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); + i++; - rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys); + kmf_set_attr_at_index(new_attrlist, i, + KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t)); + i++; + kmf_set_attr_at_index(new_attrlist, i, + KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); + i++; + + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (key == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } else { + kmf_set_attr_at_index(new_attrlist, i, + KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); + i++; + } + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + if (dirpath != NULL) { + kmf_set_attr_at_index(new_attrlist, i, + KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); + i++; + } + + keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); + if (keyfile == NULL) + return (KMF_ERR_BAD_PARAMETER); + else { + kmf_set_attr_at_index(new_attrlist, i, + KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); + i++; + } + + rv = OpenSSL_FindKey(handle, i, new_attrlist); return (rv); } @@ -2637,22 +2325,34 @@ end: } KMF_RETURN -OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, - char *reqfile) +OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; OCSP_CERTID *id = NULL; OCSP_REQUEST *req = NULL; BIO *derbio = NULL; + char *reqfile; + KMF_DATA *issuer_cert; + KMF_DATA *user_cert; - if (params->user_cert == NULL || params->issuer_cert == NULL || - reqfile == NULL) { + user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, + attrlist, numattr); + if (user_cert == NULL) return (KMF_ERR_BAD_PARAMETER); - } - ret = create_certid(handle, params->issuer_cert, params->user_cert, - &id); + issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, + attrlist, numattr); + if (issuer_cert == NULL) + return (KMF_ERR_BAD_PARAMETER); + + reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR, + attrlist, numattr); + if (reqfile == NULL) + return (KMF_ERR_BAD_PARAMETER); + + ret = create_certid(handle, issuer_cert, user_cert, &id); if (ret != KMF_OK) { return (ret); } @@ -2854,8 +2554,7 @@ end: KMF_RETURN OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, - KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, - KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; BIO *derbio = NULL; @@ -2865,19 +2564,46 @@ OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, OCSP_SINGLERESP *single = NULL; ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; int index, status, reason; + KMF_DATA *issuer_cert; + KMF_DATA *user_cert; + KMF_DATA *signer_cert; + KMF_DATA *response; + int *response_reason, *response_status, *cert_status; + boolean_t ignore_response_sign = B_FALSE; /* default is FALSE */ + uint32_t response_lifetime; + + issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, + attrlist, numattr); + if (issuer_cert == NULL) + return (KMF_ERR_BAD_PARAMETER); - if (params_in == NULL || params_in->issuer_cert == NULL || - params_in->user_cert == NULL || params_in->response == NULL) { + user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, + attrlist, numattr); + if (user_cert == NULL) return (KMF_ERR_BAD_PARAMETER); - } - if (params_out == NULL) { + response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, + attrlist, numattr); + if (response == NULL) + return (KMF_ERR_BAD_PARAMETER); + + response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR, + attrlist, numattr); + if (response_status == NULL) + return (KMF_ERR_BAD_PARAMETER); + + response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR, + attrlist, numattr); + if (response_reason == NULL) + return (KMF_ERR_BAD_PARAMETER); + + cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, + attrlist, numattr); + if (cert_status == NULL) return (KMF_ERR_BAD_PARAMETER); - } /* Read in the response */ - derbio = BIO_new_mem_buf(params_in->response->Data, - params_in->response->Length); + derbio = BIO_new_mem_buf(response->Data, response->Length); if (!derbio) { ret = KMF_ERR_MEMORY; return (ret); @@ -2891,7 +2617,7 @@ OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, /* Check the response status */ status = OCSP_response_status(resp); - params_out->response_status = status; + *response_status = status; if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { ret = KMF_ERR_OCSP_RESPONSE_STATUS; goto end; @@ -2913,9 +2639,17 @@ OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, #endif /* DEBUG */ /* Check the basic response signature if required */ - if (params_in->ignore_response_sign == B_FALSE) { + ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr, + (void *)&ignore_response_sign, NULL); + if (ret != KMF_OK) + ret = KMF_OK; + + signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, + attrlist, numattr); + + if (ignore_response_sign == B_FALSE) { ret = check_response_signature(handle, bs, - params_in->signer_cert, params_in->issuer_cert); + signer_cert, issuer_cert); if (ret != KMF_OK) goto end; } @@ -2925,8 +2659,7 @@ OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, #endif /* DEBUG */ /* Create a certid for the certificate in question */ - ret = create_certid(handle, params_in->issuer_cert, - params_in->user_cert, &id); + ret = create_certid(handle, issuer_cert, user_cert, &id); if (ret != KMF_OK) { ret = KMF_ERR_OCSP_CERTID; goto end; @@ -2953,18 +2686,21 @@ OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, &nextupd); if (status == V_OCSP_CERTSTATUS_GOOD) { - params_out->cert_status = OCSP_GOOD; + *cert_status = OCSP_GOOD; } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { - params_out->cert_status = OCSP_UNKNOWN; + *cert_status = OCSP_UNKNOWN; } else { /* revoked */ - params_out->cert_status = OCSP_REVOKED; - params_out->reason = reason; + *cert_status = OCSP_REVOKED; + *response_reason = reason; } ret = KMF_OK; - /* Verify the time */ + /* resp. time is optional, so we don't care about the return code. */ + (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr, + (void *)&response_lifetime, NULL); + if (!OCSP_check_validity(thisupd, nextupd, 300, - params_in->response_lifetime)) { + response_lifetime)) { ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; goto end; } @@ -2994,14 +2730,9 @@ fetch_key(KMF_HANDLE_T handle, char *path, KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) { KMF_RETURN rv = KMF_OK; - EVP_PKEY *pkey; + EVP_PKEY *pkey = NULL; KMF_RAW_SYM_KEY *rkey = NULL; - /* Make sure the requested file actually exists. */ - if (access(path, F_OK) != 0) { - return (KMF_ERR_KEY_NOT_FOUND); - } - if (keyclass == KMF_ASYM_PRI || keyclass == KMF_ASYM_PUB) { pkey = openssl_load_key(handle, path); @@ -3029,7 +2760,7 @@ fetch_key(KMF_HANDLE_T handle, char *path, * If the file is a recognized format, * then it is NOT a symmetric key. */ - rv = KMF_GetFileFormat(path, &fmt); + rv = kmf_get_file_format(path, &fmt); if (rv == KMF_OK || fmt != 0) { return (KMF_ERR_KEY_NOT_FOUND); } else if (rv == KMF_ERR_ENCODING) { @@ -3038,6 +2769,8 @@ fetch_key(KMF_HANDLE_T handle, char *path, * it is probably a symmetric key. */ rv = KMF_OK; + } else if (rv == KMF_ERR_OPEN_FILE) { + return (KMF_ERR_KEY_NOT_FOUND); } if (key != NULL) { @@ -3049,7 +2782,7 @@ fetch_key(KMF_HANDLE_T handle, char *path, } (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); - rv = KMF_ReadInputFile(handle, path, &keyvalue); + rv = kmf_read_input_file(handle, path, &keyvalue); if (rv != KMF_OK) goto out; @@ -3066,7 +2799,7 @@ fetch_key(KMF_HANDLE_T handle, char *path, out: if (rv != KMF_OK) { if (rkey != NULL) { - KMF_FreeRawSymKey(rkey); + kmf_free_raw_sym_key(rkey); } if (pkey != NULL) EVP_PKEY_free(pkey); @@ -3082,23 +2815,40 @@ out: } KMF_RETURN -OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, - KMF_KEY_HANDLE *key, uint32_t *numkeys) +OpenSSL_FindKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; char *fullpath = NULL; uint32_t maxkeys; + KMF_KEY_HANDLE *key; + uint32_t *numkeys; + KMF_KEY_CLASS keyclass; + KMF_RAW_KEY_DATA *rawkey; + char *dirpath; + char *keyfile; + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); + + numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (numkeys == NULL) + return (KMF_ERR_BAD_PARAMETER); - if (handle == NULL || params == NULL || numkeys == NULL) + rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, + (void *)&keyclass, NULL); + if (rv != KMF_OK) return (KMF_ERR_BAD_PARAMETER); - if (params->keyclass != KMF_ASYM_PUB && - params->keyclass != KMF_ASYM_PRI && - params->keyclass != KMF_SYMMETRIC) + if (keyclass != KMF_ASYM_PUB && + keyclass != KMF_ASYM_PRI && + keyclass != KMF_SYMMETRIC) return (KMF_ERR_BAD_KEY_CLASS); - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.keyfile); + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); + + fullpath = get_fullpath(dirpath, keyfile); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -3106,9 +2856,17 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, maxkeys = *numkeys; if (maxkeys == 0) maxkeys = 0xFFFFFFFF; - *numkeys = 0; + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + /* it is okay to have "keys" contains NULL */ + + /* + * The caller may want a list of the raw key data as well. + * Useful for importing keys from a file into other keystores. + */ + rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); + if (isdir(fullpath)) { DIR *dirp; struct dirent *dp; @@ -3128,11 +2886,14 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, (char *)&dp->d_name); rv = fetch_key(handle, fname, - params->keyclass, - key ? &key[n] : NULL); + keyclass, key ? &key[n] : NULL); - if (rv == KMF_OK) + if (rv == KMF_OK) { + if (key != NULL && rawkey != NULL) + rv = convertToRawKey( + key[n].keyp, &rawkey[n]); n++; + } if (rv != KMF_OK || key == NULL) free(fname); @@ -3142,12 +2903,16 @@ OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, free(fullpath); (*numkeys) = n; } else { - rv = fetch_key(handle, fullpath, params->keyclass, key); + rv = fetch_key(handle, fullpath, keyclass, key); if (rv == KMF_OK) (*numkeys) = 1; if (rv != KMF_OK || key == NULL) free(fullpath); + + if (rv == KMF_OK && key != NULL && rawkey != NULL) { + rv = convertToRawKey(key->keyp, rawkey); + } } if (rv == KMF_OK && (*numkeys) == 0) @@ -3236,8 +3001,7 @@ write_pkcs12(KMF_HANDLE *kmfh, X509 *ca = NULL; uchar_t *p = (uchar_t *)c->certificate.Data; - ca = d2i_X509(NULL, &p, - c->certificate.Length); + ca = d2i_X509(NULL, &p, c->certificate.Length); if (ca == NULL) { HANDLE_PK12_ERROR } @@ -3466,6 +3230,12 @@ ImportRawDSAKey(KMF_RAW_DSA_KEY *key) dsa->priv_key)) == NULL) return (NULL); + if (key->pubvalue.val != NULL) { + if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val, + key->pubvalue.len, dsa->pub_key)) == NULL) + return (NULL); + } + if ((newkey = EVP_PKEY_new()) == NULL) return (NULL); @@ -3541,45 +3311,49 @@ cleanup: return (rv); } + KMF_RETURN -OpenSSL_ExportP12(KMF_HANDLE_T handle, - KMF_EXPORTP12_PARAMS *params, - int numcerts, KMF_X509_DER_CERT *certlist, - int numkeys, KMF_KEY_HANDLE *keylist, - char *filename) +openssl_build_pk12(KMF_HANDLE_T handle, int numcerts, + KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist, + KMF_CREDENTIAL *p12cred, char *filename) +{ + KMF_RETURN rv; + + if (certlist == NULL && keylist == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = ExportPK12FromRawData(handle, p12cred, numcerts, certlist, + numkeys, keylist, filename); + + return (rv); +} + + +KMF_RETURN +OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - KMF_FINDCERT_PARAMS fcargs; BIO *bio = NULL; X509 *xcert = NULL; char *fullpath = NULL; EVP_PKEY *pkey = NULL; + char *dirpath = NULL; + char *certfile = NULL; + char *keyfile = NULL; + char *filename = NULL; + KMF_CREDENTIAL *p12cred = NULL; - /* - * First, find the certificate. - */ - if (params == NULL) + if (handle == NULL) return (KMF_ERR_BAD_PARAMETER); /* - * If the caller already sent the raw keys and certs, - * shortcut the search and just export that - * data. - * - * One *may* export a key OR a cert by itself. + * First, find the certificate. */ - if (certlist != NULL || keylist != NULL) { - rv = ExportPK12FromRawData(handle, - ¶ms->p12cred, numcerts, certlist, - numkeys, keylist, filename); - return (rv); - } - - if (params->sslparms.certfile != NULL) { - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.certfile); - + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); + if (certfile != NULL) { + fullpath = get_fullpath(dirpath, certfile); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -3588,29 +3362,19 @@ OpenSSL_ExportP12(KMF_HANDLE_T handle, return (KMF_ERR_AMBIGUOUS_PATHNAME); } - (void *)memset(&fcargs, 0, sizeof (fcargs)); - fcargs.kstype = params->kstype; - fcargs.certLabel = params->certLabel; - fcargs.issuer = params->issuer; - fcargs.subject = params->subject; - fcargs.serial = params->serial; - fcargs.idstr = params->idstr; - fcargs.sslparms.dirpath = NULL; - fcargs.sslparms.certfile = fullpath; - fcargs.sslparms.format = params->sslparms.format; - - rv = load_X509cert(kmfh, &fcargs, fullpath, &xcert); + rv = load_X509cert(kmfh, NULL, NULL, NULL, fullpath, &xcert); if (rv != KMF_OK) goto end; + + free(fullpath); } /* * Now find the private key. */ - if (params->sslparms.keyfile != NULL) { - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.keyfile); - + keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); + if (keyfile != NULL) { + fullpath = get_fullpath(dirpath, keyfile); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -3629,6 +3393,13 @@ OpenSSL_ExportP12(KMF_HANDLE_T handle, /* * Open the output file. */ + filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, + numattr); + if (filename == NULL) { + rv = KMF_ERR_BAD_PARAMETER; + goto end; + } + if ((bio = BIO_new_file(filename, "wb")) == NULL) { SET_ERROR(kmfh, ERR_get_error()); rv = KMF_ERR_OPEN_FILE; @@ -3636,8 +3407,13 @@ OpenSSL_ExportP12(KMF_HANDLE_T handle, } /* Stick the key and the cert into a PKCS#12 file */ - rv = write_pkcs12(kmfh, bio, ¶ms->p12cred, - pkey, xcert); + p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); + if (p12cred == NULL) { + rv = KMF_ERR_BAD_PARAMETER; + goto end; + } + + rv = write_pkcs12(kmfh, bio, p12cred, pkey, xcert); end: if (fullpath) @@ -3652,6 +3428,7 @@ end: return (rv); } + #define MAX_CHAIN_LENGTH 100 /* * Helper function to extract keys and certificates from @@ -3660,7 +3437,8 @@ end: * However, the file may be just a list of X509 certs with no keys. */ static KMF_RETURN -extract_objects(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, +extract_pem(KMF_HANDLE *kmfh, + char *issuer, char *subject, KMF_BIGINT *serial, char *filename, CK_UTF8CHAR *pin, CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs, int *numcerts) @@ -3690,10 +3468,11 @@ extract_objects(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, return (KMF_ERR_ENCODING); } + for (i = 0; i < sk_X509_INFO_num(x509_info_stack) && i < MAX_CHAIN_LENGTH; i++) { - /*LINTED*/ + /* LINTED */ cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i); ncerts++; } @@ -3736,12 +3515,10 @@ extract_objects(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, boolean_t match = FALSE; info = cert_infos[ncerts - 1 - i]; - if (params != NULL) { - rv = check_cert(info->x509, params, &match); - if (rv != KMF_OK || match != TRUE) { - rv = KMF_OK; - continue; - } + rv = check_cert(info->x509, issuer, subject, serial, &match); + if (rv != KMF_OK || match != TRUE) { + rv = KMF_OK; + continue; } rv = ssl_cert2KMFDATA(kmfh, info->x509, @@ -3880,7 +3657,7 @@ exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) goto cleanup; cleanup: if (rv != KMF_OK) - KMF_FreeRawKey(key); + kmf_free_raw_key(key); else key->keytype = KMF_RSA; @@ -3914,7 +3691,7 @@ exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) cleanup: if (rv != KMF_OK) - KMF_FreeRawKey(key); + kmf_free_raw_key(key); else key->keytype = KMF_DSA; @@ -3983,6 +3760,33 @@ add_key_to_list(KMF_RAW_KEY_DATA **keylist, return (KMF_OK); } +static KMF_RETURN +convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key) +{ + KMF_RETURN rv = KMF_OK; + + if (pkey == NULL || key == NULL) + return (KMF_ERR_BAD_PARAMETER); + /* Convert SSL key to raw key */ + switch (pkey->type) { + case EVP_PKEY_RSA: + rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey), + key); + if (rv != KMF_OK) + return (rv); + break; + case EVP_PKEY_DSA: + rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey), + key); + if (rv != KMF_OK) + return (rv); + break; + default: + return (KMF_ERR_BAD_PARAMETER); + } + + return (rv); +} static KMF_RETURN convertPK12Objects( @@ -3996,27 +3800,10 @@ convertPK12Objects( int i; if (sslkey != NULL) { - /* Convert SSL key to raw key */ - switch (sslkey->type) { - case EVP_PKEY_RSA: - rv = exportRawRSAKey(EVP_PKEY_get1_RSA(sslkey), - &key); - if (rv != KMF_OK) - return (rv); - - break; - case EVP_PKEY_DSA: - rv = exportRawDSAKey(EVP_PKEY_get1_DSA(sslkey), - &key); - if (rv != KMF_OK) - return (rv); - - break; - default: - return (KMF_ERR_BAD_PARAMETER); - } + rv = convertToRawKey(sslkey, &key); + if (rv == KMF_OK) + rv = add_key_to_list(keylist, &key, nkeys); - rv = add_key_to_list(keylist, &key, nkeys); if (rv != KMF_OK) return (rv); } @@ -4049,160 +3836,79 @@ convertPK12Objects( } KMF_RETURN -openssl_read_pkcs12(KMF_HANDLE *kmfh, +openssl_import_objects(KMF_HANDLE *kmfh, char *filename, KMF_CREDENTIAL *cred, KMF_DATA **certlist, int *ncerts, KMF_RAW_KEY_DATA **keylist, int *nkeys) { KMF_RETURN rv = KMF_OK; - BIO *bio = NULL; EVP_PKEY *privkey = NULL; + KMF_ENCODE_FORMAT format; + BIO *bio = NULL; X509 *cert = NULL; STACK_OF(X509) *cacerts = NULL; - bio = BIO_new_file(filename, "rb"); - if (bio == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_OPEN_FILE; - goto end; - } - - *certlist = NULL; - *keylist = NULL; - *ncerts = 0; - *nkeys = 0; - - rv = extract_pkcs12(bio, (uchar_t *)cred->cred, - (uint32_t)cred->credlen, &privkey, &cert, &cacerts); - - if (rv == KMF_OK) - /* Convert keys and certs to exportable format */ - rv = convertPK12Objects(kmfh, privkey, cert, cacerts, - keylist, nkeys, certlist, ncerts); - -end: - if (bio != NULL) - (void) BIO_free(bio); - - if (privkey) - EVP_PKEY_free(privkey); - - if (cert) - X509_free(cert); - - if (cacerts) - sk_X509_free(cacerts); - - return (rv); -} - -KMF_RETURN -openssl_import_keypair(KMF_HANDLE *kmfh, - char *filename, KMF_CREDENTIAL *cred, - KMF_DATA **certlist, int *ncerts, - KMF_RAW_KEY_DATA **keylist, int *nkeys) -{ - KMF_RETURN rv = KMF_OK; - EVP_PKEY *privkey = NULL; - KMF_ENCODE_FORMAT format; - /* * auto-detect the file format, regardless of what * the 'format' parameters in the params say. */ - rv = KMF_GetFileFormat(filename, &format); + rv = kmf_get_file_format(filename, &format); if (rv != KMF_OK) { - if (rv == KMF_ERR_OPEN_FILE) - rv = KMF_ERR_CERT_NOT_FOUND; return (rv); } - /* This function only works on PEM files */ + /* This function only works for PEM or PKCS#12 files */ if (format != KMF_FORMAT_PEM && - format != KMF_FORMAT_PEM_KEYPAIR) + format != KMF_FORMAT_PEM_KEYPAIR && + format != KMF_FORMAT_PKCS12) return (KMF_ERR_ENCODING); *certlist = NULL; *keylist = NULL; *ncerts = 0; *nkeys = 0; - rv = extract_objects(kmfh, NULL, filename, - (uchar_t *)cred->cred, (uint32_t)cred->credlen, - &privkey, certlist, ncerts); - - /* Reached end of import file? */ - if (rv == KMF_OK) - /* Convert keys and certs to exportable format */ - rv = convertPK12Objects(kmfh, privkey, NULL, NULL, - keylist, nkeys, NULL, NULL); - -end: - if (privkey) - EVP_PKEY_free(privkey); - - return (rv); -} - -KMF_RETURN -OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, - KMF_RAW_KEY_DATA *key) -{ - KMF_RETURN rv = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - char *fullpath; - EVP_PKEY *pkey = NULL; - BIO *bio = NULL; - if (key != NULL) { - if (key->keytype == KMF_RSA) { - pkey = ImportRawRSAKey(&key->rawdata.rsa); - } else if (key->keytype == KMF_DSA) { - pkey = ImportRawDSAKey(&key->rawdata.dsa); - } else { - rv = KMF_ERR_BAD_PARAMETER; + if (format == KMF_FORMAT_PKCS12) { + bio = BIO_new_file(filename, "rb"); + if (bio == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_OPEN_FILE; + goto end; } - } else { - rv = KMF_ERR_BAD_PARAMETER; - } - if (rv != KMF_OK || pkey == NULL) - return (rv); - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.keyfile); + rv = extract_pkcs12(bio, (uchar_t *)cred->cred, + (uint32_t)cred->credlen, &privkey, &cert, &cacerts); - if (fullpath == NULL) - return (KMF_ERR_BAD_PARAMETER); + if (rv == KMF_OK) + /* Convert keys and certs to exportable format */ + rv = convertPK12Objects(kmfh, privkey, cert, cacerts, + keylist, nkeys, certlist, ncerts); - /* If the requested file exists, return an error */ - if (access(fullpath, F_OK) == 0) { - free(fullpath); - return (KMF_ERR_DUPLICATE_KEYFILE); - } + } else { + rv = extract_pem(kmfh, NULL, NULL, NULL, filename, + (uchar_t *)cred->cred, (uint32_t)cred->credlen, + &privkey, certlist, ncerts); - bio = BIO_new_file(fullpath, "wb"); - if (bio == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - rv = KMF_ERR_OPEN_FILE; - goto cleanup; + /* Reached end of import file? */ + if (rv == KMF_OK) + /* Convert keys and certs to exportable format */ + rv = convertPK12Objects(kmfh, privkey, NULL, NULL, + keylist, nkeys, NULL, NULL); } - rv = ssl_write_private_key(kmfh, params->sslparms.format, - bio, ¶ms->cred, pkey); +end: + if (privkey) + EVP_PKEY_free(privkey); -cleanup: - if (fullpath) - free(fullpath); + if (bio != NULL) + (void) BIO_free(bio); - if (pkey) - EVP_PKEY_free(pkey); + if (cert) + X509_free(cert); - if (bio) - (void) BIO_free(bio); + if (cacerts) + sk_X509_free(cacerts); - /* Protect the file by making it read-only */ - if (rv == KMF_OK) { - (void) chmod(fullpath, 0400); - } return (rv); } @@ -4322,8 +4028,8 @@ out: } KMF_RETURN -OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, - KMF_KEY_HANDLE *symkey) +OpenSSL_CreateSymKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -4333,21 +4039,46 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, unsigned char *des3key = NULL; unsigned char *random = NULL; int fd = -1; + KMF_KEY_HANDLE *symkey; + KMF_KEY_ALG keytype; + uint32_t keylen; + uint32_t keylen_size = sizeof (keylen); + char *dirpath; + char *keyfile; if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); - if (params == NULL || params->sslparms.keyfile == NULL) { + symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (symkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + + keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); + if (keyfile == NULL) return (KMF_ERR_BAD_PARAMETER); - } - fullpath = get_fullpath(params->sslparms.dirpath, - params->sslparms.keyfile); + ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); + if (ret != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, + &keylen, &keylen_size); + if (ret == KMF_ERR_ATTR_NOT_FOUND && + (keytype == KMF_DES || keytype == KMF_DES3)) + /* keylength is not required for DES and 3DES */ + ret = KMF_OK; + if (ret != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + fullpath = get_fullpath(dirpath, keyfile); if (fullpath == NULL) return (KMF_ERR_BAD_PARAMETER); /* If the requested file exists, return an error */ - if (access(fullpath, F_OK) == 0) { + if (test_for_file(fullpath, 0400) == 1) { free(fullpath); return (KMF_ERR_DUPLICATE_KEYFILE); } @@ -4365,7 +4096,7 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, } (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); - if (params->keytype == KMF_DES) { + if (keytype == KMF_DES) { if ((ret = create_deskey(&deskey)) != KMF_OK) { goto out; } @@ -4374,7 +4105,7 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, symkey->keyalg = KMF_DES; - } else if (params->keytype == KMF_DES3) { + } else if (keytype == KMF_DES3) { if ((ret = create_des3key(&des3key)) != KMF_OK) { goto out; } @@ -4382,25 +4113,25 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, rkey->keydata.len = DES3_KEY_SIZE; symkey->keyalg = KMF_DES3; - } else if (params->keytype == KMF_AES || params->keytype == KMF_RC4 || - params->keytype == KMF_GENERIC_SECRET) { + } else if (keytype == KMF_AES || keytype == KMF_RC4 || + keytype == KMF_GENERIC_SECRET) { int bytes; - if (params->keylength % 8 != 0) { + if (keylen % 8 != 0) { ret = KMF_ERR_BAD_KEY_SIZE; goto out; } - if (params->keytype == KMF_AES) { - if (params->keylength != 128 && - params->keylength != 192 && - params->keylength != 256) { + if (keytype == KMF_AES) { + if (keylen != 128 && + keylen != 192 && + keylen != 256) { ret = KMF_ERR_BAD_KEY_SIZE; goto out; } } - bytes = params->keylength/8; + bytes = keylen/8; random = malloc(bytes); if (random == NULL) { ret = KMF_ERR_MEMORY; @@ -4413,7 +4144,7 @@ OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, rkey->keydata.val = (uchar_t *)random; rkey->keydata.len = bytes; - symkey->keyalg = params->keytype; + symkey->keyalg = keytype; } else { ret = KMF_ERR_BAD_KEY_TYPE; @@ -4436,7 +4167,7 @@ out: free(fullpath); } if (ret != KMF_OK) { - KMF_FreeRawSymKey(rkey); + kmf_free_raw_sym_key(rkey); symkey->keyp = NULL; symkey->keyalg = KMF_KEYALG_NONE; } @@ -4444,159 +4175,6 @@ out: return (ret); } - -KMF_RETURN -OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - BIO *bcrl = NULL; - X509_CRL *xcrl = NULL; - X509 *xcert = NULL; - EVP_PKEY *pkey; - int sslret; - KMF_ENCODE_FORMAT crl_format; - unsigned char *p; - long len; - - if (params->crl_name == NULL || params->tacert == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - ret = KMF_GetFileFormat(params->crl_name, &crl_format); - if (ret != KMF_OK) - return (ret); - - bcrl = BIO_new_file(params->crl_name, "rb"); - if (bcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto cleanup; - } - - if (crl_format == KMF_FORMAT_ASN1) { - xcrl = d2i_X509_CRL_bio(bcrl, NULL); - } else if (crl_format == KMF_FORMAT_PEM) { - xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); - } else { - ret = KMF_ERR_BAD_PARAMETER; - goto cleanup; - } - - if (xcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CRLFILE; - goto cleanup; - } - - p = params->tacert->Data; - len = params->tacert->Length; - xcert = d2i_X509(NULL, (const uchar_t **)&p, len); - - if (xcert == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CERTFILE; - goto cleanup; - } - - /* Get issuer certificate public key */ - pkey = X509_get_pubkey(xcert); - if (!pkey) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CERT_FORMAT; - goto cleanup; - } - - /* Verify CRL signature */ - sslret = X509_CRL_verify(xcrl, pkey); - EVP_PKEY_free(pkey); - if (sslret > 0) { - ret = KMF_OK; - } else { - SET_ERROR(kmfh, sslret); - ret = KMF_ERR_BAD_CRLFILE; - } - -cleanup: - if (bcrl != NULL) - (void) BIO_free(bcrl); - - if (xcrl != NULL) - X509_CRL_free(xcrl); - - if (xcert != NULL) - X509_free(xcert); - - return (ret); - -} - -KMF_RETURN -OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, - KMF_CHECKCRLDATE_PARAMS *params) -{ - - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - KMF_ENCODE_FORMAT crl_format; - BIO *bcrl = NULL; - X509_CRL *xcrl = NULL; - int i; - - if (params == NULL || params->crl_name == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format); - if (ret != KMF_OK) - return (ret); - - bcrl = BIO_new_file(params->crl_name, "rb"); - if (bcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto cleanup; - } - - if (crl_format == KMF_FORMAT_ASN1) { - xcrl = d2i_X509_CRL_bio(bcrl, NULL); - } else if (crl_format == KMF_FORMAT_PEM) { - xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); - } - - if (xcrl == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_BAD_CRLFILE; - goto cleanup; - } - - i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); - if (i >= 0) { - ret = KMF_ERR_VALIDITY_PERIOD; - goto cleanup; - } - - if (X509_CRL_get_nextUpdate(xcrl)) { - i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); - - if (i <= 0) { - ret = KMF_ERR_VALIDITY_PERIOD; - goto cleanup; - } - } - - ret = KMF_OK; - -cleanup: - if (bcrl != NULL) - (void) BIO_free(bcrl); - - if (xcrl != NULL) - X509_CRL_free(xcrl); - - return (ret); -} - /* * Check a file to see if it is a CRL file with PEM or DER format. * If success, return its format in the "pformat" argument. @@ -4669,7 +4247,7 @@ OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, return (KMF_ERR_BAD_PARAMETER); } - ret = KMF_GetFileFormat(filename, pformat); + ret = kmf_get_file_format(filename, pformat); if (ret != KMF_OK) return (ret); @@ -4733,7 +4311,7 @@ OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, (void) memcpy(rkey->keydata.val, rawkey->keydata.val, rkey->keydata.len); } else { - rv = KMF_ReadInputFile(handle, symkey->keylabel, &keyvalue); + rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue); if (rv != KMF_OK) return (rv); rkey->keydata.len = keyvalue.Length; @@ -4815,7 +4393,7 @@ OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle, } pkey = X509_get_pubkey(xcert); - if (!pkey) { + if (pkey == NULL) { SET_ERROR(kmfh, ERR_get_error()); ret = KMF_ERR_BAD_CERT_FORMAT; goto cleanup; @@ -4944,3 +4522,764 @@ cleanup: return (ret); } + +/* + * substitute for the unsafe access(2) function. + * If the file in question already exists, return 1. + * else 0. If an error occurs during testing (other + * than EEXIST), return -1. + */ +static int +test_for_file(char *filename, mode_t mode) +{ + int fd; + + /* + * Try to create the file with the EXCL flag. + * The call should fail if the file exists. + */ + fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode); + if (fd == -1 && errno == EEXIST) + return (1); + else if (fd == -1) /* some other error */ + return (-1); + + /* The file did NOT exist. Delete the testcase. */ + (void) close(fd); + (void) unlink(filename); + return (0); +} + +KMF_RETURN +OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL; + KMF_RAW_KEY_DATA *rawkey; + EVP_PKEY *pkey = NULL; + KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM; + KMF_CREDENTIAL cred = {NULL, 0}; + BIO *out = NULL; + int keys = 0; + char *fullpath = NULL; + char *keyfile = NULL; + char *dirpath = NULL; + + pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); + if (pubkey != NULL) + keys++; + + prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); + if (prikey != NULL) + keys++; + + rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); + if (rawkey != NULL) + keys++; + + /* + * Exactly 1 type of key must be passed to this function. + */ + if (keys != 1) + return (KMF_ERR_BAD_PARAMETER); + + keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, + numattr); + if (keyfile == NULL) + return (KMF_ERR_BAD_PARAMETER); + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + + fullpath = get_fullpath(dirpath, keyfile); + + /* Once we have the full path, we don't need the pieces */ + if (fullpath == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* If the requested file exists, return an error */ + if (test_for_file(fullpath, 0400) == 1) { + free(fullpath); + return (KMF_ERR_DUPLICATE_KEYFILE); + } + + rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, + &format, NULL); + if (rv != KMF_OK) + /* format is optional. */ + rv = KMF_OK; + + /* CRED is not required for OpenSSL files */ + (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + &cred, NULL); + + /* Store the private key to the keyfile */ + out = BIO_new_file(fullpath, "wb"); + if (out == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + rv = KMF_ERR_OPEN_FILE; + goto end; + } + + if (prikey != NULL && prikey->keyp != NULL) { + if (prikey->keyalg == KMF_RSA || + prikey->keyalg == KMF_DSA) { + pkey = (EVP_PKEY *)prikey->keyp; + + rv = ssl_write_key(kmfh, format, + out, &cred, pkey, TRUE); + + if (rv == KMF_OK && prikey->keylabel == NULL) { + prikey->keylabel = strdup(fullpath); + if (prikey->keylabel == NULL) + rv = KMF_ERR_MEMORY; + } + } + } else if (pubkey != NULL && pubkey->keyp != NULL) { + if (pubkey->keyalg == KMF_RSA || + pubkey->keyalg == KMF_DSA) { + pkey = (EVP_PKEY *)pubkey->keyp; + + rv = ssl_write_key(kmfh, format, + out, &cred, pkey, FALSE); + + if (rv == KMF_OK && pubkey->keylabel == NULL) { + pubkey->keylabel = strdup(fullpath); + if (pubkey->keylabel == NULL) + rv = KMF_ERR_MEMORY; + } + } + } else if (rawkey != NULL) { + /* RAW keys are always private */ + if (rawkey->keytype == KMF_RSA) { + pkey = ImportRawRSAKey(&rawkey->rawdata.rsa); + } else if (rawkey->keytype == KMF_DSA) { + pkey = ImportRawDSAKey(&rawkey->rawdata.dsa); + } else { + rv = KMF_ERR_BAD_PARAMETER; + } + rv = ssl_write_key(kmfh, format, out, &cred, pkey, TRUE); + } + +end: + + if (out) + (void) BIO_free(out); + + if (rv == KMF_OK) + (void) chmod(fullpath, 0400); + + free(fullpath); + return (rv); +} + +KMF_RETURN +OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + X509_CRL *xcrl = NULL; + X509 *xcert = NULL; + EVP_PKEY *pkey; + KMF_ENCODE_FORMAT format; + BIO *in = NULL, *out = NULL; + int openssl_ret = 0; + KMF_ENCODE_FORMAT outformat; + boolean_t crlcheck = FALSE; + char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile; + + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + /* CRL check is optional */ + (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr, + &crlcheck, NULL); + + certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); + if (crlcheck == B_TRUE && certfile == NULL) { + return (KMF_ERR_BAD_CERTFILE); + } + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr); + outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr); + + crlfile = get_fullpath(dirpath, incrl); + + if (crlfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + outcrlfile = get_fullpath(dirpath, outcrl); + if (outcrlfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + if (isdir(outcrlfile)) { + free(outcrlfile); + return (KMF_ERR_BAD_CRLFILE); + } + + ret = kmf_is_crl_file(handle, crlfile, &format); + if (ret != KMF_OK) { + free(outcrlfile); + return (ret); + } + + in = BIO_new_file(crlfile, "rb"); + if (in == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (format == KMF_FORMAT_ASN1) { + xcrl = d2i_X509_CRL_bio(in, NULL); + } else if (format == KMF_FORMAT_PEM) { + xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + } + + if (xcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CRLFILE; + goto end; + } + + /* If bypasscheck is specified, no need to verify. */ + if (crlcheck == B_FALSE) + goto output; + + ret = kmf_is_cert_file(handle, certfile, &format); + if (ret != KMF_OK) + goto end; + + /* Read in the CA cert file and convert to X509 */ + if (BIO_read_filename(in, certfile) <= 0) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (format == KMF_FORMAT_ASN1) { + xcert = d2i_X509_bio(in, NULL); + } else if (format == KMF_FORMAT_PEM) { + xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); + } else { + ret = KMF_ERR_BAD_CERT_FORMAT; + goto end; + } + + if (xcert == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CERT_FORMAT; + goto end; + } + /* Now get the public key from the CA cert */ + pkey = X509_get_pubkey(xcert); + if (pkey == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CERTFILE; + goto end; + } + + /* Verify the CRL with the CA's public key */ + openssl_ret = X509_CRL_verify(xcrl, pkey); + EVP_PKEY_free(pkey); + if (openssl_ret > 0) { + ret = KMF_OK; /* verify succeed */ + } else { + SET_ERROR(kmfh, openssl_ret); + ret = KMF_ERR_BAD_CRLFILE; + } + +output: + ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, + &outformat, NULL); + if (ret != KMF_OK) { + ret = KMF_OK; + outformat = KMF_FORMAT_PEM; + } + + out = BIO_new_file(outcrlfile, "wb"); + if (out == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (outformat == KMF_FORMAT_ASN1) { + openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); + } else if (outformat == KMF_FORMAT_PEM) { + openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); + } else { + ret = KMF_ERR_BAD_PARAMETER; + goto end; + } + + if (openssl_ret <= 0) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_WRITE_FILE; + } else { + ret = KMF_OK; + } + +end: + if (xcrl != NULL) + X509_CRL_free(xcrl); + + if (xcert != NULL) + X509_free(xcert); + + if (in != NULL) + (void) BIO_free(in); + + if (out != NULL) + (void) BIO_free(out); + + if (outcrlfile != NULL) + free(outcrlfile); + + return (ret); +} + +KMF_RETURN +OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + X509_CRL *x = NULL; + KMF_ENCODE_FORMAT format; + char *crlfile = NULL; + BIO *in = NULL; + BIO *mem = NULL; + long len; + char *memptr; + char *data = NULL; + char **crldata; + char *crlfilename, *dirpath; + + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, + attrlist, numattr); + if (crlfilename == NULL) + return (KMF_ERR_BAD_CRLFILE); + + crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR, + attrlist, numattr); + + if (crldata == NULL) + return (KMF_ERR_BAD_PARAMETER); + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + + crlfile = get_fullpath(dirpath, crlfilename); + + if (crlfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + if (isdir(crlfile)) { + free(crlfile); + return (KMF_ERR_BAD_CRLFILE); + } + + ret = kmf_is_crl_file(handle, crlfile, &format); + if (ret != KMF_OK) { + free(crlfile); + return (ret); + } + + if (bio_err == NULL) + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + in = BIO_new_file(crlfile, "rb"); + if (in == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (format == KMF_FORMAT_ASN1) { + x = d2i_X509_CRL_bio(in, NULL); + } else if (format == KMF_FORMAT_PEM) { + x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + } + + if (x == NULL) { /* should not happen */ + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + mem = BIO_new(BIO_s_mem()); + if (mem == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_MEMORY; + goto end; + } + + (void) X509_CRL_print(mem, x); + len = BIO_get_mem_data(mem, &memptr); + if (len <= 0) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_MEMORY; + goto end; + } + + data = malloc(len + 1); + if (data == NULL) { + ret = KMF_ERR_MEMORY; + goto end; + } + + (void) memcpy(data, memptr, len); + data[len] = '\0'; + *crldata = data; + +end: + if (x != NULL) + X509_CRL_free(x); + + if (crlfile != NULL) + free(crlfile); + + if (in != NULL) + (void) BIO_free(in); + + if (mem != NULL) + (void) BIO_free(mem); + + return (ret); +} + +KMF_RETURN +OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_ENCODE_FORMAT format; + char *crlfile = NULL; + BIO *in = NULL; + char *crlfilename, *dirpath; + + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, + attrlist, numattr); + + if (crlfilename == NULL) + return (KMF_ERR_BAD_CRLFILE); + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + + crlfile = get_fullpath(dirpath, crlfilename); + + if (crlfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + if (isdir(crlfile)) { + ret = KMF_ERR_BAD_CRLFILE; + goto end; + } + + ret = kmf_is_crl_file(handle, crlfile, &format); + if (ret != KMF_OK) + goto end; + + if (unlink(crlfile) != 0) { + SET_SYS_ERROR(kmfh, errno); + ret = KMF_ERR_INTERNAL; + goto end; + } + +end: + if (in != NULL) + (void) BIO_free(in); + if (crlfile != NULL) + free(crlfile); + + return (ret); +} + +KMF_RETURN +OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_ENCODE_FORMAT format; + BIO *in = NULL; + X509 *xcert = NULL; + X509_CRL *xcrl = NULL; + STACK_OF(X509_REVOKED) *revoke_stack = NULL; + X509_REVOKED *revoke; + int i; + char *crlfilename, *crlfile, *dirpath, *certfile; + + if (numattr == 0 || attrlist == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, + attrlist, numattr); + + if (crlfilename == NULL) + return (KMF_ERR_BAD_CRLFILE); + + certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); + if (certfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + + crlfile = get_fullpath(dirpath, crlfilename); + + if (crlfile == NULL) + return (KMF_ERR_BAD_CRLFILE); + + if (isdir(crlfile)) { + ret = KMF_ERR_BAD_CRLFILE; + goto end; + } + + ret = kmf_is_crl_file(handle, crlfile, &format); + if (ret != KMF_OK) + goto end; + + /* Read the CRL file and load it into a X509_CRL structure */ + in = BIO_new_file(crlfilename, "rb"); + if (in == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (format == KMF_FORMAT_ASN1) { + xcrl = d2i_X509_CRL_bio(in, NULL); + } else if (format == KMF_FORMAT_PEM) { + xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + } + + if (xcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CRLFILE; + goto end; + } + (void) BIO_free(in); + + /* Read the Certificate file and load it into a X509 structure */ + ret = kmf_is_cert_file(handle, certfile, &format); + if (ret != KMF_OK) + goto end; + + in = BIO_new_file(certfile, "rb"); + if (in == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto end; + } + + if (format == KMF_FORMAT_ASN1) { + xcert = d2i_X509_bio(in, NULL); + } else if (format == KMF_FORMAT_PEM) { + xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); + } + + if (xcert == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CERTFILE; + goto end; + } + + /* Check if the certificate and the CRL have same issuer */ + if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { + ret = KMF_ERR_ISSUER; + goto end; + } + + /* Check to see if the certificate serial number is revoked */ + revoke_stack = X509_CRL_get_REVOKED(xcrl); + if (sk_X509_REVOKED_num(revoke_stack) <= 0) { + /* No revoked certificates in the CRL file */ + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_EMPTY_CRL; + goto end; + } + + for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { + /*LINTED*/ + revoke = sk_X509_REVOKED_value(revoke_stack, i); + if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, + revoke->serialNumber) == 0) { + break; + } + } + + if (i < sk_X509_REVOKED_num(revoke_stack)) { + ret = KMF_OK; + } else { + ret = KMF_ERR_NOT_REVOKED; + } + +end: + if (in != NULL) + (void) BIO_free(in); + if (xcrl != NULL) + X509_CRL_free(xcrl); + if (xcert != NULL) + X509_free(xcert); + + return (ret); +} + +KMF_RETURN +OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + BIO *bcrl = NULL; + X509_CRL *xcrl = NULL; + X509 *xcert = NULL; + EVP_PKEY *pkey; + int sslret; + KMF_ENCODE_FORMAT crl_format; + unsigned char *p; + long len; + + if (handle == NULL || crlname == NULL || tacert == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = kmf_get_file_format(crlname, &crl_format); + if (ret != KMF_OK) + return (ret); + + bcrl = BIO_new_file(crlname, "rb"); + if (bcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto cleanup; + } + + if (crl_format == KMF_FORMAT_ASN1) { + xcrl = d2i_X509_CRL_bio(bcrl, NULL); + } else if (crl_format == KMF_FORMAT_PEM) { + xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); + } else { + ret = KMF_ERR_BAD_PARAMETER; + goto cleanup; + } + + if (xcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CRLFILE; + goto cleanup; + } + + p = tacert->Data; + len = tacert->Length; + xcert = d2i_X509(NULL, (const uchar_t **)&p, len); + + if (xcert == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CERTFILE; + goto cleanup; + } + + /* Get issuer certificate public key */ + pkey = X509_get_pubkey(xcert); + if (pkey == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CERT_FORMAT; + goto cleanup; + } + + /* Verify CRL signature */ + sslret = X509_CRL_verify(xcrl, pkey); + EVP_PKEY_free(pkey); + if (sslret > 0) { + ret = KMF_OK; + } else { + SET_ERROR(kmfh, sslret); + ret = KMF_ERR_BAD_CRLFILE; + } + +cleanup: + if (bcrl != NULL) + (void) BIO_free(bcrl); + + if (xcrl != NULL) + X509_CRL_free(xcrl); + + if (xcert != NULL) + X509_free(xcert); + + return (ret); + +} + +KMF_RETURN +OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname) +{ + KMF_RETURN ret = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_ENCODE_FORMAT crl_format; + BIO *bcrl = NULL; + X509_CRL *xcrl = NULL; + int i; + + if (handle == NULL || crlname == NULL) { + return (KMF_ERR_BAD_PARAMETER); + } + + ret = kmf_is_crl_file(handle, crlname, &crl_format); + if (ret != KMF_OK) + return (ret); + + bcrl = BIO_new_file(crlname, "rb"); + if (bcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_OPEN_FILE; + goto cleanup; + } + + if (crl_format == KMF_FORMAT_ASN1) { + xcrl = d2i_X509_CRL_bio(bcrl, NULL); + } else if (crl_format == KMF_FORMAT_PEM) { + xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); + } + + if (xcrl == NULL) { + SET_ERROR(kmfh, ERR_get_error()); + ret = KMF_ERR_BAD_CRLFILE; + goto cleanup; + } + + i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); + if (i >= 0) { + ret = KMF_ERR_VALIDITY_PERIOD; + goto cleanup; + } + + if (X509_CRL_get_nextUpdate(xcrl)) { + i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); + + if (i <= 0) { + ret = KMF_ERR_VALIDITY_PERIOD; + goto cleanup; + } + } + + ret = KMF_OK; + +cleanup: + if (bcrl != NULL) + (void) BIO_free(bcrl); + + if (xcrl != NULL) + X509_CRL_free(xcrl); + + return (ret); +} diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com b/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com index fd46f0e5f8..2651b5d4de 100644 --- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com +++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com @@ -29,7 +29,10 @@ LIBRARY= kmf_pkcs11.a VERS= .1 -OBJECTS= pkcs11_spi.o + +PKCS11_COBJECTS = pkcs11_spi.o +BIGNUM_COBJECTS = bignumimpl.o +OBJECTS = $(PKCS11_COBJECTS) $(BIGNUM_COBJECTS) include $(SRC)/lib/Makefile.lib @@ -38,11 +41,18 @@ KMFINC= -I../../../include -I../../../ber_der/inc PKCS11LIBS= -lkmf -lkmfberder -lmd -lpkcs11 -lcryptoutil -lc +BIGNUMDIR= $(SRC)/common/bignum + SRCDIR= ../common INCDIR= ../../include +SRCS = \ + $(PKCS11_COBJECTS:%.o=$(SRCDIR)/%.c) \ + $(BIGNUM_COBJECTS:%.o=$(BIGNUMDIR)/%.c) + + CFLAGS += $(CCVERBOSE) -CPPFLAGS += -D_REENTRANT $(KMFINC) -I$(INCDIR) -I/usr/include/libxml2 +CPPFLAGS += -D_REENTRANT $(KMFINC) -I$(INCDIR) -I/usr/include/libxml2 -I$(BIGNUMDIR) PICS= $(OBJECTS:%=pics/%) SONAME= $(PLUGIN) @@ -62,4 +72,8 @@ lint: lintcheck FRC: +pics/%.o: $(BIGNUMDIR)/%.c + $(COMPILE.c) -o $@ $(BIGNUM_CFG) $< + $(POST_PROCESS_O) + include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/mapfile-vers b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/mapfile-vers index ee3b6bcb92..0e120d0b9b 100644 --- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/mapfile-vers +++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/mapfile-vers @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -28,23 +28,24 @@ SUNWprivate_1.1 { global: KMF_Plugin_Initialize; - KMFPK11_FindCert; - KMFPK11_FreeKMFCert; - KMFPK11_StoreCert; - KMFPK11_ImportCert; - KMFPK11_DeleteCert; - KMFPK11_CreateKeypair; - KMFPK11_FindKey; - KMFPK11_EncodePubKeyData; - KMFPK11_SignData; - KMFPK11_DeleteKey; - KMFPK11_GetErrorString; - KMFPK11_GetPrikeyByCert; - KMFPK11_DecryptData; - KMFPK11_StorePrivateKey; - KMFPK11_CreateSymKey; - KMFPK11_GetSymKeyValue; - KMFPK11_SetTokenPin; + KMFPK11_CreateKeypair; + KMFPK11_CreateSymKey; + KMFPK11_DecryptData; + KMFPK11_DeleteCert; + KMFPK11_DeleteKey; + KMFPK11_EncodePubKeyData; + KMFPK11_ExportPK12; + KMFPK11_FindCert; + KMFPK11_FindKey; + KMFPK11_FindPrikeyByCert; + KMFPK11_FreeKMFCert; + KMFPK11_GetErrorString; + KMFPK11_GetSymKeyValue; + KMFPK11_ImportCert; + KMFPK11_SetTokenPin; + KMFPK11_SignData; + KMFPK11_StoreCert; + KMFPK11_StoreKey; local: *; }; diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c index f000c5eadd..3d7cfae6d2 100644 --- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c @@ -36,6 +36,7 @@ #include <algorithm.h> #include <fcntl.h> #include <sha1.h> +#include <bignum.h> #include <cryptoutil.h> #include <security/cryptoki.h> @@ -67,38 +68,36 @@ static KMF_RETURN keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **); static KMF_RETURN -create_generic_secret_key(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, - CK_OBJECT_HANDLE *); +create_generic_secret_key(KMF_HANDLE_T, + int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *); KMF_RETURN -KMFPK11_ConfigureKeystore(KMF_HANDLE_T, KMF_CONFIG_PARAMS *); +KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_FindCert(KMF_HANDLE_T, - KMF_FINDCERT_PARAMS *, - KMF_X509_DER_CERT *, - uint32_t *); +KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); void KMFPK11_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *kmf_cert); KMF_RETURN -KMFPK11_StoreCert(KMF_HANDLE_T, KMF_STORECERT_PARAMS *, KMF_DATA *); +KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_ImportCert(KMF_HANDLE_T, KMF_IMPORTCERT_PARAMS *); +KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_DeleteCert(KMF_HANDLE_T, KMF_DELETECERT_PARAMS *); +KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, - KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); +KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, - KMF_KEY_HANDLE *, boolean_t); +KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); + +KMF_RETURN +KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); @@ -111,35 +110,32 @@ KMF_RETURN KMFPK11_GetErrorString(KMF_HANDLE_T, char **); KMF_RETURN -KMFPK11_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, - KMF_KEY_HANDLE *, KMF_KEY_ALG); +KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, KMF_DATA *, KMF_DATA *); KMF_RETURN -KMFPK11_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, - KMF_KEY_HANDLE *, uint32_t *); +KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN -KMFPK11_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, - KMF_RAW_KEY_DATA *); - -KMF_RETURN -KMFPK11_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, - KMF_KEY_HANDLE *); +KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); KMF_RETURN -KMFPK11_SetTokenPin(KMF_HANDLE_T, KMF_SETPIN_PARAMS *, KMF_CREDENTIAL *); +KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); KMF_RETURN KMFPK11_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, KMF_DATA *, KMF_DATA *, KMF_DATA *); +KMF_RETURN +KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); + + static KMF_PLUGIN_FUNCLIST pk11token_plugin_table = { @@ -161,14 +157,14 @@ KMF_PLUGIN_FUNCLIST pk11token_plugin_table = NULL, /* FindCRL */ NULL, /* FindCertInCRL */ KMFPK11_GetErrorString, - KMFPK11_GetPrikeyByCert, + KMFPK11_FindPrikeyByCert, KMFPK11_DecryptData, - NULL, /* ExportP12 */ - KMFPK11_StorePrivateKey, + KMFPK11_ExportPK12, KMFPK11_CreateSymKey, KMFPK11_GetSymKeyValue, KMFPK11_SetTokenPin, KMFPK11_VerifyDataWithCert, + KMFPK11_StoreKey, NULL /* Finalize */ }; @@ -179,15 +175,23 @@ KMF_Plugin_Initialize() } KMF_RETURN -KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) +KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; + char *label; + boolean_t readonly = B_TRUE; - if (params == NULL || params->pkcs11config.label == NULL) + label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr); + if (label == NULL) { return (KMF_ERR_BAD_PARAMETER); + } + + /* "readonly" is optional. Default is TRUE */ + (void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr, + (void *)&readonly, NULL); - rv = KMF_SelectToken(handle, params->pkcs11config.label, - params->pkcs11config.readonly); + rv = kmf_select_token(handle, label, readonly); return (rv); } @@ -207,8 +211,8 @@ pk11_authenticate(KMF_HANDLE_T handle, return (KMF_ERR_BAD_PARAMETER); } - if ((ck_rv = C_Login(hSession, CKU_USER, - (uchar_t *)cred->cred, cred->credlen)) != CKR_OK) { + if ((ck_rv = C_Login(hSession, CKU_USER, (uchar_t *)cred->cred, + cred->credlen)) != CKR_OK) { if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) { handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; handle->lasterr.errcode = ck_rv; @@ -306,7 +310,7 @@ PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj, /* re-query the object with room for the value attr */ ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, - templ, i); + templ, i); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); @@ -318,7 +322,7 @@ PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj, kmfcert->certificate.Length = value_len; kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED; kmfcert->kmf_private.keystore_type = - KMF_KEYSTORE_PK11TOKEN; + KMF_KEYSTORE_PK11TOKEN; ckrv = getObjectLabel(kmfh, hObj, &label); if (ckrv == CKR_OK && label != NULL) { @@ -417,8 +421,8 @@ matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, name.Length = certattr.ulValueLen; rv = DerDecodeName(&name, &dn); if (rv == KMF_OK) { - rv = KMF_CompareRDNs(issuer, &dn); - KMF_FreeDN(&dn); + rv = kmf_compare_rdns(issuer, &dn); + kmf_free_dn(&dn); } free(certattr.pValue); } @@ -438,8 +442,8 @@ matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, name.Length = certattr.ulValueLen; rv = DerDecodeName(&name, &dn); if (rv == KMF_OK) { - rv = KMF_CompareRDNs(subject, &dn); - KMF_FreeDN(&dn); + rv = kmf_compare_rdns(subject, &dn); + kmf_free_dn(&dn); } free(certattr.pValue); } @@ -470,7 +474,7 @@ pk11_delete_obj_from_list(OBJLIST **newlist, } /* - * prepare_object_search + * search_certs * * Because this code is shared by the FindCert and * DeleteCert functions, put it in a separate routine @@ -502,8 +506,7 @@ search_certs(KMF_HANDLE_T handle, i = 0; SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++; SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++; - SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, - sizeof (ctype)); i++; + SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, sizeof (ctype)); i++; if (label != NULL && strlen(label)) { SETATTR(templ, i, CKA_LABEL, label, strlen(label)); @@ -514,17 +517,16 @@ search_certs(KMF_HANDLE_T handle, } if (issuer != NULL && strlen(issuer)) { - if ((rv = KMF_DNParser(issuer, &issuerDN)) != KMF_OK) + if ((rv = kmf_dn_parser(issuer, &issuerDN)) != KMF_OK) return (rv); } if (subject != NULL && strlen(subject)) { - if ((rv = KMF_DNParser(subject, &subjectDN)) != KMF_OK) + if ((rv = kmf_dn_parser(subject, &subjectDN)) != KMF_OK) return (rv); } if (serial != NULL && serial->val != NULL && serial->len > 0) { - SETATTR(templ, i, CKA_SERIAL_NUMBER, - serial->val, serial->len); + SETATTR(templ, i, CKA_SERIAL_NUMBER, serial->val, serial->len); i++; } @@ -606,7 +608,7 @@ cleanup: goto cleanup1; } - rv = KMF_CheckCertDate(handle, + rv = kmf_check_cert_date(handle, &tmp_kmf_cert.certificate); if (validity == KMF_NONEXPIRED_CERTS) { @@ -643,7 +645,7 @@ cleanup: } } i++; - KMF_FreeKMFCert(handle, &tmp_kmf_cert); + kmf_free_kmf_cert(handle, &tmp_kmf_cert); } *numobj = num_ok_certs; *objlist = newlist; @@ -658,10 +660,10 @@ cleanup1: } if (issuer != NULL) - KMF_FreeDN(&issuerDN); + kmf_free_dn(&issuerDN); if (subject != NULL) - KMF_FreeDN(&subjectDN); + kmf_free_dn(&subjectDN); return (rv); } @@ -671,22 +673,29 @@ cleanup1: * just return the number of certs found (in num_certs). */ KMF_RETURN -KMFPK11_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, - KMF_X509_DER_CERT *kmf_cert, - uint32_t *num_certs) +KMFPK11_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = 0; uint32_t want_certs; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; OBJLIST *objlist = NULL; + uint32_t *num_certs; + KMF_X509_DER_CERT *kmf_cert = NULL; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; + boolean_t private; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL || num_certs == NULL) + num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (num_certs == NULL) return (KMF_ERR_BAD_PARAMETER); if (*num_certs > 0) @@ -696,19 +705,40 @@ KMFPK11_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, *num_certs = 0; - rv = search_certs(handle, - params->certLabel, params->issuer, - params->subject, params->serial, - params->pkcs11parms.private, - params->find_cert_validity, - &objlist, num_certs); + /* Get the optional returned certificate list */ + kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, + numattr); + + /* Get optional search criteria attributes */ + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); + if (rv != KMF_OK) { + validity = KMF_ALL_CERTS; + rv = KMF_OK; + } + + rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr, + (void *)&private, NULL); + if (rv != KMF_OK) { + private = B_FALSE; + rv = KMF_OK; + } + + /* Start searching */ + rv = search_certs(handle, certlabel, issuer, subject, serial, private, + validity, &objlist, num_certs); if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) { OBJLIST *node = objlist; int i = 0; while (node != NULL && i < want_certs) { rv = PK11Cert2KMFCert(kmfh, node->handle, - &kmf_cert[i]); + &kmf_cert[i]); i++; node = node->next; } @@ -725,8 +755,7 @@ KMFPK11_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, /*ARGSUSED*/ void -KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, - KMF_X509_DER_CERT *kmf_cert) +KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) { if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) { free(kmf_cert->certificate.Data); @@ -758,7 +787,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, CK_ATTRIBUTE rsaTemplate[4]; CK_ATTRIBUTE dsaTemplate[6]; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) @@ -778,7 +807,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType, sizeof (ckKeyType)); SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data, &Modulus.Length); SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT, Exponent.Data, - &Exponent.Length); + &Exponent.Length); SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass, sizeof (ckObjClass)); SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType, sizeof (ckKeyType)); @@ -791,8 +820,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, case KMF_RSA: /* Get the length of the fields */ rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pKey->keyp, - rsaTemplate, 4); + (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); return (KMF_ERR_BAD_PARAMETER); @@ -811,13 +839,12 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, } SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data, - Modulus.Length); + Modulus.Length); SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT, - Exponent.Data, Exponent.Length); + Exponent.Data, Exponent.Length); /* Now get the values */ rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pKey->keyp, - rsaTemplate, 4); + (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); free(Modulus.Data); @@ -829,7 +856,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, * This is the KEY algorithm, not the * signature algorithm. */ - Algorithm = X509_AlgIdToAlgorithmOid(KMF_ALGID_RSA); + Algorithm = x509_algid_to_algoid(KMF_ALGID_RSA); if (Algorithm != NULL) { /* Encode the RSA Key Data */ @@ -838,9 +865,9 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, free(Exponent.Data); return (KMF_ERR_MEMORY); } - if (kmfber_printf(asn1, "{II}", - Modulus.Data, Modulus.Length, - Exponent.Data, Exponent.Length) == -1) { + if (kmfber_printf(asn1, "{II}", Modulus.Data, + Modulus.Length, Exponent.Data, + Exponent.Length) == -1) { kmfber_free(asn1, 1); free(Modulus.Data); free(Exponent.Data); @@ -862,8 +889,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, case KMF_DSA: /* Get the length of the fields */ rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pKey->keyp, - dsaTemplate, 6); + (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); return (KMF_ERR_BAD_PARAMETER); @@ -898,18 +924,17 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, return (KMF_ERR_MEMORY); } SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data, - Prime.Length); + Prime.Length); SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data, - Subprime.Length); + Subprime.Length); SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data, - Base.Length); + Base.Length); SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data, - Value.Length); + Value.Length); /* Now get the values */ rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pKey->keyp, - dsaTemplate, 6); + (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6); if (rv != CKR_OK) { free(Prime.Data); free(Subprime.Data); @@ -922,8 +947,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, * This is the KEY algorithm, not the * signature algorithm. */ - Algorithm = - X509_AlgIdToAlgorithmOid(KMF_ALGID_DSA); + Algorithm = x509_algid_to_algoid(KMF_ALGID_DSA); /* Encode the DSA Algorithm Parameters */ if ((asn1 = kmfder_alloc()) == NULL) { @@ -934,10 +958,9 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, return (KMF_ERR_MEMORY); } - if (kmfber_printf(asn1, "{III}", - Prime.Data, Prime.Length, - Subprime.Data, Subprime.Length, - Base.Data, Base.Length) == -1) { + if (kmfber_printf(asn1, "{III}", Prime.Data, + Prime.Length, Subprime.Data, Subprime.Length, + Base.Data, Base.Length) == -1) { kmfber_free(asn1, 1); free(Prime.Data); @@ -966,7 +989,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, } if (kmfber_printf(asn1, "I", - Value.Data, Value.Length) == -1) { + Value.Data, Value.Length) == -1) { kmfber_free(asn1, 1); free(Value.Data); return (KMF_ERR_ENCODING); @@ -987,7 +1010,7 @@ KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, spki.algorithm.algorithm = *Algorithm; if (PubKeyParams != NULL) { spki.algorithm.parameters.Data = - (uchar_t *)PubKeyParams->bv_val; + (uchar_t *)PubKeyParams->bv_val; spki.algorithm.parameters.Length = PubKeyParams->bv_len; } else { spki.algorithm.parameters.Data = NULL; @@ -1040,7 +1063,7 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) CK_OBJECT_HANDLE hCert = NULL; int i; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_INTERNAL); /* should not happen */ if (kmfh->pk11handle == CK_INVALID_HANDLE) @@ -1055,7 +1078,7 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) * the PKCS#11 attributes can be filled in correctly. */ rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert, - &signed_cert_ptr); + &signed_cert_ptr); if (rv != KMF_OK) { return (KMF_ERR_ENCODING); } @@ -1101,7 +1124,7 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) /* Generate an ID from the SPKI data */ rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo, - &Id); + &Id); if (rv != KMF_OK) { SET_ERROR(kmfh, rv); @@ -1109,10 +1132,10 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) } i = 0; - SETATTR(x509templ, i, CKA_CLASS, &certClass, - sizeof (certClass)); i++; + SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++; SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype, - sizeof (certtype)); i++; + sizeof (certtype)); + i++; SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++; SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++; SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++; @@ -1120,8 +1143,7 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++; SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++; if (label != NULL && strlen(label)) { - SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); - i++; + SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); i++; } /* * The cert object handle is actually "leaked" here. If the app @@ -1141,7 +1163,7 @@ cleanup: free(Id.Data); if (signed_cert_ptr) { - KMF_FreeSignedCert(signed_cert_ptr); + kmf_free_signed_cert(signed_cert_ptr); free(signed_cert_ptr); } return (rv); @@ -1149,67 +1171,75 @@ cleanup: KMF_RETURN -KMFPK11_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, - KMF_DATA *pcert) +KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = 0; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_DATA *cert = NULL; + char *label = NULL; - if (!kmfh) - return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ + if (kmfh == NULL) + return (KMF_ERR_UNINITIALIZED); if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL || cert->Data == NULL || cert->Length == 0) return (KMF_ERR_BAD_PARAMETER); - rv = CreateCertObject(handle, params->certLabel, pcert); + /* label attribute is optional */ + label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + + rv = CreateCertObject(handle, label, cert); return (rv); } - - KMF_RETURN -KMFPK11_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *params) +KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = 0; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + char *certfile = NULL; + char *label = NULL; KMF_ENCODE_FORMAT format; KMF_DATA cert1 = { NULL, 0}; KMF_DATA cert2 = { NULL, 0}; - if (!kmfh) - return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ + if (kmfh == NULL) + return (KMF_ERR_UNINITIALIZED); if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL || params->certfile == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - /* - * Check if the input cert file is a valid certificate and - * auto-detect the file format of it. + * Get the input cert filename attribute, check if it is a valid + * certificate and auto-detect the file format of it. */ - rv = KMF_IsCertFile(handle, params->certfile, &format); + certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); + if (certfile == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_is_cert_file(handle, certfile, &format); if (rv != KMF_OK) return (rv); /* Read in the CERT file */ - rv = KMF_ReadInputFile(handle, params->certfile, &cert1); + rv = kmf_read_input_file(handle, certfile, &cert1); if (rv != KMF_OK) { return (rv); } + /* The label attribute is optional */ + label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + /* * If the input certificate is in PEM format, we need to convert * it to DER first. */ if (format == KMF_FORMAT_PEM) { int derlen; - rv = KMF_Pem2Der(cert1.Data, cert1.Length, + rv = kmf_pem_to_der(cert1.Data, cert1.Length, &cert2.Data, &derlen); if (rv != KMF_OK) { goto out; @@ -1217,7 +1247,7 @@ KMFPK11_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *params) cert2.Length = (size_t)derlen; } - rv = CreateCertObject(handle, params->certLabel, + rv = CreateCertObject(handle, label, format == KMF_FORMAT_ASN1 ? &cert1 : &cert2); out: @@ -1233,41 +1263,60 @@ out: } KMF_RETURN -KMFPK11_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) +KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = 0; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; OBJLIST *objlist; uint32_t numObjects = 0; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_CERT_VALIDITY validity; + boolean_t private; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL) - return (KMF_ERR_BAD_PARAMETER); + + /* Get the search criteria attributes. They are all optional. */ + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + + rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, + &validity, NULL); + if (rv != KMF_OK) { + validity = KMF_ALL_CERTS; + rv = KMF_OK; + } + + rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr, + (void *)&private, NULL); + if (rv != KMF_OK) { + private = B_FALSE; + rv = KMF_OK; + } /* - * Use the same search routine as is used for the FindCert - * operation. + * Start searching for certificates that match the criteria and + * delete them. */ objlist = NULL; - rv = search_certs(handle, - params->certLabel, params->issuer, - params->subject, params->serial, - params->pkcs11parms.private, - params->find_cert_validity, - &objlist, &numObjects); + rv = search_certs(handle, certlabel, issuer, subject, serial, + private, validity, &objlist, &numObjects); if (rv == KMF_OK && objlist != NULL) { OBJLIST *node = objlist; while (node != NULL) { CK_RV ckrv; - ckrv = C_DestroyObject(kmfh->pk11handle, - node->handle); + ckrv = C_DestroyObject(kmfh->pk11handle, node->handle); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; @@ -1286,8 +1335,9 @@ out: } KMF_RETURN -KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, - KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) +KMFPK11_CreateKeypair(KMF_HANDLE_T handle, + int numattr, + KMF_ATTRIBUTE *attlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -1302,14 +1352,15 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, static CK_ULONG rsaKeyType = CKK_RSA; static CK_ULONG modulusBits = 1024; + uint32_t modulusBits_size = sizeof (CK_ULONG); static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01}; static CK_BBOOL true = TRUE; static CK_BBOOL ontoken = TRUE; static CK_BBOOL false = FALSE; static CK_ULONG dsaKeyType = CKK_DSA; - CK_ATTRIBUTE rsaPubKeyTemplate[8]; - CK_ATTRIBUTE rsaPriKeyTemplate[6]; + CK_ATTRIBUTE rsaPubKeyTemplate[16]; + CK_ATTRIBUTE rsaPriKeyTemplate[16]; static CK_BYTE ckDsaPrime[128] = { 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2, @@ -1381,106 +1432,146 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, char IDHashData[SHA1_HASH_LENGTH]; KMF_DATA IDInput, IDOutput; SHA1_CTX ctx; + KMF_CREDENTIAL *cred; + KMF_KEY_ALG keytype = KMF_RSA; + boolean_t storekey = TRUE; + char *keylabel = NULL; + KMF_KEY_HANDLE *pubkey, *privkey; #define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \ sizeof (CK_ATTRIBUTE)) #define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \ sizeof (CK_ATTRIBUTE)) - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL) + /* "storekey" is optional. Default is TRUE */ + (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr, + &storekey, NULL); + + cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr); + if (cred == NULL) return (KMF_ERR_BAD_PARAMETER); - rv = pk11_authenticate(handle, ¶ms->cred); - if (rv != KMF_OK) { + rv = pk11_authenticate(handle, cred); + if (rv != KMF_OK) return (rv); - } - if (params->keytype == KMF_RSA) { - CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, - NULL, 0}; + /* keytype is optional. KMF_RSA is default */ + (void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr, + (void *)&keytype, NULL); + + pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr); + if (pubkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr); + if (privkey == NULL) + return (KMF_ERR_BAD_PARAMETER); + + (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); + (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); + if (keytype == KMF_RSA) { + CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0}; CK_BYTE *modulus; CK_ULONG modulusLength; CK_ATTRIBUTE modattr[1]; + KMF_BIGINT *rsaexp = NULL; + int numpubattr = 0, numpriattr = 0; + + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr, + &modulusBits, &modulusBits_size); + if (rv == KMF_ERR_ATTR_NOT_FOUND) + /* Default modulusBits = 1024 */ + rv = KMF_OK; + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); - SETATTR(rsaPubKeyTemplate, 0, CKA_CLASS, - &pubClass, sizeof (pubClass)); - SETATTR(rsaPubKeyTemplate, 1, CKA_KEY_TYPE, - &rsaKeyType, sizeof (rsaKeyType)); - SETATTR(rsaPubKeyTemplate, 2, CKA_TOKEN, - &false, sizeof (false)); - SETATTR(rsaPubKeyTemplate, 3, CKA_PRIVATE, - &false, sizeof (false)); - SETATTR(rsaPubKeyTemplate, 4, CKA_MODULUS_BITS, - &modulusBits, sizeof (modulusBits)); - if (params->rsa_exponent.len > 0 && - params->rsa_exponent.val != NULL) { - SETATTR(rsaPubKeyTemplate, 5, - CKA_PUBLIC_EXPONENT, - params->rsa_exponent.val, - params->rsa_exponent.len); + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_CLASS, + &pubClass, sizeof (pubClass)); + numpubattr++; + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_KEY_TYPE, + &rsaKeyType, sizeof (rsaKeyType)); + numpubattr++; + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN, + (storekey ? &true : &false), sizeof (CK_BBOOL)); + numpubattr++; + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_PRIVATE, + &false, sizeof (false)); + numpubattr++; + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS, + &modulusBits, sizeof (modulusBits)); + numpubattr++; + + if ((rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, + numattr)) != NULL && + (rsaexp->len > 0 && rsaexp->val != NULL)) { + SETATTR(rsaPubKeyTemplate, numpubattr, + CKA_PUBLIC_EXPONENT, + rsaexp->val, rsaexp->len); + numpubattr++; } else { - SETATTR(rsaPubKeyTemplate, 5, - CKA_PUBLIC_EXPONENT, &PubExpo, - sizeof (PubExpo)); - } - SETATTR(rsaPubKeyTemplate, 6, CKA_ENCRYPT, - &true, sizeof (true)); - SETATTR(rsaPubKeyTemplate, 7, CKA_VERIFY, - &true, sizeof (true)); - - SETATTR(rsaPriKeyTemplate, 0, CKA_CLASS, &priClass, - sizeof (priClass)); - SETATTR(rsaPriKeyTemplate, 1, CKA_KEY_TYPE, &rsaKeyType, - sizeof (rsaKeyType)); - SETATTR(rsaPriKeyTemplate, 2, CKA_TOKEN, &ontoken, - sizeof (ontoken)); - SETATTR(rsaPriKeyTemplate, 3, CKA_PRIVATE, &true, - sizeof (true)); - SETATTR(rsaPriKeyTemplate, 4, CKA_DECRYPT, &true, - sizeof (true)); - SETATTR(rsaPriKeyTemplate, 5, CKA_SIGN, &true, - sizeof (true)); + rv = KMF_OK; + SETATTR(rsaPubKeyTemplate, numpubattr, + CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo)); + numpubattr++; + } + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT, + &true, sizeof (true)); + numpubattr++; + SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY, + &true, sizeof (true)); + numpubattr++; + + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_CLASS, &priClass, + sizeof (priClass)); + numpriattr++; + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_KEY_TYPE, + &rsaKeyType, sizeof (rsaKeyType)); + numpriattr++; + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN, + (storekey ? &true : &false), sizeof (CK_BBOOL)); + numpriattr++; + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true, + sizeof (true)); + numpriattr++; + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true, + sizeof (true)); + numpriattr++; + SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true, + sizeof (true)); + numpriattr++; SETATTR(modattr, 0, CKA_MODULUS, NULL, &modulusLength); - modulusBits = params->keylength; - pubKey = CK_INVALID_HANDLE; priKey = CK_INVALID_HANDLE; ckrv = C_GenerateKeyPair(hSession, &keyGenMech, - rsaPubKeyTemplate, - (sizeof (rsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), - rsaPriKeyTemplate, - (sizeof (rsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), - &pubKey, &priKey); + rsaPubKeyTemplate, numpubattr, + rsaPriKeyTemplate, numpriattr, + &pubKey, &priKey); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); return (KMF_ERR_KEYGEN_FAILED); } - if (privkey != NULL) { - privkey->kstype = KMF_KEYSTORE_PK11TOKEN; - privkey->keyalg = KMF_RSA; - privkey->keyclass = KMF_ASYM_PRI; - privkey->keyp = (void *)priKey; - } - if (pubkey != NULL) { - pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; - pubkey->keyalg = KMF_RSA; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->keyp = (void *)pubKey; - } + privkey->kstype = KMF_KEYSTORE_PK11TOKEN; + privkey->keyalg = KMF_RSA; + privkey->keyclass = KMF_ASYM_PRI; + privkey->keyp = (void *)priKey; + + pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; + pubkey->keyalg = KMF_RSA; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->keyp = (void *)pubKey; /* Get the Modulus field to use as input for creating the ID */ rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pubKey, - modattr, 1); + (CK_OBJECT_HANDLE)pubKey, modattr, 1); if (rv != CKR_OK) { SET_ERROR(kmfh, ckrv); return (KMF_ERR_BAD_PARAMETER); @@ -1493,8 +1584,7 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, modattr[0].pValue = modulus; rv = C_GetAttributeValue(kmfh->pk11handle, - (CK_OBJECT_HANDLE)pubKey, - modattr, 1); + (CK_OBJECT_HANDLE)pubKey, modattr, 1); if (rv != CKR_OK) { SET_ERROR(kmfh, ckrv); free(modulus); @@ -1504,43 +1594,40 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, IDInput.Data = modulus; IDInput.Length = modulusLength; - } else if (params->keytype == KMF_DSA) { + } else if (keytype == KMF_DSA) { CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0}; CK_BYTE *keyvalue; CK_ULONG valueLen; CK_ATTRIBUTE valattr[1]; SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN, - &ontoken, sizeof (ontoken)); + (storekey ? &true : &false), sizeof (CK_BBOOL)); SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen); ckrv = C_GenerateKeyPair(hSession, &keyGenMech, - ckDsaPubKeyTemplate, - (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), - ckDsaPriKeyTemplate, - (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), - &pubKey, &priKey); + ckDsaPubKeyTemplate, + (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), + ckDsaPriKeyTemplate, + (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), + &pubKey, &priKey); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); return (KMF_ERR_KEYGEN_FAILED); } - if (privkey != NULL) { - privkey->kstype = KMF_KEYSTORE_PK11TOKEN; - privkey->keyalg = KMF_DSA; - privkey->keyclass = KMF_ASYM_PRI; - privkey->keyp = (void *)priKey; - } - if (pubkey != NULL) { - pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; - pubkey->keyalg = KMF_DSA; - pubkey->keyclass = KMF_ASYM_PUB; - pubkey->keyp = (void *)pubKey; - } + privkey->kstype = KMF_KEYSTORE_PK11TOKEN; + privkey->keyalg = KMF_DSA; + privkey->keyclass = KMF_ASYM_PRI; + privkey->keyp = (void *)priKey; + + pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; + pubkey->keyalg = KMF_DSA; + pubkey->keyclass = KMF_ASYM_PUB; + pubkey->keyp = (void *)pubKey; + /* Get the Public Value to use as input for creating the ID */ rv = C_GetAttributeValue(hSession, - (CK_OBJECT_HANDLE)pubKey, - valattr, 1); + (CK_OBJECT_HANDLE)pubKey, valattr, 1); if (rv != CKR_OK) { SET_ERROR(kmfh, ckrv); return (KMF_ERR_BAD_PARAMETER); @@ -1553,8 +1640,7 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, valattr[0].pValue = keyvalue; rv = C_GetAttributeValue(hSession, - (CK_OBJECT_HANDLE)pubKey, - valattr, 1); + (CK_OBJECT_HANDLE)pubKey, valattr, 1); if (rv != CKR_OK) { SET_ERROR(kmfh, ckrv); free(keyvalue); @@ -1567,41 +1653,35 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, return (KMF_ERR_BAD_PARAMETER); } - if (params->keylabel != NULL && - strlen(params->keylabel)) { - - SETATTR(labelattr, 0, CKA_LABEL, params->keylabel, - strlen(params->keylabel)); + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr); + if (keylabel != NULL && strlen(keylabel)) { + SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel)); /* Set the CKA_LABEL if one was indicated */ if ((ckrv = C_SetAttributeValue(hSession, pubKey, - labelattr, 1)) != CKR_OK) { + labelattr, 1)) != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; goto cleanup; } - if (pubkey != NULL) { - pubkey->keylabel = - (char *)strdup(params->keylabel); - if (pubkey->keylabel == NULL) { - rv = KMF_ERR_MEMORY; - goto cleanup; - } + pubkey->keylabel = (char *)strdup(keylabel); + if (pubkey->keylabel == NULL) { + rv = KMF_ERR_MEMORY; + goto cleanup; } if ((ckrv = C_SetAttributeValue(hSession, priKey, - labelattr, 1)) != CKR_OK) { + labelattr, 1)) != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; goto cleanup; } - if (privkey != NULL) { - privkey->keylabel = - (char *)strdup(params->keylabel); - if (privkey->keylabel == NULL) { - rv = KMF_ERR_MEMORY; - goto cleanup; - } + privkey->keylabel = (char *)strdup(keylabel); + if (privkey->keylabel == NULL) { + rv = KMF_ERR_MEMORY; + goto cleanup; } + } else { + rv = KMF_OK; } /* Now, assign a CKA_ID value so it can be searched */ @@ -1623,13 +1703,13 @@ KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, } SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length); if ((ckrv = C_SetAttributeValue(hSession, pubKey, - idattr, 1)) != CKR_OK) { + idattr, 1)) != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; goto cleanup; } if ((ckrv = C_SetAttributeValue(hSession, priKey, - idattr, 1)) != CKR_OK) { + idattr, 1)) != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; goto cleanup; @@ -1641,44 +1721,52 @@ cleanup: (void) C_DestroyObject(hSession, pubKey); if (priKey != CK_INVALID_HANDLE) (void) C_DestroyObject(hSession, priKey); - if (privkey) { - privkey->keyp = NULL; - if (privkey->keylabel) - free(privkey->keylabel); - } - if (pubkey) { - pubkey->keyp = NULL; - if (pubkey->keylabel) - free(pubkey->keylabel); - } + + if (privkey->keylabel) + free(privkey->keylabel); + if (pubkey->keylabel) + free(pubkey->keylabel); } return (rv); } KMF_RETURN -KMFPK11_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, - KMF_KEY_HANDLE *key, boolean_t destroy) +KMFPK11_DeleteKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; CK_RV ckrv = CKR_OK; KMF_RETURN rv = KMF_OK; + KMF_KEY_HANDLE *key; + KMF_CREDENTIAL cred; + boolean_t destroy = B_TRUE; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); if (key == NULL || key->keyp == NULL) return (KMF_ERR_BAD_PARAMETER); if (key->keyclass != KMF_ASYM_PUB && - key->keyclass != KMF_ASYM_PRI && - key->keyclass != KMF_SYMMETRIC) + key->keyclass != KMF_ASYM_PRI && + key->keyclass != KMF_SYMMETRIC) return (KMF_ERR_BAD_KEY_CLASS); + /* "destroy" is optional. Default is TRUE */ + (void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, + (void *)&destroy, NULL); + if (destroy) { - rv = pk11_authenticate(handle, ¶ms->cred); + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = pk11_authenticate(handle, &cred); if (rv != KMF_OK) { return (rv); } @@ -1686,19 +1774,17 @@ KMFPK11_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, if (!key->israw && destroy) ckrv = C_DestroyObject(kmfh->pk11handle, - (CK_OBJECT_HANDLE)key->keyp); + (CK_OBJECT_HANDLE)key->keyp); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); /* Report authentication failures to the caller */ - if (ckrv == CKR_PIN_EXPIRED || - ckrv == CKR_SESSION_READ_ONLY) + if (ckrv == CKR_PIN_EXPIRED || ckrv == CKR_SESSION_READ_ONLY) rv = KMF_ERR_AUTH_FAILED; else rv = KMF_ERR_INTERNAL; } return (rv); - } KMF_RETURN @@ -1712,9 +1798,9 @@ KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, CK_SESSION_HANDLE hSession = kmfh->pk11handle; CK_MECHANISM mechanism; PKCS_ALGORITHM_MAP *pAlgMap; - KMF_ALGORITHM_INDEX AlgId; + KMF_ALGORITHM_INDEX AlgId; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) @@ -1725,13 +1811,13 @@ KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, return (KMF_ERR_BAD_PARAMETER); /* These functions are available to the plugin from libkmf */ - AlgId = X509_AlgorithmOidToAlgId(algOID); + AlgId = x509_algoid_to_algid(algOID); if (AlgId == KMF_ALGID_NONE) return (KMF_ERR_BAD_PARAMETER); /* Map the Algorithm OID to a PKCS#11 mechanism */ - pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, - AlgId, PKCS_GetDefaultSignatureMode(AlgId)); + pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, + AlgId, PKCS_GetDefaultSignatureMode(AlgId)); if (pAlgMap == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -1746,9 +1832,8 @@ KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, return (KMF_ERR_INTERNAL); } - ckrv = C_Sign(hSession, - tobesigned->Data, tobesigned->Length, - output->Data, (CK_ULONG *)&output->Length); + ckrv = C_Sign(hSession, tobesigned->Data, tobesigned->Length, + output->Data, (CK_ULONG *)&output->Length); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); @@ -1816,11 +1901,10 @@ getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, return (rv); } + KMF_RETURN -KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, - KMF_CRYPTOWITHCERT_PARAMS *params, - KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, - KMF_KEY_ALG keytype) +KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) { KMF_X509_SPKI *pubkey; KMF_X509_CERTIFICATE *SignerCert = NULL; @@ -1833,9 +1917,27 @@ KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, CK_OBJECT_CLASS certClass = CKO_PRIVATE_KEY; CK_BBOOL true = TRUE; KMF_DATA Id = { NULL, 0 }; + KMF_KEY_HANDLE *key = NULL; + KMF_DATA *cert = NULL; + KMF_CREDENTIAL cred; + KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF; + CK_ULONG keytype; + + /* Get the key handle */ + key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (key == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* Get the optional encoded format */ + (void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, + (void *)&format, NULL); /* Decode the signer cert so we can get the SPKI data */ - if ((rv = DerDecodeSignedCertificate(SignerCertData, + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert == NULL || cert->Data == NULL) + return (KMF_ERR_BAD_PARAMETER); + + if ((rv = DerDecodeSignedCertificate(cert, &SignerCert)) != KMF_OK) return (rv); @@ -1844,22 +1946,28 @@ KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, /* Generate an ID from the SPKI data */ rv = GetIDFromSPKI(pubkey, &Id); - if (rv != KMF_OK) { SET_ERROR(kmfh, rv); goto errout; } - SETATTR(templ, 0, CKA_CLASS, &certClass, sizeof (certClass)); - SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true)); - SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true)); - SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length); + /* Get the credential and login */ + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); - rv = pk11_authenticate(handle, ¶ms->cred); + rv = pk11_authenticate(handle, &cred); if (rv != KMF_OK) { return (rv); } + /* Start searching */ + SETATTR(templ, 0, CKA_CLASS, &certClass, sizeof (certClass)); + SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true)); + SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true)); + SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length); + if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_INTERNAL; @@ -1881,14 +1989,29 @@ KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, key->kstype = KMF_KEYSTORE_PK11TOKEN; key->keyclass = KMF_ASYM_PRI; - key->keyalg = keytype; key->keyp = (void *)pri_obj; + key->israw = FALSE; (void) C_FindObjectsFinal(kmfh->pk11handle); ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp, - &key->keylabel); + &key->keylabel); + if (ckrv != CKR_OK) { + SET_ERROR(handle, ckrv); + rv = KMF_ERR_INTERNAL; + } else { + rv = KMF_OK; + } + /* + * The key->keyalg value is needed if we need to convert the key + * to raw key. However, the key->keyalg value will not be set if + * this function is not called thru the kmf_find_prikey_by_cert() + * framework function. To be safe, we will get the keytype from + * the key object and set key->keyalg value here. + */ + ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp, + &keytype); if (ckrv != CKR_OK) { SET_ERROR(handle, ckrv); rv = KMF_ERR_INTERNAL; @@ -1896,7 +2019,17 @@ KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, rv = KMF_OK; } - if (rv == KMF_OK && params->format == KMF_FORMAT_RAWKEY) { + if (keytype == CKK_RSA) + key->keyalg = KMF_RSA; + else if (keytype == CKK_DSA) + key->keyalg = KMF_DSA; + else { + /* For asymmetric keys, we only support RSA and DSA */ + rv = KMF_ERR_KEY_NOT_FOUND; + goto errout; + } + + if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) { KMF_RAW_KEY_DATA *rkey = NULL; rv = keyObj2RawKey(handle, key, &rkey); if (rv == KMF_OK) { @@ -1910,7 +2043,7 @@ errout: free(Id.Data); if (SignerCert != NULL) { - KMF_FreeSignedCert(SignerCert); + kmf_free_signed_cert(SignerCert); free(SignerCert); } return (rv); @@ -1932,7 +2065,7 @@ KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, int i, blocks; CK_ATTRIBUTE ckTemplate[1]; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) @@ -1942,12 +2075,12 @@ KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, ciphertext == NULL || output == NULL) return (KMF_ERR_BAD_PARAMETER); - AlgId = X509_AlgorithmOidToAlgId(algOID); + AlgId = x509_algoid_to_algid(algOID); if (AlgId == KMF_ALGID_NONE) return (KMF_ERR_BAD_PARAMETER); /* Map the Algorithm ID to a PKCS#11 mechanism */ - pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, + pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, AlgId, PKCS_GetDefaultSignatureMode(AlgId)); if (pAlgMap == NULL) @@ -1980,7 +2113,7 @@ KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, for (i = 0; i < blocks; i++) { ckrv = C_DecryptInit(hSession, &mechanism, - (CK_OBJECT_HANDLE)key->keyp); + (CK_OBJECT_HANDLE)key->keyp); if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); @@ -2019,7 +2152,7 @@ get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa) KMF_RETURN rv = KMF_OK; CK_RV ckrv; CK_SESSION_HANDLE sess = kmfh->pk11handle; - CK_ATTRIBUTE rsa_pri_attrs[8] = { + CK_ATTRIBUTE rsa_pri_attrs[8] = { { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, { CKA_PRIVATE_EXPONENT, NULL, 0 }, /* optional */ @@ -2029,11 +2162,11 @@ get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa) { CKA_EXPONENT_2, NULL, 0 }, /* | */ { CKA_COEFFICIENT, NULL, 0 } /* V */ }; - CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); - int i; + CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); + int i; if ((ckrv = C_GetAttributeValue(sess, obj, - rsa_pri_attrs, count)) != CKR_OK) { + rsa_pri_attrs, count)) != CKR_OK) { SET_ERROR(kmfh, ckrv); /* Tell the caller know why the key data cannot be retrieved. */ if (ckrv == CKR_ATTRIBUTE_SENSITIVE) @@ -2059,7 +2192,7 @@ get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa) } /* Now that we have space, really get the attributes */ if ((rv = C_GetAttributeValue(sess, obj, - rsa_pri_attrs, count)) != CKR_OK) { + rsa_pri_attrs, count)) != CKR_OK) { SET_ERROR(kmfh, rv); rv = KMF_ERR_INTERNAL; goto end; @@ -2109,10 +2242,78 @@ end: return (rv); } +#define DSA_PRIME_BUFSIZE 256 /* 8192 bits */ +#define DSA_PRIVATE_BUFSIZE 5 /* 160 bits */ + +/* + * This function calculates the pubkey value from the prime, + * base and private key values of a DSA key. + */ +static KMF_RETURN +compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa) +{ + KMF_RETURN rv = KMF_OK; + BIGNUM p, g, x, y; + BIG_ERR_CODE err; + uchar_t *pubvalue; + uint32_t pubvalue_len; + + if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { + rv = KMF_ERR_MEMORY; + return (rv); + } + bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len); + + if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { + rv = KMF_ERR_MEMORY; + goto ret1; + } + bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len); + + if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) { + rv = KMF_ERR_MEMORY; + goto ret2; + } + bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len); + + if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { + rv = KMF_ERR_MEMORY; + goto ret3; + } + + err = big_modexp(&y, &g, &x, &p, NULL); + if (err != BIG_OK) { + rv = KMF_ERR_INTERNAL; + goto ret3; + } + + pubvalue_len = y.len * (int)sizeof (uint32_t); + if ((pubvalue = malloc(pubvalue_len)) == NULL) { + rv = KMF_ERR_MEMORY; + goto ret4; + } + bignum2bytestring(pubvalue, &y, pubvalue_len); + + rawdsa->pubvalue.val = pubvalue; + rawdsa->pubvalue.len = pubvalue_len; + +ret4: + big_finish(&y); +ret3: + big_finish(&x); +ret2: + big_finish(&g); +ret1: + big_finish(&p); + return (rv); +} + + static KMF_RETURN get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) { KMF_RETURN rv = KMF_OK; + CK_RV ckrv; CK_SESSION_HANDLE sess = kmfh->pk11handle; CK_ATTRIBUTE dsa_pri_attrs[8] = { { CKA_PRIME, NULL, 0 }, @@ -2123,9 +2324,15 @@ get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE); int i; - if ((rv = C_GetAttributeValue(sess, obj, - dsa_pri_attrs, count)) != CKR_OK) { - SET_ERROR(kmfh, rv); + if ((ckrv = C_GetAttributeValue(sess, obj, + dsa_pri_attrs, count)) != CKR_OK) { + SET_ERROR(kmfh, ckrv); + + /* Tell the caller know why the key data cannot be retrieved. */ + if (ckrv == CKR_ATTRIBUTE_SENSITIVE) + return (KMF_ERR_SENSITIVE_KEY); + else if (ckrv == CKR_KEY_UNEXTRACTABLE) + return (KMF_ERR_UNEXTRACTABLE_KEY); return (KMF_ERR_INTERNAL); } @@ -2143,7 +2350,7 @@ get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) } } if ((rv = C_GetAttributeValue(sess, obj, - dsa_pri_attrs, count)) != CKR_OK) { + dsa_pri_attrs, count)) != CKR_OK) { SET_ERROR(kmfh, rv); rv = KMF_ERR_INTERNAL; goto end; @@ -2156,6 +2363,9 @@ get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base); attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value); + /* Compute the public key value and store it */ + rv = compute_dsa_pubvalue(rawdsa); + end: if (rv != KMF_OK) { for (i = 0; i < count; i++) { @@ -2181,19 +2391,16 @@ get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym) sym_attr[0].pValue = NULL; sym_attr[0].ulValueLen = value_len; if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) { - /* - * Don't return error if the key is sensitive, just - * don't return any raw data. Operations like "list" - * need to succeed even if the raw data is not - * available. - */ + rawsym->keydata.val = NULL; + rawsym->keydata.len = 0; if (ckrv == CKR_ATTRIBUTE_SENSITIVE) { - rawsym->keydata.val = NULL; - rawsym->keydata.len = 0; - return (CKR_OK); + return (KMF_ERR_SENSITIVE_KEY); + } else if (ckrv == CKR_KEY_UNEXTRACTABLE) { + return (KMF_ERR_UNEXTRACTABLE_KEY); + } else { + SET_ERROR(kmfh, ckrv); + return (KMF_ERR_INTERNAL); } - SET_ERROR(kmfh, ckrv); - return (KMF_ERR_INTERNAL); } /* Allocate memory for pValue */ @@ -2232,10 +2439,10 @@ keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey, if (inkey->keyalg == KMF_RSA) { rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, - &rkey->rawdata.rsa); + &rkey->rawdata.rsa); } else if (inkey->keyalg == KMF_DSA) { rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, - &rkey->rawdata.dsa); + &rkey->rawdata.dsa); } else if (inkey->keyalg == KMF_AES || inkey->keyalg == KMF_RC4 || inkey->keyalg == KMF_DES || @@ -2243,6 +2450,18 @@ keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey, inkey->keyalg == KMF_GENERIC_SECRET) { rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, &rkey->rawdata.sym); + /* + * If sensitive or non-extractable, mark them as such + * but return "OK" status so the keys get counted + * when doing FindKey operations. + */ + if (rv == KMF_ERR_SENSITIVE_KEY) { + rkey->sensitive = B_TRUE; + rv = KMF_OK; + } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) { + rkey->not_extractable = B_TRUE; + rv = KMF_OK; + } } else { rv = KMF_ERR_BAD_PARAMETER; } @@ -2333,8 +2552,8 @@ IDStringToData(char *idstr, KMF_DATA *iddata) } KMF_RETURN -KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, - KMF_KEY_HANDLE *keys, uint32_t *numkeys) +KMFPK11_FindKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -2344,63 +2563,80 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, CK_OBJECT_CLASS class; CK_BBOOL true = TRUE; CK_ULONG alg; - CK_BBOOL is_token; + boolean_t is_token, is_private; + KMF_KEY_HANDLE *keys; + uint32_t *numkeys; + KMF_CREDENTIAL cred; + KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE; + char *findLabel, *idstr; + KMF_KEY_ALG keytype = KMF_KEYALG_NONE; + KMF_ENCODE_FORMAT format; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (parms == NULL || numkeys == NULL) + numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); + if (numkeys == NULL) return (KMF_ERR_BAD_PARAMETER); - if (numkeys != NULL && *numkeys > 0) + if (*numkeys > 0) want_keys = *numkeys; else want_keys = MAXINT; /* count them all */ - is_token = parms->pkcs11parms.token; - if (parms->keyclass == KMF_ASYM_PUB) { + /* keyclass is optional */ + (void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, + (void *)&keyclass, NULL); + + if (keyclass == KMF_ASYM_PUB) { class = CKO_PUBLIC_KEY; - } else if (parms->keyclass == KMF_ASYM_PRI) { + } else if (keyclass == KMF_ASYM_PRI) { class = CKO_PRIVATE_KEY; - } else if (parms->keyclass == KMF_SYMMETRIC) { + } else if (keyclass == KMF_SYMMETRIC) { class = CKO_SECRET_KEY; - } else { - return (KMF_ERR_BAD_KEY_CLASS); } + rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr, + (void *)&is_token, NULL); + if (rv != KMF_OK) + return (rv); + i = 0; - pTmpl[i].type = CKA_TOKEN; - pTmpl[i].pValue = &is_token; - pTmpl[i].ulValueLen = sizeof (CK_BBOOL); - i++; + if (is_token) { + SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true)); + i++; + } - pTmpl[i].type = CKA_CLASS; - pTmpl[i].pValue = &class; - pTmpl[i].ulValueLen = sizeof (class); - i++; + if (keyclass != KMF_KEYCLASS_NONE) { + SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class)); + i++; + } - if (parms->findLabel != NULL && strlen(parms->findLabel)) { - pTmpl[i].type = CKA_LABEL; - pTmpl[i].pValue = parms->findLabel; - pTmpl[i].ulValueLen = strlen(parms->findLabel); + findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + + if (findLabel != NULL && strlen(findLabel)) { + SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel)); i++; } + /* keytype is optional */ + (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); - if (parms->keytype != 0) { - rv = kmf2pk11keytype(parms->keytype, &alg); + if (keytype != 0) { + rv = kmf2pk11keytype(keytype, &alg); if (rv != KMF_OK) { return (KMF_ERR_BAD_KEY_TYPE); } - pTmpl[i].type = CKA_KEY_TYPE; - pTmpl[i].pValue = &alg; - pTmpl[i].ulValueLen = sizeof (alg); + SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg)); i++; } - if (parms->idstr != NULL) { + idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr); + + if (idstr != NULL) { KMF_DATA iddata = { NULL, 0 }; /* @@ -2411,21 +2647,21 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, * We must convert this back to binary in order to * use it in a search. */ - rv = IDStringToData(parms->idstr, &iddata); + rv = IDStringToData(idstr, &iddata); if (rv == KMF_OK) { - pTmpl[i].type = CKA_ID; - pTmpl[i].pValue = iddata.Data; - pTmpl[i].ulValueLen = iddata.Length; + SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length); i++; } else { return (rv); } } - if (parms->pkcs11parms.private) { - pTmpl[i].type = CKA_PRIVATE; - pTmpl[i].pValue = &true; - pTmpl[i].ulValueLen = sizeof (true); + /* is_private is optional */ + (void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr, + (void *)&is_private, NULL); + + if (is_private) { + SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true)); i++; } @@ -2433,13 +2669,20 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, * Authenticate if the object is a token object, * a private or secred key, or if the user passed in credentials. */ - if (parms->cred.credlen > 0) { - rv = pk11_authenticate(handle, &parms->cred); - if (rv != KMF_OK) { - return (rv); + if ((rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL)) == KMF_OK) { + if (cred.credlen > 0) { + rv = pk11_authenticate(handle, &cred); + if (rv != KMF_OK) + return (rv); } + } else { + rv = KMF_OK; /* cred is optional */ } + keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + /* it is okay to have "keys" contains NULL */ + ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i); if (ckrv == CKR_OK) { CK_ULONG obj_count, n = 0; @@ -2447,42 +2690,56 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, CK_OBJECT_HANDLE hObj; ckrv = C_FindObjects(kmfh->pk11handle, &hObj, - 1, &obj_count); + 1, &obj_count); if (ckrv == CKR_OK && obj_count == 1) { if (keys != NULL) { CK_ULONG keytype; keys[n].kstype = KMF_KEYSTORE_PK11TOKEN; - keys[n].keyclass = parms->keyclass; + keys[n].keyclass = keyclass; keys[n].israw = FALSE; keys[n].keyp = (void *)hObj; ckrv = getObjectKeytype(handle, - (CK_OBJECT_HANDLE)keys[n].keyp, - &keytype); + (CK_OBJECT_HANDLE)keys[n].keyp, + &keytype); if (ckrv != CKR_OK) goto end; ckrv = getObjectLabel(handle, - (CK_OBJECT_HANDLE)keys[n].keyp, - &(keys[n].keylabel)); + (CK_OBJECT_HANDLE)keys[n].keyp, + &(keys[n].keylabel)); if (ckrv != CKR_OK) goto end; - if (keytype == CKK_RSA) + if (keytype == CKK_RSA) { keys[n].keyalg = KMF_RSA; - else if (keytype == CKK_DSA) + keys[n].keyclass = KMF_ASYM_PRI; + } else if (keytype == CKK_DSA) { keys[n].keyalg = KMF_DSA; - else if (keytype == CKK_AES) + keys[n].keyclass = KMF_ASYM_PRI; + } else if (keytype == CKK_AES) { keys[n].keyalg = KMF_AES; - else if (keytype == CKK_RC4) + keys[n].keyclass = + KMF_SYMMETRIC; + } else if (keytype == CKK_RC4) { keys[n].keyalg = KMF_RC4; - else if (keytype == CKK_DES) + keys[n].keyclass = + KMF_SYMMETRIC; + } else if (keytype == CKK_DES) { keys[n].keyalg = KMF_DES; - else if (keytype == CKK_DES3) + keys[n].keyclass = + KMF_SYMMETRIC; + } else if (keytype == CKK_DES3) { keys[n].keyalg = KMF_DES3; - else if (keytype == CKK_GENERIC_SECRET) + keys[n].keyclass = + KMF_SYMMETRIC; + } else if (keytype == + CKK_GENERIC_SECRET) { keys[n].keyalg = KMF_GENERIC_SECRET; + keys[n].keyclass = + KMF_SYMMETRIC; + } } n++; @@ -2495,21 +2752,30 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, /* "numkeys" indicates the number that were actually found */ *numkeys = n; } + if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) { - if (parms->format == KMF_FORMAT_RAWKEY) { - /* Convert keys to "rawkey" format */ - for (i = 0; i < (*numkeys); i++) { - KMF_RAW_KEY_DATA *rkey = NULL; - rv = keyObj2RawKey(handle, &keys[i], &rkey); - if (rv == KMF_OK) { - keys[i].keyp = rkey; - keys[i].israw = TRUE; - } else { - break; + if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, + numattr, (void *)&format, NULL)) == KMF_OK) { + if (format == KMF_FORMAT_RAWKEY || + format == KMF_FORMAT_PEM) { + /* Convert keys to "rawkey" format */ + for (i = 0; i < (*numkeys); i++) { + KMF_RAW_KEY_DATA *rkey = NULL; + rv = keyObj2RawKey(handle, &keys[i], + &rkey); + if (rv == KMF_OK) { + keys[i].keyp = rkey; + keys[i].israw = TRUE; + } else { + break; + } } } + } else { + rv = KMF_OK; /* format is optional */ } } + end: if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); @@ -2549,8 +2815,9 @@ convertDate(char *fulldate) return ((char *)strdup(newtime)); } -KMF_RETURN -KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, +static KMF_RETURN +store_raw_key(KMF_HANDLE_T handle, + KMF_ATTRIBUTE *attrlist, int numattr, KMF_RAW_KEY_DATA *rawkey) { KMF_RETURN rv = KMF_OK; @@ -2567,20 +2834,18 @@ KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, KMF_DATA subject = {NULL, 0}; KMF_X509EXT_KEY_USAGE kuext; KMF_X509_CERTIFICATE *x509 = NULL; - CK_BBOOL kufound; + CK_BBOOL kufound = B_FALSE; + KMF_DATA *cert = NULL; char *notbefore = NULL, *start = NULL; char *notafter = NULL, *end = NULL; + char *keylabel = NULL; - if (!kmfh) + if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL || params->certificate == NULL || - rawkey == NULL) - return (KMF_ERR_BAD_PARAMETER); - if (rawkey->keytype == KMF_RSA) keytype = CKK_RSA; else if (rawkey->keytype == KMF_DSA) @@ -2588,57 +2853,77 @@ KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, else return (KMF_ERR_BAD_PARAMETER); - rv = pk11_authenticate(handle, ¶ms->cred); - if (rv != KMF_OK) { - return (rv); - } + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); - id.Data = NULL; - id.Length = 0; - rv = KMF_GetCertIDData(params->certificate, &id); - if (rv != KMF_OK) { - goto cleanup; - } + i = 0; + SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++; + SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++; + SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++; + SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++; + SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++; - rv = DerDecodeSignedCertificate( - (const KMF_DATA *)params->certificate, &x509); - if (rv != KMF_OK) { - goto cleanup; - } + cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); + if (cert != NULL) { + id.Data = NULL; + id.Length = 0; + rv = kmf_get_cert_id_data(cert, &id); + if (rv != KMF_OK) { + goto cleanup; + } - rv = DerEncodeName(&x509->certificate.subject, &subject); - if (rv != KMF_OK) { - goto cleanup; - } + rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509); + if (rv != KMF_OK) { + goto cleanup; + } - rv = KMF_GetCertStartDateString(handle, params->certificate, - ¬before); - if (rv != KMF_OK) { - goto cleanup; - } - start = convertDate(notbefore); + rv = DerEncodeName(&x509->certificate.subject, &subject); + if (rv != KMF_OK) { + goto cleanup; + } + SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length); + i++; - rv = KMF_GetCertEndDateString(handle, params->certificate, - ¬after); - if (rv != KMF_OK) { - goto cleanup; - } - end = convertDate(notafter); + rv = kmf_get_cert_start_date_str(handle, cert, ¬before); + if (rv != KMF_OK) { + goto cleanup; + } + start = convertDate(notbefore); - if ((rv = KMF_GetCertKeyUsageExt(params->certificate, &kuext)) - != KMF_OK && rv != KMF_ERR_EXTENSION_NOT_FOUND) - goto cleanup; + rv = kmf_get_cert_end_date_str(handle, cert, ¬after); + if (rv != KMF_OK) { + goto cleanup; + } + end = convertDate(notafter); + if (id.Data != NULL && id.Data != NULL && id.Length > 0) { + SETATTR(templ, i, CKA_ID, id.Data, id.Length); + i++; + } + if (start != NULL) { + /* + * This makes some potentially dangerous assumptions: + * 1. that the startdate in the parameter block is + * properly formatted as YYYYMMDD + * 2. That the CK_DATE structure is always the same. + */ + (void) memcpy(&startdate, start, sizeof (CK_DATE)); + SETATTR(templ, i, CKA_START_DATE, &startdate, + sizeof (startdate)); + i++; + } + if (end != NULL) { + (void) memcpy(&enddate, end, sizeof (CK_DATE)); + SETATTR(templ, i, CKA_END_DATE, &enddate, + sizeof (enddate)); + i++; + } - kufound = (rv == KMF_OK); - rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND above */ + if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK && + rv != KMF_ERR_EXTENSION_NOT_FOUND) + goto cleanup; - i = 0; - SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++; - SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++; - SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++; - SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++; - SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length); i++; - SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++; + kufound = (rv == KMF_OK); + rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */ + } /* * Only set the KeyUsage stuff if the KU extension was present. @@ -2647,110 +2932,90 @@ KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, CK_BBOOL condition; condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ? - B_TRUE : B_FALSE; - SETATTR(templ, i, CKA_UNWRAP, &condition, - sizeof (CK_BBOOL)); i++; + B_TRUE : B_FALSE; + SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL)); + i++; condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ? - B_TRUE : B_FALSE; - SETATTR(templ, i, CKA_DECRYPT, &condition, - sizeof (CK_BBOOL)); i++; + B_TRUE : B_FALSE; + SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL)); + i++; condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? - B_TRUE : B_FALSE; - SETATTR(templ, i, CKA_SIGN, &condition, - sizeof (CK_BBOOL)); i++; + B_TRUE : B_FALSE; + SETATTR(templ, i, CKA_SIGN, &condition, sizeof (CK_BBOOL)); + i++; condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? - B_TRUE : B_FALSE; + B_TRUE : B_FALSE; SETATTR(templ, i, CKA_SIGN_RECOVER, &condition, - sizeof (CK_BBOOL)); i++; - } - if (params->label != NULL) { - SETATTR(templ, i, CKA_LABEL, params->label, - strlen(params->label)); - i++; - } - if (id.Data != NULL && - id.Data != NULL && id.Length > 0) { - SETATTR(templ, i, CKA_ID, id.Data, id.Length); - i++; - } - if (start != NULL) { - /* - * This make some potentially dangerous assumptions: - * 1. that the startdate in the parameter block is - * properly formatted as YYYYMMDD - * 2. That the CK_DATE structure is always the same. - */ - (void) memcpy(&startdate, start, sizeof (CK_DATE)); - SETATTR(templ, i, CKA_START_DATE, &startdate, - sizeof (startdate)); + sizeof (CK_BBOOL)); i++; + } - if (end != NULL) { - (void) memcpy(&enddate, end, sizeof (CK_DATE)); - SETATTR(templ, i, CKA_END_DATE, &enddate, sizeof (enddate)); + + if (keylabel != NULL) { + SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); i++; } if (keytype == CKK_RSA) { SETATTR(templ, i, CKA_MODULUS, - rawkey->rawdata.rsa.mod.val, - rawkey->rawdata.rsa.mod.len); + rawkey->rawdata.rsa.mod.val, + rawkey->rawdata.rsa.mod.len); i++; SETATTR(templ, i, CKA_PUBLIC_EXPONENT, - rawkey->rawdata.rsa.pubexp.val, - rawkey->rawdata.rsa.pubexp.len); + rawkey->rawdata.rsa.pubexp.val, + rawkey->rawdata.rsa.pubexp.len); i++; if (rawkey->rawdata.rsa.priexp.val != NULL) { SETATTR(templ, i, CKA_PRIVATE_EXPONENT, - rawkey->rawdata.rsa.priexp.val, - rawkey->rawdata.rsa.priexp.len); + rawkey->rawdata.rsa.priexp.val, + rawkey->rawdata.rsa.priexp.len); i++; } if (rawkey->rawdata.rsa.prime1.val != NULL) { SETATTR(templ, i, CKA_PRIME_1, - rawkey->rawdata.rsa.prime1.val, - rawkey->rawdata.rsa.prime1.len); + rawkey->rawdata.rsa.prime1.val, + rawkey->rawdata.rsa.prime1.len); i++; } if (rawkey->rawdata.rsa.prime2.val != NULL) { SETATTR(templ, i, CKA_PRIME_2, - rawkey->rawdata.rsa.prime2.val, - rawkey->rawdata.rsa.prime2.len); + rawkey->rawdata.rsa.prime2.val, + rawkey->rawdata.rsa.prime2.len); i++; } if (rawkey->rawdata.rsa.exp1.val != NULL) { SETATTR(templ, i, CKA_EXPONENT_1, - rawkey->rawdata.rsa.exp1.val, - rawkey->rawdata.rsa.exp1.len); + rawkey->rawdata.rsa.exp1.val, + rawkey->rawdata.rsa.exp1.len); i++; } if (rawkey->rawdata.rsa.exp2.val != NULL) { SETATTR(templ, i, CKA_EXPONENT_2, - rawkey->rawdata.rsa.exp2.val, - rawkey->rawdata.rsa.exp2.len); + rawkey->rawdata.rsa.exp2.val, + rawkey->rawdata.rsa.exp2.len); i++; } if (rawkey->rawdata.rsa.coef.val != NULL) { SETATTR(templ, i, CKA_COEFFICIENT, - rawkey->rawdata.rsa.coef.val, - rawkey->rawdata.rsa.coef.len); + rawkey->rawdata.rsa.coef.val, + rawkey->rawdata.rsa.coef.len); i++; } } else { SETATTR(templ, i, CKA_PRIME, - rawkey->rawdata.dsa.prime.val, - rawkey->rawdata.dsa.prime.len); + rawkey->rawdata.dsa.prime.val, + rawkey->rawdata.dsa.prime.len); i++; SETATTR(templ, i, CKA_SUBPRIME, - rawkey->rawdata.dsa.subprime.val, - rawkey->rawdata.dsa.subprime.len); + rawkey->rawdata.dsa.subprime.val, + rawkey->rawdata.dsa.subprime.len); i++; SETATTR(templ, i, CKA_BASE, - rawkey->rawdata.dsa.base.val, - rawkey->rawdata.dsa.base.len); + rawkey->rawdata.dsa.base.val, + rawkey->rawdata.dsa.base.len); i++; SETATTR(templ, i, CKA_VALUE, - rawkey->rawdata.dsa.value.val, - rawkey->rawdata.dsa.value.len); + rawkey->rawdata.dsa.value.val, + rawkey->rawdata.dsa.value.len); i++; } @@ -2770,17 +3035,17 @@ KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, rv = KMF_ERR_INTERNAL; } cleanup: - KMF_FreeData(&id); - KMF_FreeData(&subject); - KMF_FreeSignedCert(x509); + kmf_free_data(&id); + kmf_free_data(&subject); + kmf_free_signed_cert(x509); free(x509); return (rv); } KMF_RETURN -KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, - KMF_KEY_HANDLE *symkey) +KMFPK11_CreateSymKey(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -2794,7 +3059,17 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, CK_BBOOL true = TRUE; CK_BBOOL false = FALSE; CK_ATTRIBUTE templ[15]; - int i; + CK_BYTE *keydata = NULL; + int i = 0; + KMF_KEY_HANDLE *symkey; + KMF_KEY_ALG keytype; + uint32_t keylen = 0; + uint32_t attrkeylen = 0; + uint32_t keylen_size = sizeof (uint32_t); + char *keylabel = NULL; + KMF_CREDENTIAL cred; + uint32_t is_sensitive = B_FALSE; + uint32_t is_not_extractable = B_FALSE; if (kmfh == NULL) return (KMF_ERR_UNINITIALIZED); @@ -2802,8 +3077,29 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, if (kmfh->pk11handle == CK_INVALID_HANDLE) return (KMF_ERR_NO_TOKEN_SELECTED); - if (params == NULL) + symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); + if (symkey == NULL) return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, + (void *)&keytype, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + if (keylabel == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr, + (void *)&is_sensitive, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr, + (void *)&is_not_extractable, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + /* * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key. * @@ -2811,68 +3107,115 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, * C_GenerateKey() for some PKCS11 providers, we will handle it * differently. */ - if (params->keytype == KMF_GENERIC_SECRET) { - rv = create_generic_secret_key(handle, params, &keyhandle); + if (keytype == KMF_GENERIC_SECRET) { + rv = create_generic_secret_key(handle, numattr, + attrlist, &keyhandle); if (rv != KMF_OK) goto out; else goto setup; } + rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr, + NULL, &attrkeylen); + if (rv == KMF_OK && attrkeylen > 0) { + keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist, + numattr); + } else { + keydata = NULL; + attrkeylen = 0; + rv = KMF_OK; + } + if (keydata != NULL) { + if (keytype == KMF_DES && attrkeylen != 8) { + rv = KMF_ERR_BAD_KEY_SIZE; + goto out; + } + if (keytype == KMF_DES3 && attrkeylen != 24) { + rv = KMF_ERR_BAD_KEY_SIZE; + goto out; + } + /* + * This may override what the user gave on the + * command line. + */ + keylen = attrkeylen * 8; /* bytes to bits */ + } else { + /* + * If keydata was not given, key length must be + * provided. + */ + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, + &keylen, &keylen_size); + if (rv == KMF_ERR_ATTR_NOT_FOUND && + (keytype == KMF_DES || keytype == KMF_DES3)) + /* keylength is not required for DES and 3DES */ + rv = KMF_OK; + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + } + + if ((keylen % 8) != 0) { + return (KMF_ERR_BAD_KEY_SIZE); + } + secKeyLen = keylen / 8; /* in bytes for RC4/AES */ + + /* + * Only set CKA_VALUE_LEN if the key data was not given and + * we are creating an RC4 or AES key. + */ + if (keydata == NULL && + (keytype == KMF_AES || keytype == KMF_RC4)) { + SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen, + sizeof (secKeyLen)); + i++; + } + /* Other keytypes */ keyGenMech.pParameter = NULL_PTR; keyGenMech.ulParameterLen = 0; - switch (params->keytype) { - case KMF_AES: - keyGenMech.mechanism = CKM_AES_KEY_GEN; - secKeyType = CKK_AES; - break; - case KMF_RC4: - keyGenMech.mechanism = CKM_RC4_KEY_GEN; - secKeyType = CKK_RC4; - break; - case KMF_DES: - keyGenMech.mechanism = CKM_DES_KEY_GEN; - secKeyType = CKK_DES; - break; - case KMF_DES3: - keyGenMech.mechanism = CKM_DES3_KEY_GEN; - secKeyType = CKK_DES3; - break; - default: - return (KMF_ERR_BAD_KEY_TYPE); + switch (keytype) { + case KMF_AES: + keyGenMech.mechanism = CKM_AES_KEY_GEN; + secKeyType = CKK_AES; + break; + case KMF_RC4: + keyGenMech.mechanism = CKM_RC4_KEY_GEN; + secKeyType = CKK_RC4; + break; + case KMF_DES: + keyGenMech.mechanism = CKM_DES_KEY_GEN; + secKeyType = CKK_DES; + break; + case KMF_DES3: + keyGenMech.mechanism = CKM_DES3_KEY_GEN; + secKeyType = CKK_DES3; + break; + default: + return (KMF_ERR_BAD_KEY_TYPE); + } + if (keydata != NULL) { + SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen); + i++; } - - i = 0; SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); i++; SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); i++; - if (params->keytype == KMF_AES || params->keytype == KMF_RC4) { - if ((params->keylength % 8) != 0) { - return (KMF_ERR_BAD_KEY_SIZE); - } - secKeyLen = params->keylength/8; /* in bytes for RC4/AES */ - SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen, - sizeof (secKeyLen)); + if (keylabel != NULL) { + SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); i++; } - if (params->keylabel != NULL) { - SETATTR(templ, i, CKA_LABEL, params->keylabel, - strlen(params->keylabel)); - i++; - } - - if (params->pkcs11parms.sensitive == B_TRUE) { + if (is_sensitive == B_TRUE) { SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); } else { SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); } i++; - if (params->pkcs11parms.not_extractable == B_TRUE) { + if (is_not_extractable == B_TRUE) { SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); } else { SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); @@ -2892,12 +3235,23 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true)); i++; - rv = pk11_authenticate(handle, ¶ms->cred); + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = pk11_authenticate(handle, &cred); if (rv != KMF_OK) { return (rv); } - ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i, &keyhandle); + /* If the key data was given, use C_CreateObject */ + if (keydata != NULL) { + ckrv = C_CreateObject(hSession, templ, i, &keyhandle); + } else { + ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i, + &keyhandle); + } if (ckrv != CKR_OK) { SET_ERROR(kmfh, ckrv); rv = KMF_ERR_KEYGEN_FAILED; @@ -2906,7 +3260,7 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, setup: symkey->kstype = KMF_KEYSTORE_PK11TOKEN; - symkey->keyalg = params->keytype; + symkey->keyalg = keytype; symkey->keyclass = KMF_SYMMETRIC; symkey->israw = FALSE; symkey->keyp = (void *)keyhandle; @@ -2915,7 +3269,6 @@ out: return (rv); } - KMF_RETURN KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, KMF_RAW_SYM_KEY *rkey) @@ -2934,19 +3287,29 @@ KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, else if (symkey->keyclass != KMF_SYMMETRIC) return (KMF_ERR_BAD_KEY_CLASS); + /* + * If the key is already in "raw" format, copy the data + * to the new record if possible. + */ if (symkey->israw) { KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp; - if (rawkey == NULL || - rawkey->rawdata.sym.keydata.val == NULL || - rawkey->rawdata.sym.keydata.len == 0) + if (rawkey == NULL) return (KMF_ERR_BAD_KEYHANDLE); + if (rawkey->sensitive) + return (KMF_ERR_SENSITIVE_KEY); + if (rawkey->not_extractable) + return (KMF_ERR_UNEXTRACTABLE_KEY); + + if (rawkey->rawdata.sym.keydata.val == NULL || + rawkey->rawdata.sym.keydata.len == 0) + return (KMF_ERR_GETKEYVALUE_FAILED); rkey->keydata.len = rawkey->rawdata.sym.keydata.len; if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) return (KMF_ERR_MEMORY); (void) memcpy(rkey->keydata.val, - rawkey->rawdata.sym.keydata.val, rkey->keydata.len); + rawkey->rawdata.sym.keydata.val, rkey->keydata.len); } else { rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey); } @@ -2955,20 +3318,50 @@ KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, } KMF_RETURN -KMFPK11_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, - KMF_CREDENTIAL *newpin) +KMFPK11_SetTokenPin(KMF_HANDLE_T handle, + int numattr, KMF_ATTRIBUTE *attrlist) { KMF_RETURN ret = KMF_OK; CK_RV rv = CKR_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; CK_SESSION_HANDLE session = NULL; + KMF_CREDENTIAL oldcred = {NULL, 0}; + KMF_CREDENTIAL newcred = {NULL, 0}; + CK_SLOT_ID slotid; + + if (handle == NULL || attrlist == NULL || numattr == 0) + return (KMF_ERR_BAD_PARAMETER); - if (handle == NULL || params == NULL || newpin == NULL) + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, + (void *)&oldcred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_NEWPIN_ATTR, attrlist, numattr, + (void *)&newcred, NULL); + if (rv != KMF_OK) return (KMF_ERR_BAD_PARAMETER); - rv = C_OpenSession(params->pkcs11parms.slot, - CKF_SERIAL_SESSION | CKF_RW_SESSION, - NULL, NULL, &session); + rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr, + (void *)&slotid, NULL); + if (rv != KMF_OK) { + char *tokenlabel = NULL; + /* + * If a slot wasn't given, the user must pass + * a token label so we can find the slot here. + */ + rv = kmf_get_string_attr(KMF_TOKEN_LABEL_ATTR, attrlist, + numattr, &tokenlabel); + if (rv != KMF_OK) + return (rv); + + rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid); + if (rv != KMF_OK) + return (rv); + } + + rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION, + NULL, NULL, &session); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); ret = KMF_ERR_UNINITIALIZED; @@ -2976,8 +3369,8 @@ KMFPK11_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, } rv = C_SetPIN(session, - (CK_BYTE *)params->cred.cred, params->cred.credlen, - (CK_BYTE *)newpin->cred, newpin->credlen); + (CK_BYTE *)oldcred.cred, oldcred.credlen, + (CK_BYTE *)newcred.cred, newcred.credlen); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); @@ -3007,8 +3400,7 @@ create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech, int i; rv = C_Initialize(NULL); - if ((rv != CKR_OK) && - (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { + if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { kmf_rv = KMF_ERR_UNINITIALIZED; goto out; } @@ -3038,7 +3430,7 @@ create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech, } if (i < pulCount) { rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, - NULL, NULL, sessionp); + NULL, NULL, sessionp); if (rv != CKR_OK) { kmf_rv = KMF_ERR_UNINITIALIZED; @@ -3072,20 +3464,20 @@ verify_data(KMF_HANDLE_T handle, if (AlgorithmId == KMF_ALGID_NONE) return (KMF_ERR_BAD_ALGORITHM); - pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, - AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); + pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, + AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); if (!pAlgMap) return (KMF_ERR_BAD_ALGORITHM); ret = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism, - CKF_VERIFY); + CKF_VERIFY); if (ret != KMF_OK) return (ret); /* Fetch the verifying key */ ret = PKCS_AcquirePublicKeyHandle(ckSession, keyp, - pAlgMap->key_type, &ckKeyHandle, &bTempKey); + pAlgMap->key_type, &ckKeyHandle, &bTempKey); if (ret != KMF_OK) { return (ret); @@ -3104,11 +3496,9 @@ verify_data(KMF_HANDLE_T handle, goto cleanup; } - ckRv = C_Verify(ckSession, - (CK_BYTE *)data->Data, - (CK_ULONG)data->Length, - (CK_BYTE *)signed_data->Data, - (CK_ULONG)signed_data->Length); + ckRv = C_Verify(ckSession, (CK_BYTE *)data->Data, + (CK_ULONG)data->Length, (CK_BYTE *)signed_data->Data, + (CK_ULONG)signed_data->Length); if (ckRv != CKR_OK) { SET_ERROR(kmfh, ckRv); @@ -3150,7 +3540,7 @@ KMFPK11_VerifyDataWithCert(KMF_HANDLE_T handle, /* If no algorithm specified, use the certs signature algorithm */ if (algid == KMF_ALGID_NONE) { - algid = X509_AlgorithmOidToAlgId(CERT_ALG_OID(SignerCert)); + algid = x509_algoid_to_algid(CERT_ALG_OID(SignerCert)); } if (algid == KMF_ALGID_NONE) { @@ -3161,7 +3551,7 @@ KMFPK11_VerifyDataWithCert(KMF_HANDLE_T handle, cleanup: if (SignerCert) { - KMF_FreeSignedCert(SignerCert); + kmf_free_signed_cert(SignerCert); free(SignerCert); } @@ -3170,7 +3560,7 @@ cleanup: static KMF_RETURN create_generic_secret_key(KMF_HANDLE_T handle, - KMF_CREATESYMKEY_PARAMS *params, CK_OBJECT_HANDLE *key) + int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key) { KMF_RETURN rv = KMF_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; @@ -3185,45 +3575,90 @@ create_generic_secret_key(KMF_HANDLE_T handle, int i; int random_fd = -1; int nread; + int freebuf = 0; char *buf = NULL; + uint32_t keylen = 0, attrkeylen = 0; + char *keylabel = NULL; + KMF_CREDENTIAL *cred; + uint32_t is_sensitive, is_not_extractable; - /* - * Check the key size. - */ - if ((params->keylength % 8) != 0) { - return (KMF_ERR_BAD_KEY_SIZE); + keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); + if (keylabel == NULL) + return (KMF_ERR_BAD_PARAMETER); + + cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); + if (cred == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr, + (void *)&is_sensitive, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr, + (void *)&is_not_extractable, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr, + NULL, &attrkeylen); + if (rv == KMF_OK && attrkeylen > 0) { + buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist, + numattr); + secKeyLen = attrkeylen; } else { - secKeyLen = params->keylength/8; /* in bytes */ + buf = NULL; + rv = KMF_OK; } + if (buf == NULL) { + /* + * If the key data was not given, key length must + * be provided. + */ + rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, + &keylen, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); - /* - * Generate a random number with the key size first. - */ - buf = malloc(secKeyLen); - if (buf == NULL) - return (KMF_ERR_MEMORY); + /* + * Check the key size. + */ + if ((keylen % 8) != 0) { + return (KMF_ERR_BAD_KEY_SIZE); + } else { + secKeyLen = keylen/8; /* in bytes */ + } - while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) { - if (errno != EINTR) - break; - } + /* + * Generate a random number with the key size first. + */ + buf = malloc(secKeyLen); + if (buf == NULL) + return (KMF_ERR_MEMORY); - if (random_fd < 0) { - rv = KMF_ERR_KEYGEN_FAILED; - goto out; - } + freebuf = 1; + while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) { + if (errno != EINTR) + break; + } - nread = read(random_fd, buf, secKeyLen); - if (nread <= 0 || nread != secKeyLen) { - rv = KMF_ERR_KEYGEN_FAILED; - goto out; + if (random_fd < 0) { + rv = KMF_ERR_KEYGEN_FAILED; + goto out; + } + + nread = read(random_fd, buf, secKeyLen); + if (nread <= 0 || nread != secKeyLen) { + rv = KMF_ERR_KEYGEN_FAILED; + goto out; + } } /* * Authenticate into the token and call C_CreateObject to generate * a generic secret token key. */ - rv = pk11_authenticate(handle, ¶ms->cred); + rv = pk11_authenticate(handle, cred); if (rv != KMF_OK) { goto out; } @@ -3236,20 +3671,19 @@ create_generic_secret_key(KMF_HANDLE_T handle, SETATTR(templ, i, CKA_VALUE, buf, secKeyLen); i++; - if (params->keylabel != NULL) { - SETATTR(templ, i, CKA_LABEL, params->keylabel, - strlen(params->keylabel)); + if (keylabel != NULL) { + SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); i++; } - if (params->pkcs11parms.sensitive == B_TRUE) { + if (is_sensitive == B_TRUE) { SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); } else { SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); } i++; - if (params->pkcs11parms.not_extractable == B_TRUE) { + if (is_not_extractable == B_TRUE) { SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); } else { SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); @@ -3270,7 +3704,7 @@ create_generic_secret_key(KMF_HANDLE_T handle, } out: - if (buf != NULL) + if (buf != NULL && freebuf) free(buf); if (random_fd != -1) @@ -3278,3 +3712,241 @@ out: return (rv); } + +KMF_RETURN +KMFPK11_StoreKey(KMF_HANDLE_T handle, + int numattr, + KMF_ATTRIBUTE *attlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_CREDENTIAL cred = {NULL, 0}; + KMF_KEY_HANDLE *key; + KMF_RAW_KEY_DATA *rawkey; + CK_BBOOL btrue = TRUE; + CK_ATTRIBUTE tokenattr[1]; + CK_OBJECT_HANDLE newobj; + CK_RV ckrv; + + if (kmfh == NULL) + return (KMF_ERR_UNINITIALIZED); + + if (kmfh->pk11handle == CK_INVALID_HANDLE) + return (KMF_ERR_NO_TOKEN_SELECTED); + + rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr, + (void *)&cred, NULL); + if (rv != KMF_OK) + return (KMF_ERR_BAD_PARAMETER); + + rv = pk11_authenticate(handle, &cred); + if (rv != KMF_OK) + return (rv); + + key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr); + if (key == NULL) { + key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, + numattr); + if (key == NULL) + rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist, + numattr); + } + if (key == NULL && rawkey == NULL) + return (KMF_ERR_ATTR_NOT_FOUND); + + if (rawkey != NULL) { + rv = store_raw_key(handle, attlist, numattr, rawkey); + } else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) { + + SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue)); + /* Copy the key object to the token */ + ckrv = C_CopyObject(kmfh->pk11handle, + (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj); + if (ckrv != CKR_OK) { + SET_ERROR(kmfh, ckrv); + return (KMF_ERR_INTERNAL); + } + + /* Replace the object handle with the new token-based one */ + ckrv = C_DestroyObject(kmfh->pk11handle, + (CK_OBJECT_HANDLE)key->keyp); + if (ckrv != CKR_OK) { + SET_ERROR(kmfh, ckrv); + return (KMF_ERR_INTERNAL); + } + key->keyp = (void *)newobj; + } else { + rv = KMF_ERR_BAD_PARAMETER; + } + + return (rv); +} + + +KMF_RETURN +KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; + KMF_CREDENTIAL *cred = NULL; + KMF_CREDENTIAL *p12cred = NULL; + char *filename = NULL; + KMF_X509_DER_CERT *certlist = NULL; + KMF_KEY_HANDLE *keylist = NULL; + uint32_t numcerts; + uint32_t numkeys; + char *certlabel = NULL; + char *issuer = NULL; + char *subject = NULL; + KMF_BIGINT *serial = NULL; + KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; + KMF_ATTRIBUTE fc_attrlist[16]; + int i; + + if (kmfh == NULL) + return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ + + if (kmfh->pk11handle == CK_INVALID_HANDLE) + return (KMF_ERR_NO_TOKEN_SELECTED); + + /* First get the required attributes */ + cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); + if (cred == NULL) + return (KMF_ERR_BAD_PARAMETER); + + p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); + if (p12cred == NULL) + return (KMF_ERR_BAD_PARAMETER); + + filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, + numattr); + if (filename == NULL) + return (KMF_ERR_BAD_PARAMETER); + + /* Find all the certificates that match the searching criteria */ + i = 0; + kmf_set_attr_at_index(fc_attrlist, i, + KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); + i++; + + kmf_set_attr_at_index(fc_attrlist, i, + KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t)); + i++; + + certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); + if (certlabel != NULL) { + kmf_set_attr_at_index(fc_attrlist, i, + KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); + i++; + } + + issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); + if (issuer != NULL) { + kmf_set_attr_at_index(fc_attrlist, i, + KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); + i++; + } + + subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); + if (subject != NULL) { + kmf_set_attr_at_index(fc_attrlist, i, + KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); + i++; + } + + serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); + if (serial != NULL) { + kmf_set_attr_at_index(fc_attrlist, i, + KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); + i++; + } + + rv = KMFPK11_FindCert(handle, i, fc_attrlist); + + if (rv == KMF_OK && numcerts > 0) { + certlist = (KMF_X509_DER_CERT *)malloc(numcerts * + sizeof (KMF_X509_DER_CERT)); + if (certlist == NULL) + return (KMF_ERR_MEMORY); + + (void) memset(certlist, 0, numcerts * + sizeof (KMF_X509_DER_CERT)); + + kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR, + certlist, sizeof (KMF_X509_DER_CERT)); + i++; + + rv = kmf_find_cert(handle, i, fc_attrlist); + if (rv != KMF_OK) { + free(certlist); + return (rv); + } + } else { + return (rv); + } + + /* For each certificate, find the matching private key */ + numkeys = 0; + for (i = 0; i < numcerts; i++) { + KMF_ATTRIBUTE fk_attrlist[16]; + int j = 0; + KMF_KEY_HANDLE newkey; + KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY; + + kmf_set_attr_at_index(fk_attrlist, j, + KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); + j++; + + kmf_set_attr_at_index(fk_attrlist, j, + KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); + j++; + + kmf_set_attr_at_index(fk_attrlist, j, + KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); + j++; + + kmf_set_attr_at_index(fk_attrlist, j, + KMF_CERT_DATA_ATTR, &certlist[i].certificate, + sizeof (KMF_DATA)); + j++; + + kmf_set_attr_at_index(fk_attrlist, j, + KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE)); + j++; + + rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist); + if (rv == KMF_OK) { + numkeys++; + keylist = realloc(keylist, + numkeys * sizeof (KMF_KEY_HANDLE)); + if (keylist == NULL) { + rv = KMF_ERR_MEMORY; + goto out; + } + keylist[numkeys - 1] = newkey; + } else if (rv == KMF_ERR_KEY_NOT_FOUND) { + /* it is OK if a key is not found */ + rv = KMF_OK; + } + } + + if (rv != KMF_OK) + goto out; + + rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist, + p12cred, filename); + +out: + if (certlist != NULL) { + for (i = 0; i < numcerts; i++) + kmf_free_kmf_cert(handle, &certlist[i]); + free(certlist); + } + if (keylist != NULL) { + for (i = 0; i < numkeys; i++) + kmf_free_kmf_key(handle, &keylist[i]); + free(keylist); + } + + return (rv); +} |
