13089Swyllys /*
23089Swyllys * CDDL HEADER START
33089Swyllys *
43089Swyllys * The contents of this file are subject to the terms of the
53089Swyllys * Common Development and Distribution License (the "License").
63089Swyllys * You may not use this file except in compliance with the License.
73089Swyllys *
83089Swyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93089Swyllys * or http://www.opensolaris.org/os/licensing.
103089Swyllys * See the License for the specific language governing permissions
113089Swyllys * and limitations under the License.
123089Swyllys *
133089Swyllys * When distributing Covered Code, include this CDDL HEADER in each
143089Swyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153089Swyllys * If applicable, add the following below this CDDL HEADER, with the
163089Swyllys * fields enclosed by brackets "[]" replaced with your own identifying
173089Swyllys * information: Portions Copyright [yyyy] [name of copyright owner]
183089Swyllys *
193089Swyllys * CDDL HEADER END
20*12234Swyllys.ingersoll@sun.com *
213089Swyllys * PKCS11 token KMF Plugin
223089Swyllys *
23*12234Swyllys.ingersoll@sun.com * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
243089Swyllys */
253089Swyllys
263089Swyllys #include <stdio.h> /* debugging only */
273089Swyllys #include <errno.h>
283089Swyllys #include <values.h>
293089Swyllys
303089Swyllys #include <kmfapiP.h>
313089Swyllys #include <ber_der.h>
323825Swyllys #include <fcntl.h>
333825Swyllys #include <sha1.h>
345051Swyllys #include <bignum.h>
353089Swyllys
363089Swyllys #include <cryptoutil.h>
373089Swyllys #include <security/cryptoki.h>
383089Swyllys #include <security/pkcs11.h>
393089Swyllys
403812Shylee #define DEV_RANDOM "/dev/random"
413812Shylee
423089Swyllys #define SETATTR(t, n, atype, value, size) \
433089Swyllys t[n].type = atype; \
443089Swyllys t[n].pValue = (CK_BYTE *)value; \
453089Swyllys t[n].ulValueLen = (CK_ULONG)size;
463089Swyllys
473089Swyllys #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \
483089Swyllys h->lasterr.errcode = c;
493089Swyllys
503089Swyllys typedef struct _objlist {
513089Swyllys CK_OBJECT_HANDLE handle;
523089Swyllys struct _objlist *next;
533089Swyllys } OBJLIST;
543089Swyllys
553089Swyllys static KMF_RETURN
563089Swyllys search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *,
573089Swyllys boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *);
583089Swyllys
593408Swyllys static CK_RV
603408Swyllys getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **);
613408Swyllys
623089Swyllys static KMF_RETURN
633089Swyllys keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **);
643089Swyllys
653812Shylee static KMF_RETURN
665051Swyllys create_generic_secret_key(KMF_HANDLE_T,
675051Swyllys int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *);
683812Shylee
693089Swyllys KMF_RETURN
705051Swyllys KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
713089Swyllys
723089Swyllys KMF_RETURN
735051Swyllys KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
743089Swyllys
753089Swyllys void
763089Swyllys KMFPK11_FreeKMFCert(KMF_HANDLE_T,
773089Swyllys KMF_X509_DER_CERT *kmf_cert);
783089Swyllys
793089Swyllys KMF_RETURN
805051Swyllys KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
813089Swyllys
823089Swyllys KMF_RETURN
835051Swyllys KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
843089Swyllys
853089Swyllys KMF_RETURN
865051Swyllys KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
873089Swyllys
883089Swyllys KMF_RETURN
895051Swyllys KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
903089Swyllys
913089Swyllys KMF_RETURN
925051Swyllys KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
935051Swyllys
945051Swyllys KMF_RETURN
955051Swyllys KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
963089Swyllys
973089Swyllys KMF_RETURN
983089Swyllys KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
993089Swyllys
1003089Swyllys KMF_RETURN
1013089Swyllys KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
1023089Swyllys KMF_DATA *, KMF_DATA *);
1033089Swyllys
1043089Swyllys KMF_RETURN
1053089Swyllys KMFPK11_GetErrorString(KMF_HANDLE_T, char **);
1063089Swyllys
1073089Swyllys KMF_RETURN
1085051Swyllys KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1093089Swyllys
1103089Swyllys KMF_RETURN
1113089Swyllys KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
1123089Swyllys KMF_DATA *, KMF_DATA *);
1133089Swyllys
1143089Swyllys KMF_RETURN
1155051Swyllys KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1163089Swyllys
1173089Swyllys KMF_RETURN
1185051Swyllys KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1193089Swyllys
1203089Swyllys KMF_RETURN
1213089Swyllys KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
1223089Swyllys
1233089Swyllys KMF_RETURN
1245051Swyllys KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1253089Swyllys
1263754Swyllys KMF_RETURN
1275051Swyllys KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1285051Swyllys
1295051Swyllys
1303089Swyllys static
1313089Swyllys KMF_PLUGIN_FUNCLIST pk11token_plugin_table =
1323089Swyllys {
1333089Swyllys 1, /* Version */
1343089Swyllys KMFPK11_ConfigureKeystore,
1353089Swyllys KMFPK11_FindCert,
1363089Swyllys KMFPK11_FreeKMFCert,
1373089Swyllys KMFPK11_StoreCert,
1383089Swyllys KMFPK11_ImportCert,
1393089Swyllys NULL, /* ImportCRL */
1403089Swyllys KMFPK11_DeleteCert,
1413089Swyllys NULL, /* DeleteCRL */
1423089Swyllys KMFPK11_CreateKeypair,
1433089Swyllys KMFPK11_FindKey,
1443089Swyllys KMFPK11_EncodePubKeyData,
1453089Swyllys KMFPK11_SignData,
1463089Swyllys KMFPK11_DeleteKey,
1473089Swyllys NULL, /* ListCRL */
1483089Swyllys NULL, /* FindCRL */
1493089Swyllys NULL, /* FindCertInCRL */
1503089Swyllys KMFPK11_GetErrorString,
1515051Swyllys KMFPK11_FindPrikeyByCert,
1523089Swyllys KMFPK11_DecryptData,
1535051Swyllys KMFPK11_ExportPK12,
1543089Swyllys KMFPK11_CreateSymKey,
1553089Swyllys KMFPK11_GetSymKeyValue,
1563089Swyllys KMFPK11_SetTokenPin,
1575051Swyllys KMFPK11_StoreKey,
1583089Swyllys NULL /* Finalize */
1593089Swyllys };
1603089Swyllys
1613089Swyllys KMF_PLUGIN_FUNCLIST *
KMF_Plugin_Initialize()1623089Swyllys KMF_Plugin_Initialize()
1633089Swyllys {
1643089Swyllys return (&pk11token_plugin_table);
1653089Swyllys }
1663089Swyllys
1673089Swyllys KMF_RETURN
KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1685051Swyllys KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,
1695051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
1703089Swyllys {
1713089Swyllys KMF_RETURN rv = KMF_OK;
1725051Swyllys char *label;
1735051Swyllys boolean_t readonly = B_TRUE;
1745051Swyllys
1755051Swyllys label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
1765051Swyllys if (label == NULL) {
1773089Swyllys return (KMF_ERR_BAD_PARAMETER);
1785051Swyllys }
1795051Swyllys
1805051Swyllys /* "readonly" is optional. Default is TRUE */
1815051Swyllys (void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr,
1825051Swyllys (void *)&readonly, NULL);
1835051Swyllys
1845051Swyllys rv = kmf_select_token(handle, label, readonly);
1853089Swyllys
1863089Swyllys return (rv);
1873089Swyllys }
1883089Swyllys
1893089Swyllys static KMF_RETURN
pk11_authenticate(KMF_HANDLE_T handle,KMF_CREDENTIAL * cred)1903089Swyllys pk11_authenticate(KMF_HANDLE_T handle,
1913089Swyllys KMF_CREDENTIAL *cred)
1923089Swyllys {
1933089Swyllys
1943089Swyllys CK_RV ck_rv = CKR_OK;
1953089Swyllys CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle;
1963089Swyllys
1973089Swyllys if (hSession == NULL)
1983089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
1993089Swyllys
2006354Swyllys if (cred == NULL || cred->cred == NULL) {
2013089Swyllys return (KMF_ERR_BAD_PARAMETER);
2023089Swyllys }
2033089Swyllys
2045051Swyllys if ((ck_rv = C_Login(hSession, CKU_USER, (uchar_t *)cred->cred,
2055051Swyllys cred->credlen)) != CKR_OK) {
2063089Swyllys if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) {
2073089Swyllys handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
2083089Swyllys handle->lasterr.errcode = ck_rv;
2093089Swyllys return (KMF_ERR_AUTH_FAILED);
2103089Swyllys }
2113089Swyllys }
2123089Swyllys
2133089Swyllys return (KMF_OK);
2143089Swyllys }
2153089Swyllys
2163089Swyllys static KMF_RETURN
PK11Cert2KMFCert(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE hObj,KMF_X509_DER_CERT * kmfcert)2173089Swyllys PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
2183089Swyllys KMF_X509_DER_CERT *kmfcert)
2193089Swyllys {
2203089Swyllys KMF_RETURN rv = 0;
2213089Swyllys CK_RV ckrv = CKR_OK;
2223089Swyllys
2233089Swyllys CK_CERTIFICATE_TYPE cktype;
2243089Swyllys CK_OBJECT_CLASS class;
2253089Swyllys CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len;
2263089Swyllys CK_BYTE *subject = NULL, *value = NULL;
2273408Swyllys char *label = NULL;
2283089Swyllys CK_ATTRIBUTE templ[10];
2293089Swyllys
2303408Swyllys (void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE));
2313089Swyllys SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class));
2323089Swyllys
2333089Swyllys /* Is this a certificate object ? */
2343089Swyllys ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
2353089Swyllys if (ckrv != CKR_OK || class != CKO_CERTIFICATE) {
2363089Swyllys SET_ERROR(kmfh, ckrv);
2373089Swyllys return (KMF_ERR_INTERNAL);
2383089Swyllys }
2393089Swyllys
2403089Swyllys SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype));
2413408Swyllys ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
2423089Swyllys
2433089Swyllys if (ckrv != CKR_OK || cktype != CKC_X_509) {
2443089Swyllys SET_ERROR(kmfh, ckrv);
2453089Swyllys return (ckrv);
2463089Swyllys } else {
2473408Swyllys int i = 0;
2483089Swyllys /* What attributes are available and how big are they? */
2493408Swyllys subject_len = issuer_len = serno_len = id_len = value_len = 0;
2503408Swyllys
2513408Swyllys SETATTR(templ, i, CKA_SUBJECT, NULL, subject_len);
2523408Swyllys i++;
2533408Swyllys SETATTR(templ, i, CKA_ISSUER, NULL, issuer_len);
2543408Swyllys i++;
2553408Swyllys SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len);
2563408Swyllys i++;
2573408Swyllys SETATTR(templ, i, CKA_ID, NULL, id_len);
2583408Swyllys i++;
2593408Swyllys SETATTR(templ, i, CKA_VALUE, NULL, value_len);
2603408Swyllys i++;
2613089Swyllys
2623089Swyllys /*
2633089Swyllys * Query the object with NULL values in the pValue spot
2643089Swyllys * so we know how much space to allocate for each field.
2653089Swyllys */
2663408Swyllys ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i);
2673089Swyllys if (ckrv != CKR_OK) {
2683089Swyllys SET_ERROR(kmfh, ckrv);
2693089Swyllys return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */
2703089Swyllys }
2713089Swyllys
2723089Swyllys subject_len = templ[0].ulValueLen;
2733089Swyllys issuer_len = templ[1].ulValueLen;
2743089Swyllys serno_len = templ[2].ulValueLen;
2753089Swyllys id_len = templ[3].ulValueLen;
2763089Swyllys value_len = templ[4].ulValueLen;
2773089Swyllys
2783089Swyllys /*
2793089Swyllys * For PKCS#11 CKC_X_509 certificate objects,
2803089Swyllys * the following attributes must be defined.
2813089Swyllys * CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER,
2823089Swyllys * CKA_VALUE.
2833089Swyllys */
2843089Swyllys if (subject_len == 0 || issuer_len == 0 ||
2853089Swyllys serno_len == 0 || value_len == 0) {
2863089Swyllys return (KMF_ERR_INTERNAL);
2873089Swyllys }
2883089Swyllys
2893089Swyllys /* Only fetch the value field if we are saving the data */
2903089Swyllys if (kmfcert != NULL) {
2913089Swyllys int i = 0;
2923089Swyllys value = malloc(value_len);
2933089Swyllys if (value == NULL) {
2943089Swyllys rv = KMF_ERR_MEMORY;
2953089Swyllys goto errout;
2963089Swyllys }
2973089Swyllys
2983089Swyllys SETATTR(templ, i, CKA_VALUE, value, value_len);
2993089Swyllys i++;
3003089Swyllys
3013089Swyllys /* re-query the object with room for the value attr */
3023089Swyllys ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj,
3035051Swyllys templ, i);
3043089Swyllys
3053089Swyllys if (ckrv != CKR_OK) {
3063089Swyllys SET_ERROR(kmfh, ckrv);
3073089Swyllys rv = KMF_ERR_INTERNAL;
3083089Swyllys goto errout;
3093089Swyllys }
3103089Swyllys
3113089Swyllys kmfcert->certificate.Data = value;
3123089Swyllys kmfcert->certificate.Length = value_len;
3133089Swyllys kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED;
3143089Swyllys kmfcert->kmf_private.keystore_type =
3155051Swyllys KMF_KEYSTORE_PK11TOKEN;
3163408Swyllys
3173408Swyllys ckrv = getObjectLabel(kmfh, hObj, &label);
3183408Swyllys if (ckrv == CKR_OK && label != NULL) {
3193408Swyllys kmfcert->kmf_private.label = (char *)label;
3203408Swyllys }
3213089Swyllys
3223089Swyllys rv = KMF_OK;
3233089Swyllys }
3243089Swyllys }
3253089Swyllys
3263089Swyllys errout:
3273089Swyllys if (rv != KMF_OK) {
3283089Swyllys if (subject)
3293089Swyllys free(subject);
3303089Swyllys if (value)
3313089Swyllys free(value);
3323089Swyllys
3333089Swyllys if (kmfcert) {
3343089Swyllys kmfcert->certificate.Data = NULL;
3353089Swyllys kmfcert->certificate.Length = 0;
3363089Swyllys }
3373089Swyllys }
3383089Swyllys return (rv);
3393089Swyllys }
3403089Swyllys
3413089Swyllys static void
free_objlist(OBJLIST * head)3423089Swyllys free_objlist(OBJLIST *head)
3433089Swyllys {
3443089Swyllys OBJLIST *temp = head;
3453089Swyllys
3463089Swyllys while (temp != NULL) {
3473089Swyllys head = head->next;
3483089Swyllys free(temp);
3493089Swyllys temp = head;
3503089Swyllys }
3513089Swyllys }
3523089Swyllys
3533089Swyllys /*
3543089Swyllys * The caller should make sure that the templ->pValue is NULL since
3553089Swyllys * it will be overwritten below.
3563089Swyllys */
3573089Swyllys static KMF_RETURN
get_attr(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE * templ)3583089Swyllys get_attr(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
3593089Swyllys CK_ATTRIBUTE *templ)
3603089Swyllys {
3613089Swyllys CK_RV rv;
3623089Swyllys
3633089Swyllys rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
3643089Swyllys if (rv != CKR_OK) {
3653089Swyllys SET_ERROR(kmfh, rv);
3663089Swyllys return (KMF_ERR_INTERNAL);
3673089Swyllys }
3683089Swyllys
3693089Swyllys if (templ->ulValueLen > 0) {
3703089Swyllys templ->pValue = malloc(templ->ulValueLen);
3713089Swyllys if (templ->pValue == NULL)
3723089Swyllys return (KMF_ERR_MEMORY);
3733089Swyllys
3743089Swyllys rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
3753089Swyllys if (rv != CKR_OK) {
3763089Swyllys SET_ERROR(kmfh, rv);
3773089Swyllys return (KMF_ERR_INTERNAL);
3783089Swyllys }
3793089Swyllys }
3803089Swyllys
3813089Swyllys return (KMF_OK);
3823089Swyllys }
3833089Swyllys
3843089Swyllys /*
3853089Swyllys * Match a certificate with an issuer and/or subject name.
3863089Swyllys * This is tricky because we cannot reliably compare DER encodings
3873089Swyllys * because RDNs may have their AV-pairs in different orders even
3883089Swyllys * if the values are the same. You must compare individual
3893089Swyllys * AV pairs for the RDNs.
3903089Swyllys *
3913089Swyllys * RETURN: 0 for a match, non-zero for a non-match.
3923089Swyllys */
3933089Swyllys static KMF_RETURN
matchcert(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_X509_NAME * issuer,KMF_X509_NAME * subject)3943089Swyllys matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
3953089Swyllys KMF_X509_NAME *issuer, KMF_X509_NAME *subject)
3963089Swyllys {
3973089Swyllys KMF_RETURN rv = KMF_OK;
3983089Swyllys CK_ATTRIBUTE certattr;
3993089Swyllys KMF_DATA name;
4003089Swyllys KMF_X509_NAME dn;
4013089Swyllys
4023089Swyllys if (issuer->numberOfRDNs > 0) {
4033089Swyllys certattr.type = CKA_ISSUER;
4043089Swyllys certattr.pValue = NULL;
4053089Swyllys certattr.ulValueLen = 0;
4063089Swyllys
4073089Swyllys rv = get_attr(kmfh, obj, &certattr);
4083089Swyllys
4093089Swyllys if (rv == KMF_OK) {
4103089Swyllys name.Data = certattr.pValue;
4113089Swyllys name.Length = certattr.ulValueLen;
4123089Swyllys rv = DerDecodeName(&name, &dn);
4133089Swyllys if (rv == KMF_OK) {
4145051Swyllys rv = kmf_compare_rdns(issuer, &dn);
4155051Swyllys kmf_free_dn(&dn);
4163089Swyllys }
4173089Swyllys free(certattr.pValue);
4183089Swyllys }
4193089Swyllys
4203089Swyllys if (rv != KMF_OK)
4213089Swyllys return (rv);
4223089Swyllys }
4233089Swyllys if (subject->numberOfRDNs > 0) {
4243089Swyllys certattr.type = CKA_SUBJECT;
4253089Swyllys certattr.pValue = NULL;
4263089Swyllys certattr.ulValueLen = 0;
4273089Swyllys
4283089Swyllys rv = get_attr(kmfh, obj, &certattr);
4293089Swyllys
4303089Swyllys if (rv == KMF_OK) {
4313089Swyllys name.Data = certattr.pValue;
4323089Swyllys name.Length = certattr.ulValueLen;
4333089Swyllys rv = DerDecodeName(&name, &dn);
4343089Swyllys if (rv == KMF_OK) {
4355051Swyllys rv = kmf_compare_rdns(subject, &dn);
4365051Swyllys kmf_free_dn(&dn);
4373089Swyllys }
4383089Swyllys free(certattr.pValue);
4393089Swyllys }
4403089Swyllys }
4413089Swyllys
4423089Swyllys return (rv);
4433089Swyllys }
4443089Swyllys
4453089Swyllys /*
4463089Swyllys * delete "curr" node from the "newlist".
4473089Swyllys */
4483089Swyllys static void
pk11_delete_obj_from_list(OBJLIST ** newlist,OBJLIST ** prev,OBJLIST ** curr)4493089Swyllys pk11_delete_obj_from_list(OBJLIST **newlist,
4503089Swyllys OBJLIST **prev, OBJLIST **curr)
4513089Swyllys {
4523089Swyllys
4533089Swyllys if (*curr == *newlist) {
4543089Swyllys /* first node in the list */
4553089Swyllys *newlist = (*curr)->next;
4563089Swyllys *prev = (*curr)->next;
4573089Swyllys free(*curr);
4583089Swyllys *curr = *newlist;
4593089Swyllys } else {
4603089Swyllys (*prev)->next = (*curr)->next;
4613089Swyllys free(*curr);
4623089Swyllys *curr = (*prev)->next;
4633089Swyllys }
4643089Swyllys }
4653089Swyllys
4663089Swyllys /*
4675051Swyllys * search_certs
4683089Swyllys *
4693089Swyllys * Because this code is shared by the FindCert and
4703089Swyllys * DeleteCert functions, put it in a separate routine
4713089Swyllys * to save some work and make code easier to debug and
4723089Swyllys * read.
4733089Swyllys */
4743089Swyllys static KMF_RETURN
search_certs(KMF_HANDLE_T handle,char * label,char * issuer,char * subject,KMF_BIGINT * serial,boolean_t private,KMF_CERT_VALIDITY validity,OBJLIST ** objlist,uint32_t * numobj)4753089Swyllys search_certs(KMF_HANDLE_T handle,
4763089Swyllys char *label, char *issuer, char *subject, KMF_BIGINT *serial,
4773089Swyllys boolean_t private, KMF_CERT_VALIDITY validity,
4783089Swyllys OBJLIST **objlist, uint32_t *numobj)
4793089Swyllys {
4803089Swyllys KMF_RETURN rv = KMF_OK;
4813089Swyllys CK_RV ckrv = CKR_OK;
4823089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4833089Swyllys CK_ATTRIBUTE templ[10];
4843089Swyllys CK_BBOOL true = TRUE;
4853089Swyllys CK_OBJECT_CLASS oclass = CKO_CERTIFICATE;
4863089Swyllys CK_CERTIFICATE_TYPE ctype = CKC_X_509;
4873089Swyllys KMF_X509_NAME subjectDN, issuerDN;
4883089Swyllys int i;
4893089Swyllys OBJLIST *newlist, *tail;
4903089Swyllys CK_ULONG num = 0;
4913089Swyllys uint32_t num_ok_certs = 0; /* number of non-expired or expired certs */
4923089Swyllys
4933089Swyllys (void) memset(&templ, 0, 10 * sizeof (CK_ATTRIBUTE));
4943089Swyllys (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
4953089Swyllys (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
4963089Swyllys i = 0;
4973089Swyllys SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
4983089Swyllys SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++;
4995051Swyllys SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, sizeof (ctype)); i++;
5003089Swyllys
5013089Swyllys if (label != NULL && strlen(label)) {
5023089Swyllys SETATTR(templ, i, CKA_LABEL, label, strlen(label));
5033089Swyllys i++;
5043089Swyllys }
5053089Swyllys if (private) {
5063089Swyllys SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); i++;
5073089Swyllys }
5083089Swyllys
5093089Swyllys if (issuer != NULL && strlen(issuer)) {
5105051Swyllys if ((rv = kmf_dn_parser(issuer, &issuerDN)) != KMF_OK)
5113089Swyllys return (rv);
5123089Swyllys }
5133089Swyllys if (subject != NULL && strlen(subject)) {
5145051Swyllys if ((rv = kmf_dn_parser(subject, &subjectDN)) != KMF_OK)
5153089Swyllys return (rv);
5163089Swyllys }
5173089Swyllys
5183089Swyllys if (serial != NULL && serial->val != NULL && serial->len > 0) {
5195051Swyllys SETATTR(templ, i, CKA_SERIAL_NUMBER, serial->val, serial->len);
5203089Swyllys i++;
5213089Swyllys }
5223089Swyllys
5233089Swyllys (*numobj) = 0;
5243089Swyllys *objlist = NULL;
5253089Swyllys newlist = NULL;
5263089Swyllys
5273089Swyllys ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, i);
5283089Swyllys if (ckrv != CKR_OK)
5293089Swyllys goto cleanup;
5303089Swyllys
5313089Swyllys tail = newlist = NULL;
5323089Swyllys while (ckrv == CKR_OK) {
5333089Swyllys CK_OBJECT_HANDLE tObj;
5343089Swyllys ckrv = C_FindObjects(kmfh->pk11handle, &tObj, 1, &num);
5353089Swyllys if (ckrv != CKR_OK || num == 0)
5363089Swyllys break;
5373089Swyllys
5383089Swyllys /*
5393089Swyllys * 'matchcert' returns 0 if subject/issuer match
5403089Swyllys *
5413089Swyllys * If no match, move on to the next one
5423089Swyllys */
5433089Swyllys if (matchcert(kmfh, tObj, &issuerDN, &subjectDN))
5443089Swyllys continue;
5453089Swyllys
5463089Swyllys if (newlist == NULL) {
5473089Swyllys newlist = malloc(sizeof (OBJLIST));
5483089Swyllys if (newlist == NULL) {
5493089Swyllys rv = KMF_ERR_MEMORY;
5503089Swyllys break;
5513089Swyllys }
5523089Swyllys newlist->handle = tObj;
5533089Swyllys newlist->next = NULL;
5543089Swyllys tail = newlist;
5553089Swyllys } else {
5563089Swyllys tail->next = malloc(sizeof (OBJLIST));
5573089Swyllys if (tail->next != NULL) {
5583089Swyllys tail = tail->next;
5593089Swyllys } else {
5603089Swyllys rv = KMF_ERR_MEMORY;
5613089Swyllys break;
5623089Swyllys }
5633089Swyllys tail->handle = tObj;
5643089Swyllys tail->next = NULL;
5653089Swyllys }
5663089Swyllys (*numobj)++;
5673089Swyllys }
5683089Swyllys ckrv = C_FindObjectsFinal(kmfh->pk11handle);
5693089Swyllys
5703089Swyllys cleanup:
5713089Swyllys if (ckrv != CKR_OK) {
5723089Swyllys SET_ERROR(kmfh, ckrv);
5733089Swyllys rv = KMF_ERR_INTERNAL;
5743089Swyllys if (newlist != NULL) {
5753089Swyllys free_objlist(newlist);
5763089Swyllys *numobj = 0;
5773089Swyllys newlist = NULL;
5783089Swyllys }
5793089Swyllys } else {
5803089Swyllys if (validity == KMF_ALL_CERTS) {
5813089Swyllys *objlist = newlist;
5823089Swyllys } else {
5833089Swyllys OBJLIST *node, *prev;
5843089Swyllys KMF_X509_DER_CERT tmp_kmf_cert;
5853089Swyllys uint32_t i = 0;
5863089Swyllys
5873089Swyllys node = prev = newlist;
5883089Swyllys /*
5893089Swyllys * Now check to see if any found certificate is expired
5903089Swyllys * or valid.
5913089Swyllys */
5923089Swyllys while (node != NULL && i < (*numobj)) {
5933089Swyllys (void) memset(&tmp_kmf_cert, 0,
5943089Swyllys sizeof (KMF_X509_DER_CERT));
5953089Swyllys rv = PK11Cert2KMFCert(kmfh, node->handle,
5963089Swyllys &tmp_kmf_cert);
5973089Swyllys if (rv != KMF_OK) {
5983089Swyllys goto cleanup1;
5993089Swyllys }
6003089Swyllys
6015051Swyllys rv = kmf_check_cert_date(handle,
6023089Swyllys &tmp_kmf_cert.certificate);
6033089Swyllys
6043089Swyllys if (validity == KMF_NONEXPIRED_CERTS) {
6053089Swyllys if (rv == KMF_OK) {
6063089Swyllys num_ok_certs++;
6073089Swyllys prev = node;
6083089Swyllys node = node->next;
6093089Swyllys } else if (rv ==
6103089Swyllys KMF_ERR_VALIDITY_PERIOD) {
6113089Swyllys /*
6123089Swyllys * expired - remove it from list
6133089Swyllys */
6143089Swyllys pk11_delete_obj_from_list(
6153089Swyllys &newlist, &prev, &node);
6163089Swyllys } else {
6173089Swyllys goto cleanup1;
6183089Swyllys }
6193089Swyllys }
6203089Swyllys
6213089Swyllys if (validity == KMF_EXPIRED_CERTS) {
6223089Swyllys if (rv == KMF_ERR_VALIDITY_PERIOD) {
6233089Swyllys num_ok_certs++;
6243089Swyllys prev = node;
6253089Swyllys node = node->next;
6263089Swyllys rv = KMF_OK;
6273089Swyllys } else if (rv == KMF_OK) {
6283089Swyllys /*
6293089Swyllys * valid - remove it from list
6303089Swyllys */
6313089Swyllys pk11_delete_obj_from_list(
6323089Swyllys &newlist, &prev, &node);
6333089Swyllys } else {
6343089Swyllys goto cleanup1;
6353089Swyllys }
6363089Swyllys }
6373089Swyllys i++;
6385051Swyllys kmf_free_kmf_cert(handle, &tmp_kmf_cert);
6393089Swyllys }
6403089Swyllys *numobj = num_ok_certs;
6413089Swyllys *objlist = newlist;
6423089Swyllys }
6433089Swyllys }
6443089Swyllys
6453089Swyllys cleanup1:
6463089Swyllys if (rv != KMF_OK && newlist != NULL) {
6473089Swyllys free_objlist(newlist);
6483089Swyllys *numobj = 0;
6493089Swyllys *objlist = NULL;
6503089Swyllys }
6513089Swyllys
6523089Swyllys if (issuer != NULL)
6535051Swyllys kmf_free_dn(&issuerDN);
6543089Swyllys
6553089Swyllys if (subject != NULL)
6565051Swyllys kmf_free_dn(&subjectDN);
6573089Swyllys
6583089Swyllys return (rv);
6593089Swyllys }
6603089Swyllys
6613089Swyllys /*
6623089Swyllys * The caller may pass a NULL value for kmf_cert below and the function will
6633089Swyllys * just return the number of certs found (in num_certs).
6643089Swyllys */
6653089Swyllys KMF_RETURN
KMFPK11_FindCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)6665051Swyllys KMFPK11_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
6673089Swyllys {
6683089Swyllys KMF_RETURN rv = 0;
6693089Swyllys uint32_t want_certs;
6703089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
6713089Swyllys OBJLIST *objlist = NULL;
6725051Swyllys uint32_t *num_certs;
6735051Swyllys KMF_X509_DER_CERT *kmf_cert = NULL;
6745051Swyllys char *certlabel = NULL;
6755051Swyllys char *issuer = NULL;
6765051Swyllys char *subject = NULL;
6775051Swyllys KMF_BIGINT *serial = NULL;
6785051Swyllys KMF_CERT_VALIDITY validity;
6796354Swyllys KMF_CREDENTIAL *cred = NULL;
6805051Swyllys boolean_t private;
6815051Swyllys
6825051Swyllys if (kmfh == NULL)
6833089Swyllys return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
6843089Swyllys
6853089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
6863089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
6873089Swyllys
6885051Swyllys num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
6895051Swyllys if (num_certs == NULL)
6903089Swyllys return (KMF_ERR_BAD_PARAMETER);
6913089Swyllys
6923089Swyllys if (*num_certs > 0)
6933089Swyllys want_certs = *num_certs;
6943089Swyllys else
6953089Swyllys want_certs = MAXINT; /* count them all */
6963089Swyllys
6973089Swyllys *num_certs = 0;
6983089Swyllys
6995051Swyllys /* Get the optional returned certificate list */
7005051Swyllys kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
7015051Swyllys numattr);
7025051Swyllys
7035051Swyllys /* Get optional search criteria attributes */
7045051Swyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
7055051Swyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
7065051Swyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
7075051Swyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
7085051Swyllys
7095051Swyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
7105051Swyllys &validity, NULL);
7115051Swyllys if (rv != KMF_OK) {
7125051Swyllys validity = KMF_ALL_CERTS;
7135051Swyllys rv = KMF_OK;
7145051Swyllys }
7155051Swyllys
7165051Swyllys rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
7175051Swyllys (void *)&private, NULL);
7185051Swyllys if (rv != KMF_OK) {
7195051Swyllys private = B_FALSE;
7205051Swyllys rv = KMF_OK;
7215051Swyllys }
7225051Swyllys
7236354Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
7246354Swyllys if (cred != NULL) {
7256354Swyllys rv = pk11_authenticate(handle, cred);
7266354Swyllys if (rv != KMF_OK)
7276354Swyllys return (rv);
7286354Swyllys }
7296354Swyllys
7305051Swyllys /* Start searching */
7315051Swyllys rv = search_certs(handle, certlabel, issuer, subject, serial, private,
7325051Swyllys validity, &objlist, num_certs);
7333089Swyllys
7343089Swyllys if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) {
7353089Swyllys OBJLIST *node = objlist;
7363089Swyllys int i = 0;
7373089Swyllys while (node != NULL && i < want_certs) {
7383089Swyllys rv = PK11Cert2KMFCert(kmfh, node->handle,
7395051Swyllys &kmf_cert[i]);
7403089Swyllys i++;
7413089Swyllys node = node->next;
7423089Swyllys }
7433089Swyllys }
7443089Swyllys
7453089Swyllys if (objlist != NULL)
7463089Swyllys free_objlist(objlist);
7473089Swyllys
7483089Swyllys if (*num_certs == 0)
7493089Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
7503089Swyllys
7513089Swyllys return (rv);
7523089Swyllys }
7533089Swyllys
7543089Swyllys /*ARGSUSED*/
7553089Swyllys void
KMFPK11_FreeKMFCert(KMF_HANDLE_T handle,KMF_X509_DER_CERT * kmf_cert)7565051Swyllys KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert)
7573089Swyllys {
7583089Swyllys if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) {
7593089Swyllys free(kmf_cert->certificate.Data);
7603089Swyllys kmf_cert->certificate.Data = NULL;
7613089Swyllys kmf_cert->certificate.Length = 0;
7623089Swyllys
7633089Swyllys if (kmf_cert->kmf_private.label != NULL) {
7643089Swyllys free(kmf_cert->kmf_private.label);
7653089Swyllys kmf_cert->kmf_private.label = NULL;
7663089Swyllys }
7673089Swyllys }
7683089Swyllys }
7693089Swyllys
7703089Swyllys KMF_RETURN
KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * pKey,KMF_DATA * eData)7713089Swyllys KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey,
77211973Swyllys.ingersoll@sun.com KMF_DATA *eData)
7733089Swyllys {
7743089Swyllys KMF_RETURN ret = KMF_OK;
7753089Swyllys CK_RV rv;
7763089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
7773089Swyllys CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY;
7783089Swyllys CK_KEY_TYPE ckKeyType;
7793089Swyllys KMF_DATA Modulus, Exponent, Prime, Subprime, Base, Value;
7803089Swyllys KMF_OID *Algorithm;
7813089Swyllys BerElement *asn1 = NULL;
7823089Swyllys BerValue *PubKeyParams = NULL, *EncodedKey = NULL;
7833089Swyllys KMF_X509_SPKI spki;
78411973Swyllys.ingersoll@sun.com CK_BYTE ec_params[256], ec_point[256];
7853089Swyllys
7863089Swyllys CK_ATTRIBUTE rsaTemplate[4];
7873089Swyllys CK_ATTRIBUTE dsaTemplate[6];
78811973Swyllys.ingersoll@sun.com CK_ATTRIBUTE ecdsaTemplate[6];
7893089Swyllys
7905051Swyllys if (kmfh == NULL)
7913089Swyllys return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
7923089Swyllys
7933089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
7943089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
7953089Swyllys
7963089Swyllys if (pKey == NULL || pKey->keyp == CK_INVALID_HANDLE)
7973089Swyllys return (KMF_ERR_BAD_PARAMETER);
7983089Swyllys
7993089Swyllys (void) memset(&Modulus, 0, sizeof (Modulus));
8003089Swyllys (void) memset(&Exponent, 0, sizeof (Exponent));
8013089Swyllys (void) memset(&Prime, 0, sizeof (Prime));
8023089Swyllys (void) memset(&Subprime, 0, sizeof (Subprime));
8033089Swyllys (void) memset(&Base, 0, sizeof (Base));
8043089Swyllys (void) memset(&Value, 0, sizeof (Value));
8053089Swyllys
8063089Swyllys switch (pKey->keyalg) {
8073089Swyllys case KMF_RSA:
80811973Swyllys.ingersoll@sun.com SETATTR(rsaTemplate, 0, CKA_CLASS, &ckObjClass,
80911973Swyllys.ingersoll@sun.com sizeof (ckObjClass));
81011973Swyllys.ingersoll@sun.com SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
81111973Swyllys.ingersoll@sun.com sizeof (ckKeyType));
81211973Swyllys.ingersoll@sun.com SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
81311973Swyllys.ingersoll@sun.com Modulus.Length);
81411973Swyllys.ingersoll@sun.com SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
81511973Swyllys.ingersoll@sun.com Exponent.Data, Exponent.Length);
8163089Swyllys /* Get the length of the fields */
8173089Swyllys rv = C_GetAttributeValue(kmfh->pk11handle,
8185051Swyllys (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
8193089Swyllys if (rv != CKR_OK) {
8203089Swyllys SET_ERROR(kmfh, rv);
8213089Swyllys return (KMF_ERR_BAD_PARAMETER);
8223089Swyllys }
8233089Swyllys
8243089Swyllys Modulus.Length = rsaTemplate[2].ulValueLen;
8253089Swyllys Modulus.Data = malloc(Modulus.Length);
8263089Swyllys if (Modulus.Data == NULL)
8273089Swyllys return (KMF_ERR_MEMORY);
8283089Swyllys
8293089Swyllys Exponent.Length = rsaTemplate[3].ulValueLen;
8303089Swyllys Exponent.Data = malloc(Exponent.Length);
8313089Swyllys if (Exponent.Data == NULL) {
8323089Swyllys free(Modulus.Data);
8333089Swyllys return (KMF_ERR_MEMORY);
8343089Swyllys }
8353089Swyllys
8363089Swyllys SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
8375051Swyllys Modulus.Length);
8383089Swyllys SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
8395051Swyllys Exponent.Data, Exponent.Length);
8403089Swyllys /* Now get the values */
8413089Swyllys rv = C_GetAttributeValue(kmfh->pk11handle,
8425051Swyllys (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
8433089Swyllys if (rv != CKR_OK) {
8443089Swyllys SET_ERROR(kmfh, rv);
8453089Swyllys free(Modulus.Data);
8463089Swyllys free(Exponent.Data);
8473089Swyllys return (KMF_ERR_BAD_PARAMETER);
8483089Swyllys }
8493089Swyllys
8503089Swyllys /*
8513089Swyllys * This is the KEY algorithm, not the
8523089Swyllys * signature algorithm.
8533089Swyllys */
8545051Swyllys Algorithm = x509_algid_to_algoid(KMF_ALGID_RSA);
8553089Swyllys if (Algorithm != NULL) {
8563089Swyllys
8573089Swyllys /* Encode the RSA Key Data */
8583089Swyllys if ((asn1 = kmfder_alloc()) == NULL) {
8593089Swyllys free(Modulus.Data);
8603089Swyllys free(Exponent.Data);
8613089Swyllys return (KMF_ERR_MEMORY);
8623089Swyllys }
8635051Swyllys if (kmfber_printf(asn1, "{II}", Modulus.Data,
8645051Swyllys Modulus.Length, Exponent.Data,
8655051Swyllys Exponent.Length) == -1) {
8663089Swyllys kmfber_free(asn1, 1);
8673089Swyllys free(Modulus.Data);
8683089Swyllys free(Exponent.Data);
8693089Swyllys return (KMF_ERR_ENCODING);
8703089Swyllys }
8713089Swyllys if (kmfber_flatten(asn1, &EncodedKey) == -1) {
8723089Swyllys kmfber_free(asn1, 1);
8733089Swyllys free(Modulus.Data);
8743089Swyllys free(Exponent.Data);
8753089Swyllys return (KMF_ERR_ENCODING);
8763089Swyllys }
8773089Swyllys kmfber_free(asn1, 1);
8783089Swyllys }
8793089Swyllys
8803089Swyllys free(Exponent.Data);
8813089Swyllys free(Modulus.Data);
8823089Swyllys
8833089Swyllys break;
8843089Swyllys case KMF_DSA:
88511973Swyllys.ingersoll@sun.com SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass,
88611973Swyllys.ingersoll@sun.com sizeof (ckObjClass));
88711973Swyllys.ingersoll@sun.com SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
88811973Swyllys.ingersoll@sun.com sizeof (ckKeyType));
88911973Swyllys.ingersoll@sun.com SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
89011973Swyllys.ingersoll@sun.com Prime.Length);
89111973Swyllys.ingersoll@sun.com SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
89211973Swyllys.ingersoll@sun.com Subprime.Length);
89311973Swyllys.ingersoll@sun.com SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
89411973Swyllys.ingersoll@sun.com Base.Length);
89511973Swyllys.ingersoll@sun.com SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
89611973Swyllys.ingersoll@sun.com Value.Length);
89711973Swyllys.ingersoll@sun.com
8983089Swyllys /* Get the length of the fields */
8993089Swyllys rv = C_GetAttributeValue(kmfh->pk11handle,
9005051Swyllys (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
9013089Swyllys if (rv != CKR_OK) {
9023089Swyllys SET_ERROR(kmfh, rv);
9033089Swyllys return (KMF_ERR_BAD_PARAMETER);
9043089Swyllys }
9053089Swyllys Prime.Length = dsaTemplate[2].ulValueLen;
9063089Swyllys Prime.Data = malloc(Prime.Length);
9073089Swyllys if (Prime.Data == NULL) {
9083089Swyllys return (KMF_ERR_MEMORY);
9093089Swyllys }
9103089Swyllys
9113089Swyllys Subprime.Length = dsaTemplate[3].ulValueLen;
9123089Swyllys Subprime.Data = malloc(Subprime.Length);
9133089Swyllys if (Subprime.Data == NULL) {
9143089Swyllys free(Prime.Data);
9153089Swyllys return (KMF_ERR_MEMORY);
9163089Swyllys }
9173089Swyllys
9183089Swyllys Base.Length = dsaTemplate[4].ulValueLen;
9193089Swyllys Base.Data = malloc(Base.Length);
9203089Swyllys if (Base.Data == NULL) {
9213089Swyllys free(Prime.Data);
9223089Swyllys free(Subprime.Data);
9233089Swyllys return (KMF_ERR_MEMORY);
9243089Swyllys }
9253089Swyllys
9263089Swyllys Value.Length = dsaTemplate[5].ulValueLen;
9273089Swyllys Value.Data = malloc(Value.Length);
9283089Swyllys if (Value.Data == NULL) {
9293089Swyllys free(Prime.Data);
9303089Swyllys free(Subprime.Data);
9313089Swyllys free(Base.Data);
9323089Swyllys return (KMF_ERR_MEMORY);
9333089Swyllys }
9343089Swyllys SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
9355051Swyllys Prime.Length);
9363089Swyllys SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
9375051Swyllys Subprime.Length);
9383089Swyllys SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
9395051Swyllys Base.Length);
9403089Swyllys SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
9415051Swyllys Value.Length);
9423089Swyllys
9433089Swyllys /* Now get the values */
9443089Swyllys rv = C_GetAttributeValue(kmfh->pk11handle,
9455051Swyllys (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
9463089Swyllys if (rv != CKR_OK) {
9473089Swyllys free(Prime.Data);
9483089Swyllys free(Subprime.Data);
9493089Swyllys free(Base.Data);
9503089Swyllys free(Value.Data);
9513089Swyllys SET_ERROR(kmfh, rv);
9523089Swyllys return (KMF_ERR_BAD_PARAMETER);
9533089Swyllys }
9543089Swyllys /*
9553089Swyllys * This is the KEY algorithm, not the
9563089Swyllys * signature algorithm.
9573089Swyllys */
9585051Swyllys Algorithm = x509_algid_to_algoid(KMF_ALGID_DSA);
9593089Swyllys
9603089Swyllys /* Encode the DSA Algorithm Parameters */
9613089Swyllys if ((asn1 = kmfder_alloc()) == NULL) {
9623089Swyllys free(Prime.Data);
9633089Swyllys free(Subprime.Data);
9643089Swyllys free(Base.Data);
9653089Swyllys free(Value.Data);
9663089Swyllys return (KMF_ERR_MEMORY);
9673089Swyllys }
9683089Swyllys
9695051Swyllys if (kmfber_printf(asn1, "{III}", Prime.Data,
9705051Swyllys Prime.Length, Subprime.Data, Subprime.Length,
9715051Swyllys Base.Data, Base.Length) == -1) {
9723089Swyllys
9733089Swyllys kmfber_free(asn1, 1);
9743089Swyllys free(Prime.Data);
9753089Swyllys free(Subprime.Data);
9763089Swyllys free(Base.Data);
9773089Swyllys free(Value.Data);
9783089Swyllys return (KMF_ERR_ENCODING);
9793089Swyllys }
9803089Swyllys if (kmfber_flatten(asn1, &PubKeyParams) == -1) {
9813089Swyllys kmfber_free(asn1, 1);
9823089Swyllys free(Prime.Data);
9833089Swyllys free(Subprime.Data);
9843089Swyllys free(Base.Data);
9853089Swyllys free(Value.Data);
9863089Swyllys return (KMF_ERR_ENCODING);
9873089Swyllys }
9883089Swyllys kmfber_free(asn1, 1);
9893089Swyllys free(Prime.Data);
9903089Swyllys free(Subprime.Data);
9913089Swyllys free(Base.Data);
9923089Swyllys
9933089Swyllys /* Encode the DSA Key Value */
9943089Swyllys if ((asn1 = kmfder_alloc()) == NULL) {
9953089Swyllys free(Value.Data);
9963089Swyllys return (KMF_ERR_MEMORY);
9973089Swyllys }
9983089Swyllys
9993089Swyllys if (kmfber_printf(asn1, "I",
10005051Swyllys Value.Data, Value.Length) == -1) {
10013089Swyllys kmfber_free(asn1, 1);
10023089Swyllys free(Value.Data);
10033089Swyllys return (KMF_ERR_ENCODING);
10043089Swyllys }
10053089Swyllys if (kmfber_flatten(asn1, &EncodedKey) == -1) {
10063089Swyllys kmfber_free(asn1, 1);
10073089Swyllys free(Value.Data);
10083089Swyllys return (KMF_ERR_ENCODING);
10093089Swyllys }
10103089Swyllys kmfber_free(asn1, 1);
10113089Swyllys free(Value.Data);
10123089Swyllys break;
101311973Swyllys.ingersoll@sun.com case KMF_ECDSA:
101411973Swyllys.ingersoll@sun.com /* The EC_PARAMS are the PubKey algorithm parameters */
101511973Swyllys.ingersoll@sun.com PubKeyParams = calloc(1, sizeof (BerValue));
101611973Swyllys.ingersoll@sun.com if (PubKeyParams == NULL)
101711973Swyllys.ingersoll@sun.com return (KMF_ERR_MEMORY);
101811973Swyllys.ingersoll@sun.com EncodedKey = calloc(1, sizeof (BerValue));
101911973Swyllys.ingersoll@sun.com if (EncodedKey == NULL) {
102011973Swyllys.ingersoll@sun.com free(PubKeyParams);
102111973Swyllys.ingersoll@sun.com return (KMF_ERR_MEMORY);
102211973Swyllys.ingersoll@sun.com }
102311973Swyllys.ingersoll@sun.com SETATTR(ecdsaTemplate, 0, CKA_EC_PARAMS,
102411973Swyllys.ingersoll@sun.com &ec_params, sizeof (ec_params));
102511973Swyllys.ingersoll@sun.com SETATTR(ecdsaTemplate, 1, CKA_EC_POINT,
102611973Swyllys.ingersoll@sun.com &ec_point, sizeof (ec_point));
102711973Swyllys.ingersoll@sun.com
102811973Swyllys.ingersoll@sun.com /* Get the length of the fields */
102911973Swyllys.ingersoll@sun.com rv = C_GetAttributeValue(kmfh->pk11handle,
103011973Swyllys.ingersoll@sun.com (CK_OBJECT_HANDLE)pKey->keyp,
103111973Swyllys.ingersoll@sun.com ecdsaTemplate, 2);
103211973Swyllys.ingersoll@sun.com if (rv != CKR_OK) {
103311973Swyllys.ingersoll@sun.com SET_ERROR(kmfh, rv);
103411973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_PARAMETER);
103511973Swyllys.ingersoll@sun.com }
103611973Swyllys.ingersoll@sun.com /* The params are to be used as algorithm parameters */
103711973Swyllys.ingersoll@sun.com PubKeyParams->bv_val = (char *)ec_params;
103811973Swyllys.ingersoll@sun.com PubKeyParams->bv_len = ecdsaTemplate[0].ulValueLen;
103911973Swyllys.ingersoll@sun.com /*
104011973Swyllys.ingersoll@sun.com * The EC_POINT is to be used as the subject pub key.
104111973Swyllys.ingersoll@sun.com */
104211973Swyllys.ingersoll@sun.com EncodedKey->bv_val = (char *)ec_point;
104311973Swyllys.ingersoll@sun.com EncodedKey->bv_len = ecdsaTemplate[1].ulValueLen;
104411973Swyllys.ingersoll@sun.com
104511973Swyllys.ingersoll@sun.com /* Use the EC_PUBLIC_KEY OID */
104611973Swyllys.ingersoll@sun.com Algorithm = (KMF_OID *)&KMFOID_EC_PUBLIC_KEY;
104711973Swyllys.ingersoll@sun.com break;
10483089Swyllys default:
10493089Swyllys return (KMF_ERR_BAD_PARAMETER);
10503089Swyllys }
10513089Swyllys
10523089Swyllys /* Now, build an SPKI structure for the final encoding step */
10533089Swyllys spki.algorithm.algorithm = *Algorithm;
10543089Swyllys if (PubKeyParams != NULL) {
10553089Swyllys spki.algorithm.parameters.Data =
10565051Swyllys (uchar_t *)PubKeyParams->bv_val;
10573089Swyllys spki.algorithm.parameters.Length = PubKeyParams->bv_len;
10583089Swyllys } else {
10593089Swyllys spki.algorithm.parameters.Data = NULL;
10603089Swyllys spki.algorithm.parameters.Length = 0;
10613089Swyllys }
10623089Swyllys
10633089Swyllys if (EncodedKey != NULL) {
10643089Swyllys spki.subjectPublicKey.Data = (uchar_t *)EncodedKey->bv_val;
10653089Swyllys spki.subjectPublicKey.Length = EncodedKey->bv_len;
10663089Swyllys } else {
10673089Swyllys spki.subjectPublicKey.Data = NULL;
10683089Swyllys spki.subjectPublicKey.Length = 0;
10693089Swyllys }
10703089Swyllys
10713089Swyllys /* Finally, encode the entire SPKI record */
10723089Swyllys ret = DerEncodeSPKI(&spki, eData);
10733089Swyllys
10743089Swyllys cleanup:
10753089Swyllys if (EncodedKey) {
107611973Swyllys.ingersoll@sun.com if (pKey->keyalg != KMF_ECDSA)
107711973Swyllys.ingersoll@sun.com free(EncodedKey->bv_val);
10783089Swyllys free(EncodedKey);
10793089Swyllys }
10803089Swyllys
10813089Swyllys if (PubKeyParams) {
108211973Swyllys.ingersoll@sun.com if (pKey->keyalg != KMF_ECDSA)
108311973Swyllys.ingersoll@sun.com free(PubKeyParams->bv_val);
10843089Swyllys free(PubKeyParams);
10853089Swyllys }
10863089Swyllys
10873089Swyllys return (ret);
10883089Swyllys }
10893089Swyllys
10903089Swyllys static KMF_RETURN
CreateCertObject(KMF_HANDLE_T handle,char * label,KMF_DATA * pcert)10913089Swyllys CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
10923089Swyllys {
10933089Swyllys KMF_RETURN rv = 0;
10943089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
10953089Swyllys
10963089Swyllys KMF_X509_CERTIFICATE *signed_cert_ptr = NULL;
10973089Swyllys KMF_DATA data;
10983089Swyllys KMF_DATA Id;
10993089Swyllys
11003089Swyllys CK_RV ckrv;
11013089Swyllys CK_ULONG subject_len, issuer_len, serno_len;
11023408Swyllys CK_BYTE *subject, *issuer, *serial, nullserno;
11033089Swyllys CK_BBOOL true = TRUE;
11043089Swyllys CK_CERTIFICATE_TYPE certtype = CKC_X_509;
11053089Swyllys CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
11063089Swyllys CK_ATTRIBUTE x509templ[11];
11073089Swyllys CK_OBJECT_HANDLE hCert = NULL;
11083089Swyllys int i;
11093089Swyllys
11105051Swyllys if (kmfh == NULL)
11113089Swyllys return (KMF_ERR_INTERNAL); /* should not happen */
11123089Swyllys
11133089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
11143089Swyllys return (KMF_ERR_INTERNAL); /* should not happen */
11153089Swyllys
11163089Swyllys if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0)
11173089Swyllys return (KMF_ERR_INTERNAL); /* should not happen */
11183089Swyllys
11193089Swyllys /*
11203089Swyllys * The data *must* be a DER encoded X.509 certificate.
11213089Swyllys * Convert it to a CSSM cert and then parse the fields so
11223089Swyllys * the PKCS#11 attributes can be filled in correctly.
11233089Swyllys */
11243089Swyllys rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert,
11255051Swyllys &signed_cert_ptr);
11263089Swyllys if (rv != KMF_OK) {
11273089Swyllys return (KMF_ERR_ENCODING);
11283089Swyllys }
11293089Swyllys
11303089Swyllys /*
11313089Swyllys * Encode fields into PKCS#11 attributes.
11323089Swyllys */
11333089Swyllys
11343089Swyllys /* Get the subject name */
11353089Swyllys rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data);
11363089Swyllys if (rv == KMF_OK) {
11373089Swyllys subject = data.Data;
11383089Swyllys subject_len = data.Length;
11393089Swyllys } else {
11403089Swyllys rv = KMF_ERR_ENCODING;
11413089Swyllys goto cleanup;
11423089Swyllys }
11433089Swyllys
11443089Swyllys /* Encode the issuer */
11453089Swyllys rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data);
11463089Swyllys if (rv == KMF_OK) {
11473089Swyllys issuer = data.Data;
11483089Swyllys issuer_len = data.Length;
11493089Swyllys } else {
11503089Swyllys rv = KMF_ERR_ENCODING;
11513089Swyllys goto cleanup;
11523089Swyllys }
11533089Swyllys
11543089Swyllys /* Encode serial number */
11553089Swyllys if (signed_cert_ptr->certificate.serialNumber.len > 0 &&
11563089Swyllys signed_cert_ptr->certificate.serialNumber.val != NULL) {
11573089Swyllys serial = signed_cert_ptr->certificate.serialNumber.val;
11583089Swyllys serno_len = signed_cert_ptr->certificate.serialNumber.len;
11593089Swyllys } else {
11603408Swyllys /*
11613408Swyllys * RFC3280 says to gracefully handle certs with serial numbers
11623408Swyllys * of 0.
11633408Swyllys */
11643408Swyllys nullserno = '\0';
11653408Swyllys serial = &nullserno;
11663408Swyllys serno_len = 1;
11673089Swyllys }
11683089Swyllys
11693089Swyllys /* Generate an ID from the SPKI data */
11703089Swyllys rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo,
11715051Swyllys &Id);
11723089Swyllys
11733089Swyllys if (rv != KMF_OK) {
11743089Swyllys goto cleanup;
11753089Swyllys }
11763089Swyllys
11773089Swyllys i = 0;
11785051Swyllys SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++;
11793089Swyllys SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype,
11805051Swyllys sizeof (certtype));
11815051Swyllys i++;
11823089Swyllys SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
11833089Swyllys SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++;
11843089Swyllys SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++;
11853089Swyllys SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++;
11863089Swyllys SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++;
11873089Swyllys SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++;
11883089Swyllys if (label != NULL && strlen(label)) {
11895051Swyllys SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); i++;
11903089Swyllys }
11913089Swyllys /*
11923089Swyllys * The cert object handle is actually "leaked" here. If the app
11933089Swyllys * really wants to clean up the data space, it will have to call
11943089Swyllys * KMF_DeleteCert and specify the softtoken keystore.
11953089Swyllys */
11963089Swyllys ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert);
11973089Swyllys if (ckrv != CKR_OK) {
11986354Swyllys /* Report authentication failures to the caller */
11996354Swyllys if (ckrv == CKR_USER_NOT_LOGGED_IN ||
12006354Swyllys ckrv == CKR_PIN_INCORRECT ||
12016354Swyllys ckrv == CKR_PIN_INVALID ||
12026354Swyllys ckrv == CKR_PIN_EXPIRED ||
12036354Swyllys ckrv == CKR_PIN_LOCKED ||
12046354Swyllys ckrv == CKR_SESSION_READ_ONLY)
12056354Swyllys rv = KMF_ERR_AUTH_FAILED;
12066354Swyllys else
12076354Swyllys rv = KMF_ERR_INTERNAL;
12086354Swyllys SET_ERROR(kmfh, ckrv);
12093089Swyllys }
12103089Swyllys free(subject);
12113089Swyllys free(issuer);
12123089Swyllys
12133089Swyllys cleanup:
12143089Swyllys if (Id.Data != NULL)
12153089Swyllys free(Id.Data);
12163089Swyllys
12173089Swyllys if (signed_cert_ptr) {
12185051Swyllys kmf_free_signed_cert(signed_cert_ptr);
12193089Swyllys free(signed_cert_ptr);
12203089Swyllys }
12213089Swyllys return (rv);
12223089Swyllys }
12233089Swyllys
12243089Swyllys
12253089Swyllys KMF_RETURN
KMFPK11_StoreCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)12265051Swyllys KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
12273089Swyllys {
12283089Swyllys KMF_RETURN rv = 0;
12293089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
12305051Swyllys KMF_DATA *cert = NULL;
12316354Swyllys KMF_CREDENTIAL *cred = NULL;
12325051Swyllys char *label = NULL;
12335051Swyllys
12345051Swyllys if (kmfh == NULL)
12355051Swyllys return (KMF_ERR_UNINITIALIZED);
12363089Swyllys
12373089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
12383089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
12393089Swyllys
12405051Swyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
12415051Swyllys if (cert == NULL || cert->Data == NULL || cert->Length == 0)
12423089Swyllys return (KMF_ERR_BAD_PARAMETER);
12433089Swyllys
12445051Swyllys /* label attribute is optional */
12455051Swyllys label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
12465051Swyllys
12476354Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
12486354Swyllys if (cred != NULL) {
12496354Swyllys rv = pk11_authenticate(handle, cred);
12506354Swyllys if (rv != KMF_OK)
12516354Swyllys return (rv);
12526354Swyllys }
12536354Swyllys
12545051Swyllys rv = CreateCertObject(handle, label, cert);
12553089Swyllys return (rv);
12563089Swyllys }
12573089Swyllys
12583089Swyllys KMF_RETURN
KMFPK11_ImportCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)12595051Swyllys KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
12603089Swyllys {
12613089Swyllys KMF_RETURN rv = 0;
12623089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
12635051Swyllys char *certfile = NULL;
12645051Swyllys char *label = NULL;
12653089Swyllys KMF_ENCODE_FORMAT format;
12666354Swyllys KMF_CREDENTIAL *cred = NULL;
12673089Swyllys KMF_DATA cert1 = { NULL, 0};
12683089Swyllys KMF_DATA cert2 = { NULL, 0};
12693089Swyllys
12705051Swyllys if (kmfh == NULL)
12715051Swyllys return (KMF_ERR_UNINITIALIZED);
12723089Swyllys
12733089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
12743089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
12753089Swyllys
12765051Swyllys /*
12775051Swyllys * Get the input cert filename attribute, check if it is a valid
12785051Swyllys * certificate and auto-detect the file format of it.
12795051Swyllys */
12805051Swyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
12815051Swyllys if (certfile == NULL)
12823089Swyllys return (KMF_ERR_BAD_PARAMETER);
12835051Swyllys
12845051Swyllys rv = kmf_is_cert_file(handle, certfile, &format);
12853089Swyllys if (rv != KMF_OK)
12863089Swyllys return (rv);
12873089Swyllys
12883089Swyllys /* Read in the CERT file */
12895051Swyllys rv = kmf_read_input_file(handle, certfile, &cert1);
12903089Swyllys if (rv != KMF_OK) {
12913089Swyllys return (rv);
12923089Swyllys }
12933089Swyllys
12945051Swyllys /* The label attribute is optional */
12955051Swyllys label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
12965051Swyllys
12973089Swyllys /*
12983089Swyllys * If the input certificate is in PEM format, we need to convert
12993089Swyllys * it to DER first.
13003089Swyllys */
13013089Swyllys if (format == KMF_FORMAT_PEM) {
13023089Swyllys int derlen;
13035051Swyllys rv = kmf_pem_to_der(cert1.Data, cert1.Length,
13043089Swyllys &cert2.Data, &derlen);
13053089Swyllys if (rv != KMF_OK) {
13063089Swyllys goto out;
13073089Swyllys }
13083089Swyllys cert2.Length = (size_t)derlen;
13093089Swyllys }
13103089Swyllys
13116354Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
13126354Swyllys if (cred != NULL) {
13136354Swyllys rv = pk11_authenticate(handle, cred);
13146354Swyllys if (rv != KMF_OK)
13156354Swyllys return (rv);
13166354Swyllys }
13176354Swyllys
13185051Swyllys rv = CreateCertObject(handle, label,
13193089Swyllys format == KMF_FORMAT_ASN1 ? &cert1 : &cert2);
13203089Swyllys
13213089Swyllys out:
13223089Swyllys if (cert1.Data != NULL) {
13233089Swyllys free(cert1.Data);
13243089Swyllys }
13253089Swyllys
13263089Swyllys if (cert2.Data != NULL) {
13273089Swyllys free(cert2.Data);
13283089Swyllys }
13293089Swyllys
13303089Swyllys return (rv);
13313089Swyllys }
13323089Swyllys
13333089Swyllys KMF_RETURN
KMFPK11_DeleteCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)13345051Swyllys KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
13353089Swyllys {
13363089Swyllys KMF_RETURN rv = 0;
13373089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
13383089Swyllys OBJLIST *objlist;
13393089Swyllys uint32_t numObjects = 0;
13405051Swyllys char *certlabel = NULL;
13415051Swyllys char *issuer = NULL;
13425051Swyllys char *subject = NULL;
13435051Swyllys KMF_BIGINT *serial = NULL;
13445051Swyllys KMF_CERT_VALIDITY validity;
13455051Swyllys boolean_t private;
13465051Swyllys
13475051Swyllys if (kmfh == NULL)
13483089Swyllys return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
13493089Swyllys
13503089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
13513089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
13523089Swyllys
13535051Swyllys
13545051Swyllys /* Get the search criteria attributes. They are all optional. */
13555051Swyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
13565051Swyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
13575051Swyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
13585051Swyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
13595051Swyllys
13605051Swyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
13615051Swyllys &validity, NULL);
13625051Swyllys if (rv != KMF_OK) {
13635051Swyllys validity = KMF_ALL_CERTS;
13645051Swyllys rv = KMF_OK;
13655051Swyllys }
13665051Swyllys
13675051Swyllys rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
13685051Swyllys (void *)&private, NULL);
13695051Swyllys if (rv != KMF_OK) {
13705051Swyllys private = B_FALSE;
13715051Swyllys rv = KMF_OK;
13725051Swyllys }
13733089Swyllys
13743089Swyllys /*
13755051Swyllys * Start searching for certificates that match the criteria and
13765051Swyllys * delete them.
13773089Swyllys */
13783089Swyllys objlist = NULL;
13795051Swyllys rv = search_certs(handle, certlabel, issuer, subject, serial,
13805051Swyllys private, validity, &objlist, &numObjects);
13813089Swyllys
13823089Swyllys if (rv == KMF_OK && objlist != NULL) {
13833089Swyllys OBJLIST *node = objlist;
13843089Swyllys
13853089Swyllys while (node != NULL) {
13863089Swyllys CK_RV ckrv;
13875051Swyllys ckrv = C_DestroyObject(kmfh->pk11handle, node->handle);
13883089Swyllys if (ckrv != CKR_OK) {
13893089Swyllys SET_ERROR(kmfh, ckrv);
13903089Swyllys rv = KMF_ERR_INTERNAL;
13913089Swyllys break;
13923089Swyllys }
13933089Swyllys node = node->next;
13943089Swyllys }
13953089Swyllys free_objlist(objlist);
13963089Swyllys }
13973089Swyllys
13983089Swyllys if (rv == KMF_OK && numObjects == 0)
13993089Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
14003089Swyllys
14013089Swyllys out:
14023089Swyllys return (rv);
14033089Swyllys }
14043089Swyllys
140511973Swyllys.ingersoll@sun.com static CK_RV
gendsa_keypair(KMF_HANDLE * kmfh,boolean_t storekey,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)140611973Swyllys.ingersoll@sun.com gendsa_keypair(KMF_HANDLE *kmfh, boolean_t storekey,
140711973Swyllys.ingersoll@sun.com CK_OBJECT_HANDLE *pubKey,
140811973Swyllys.ingersoll@sun.com CK_OBJECT_HANDLE *priKey)
14093089Swyllys {
141011973Swyllys.ingersoll@sun.com CK_RV ckrv = CKR_OK;
141111973Swyllys.ingersoll@sun.com CK_SESSION_HANDLE hSession = kmfh->pk11handle;
141211973Swyllys.ingersoll@sun.com static CK_ULONG dsaKeyType = CKK_DSA;
141311973Swyllys.ingersoll@sun.com static CK_BBOOL true = TRUE;
141411973Swyllys.ingersoll@sun.com static CK_BBOOL false = FALSE;
14153089Swyllys static CK_OBJECT_CLASS priClass = CKO_PRIVATE_KEY;
14163089Swyllys static CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
14173089Swyllys
14183089Swyllys static CK_BYTE ckDsaPrime[128] = {
14193089Swyllys 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2,
14203089Swyllys 0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c,
14213089Swyllys 0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3,
14223089Swyllys 0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc,
14233089Swyllys 0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c,
14243089Swyllys 0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8,
14253089Swyllys 0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8,
14263089Swyllys 0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3,
14273089Swyllys 0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09,
14283089Swyllys 0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c,
14293089Swyllys 0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5,
14303089Swyllys 0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb,
14313089Swyllys 0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b,
14323089Swyllys 0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11,
14333089Swyllys 0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27,
14343089Swyllys 0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b};
14353089Swyllys
14363089Swyllys static CK_BYTE ckDsaSubPrime[20] = {
14373089Swyllys 0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe,
14383089Swyllys 0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc,
14393089Swyllys 0x78, 0x47, 0xb0, 0xd5};
14403089Swyllys
14413089Swyllys static CK_BYTE ckDsaBase[128] = {
14423089Swyllys 0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b,
14433089Swyllys 0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5,
14443089Swyllys 0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3,
14453089Swyllys 0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c,
14463089Swyllys 0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2,
14473089Swyllys 0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd,
14483089Swyllys 0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3,
14493089Swyllys 0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a,
14503089Swyllys 0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05,
14513089Swyllys 0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a,
14523089Swyllys 0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67,
14533089Swyllys 0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73,
14543089Swyllys 0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f,
14553089Swyllys 0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19,
14563089Swyllys 0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce,
14573089Swyllys 0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 };
14583089Swyllys
14593089Swyllys static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = {
14603089Swyllys { CKA_CLASS, &pubClass, sizeof (pubClass) },
14613089Swyllys { CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) },
146211973Swyllys.ingersoll@sun.com { CKA_TOKEN, &true, sizeof (true)},
14633089Swyllys { CKA_PRIVATE, &false, sizeof (false)},
14643089Swyllys { CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) },
14653089Swyllys { CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)},
14663089Swyllys { CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) },
14673089Swyllys { CKA_VERIFY, &true, sizeof (true) },
14683089Swyllys };
14693089Swyllys
14703089Swyllys #define NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
14713089Swyllys sizeof (CK_ATTRIBUTE))
14723089Swyllys #define MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
14733089Swyllys sizeof (CK_ATTRIBUTE))
14743089Swyllys
14753089Swyllys static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = {
14763089Swyllys {CKA_CLASS, &priClass, sizeof (priClass)},
14773089Swyllys {CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)},
147811973Swyllys.ingersoll@sun.com {CKA_TOKEN, &true, sizeof (true)},
14793089Swyllys {CKA_PRIVATE, &true, sizeof (true)},
14803089Swyllys {CKA_SIGN, &true, sizeof (true)},
14813089Swyllys };
14823089Swyllys
14833089Swyllys #define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
14843089Swyllys sizeof (CK_ATTRIBUTE))
14853089Swyllys #define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
14863089Swyllys sizeof (CK_ATTRIBUTE))
148711973Swyllys.ingersoll@sun.com CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0};
148811973Swyllys.ingersoll@sun.com
148911973Swyllys.ingersoll@sun.com SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN,
149011973Swyllys.ingersoll@sun.com (storekey ? &true : &false), sizeof (CK_BBOOL));
149111973Swyllys.ingersoll@sun.com
149211973Swyllys.ingersoll@sun.com ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
149311973Swyllys.ingersoll@sun.com ckDsaPubKeyTemplate,
149411973Swyllys.ingersoll@sun.com (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)),
149511973Swyllys.ingersoll@sun.com ckDsaPriKeyTemplate,
149611973Swyllys.ingersoll@sun.com (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)),
149711973Swyllys.ingersoll@sun.com pubKey, priKey);
149811973Swyllys.ingersoll@sun.com if (ckrv != CKR_OK) {
149911973Swyllys.ingersoll@sun.com SET_ERROR(kmfh, ckrv);
150011973Swyllys.ingersoll@sun.com return (KMF_ERR_KEYGEN_FAILED);
150111973Swyllys.ingersoll@sun.com }
150211973Swyllys.ingersoll@sun.com
150311973Swyllys.ingersoll@sun.com return (ckrv);
150411973Swyllys.ingersoll@sun.com }
150511973Swyllys.ingersoll@sun.com
150611973Swyllys.ingersoll@sun.com static CK_RV
genrsa_keypair(KMF_HANDLE * kmfh,CK_ULONG modulusBits,boolean_t storekey,KMF_BIGINT * rsaexp,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)150711973Swyllys.ingersoll@sun.com genrsa_keypair(KMF_HANDLE *kmfh, CK_ULONG modulusBits,
150811973Swyllys.ingersoll@sun.com boolean_t storekey, KMF_BIGINT *rsaexp,
150911973Swyllys.ingersoll@sun.com CK_OBJECT_HANDLE *pubKey,
151011973Swyllys.ingersoll@sun.com CK_OBJECT_HANDLE *priKey)
151111973Swyllys.ingersoll@sun.com {
151211973Swyllys.ingersoll@sun.com CK_RV ckrv = CKR_OK;
151311973Swyllys.ingersoll@sun.com CK_SESSION_HANDLE hSession = kmfh->pk11handle;
151411973Swyllys.ingersoll@sun.com CK_ATTRIBUTE rsaPubKeyTemplate[16];
151511973Swyllys.ingersoll@sun.com CK_ATTRIBUTE rsaPriKeyTemplate[16];
151611973Swyllys.ingersoll@sun.com CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
151711973Swyllys.ingersoll@sun.com int numpubattr = 0, numpriattr = 0;
151811973Swyllys.ingersoll@sun.com static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01};
151911973Swyllys.ingersoll@sun.com static CK_BBOOL true = TRUE;
152011973Swyllys.ingersoll@sun.com static CK_BBOOL false = FALSE;
152111973Swyllys.ingersoll@sun.com
152211973Swyllys.ingersoll@sun.com SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN,
152311973Swyllys.ingersoll@sun.com (storekey ? &true : &false), sizeof (CK_BBOOL));
152411973Swyllys.ingersoll@sun.com numpubattr++;
152511973Swyllys.ingersoll@sun.com
152611973Swyllys.ingersoll@sun.com SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS,
152711973Swyllys.ingersoll@sun.com &modulusBits, sizeof (modulusBits));
152811973Swyllys.ingersoll@sun.com numpubattr++;
152911973Swyllys.ingersoll@sun.com
153011973Swyllys.ingersoll@sun.com if (rsaexp != NULL && (rsaexp->len > 0 && rsaexp->val != NULL)) {
153111973Swyllys.ingersoll@sun.com SETATTR(rsaPubKeyTemplate, numpubattr,
153211973Swyllys.ingersoll@sun.com CKA_PUBLIC_EXPONENT,
153311973Swyllys.ingersoll@sun.com rsaexp->val, rsaexp->len);
153411973Swyllys.ingersoll@sun.com numpubattr++;
153511973Swyllys.ingersoll@sun.com } else {
153611973Swyllys.ingersoll@sun.com SETATTR(rsaPubKeyTemplate, numpubattr,
153711973Swyllys.ingersoll@sun.com CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo));
153811973Swyllys.ingersoll@sun.com numpubattr++;
153911973Swyllys.ingersoll@sun.com }
154011973Swyllys.ingersoll@sun.com SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT,
154111973Swyllys.ingersoll@sun.com &true, sizeof (true));
154211973Swyllys.ingersoll@sun.com numpubattr++;
154311973Swyllys.ingersoll@sun.com SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY,
154411973Swyllys.ingersoll@sun.com &true, sizeof (true));
154511973Swyllys.ingersoll@sun.com numpubattr++;
154611973Swyllys.ingersoll@sun.com SETATTR(rsaPubKeyTemplate, numpubattr, CKA_WRAP,
154711973Swyllys.ingersoll@sun.com &true, sizeof (true));
154811973Swyllys.ingersoll@sun.com numpubattr++;
154911973Swyllys.ingersoll@sun.com
155011973Swyllys.ingersoll@sun.com SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN,
155111973Swyllys.ingersoll@sun.com (storekey ? &true : &false), sizeof (CK_BBOOL));
155211973Swyllys.ingersoll@sun.com numpriattr++;
155311973Swyllys.ingersoll@sun.com SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true,
155411973Swyllys.ingersoll@sun.com sizeof (true));
155511973Swyllys.ingersoll@sun.com numpriattr++;
155611973Swyllys.ingersoll@sun.com SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true,
155711973Swyllys.ingersoll@sun.com sizeof (true));
155811973Swyllys.ingersoll@sun.com numpriattr++;
155911973Swyllys.ingersoll@sun.com SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true,
156011973Swyllys.ingersoll@sun.com sizeof (true));
156111973Swyllys.ingersoll@sun.com numpriattr++;
156211973Swyllys.ingersoll@sun.com SETATTR(rsaPriKeyTemplate, numpriattr, CKA_UNWRAP, &true,
156311973Swyllys.ingersoll@sun.com sizeof (true));
156411973Swyllys.ingersoll@sun.com numpriattr++;
156511973Swyllys.ingersoll@sun.com
156611973Swyllys.ingersoll@sun.com ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
156711973Swyllys.ingersoll@sun.com rsaPubKeyTemplate, numpubattr,
156811973Swyllys.ingersoll@sun.com rsaPriKeyTemplate, numpriattr,
156911973Swyllys.ingersoll@sun.com pubKey, priKey);
157011973Swyllys.ingersoll@sun.com if (ckrv != CKR_OK) {
157111973Swyllys.ingersoll@sun.com SET_ERROR(kmfh, ckrv);
157211973Swyllys.ingersoll@sun.com return (ckrv);
157311973Swyllys.ingersoll@sun.com }
157411973Swyllys.ingersoll@sun.com
157511973Swyllys.ingersoll@sun.com return (ckrv);
157611973Swyllys.ingersoll@sun.com }
157711973Swyllys.ingersoll@sun.com
157811973Swyllys.ingersoll@sun.com static CK_RV
genecc_keypair(KMF_HANDLE * kmfh,boolean_t ontoken,KMF_OID * curveoid,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)157911973Swyllys.ingersoll@sun.com genecc_keypair(KMF_HANDLE *kmfh,
158011973Swyllys.ingersoll@sun.com boolean_t ontoken,
158111973Swyllys.ingersoll@sun.com KMF_OID *curveoid,
158211973Swyllys.ingersoll@sun.com CK_OBJECT_HANDLE *pubKey,
158311973Swyllys.ingersoll@sun.com CK_OBJECT_HANDLE *priKey)
158411973Swyllys.ingersoll@sun.com {
158511973Swyllys.ingersoll@sun.com CK_RV ckrv;
158611973Swyllys.ingersoll@sun.com CK_SESSION_HANDLE hSession = kmfh->pk11handle;
158711973Swyllys.ingersoll@sun.com CK_MECHANISM keyGenMech = {CKM_EC_KEY_PAIR_GEN, NULL, 0};
158811973Swyllys.ingersoll@sun.com const ulong_t publicKey = CKO_PUBLIC_KEY;
158911973Swyllys.ingersoll@sun.com const ulong_t privateKey = CKO_PRIVATE_KEY;
159011973Swyllys.ingersoll@sun.com const ulong_t keytype = CKK_EC;
159111973Swyllys.ingersoll@sun.com static CK_BBOOL true = TRUE;
159211973Swyllys.ingersoll@sun.com static CK_BBOOL false = FALSE;
159311973Swyllys.ingersoll@sun.com CK_ATTRIBUTE public_template[6];
159411973Swyllys.ingersoll@sun.com CK_ATTRIBUTE private_template[6];
159511973Swyllys.ingersoll@sun.com int numpubattr, numpriattr;
159611973Swyllys.ingersoll@sun.com
159711973Swyllys.ingersoll@sun.com numpubattr = 0;
159811973Swyllys.ingersoll@sun.com SETATTR(public_template, numpubattr, CKA_CLASS,
159911973Swyllys.ingersoll@sun.com &publicKey, sizeof (publicKey));
160011973Swyllys.ingersoll@sun.com numpubattr++;
160111973Swyllys.ingersoll@sun.com SETATTR(public_template, numpubattr, CKA_KEY_TYPE,
160211973Swyllys.ingersoll@sun.com &keytype, sizeof (keytype));
160311973Swyllys.ingersoll@sun.com numpubattr++;
160411973Swyllys.ingersoll@sun.com SETATTR(public_template, numpubattr, CKA_EC_PARAMS,
160511973Swyllys.ingersoll@sun.com curveoid->Data, curveoid->Length);
160611973Swyllys.ingersoll@sun.com numpubattr++;
160711973Swyllys.ingersoll@sun.com SETATTR(public_template, numpubattr, CKA_TOKEN,
160811973Swyllys.ingersoll@sun.com ontoken ? &true : &false, sizeof (true));
160911973Swyllys.ingersoll@sun.com numpubattr++;
161011973Swyllys.ingersoll@sun.com SETATTR(public_template, numpubattr, CKA_VERIFY,
161111973Swyllys.ingersoll@sun.com &true, sizeof (true));
161211973Swyllys.ingersoll@sun.com numpubattr++;
161311973Swyllys.ingersoll@sun.com SETATTR(public_template, numpubattr, CKA_PRIVATE,
161411973Swyllys.ingersoll@sun.com &false, sizeof (false));
161511973Swyllys.ingersoll@sun.com numpubattr++;
161611973Swyllys.ingersoll@sun.com
161711973Swyllys.ingersoll@sun.com numpriattr = 0;
161811973Swyllys.ingersoll@sun.com SETATTR(private_template, numpriattr, CKA_CLASS,
161911973Swyllys.ingersoll@sun.com &privateKey, sizeof (privateKey));
162011973Swyllys.ingersoll@sun.com numpriattr++;
162111973Swyllys.ingersoll@sun.com SETATTR(private_template, numpriattr, CKA_KEY_TYPE,
162211973Swyllys.ingersoll@sun.com &keytype, sizeof (keytype));
162311973Swyllys.ingersoll@sun.com numpriattr++;
162411973Swyllys.ingersoll@sun.com SETATTR(private_template, numpriattr, CKA_TOKEN,
162511973Swyllys.ingersoll@sun.com ontoken ? &true : &false, sizeof (true));
162611973Swyllys.ingersoll@sun.com numpriattr++;
162711973Swyllys.ingersoll@sun.com SETATTR(private_template, numpriattr, CKA_PRIVATE,
162811973Swyllys.ingersoll@sun.com &true, sizeof (true));
162911973Swyllys.ingersoll@sun.com numpriattr++;
163011973Swyllys.ingersoll@sun.com SETATTR(private_template, numpriattr, CKA_SIGN,
163111973Swyllys.ingersoll@sun.com &true, sizeof (true));
163211973Swyllys.ingersoll@sun.com numpriattr++;
163311973Swyllys.ingersoll@sun.com SETATTR(private_template, numpriattr, CKA_DERIVE,
163411973Swyllys.ingersoll@sun.com &true, sizeof (true));
163511973Swyllys.ingersoll@sun.com numpriattr++;
163611973Swyllys.ingersoll@sun.com
163711973Swyllys.ingersoll@sun.com ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
163811973Swyllys.ingersoll@sun.com public_template, numpubattr,
163911973Swyllys.ingersoll@sun.com private_template, numpriattr,
164011973Swyllys.ingersoll@sun.com pubKey, priKey);
164111973Swyllys.ingersoll@sun.com if (ckrv != CKR_OK) {
164211973Swyllys.ingersoll@sun.com SET_ERROR(kmfh, ckrv);
164311973Swyllys.ingersoll@sun.com return (ckrv);
164411973Swyllys.ingersoll@sun.com }
164511973Swyllys.ingersoll@sun.com
164611973Swyllys.ingersoll@sun.com return (ckrv);
164711973Swyllys.ingersoll@sun.com }
164811973Swyllys.ingersoll@sun.com
164911973Swyllys.ingersoll@sun.com KMF_RETURN
KMFPK11_CreateKeypair(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)165011973Swyllys.ingersoll@sun.com KMFPK11_CreateKeypair(KMF_HANDLE_T handle,
165111973Swyllys.ingersoll@sun.com int numattr,
165211973Swyllys.ingersoll@sun.com KMF_ATTRIBUTE *attlist)
165311973Swyllys.ingersoll@sun.com {
165411973Swyllys.ingersoll@sun.com KMF_RETURN rv = KMF_OK;
165511973Swyllys.ingersoll@sun.com KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
165611973Swyllys.ingersoll@sun.com KMF_DATA IDInput, IDOutput;
165711973Swyllys.ingersoll@sun.com KMF_CREDENTIAL *cred;
165811973Swyllys.ingersoll@sun.com KMF_KEY_ALG keytype = KMF_RSA;
165911973Swyllys.ingersoll@sun.com KMF_KEY_HANDLE *pubkey, *privkey;
166011973Swyllys.ingersoll@sun.com
166111973Swyllys.ingersoll@sun.com CK_RV ckrv = 0;
166211973Swyllys.ingersoll@sun.com CK_SESSION_HANDLE hSession = kmfh->pk11handle;
166311973Swyllys.ingersoll@sun.com CK_ATTRIBUTE labelattr[1];
166411973Swyllys.ingersoll@sun.com CK_ATTRIBUTE idattr[1];
166511973Swyllys.ingersoll@sun.com CK_OBJECT_HANDLE pubKey, priKey;
166611973Swyllys.ingersoll@sun.com
166711973Swyllys.ingersoll@sun.com char IDHashData[SHA1_HASH_LENGTH];
166811973Swyllys.ingersoll@sun.com static CK_ULONG modulusBits = 1024;
166911973Swyllys.ingersoll@sun.com uint32_t modulusBits_size = sizeof (CK_ULONG);
167011973Swyllys.ingersoll@sun.com SHA1_CTX ctx;
167111973Swyllys.ingersoll@sun.com boolean_t storekey = TRUE;
167211973Swyllys.ingersoll@sun.com char *keylabel = NULL;
16733089Swyllys
16745051Swyllys if (kmfh == NULL)
16753089Swyllys return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
16763089Swyllys
16773089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
16783089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
16793089Swyllys
16805051Swyllys /* "storekey" is optional. Default is TRUE */
16815051Swyllys (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr,
16825051Swyllys &storekey, NULL);
16835051Swyllys
16845051Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr);
16855051Swyllys if (cred == NULL)
16863089Swyllys return (KMF_ERR_BAD_PARAMETER);
16873089Swyllys
16885051Swyllys rv = pk11_authenticate(handle, cred);
16895051Swyllys if (rv != KMF_OK)
16903089Swyllys return (rv);
16915051Swyllys
16925051Swyllys /* keytype is optional. KMF_RSA is default */
16935051Swyllys (void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr,
16945051Swyllys (void *)&keytype, NULL);
16955051Swyllys
16965051Swyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
16975051Swyllys if (pubkey == NULL)
16985051Swyllys return (KMF_ERR_BAD_PARAMETER);
16995051Swyllys
17005051Swyllys privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr);
17015051Swyllys if (privkey == NULL)
17025051Swyllys return (KMF_ERR_BAD_PARAMETER);
17035051Swyllys
17045051Swyllys (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
17055051Swyllys (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
17065051Swyllys if (keytype == KMF_RSA) {
170711973Swyllys.ingersoll@sun.com CK_BYTE *modulus = NULL;
17086354Swyllys CK_ULONG modulusLength = 0;
170911973Swyllys.ingersoll@sun.com KMF_BIGINT *rsaexp = NULL;
17103089Swyllys CK_ATTRIBUTE modattr[1];
17115051Swyllys
17125051Swyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr,
17135051Swyllys &modulusBits, &modulusBits_size);
17145051Swyllys if (rv == KMF_ERR_ATTR_NOT_FOUND)
17155051Swyllys /* Default modulusBits = 1024 */
17165051Swyllys rv = KMF_OK;
17175051Swyllys if (rv != KMF_OK)
17185051Swyllys return (KMF_ERR_BAD_PARAMETER);
17195051Swyllys
172011973Swyllys.ingersoll@sun.com rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, numattr);
172111973Swyllys.ingersoll@sun.com
172211973Swyllys.ingersoll@sun.com /* Generate the RSA keypair */
172311973Swyllys.ingersoll@sun.com ckrv = genrsa_keypair(kmfh, modulusBits, storekey,
172411973Swyllys.ingersoll@sun.com rsaexp, &pubKey, &priKey);
172511973Swyllys.ingersoll@sun.com
172611973Swyllys.ingersoll@sun.com if (ckrv != CKR_OK)
172711973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_PARAMETER);
17283089Swyllys
17295051Swyllys privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
17305051Swyllys privkey->keyalg = KMF_RSA;
17315051Swyllys privkey->keyclass = KMF_ASYM_PRI;
17325051Swyllys privkey->keyp = (void *)priKey;
17335051Swyllys
17345051Swyllys pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
17355051Swyllys pubkey->keyalg = KMF_RSA;
17365051Swyllys pubkey->keyclass = KMF_ASYM_PUB;
17375051Swyllys pubkey->keyp = (void *)pubKey;
17383089Swyllys
17396354Swyllys SETATTR(modattr, 0, CKA_MODULUS, NULL, modulusLength);
17403089Swyllys /* Get the Modulus field to use as input for creating the ID */
17416354Swyllys ckrv = C_GetAttributeValue(kmfh->pk11handle,
17425051Swyllys (CK_OBJECT_HANDLE)pubKey, modattr, 1);
17436354Swyllys if (ckrv != CKR_OK) {
17443089Swyllys SET_ERROR(kmfh, ckrv);
17453089Swyllys return (KMF_ERR_BAD_PARAMETER);
17463089Swyllys }
17473089Swyllys
17483089Swyllys modulusLength = modattr[0].ulValueLen;
17493089Swyllys modulus = malloc(modulusLength);
17503089Swyllys if (modulus == NULL)
17513089Swyllys return (KMF_ERR_MEMORY);
17523089Swyllys
17533089Swyllys modattr[0].pValue = modulus;
17546354Swyllys ckrv = C_GetAttributeValue(kmfh->pk11handle,
17555051Swyllys (CK_OBJECT_HANDLE)pubKey, modattr, 1);
17566354Swyllys if (ckrv != CKR_OK) {
17573089Swyllys SET_ERROR(kmfh, ckrv);
17583089Swyllys free(modulus);
17593089Swyllys return (KMF_ERR_BAD_PARAMETER);
17603089Swyllys }
17613089Swyllys
17623089Swyllys IDInput.Data = modulus;
17633089Swyllys IDInput.Length = modulusLength;
17643089Swyllys
17655051Swyllys } else if (keytype == KMF_DSA) {
17663089Swyllys CK_BYTE *keyvalue;
17673089Swyllys CK_ULONG valueLen;
17683089Swyllys CK_ATTRIBUTE valattr[1];
17693089Swyllys
177011973Swyllys.ingersoll@sun.com /* Generate the DSA keypair */
177111973Swyllys.ingersoll@sun.com ckrv = gendsa_keypair(kmfh, storekey, &pubKey, &priKey);
177211973Swyllys.ingersoll@sun.com if (ckrv != CKR_OK)
177311973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_PARAMETER);
17743089Swyllys
17755051Swyllys privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
17765051Swyllys privkey->keyalg = KMF_DSA;
17775051Swyllys privkey->keyclass = KMF_ASYM_PRI;
17785051Swyllys privkey->keyp = (void *)priKey;
17795051Swyllys
17805051Swyllys pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
17815051Swyllys pubkey->keyalg = KMF_DSA;
17825051Swyllys pubkey->keyclass = KMF_ASYM_PUB;
17835051Swyllys pubkey->keyp = (void *)pubKey;
17845051Swyllys
17853089Swyllys /* Get the Public Value to use as input for creating the ID */
178611973Swyllys.ingersoll@sun.com SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen);
178711973Swyllys.ingersoll@sun.com
178811973Swyllys.ingersoll@sun.com ckrv = C_GetAttributeValue(hSession,
178911973Swyllys.ingersoll@sun.com (CK_OBJECT_HANDLE)pubKey, valattr, 1);
179011973Swyllys.ingersoll@sun.com if (ckrv != CKR_OK) {
179111973Swyllys.ingersoll@sun.com SET_ERROR(kmfh, ckrv);
179211973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_PARAMETER);
179311973Swyllys.ingersoll@sun.com }
179411973Swyllys.ingersoll@sun.com
179511973Swyllys.ingersoll@sun.com valueLen = valattr[0].ulValueLen;
179611973Swyllys.ingersoll@sun.com keyvalue = malloc(valueLen);
179711973Swyllys.ingersoll@sun.com if (keyvalue == NULL)
179811973Swyllys.ingersoll@sun.com return (KMF_ERR_MEMORY);
179911973Swyllys.ingersoll@sun.com
180011973Swyllys.ingersoll@sun.com valattr[0].pValue = keyvalue;
180111973Swyllys.ingersoll@sun.com ckrv = C_GetAttributeValue(hSession,
180211973Swyllys.ingersoll@sun.com (CK_OBJECT_HANDLE)pubKey, valattr, 1);
180311973Swyllys.ingersoll@sun.com if (ckrv != CKR_OK) {
180411973Swyllys.ingersoll@sun.com SET_ERROR(kmfh, ckrv);
180511973Swyllys.ingersoll@sun.com free(keyvalue);
180611973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_PARAMETER);
180711973Swyllys.ingersoll@sun.com }
180811973Swyllys.ingersoll@sun.com
180911973Swyllys.ingersoll@sun.com IDInput.Data = keyvalue;
181011973Swyllys.ingersoll@sun.com IDInput.Length = valueLen;
181111973Swyllys.ingersoll@sun.com } else if (keytype == KMF_ECDSA) {
181211973Swyllys.ingersoll@sun.com CK_BYTE *keyvalue;
181311973Swyllys.ingersoll@sun.com CK_ULONG valueLen;
181411973Swyllys.ingersoll@sun.com CK_ATTRIBUTE valattr[1];
181511973Swyllys.ingersoll@sun.com KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
181611973Swyllys.ingersoll@sun.com attlist, numattr);
181711973Swyllys.ingersoll@sun.com
181811973Swyllys.ingersoll@sun.com if (eccoid == NULL)
181911973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_PARAMETER);
182011973Swyllys.ingersoll@sun.com
182111973Swyllys.ingersoll@sun.com ckrv = genecc_keypair(kmfh, storekey, eccoid,
182211973Swyllys.ingersoll@sun.com &pubKey, &priKey);
182311973Swyllys.ingersoll@sun.com if (ckrv != CKR_OK)
182411973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_PARAMETER);
182511973Swyllys.ingersoll@sun.com
182611973Swyllys.ingersoll@sun.com privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
182711973Swyllys.ingersoll@sun.com privkey->keyalg = KMF_ECDSA;
182811973Swyllys.ingersoll@sun.com privkey->keyclass = KMF_ASYM_PRI;
182911973Swyllys.ingersoll@sun.com privkey->keyp = (void *)priKey;
183011973Swyllys.ingersoll@sun.com
183111973Swyllys.ingersoll@sun.com pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
183211973Swyllys.ingersoll@sun.com pubkey->keyalg = KMF_ECDSA;
183311973Swyllys.ingersoll@sun.com pubkey->keyclass = KMF_ASYM_PUB;
183411973Swyllys.ingersoll@sun.com pubkey->keyp = (void *)pubKey;
183511973Swyllys.ingersoll@sun.com
183611973Swyllys.ingersoll@sun.com /* Get the EC_POINT to use as input for creating the ID */
183711973Swyllys.ingersoll@sun.com SETATTR(valattr, 0, CKA_EC_POINT, NULL, &valueLen);
183811973Swyllys.ingersoll@sun.com
18396354Swyllys ckrv = C_GetAttributeValue(hSession,
18405051Swyllys (CK_OBJECT_HANDLE)pubKey, valattr, 1);
18416354Swyllys if (ckrv != CKR_OK) {
18423089Swyllys SET_ERROR(kmfh, ckrv);
18433089Swyllys return (KMF_ERR_BAD_PARAMETER);
18443089Swyllys }
18453089Swyllys
18463089Swyllys valueLen = valattr[0].ulValueLen;
18473089Swyllys keyvalue = malloc(valueLen);
18483089Swyllys if (keyvalue == NULL)
18493089Swyllys return (KMF_ERR_MEMORY);
18503089Swyllys
18513089Swyllys valattr[0].pValue = keyvalue;
18526354Swyllys ckrv = C_GetAttributeValue(hSession,
18535051Swyllys (CK_OBJECT_HANDLE)pubKey, valattr, 1);
18546354Swyllys if (ckrv != CKR_OK) {
18553089Swyllys SET_ERROR(kmfh, ckrv);
18563089Swyllys free(keyvalue);
18573089Swyllys return (KMF_ERR_BAD_PARAMETER);
18583089Swyllys }
18593089Swyllys
18603089Swyllys IDInput.Data = keyvalue;
18613089Swyllys IDInput.Length = valueLen;
18623089Swyllys } else {
18633089Swyllys return (KMF_ERR_BAD_PARAMETER);
18643089Swyllys }
18653089Swyllys
18665051Swyllys keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr);
18675051Swyllys if (keylabel != NULL && strlen(keylabel)) {
18685051Swyllys SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel));
18693089Swyllys
18703089Swyllys /* Set the CKA_LABEL if one was indicated */
18713089Swyllys if ((ckrv = C_SetAttributeValue(hSession, pubKey,
18725051Swyllys labelattr, 1)) != CKR_OK) {
18733089Swyllys SET_ERROR(kmfh, ckrv);
18743089Swyllys rv = KMF_ERR_INTERNAL;
18753089Swyllys goto cleanup;
18763089Swyllys }
18775051Swyllys pubkey->keylabel = (char *)strdup(keylabel);
18785051Swyllys if (pubkey->keylabel == NULL) {
18795051Swyllys rv = KMF_ERR_MEMORY;
18805051Swyllys goto cleanup;
18813089Swyllys }
18823089Swyllys if ((ckrv = C_SetAttributeValue(hSession, priKey,
18835051Swyllys labelattr, 1)) != CKR_OK) {
18843089Swyllys SET_ERROR(kmfh, ckrv);
18853089Swyllys rv = KMF_ERR_INTERNAL;
18863089Swyllys goto cleanup;
18873089Swyllys }
18885051Swyllys privkey->keylabel = (char *)strdup(keylabel);
18895051Swyllys if (privkey->keylabel == NULL) {
18905051Swyllys rv = KMF_ERR_MEMORY;
18915051Swyllys goto cleanup;
18923089Swyllys }
18935051Swyllys } else {
18945051Swyllys rv = KMF_OK;
18953089Swyllys }
18963089Swyllys
18973089Swyllys /* Now, assign a CKA_ID value so it can be searched */
18983089Swyllys /* ID_Input was assigned above in the RSA or DSA keygen section */
18993089Swyllys IDOutput.Data = (uchar_t *)IDHashData;
19003089Swyllys IDOutput.Length = sizeof (IDHashData);
19013089Swyllys
19023825Swyllys SHA1Init(&ctx);
19033825Swyllys SHA1Update(&ctx, IDInput.Data, IDInput.Length);
19043825Swyllys SHA1Final(IDOutput.Data, &ctx);
19053825Swyllys
19063825Swyllys IDOutput.Length = SHA1_DIGEST_LENGTH;
19073825Swyllys
19083089Swyllys free(IDInput.Data);
19093089Swyllys
19103089Swyllys if (rv != CKR_OK) {
19113089Swyllys goto cleanup;
19123089Swyllys }
19133089Swyllys SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length);
19143089Swyllys if ((ckrv = C_SetAttributeValue(hSession, pubKey,
19155051Swyllys idattr, 1)) != CKR_OK) {
19163089Swyllys SET_ERROR(kmfh, ckrv);
19173089Swyllys rv = KMF_ERR_INTERNAL;
19183089Swyllys goto cleanup;
19193089Swyllys }
19203089Swyllys if ((ckrv = C_SetAttributeValue(hSession, priKey,
19215051Swyllys idattr, 1)) != CKR_OK) {
19223089Swyllys SET_ERROR(kmfh, ckrv);
19233089Swyllys rv = KMF_ERR_INTERNAL;
19243089Swyllys goto cleanup;
19253089Swyllys }
19263089Swyllys
19273089Swyllys cleanup:
19283089Swyllys if (rv != KMF_OK) {
19293089Swyllys if (pubKey != CK_INVALID_HANDLE)
19303089Swyllys (void) C_DestroyObject(hSession, pubKey);
19313089Swyllys if (priKey != CK_INVALID_HANDLE)
19323089Swyllys (void) C_DestroyObject(hSession, priKey);
19335051Swyllys
19345051Swyllys if (privkey->keylabel)
19355051Swyllys free(privkey->keylabel);
19365051Swyllys if (pubkey->keylabel)
19375051Swyllys free(pubkey->keylabel);
19383089Swyllys }
19393089Swyllys return (rv);
19403089Swyllys }
19413089Swyllys
19423089Swyllys KMF_RETURN
KMFPK11_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)19435051Swyllys KMFPK11_DeleteKey(KMF_HANDLE_T handle,
19445051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
19453089Swyllys {
19463089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
19473089Swyllys CK_RV ckrv = CKR_OK;
19483089Swyllys KMF_RETURN rv = KMF_OK;
19495051Swyllys KMF_KEY_HANDLE *key;
19505051Swyllys KMF_CREDENTIAL cred;
19515051Swyllys boolean_t destroy = B_TRUE;
19525051Swyllys
19535051Swyllys if (kmfh == NULL)
19543089Swyllys return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
19553089Swyllys
19563089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
19573089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
19583089Swyllys
19595051Swyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
19603089Swyllys if (key == NULL || key->keyp == NULL)
19613089Swyllys return (KMF_ERR_BAD_PARAMETER);
19623089Swyllys
19633089Swyllys if (key->keyclass != KMF_ASYM_PUB &&
19645051Swyllys key->keyclass != KMF_ASYM_PRI &&
19655051Swyllys key->keyclass != KMF_SYMMETRIC)
19663089Swyllys return (KMF_ERR_BAD_KEY_CLASS);
19673089Swyllys
19685051Swyllys /* "destroy" is optional. Default is TRUE */
19695051Swyllys (void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
19705051Swyllys (void *)&destroy, NULL);
19715051Swyllys
19723089Swyllys if (destroy) {
19735051Swyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
19745051Swyllys (void *)&cred, NULL);
19755051Swyllys if (rv != KMF_OK)
19765051Swyllys return (KMF_ERR_BAD_PARAMETER);
19775051Swyllys
19785051Swyllys rv = pk11_authenticate(handle, &cred);
19793089Swyllys if (rv != KMF_OK) {
19803089Swyllys return (rv);
19813089Swyllys }
19823089Swyllys }
19833089Swyllys
19843089Swyllys if (!key->israw && destroy)
19853089Swyllys ckrv = C_DestroyObject(kmfh->pk11handle,
19865051Swyllys (CK_OBJECT_HANDLE)key->keyp);
19873089Swyllys
19883089Swyllys if (ckrv != CKR_OK) {
19893089Swyllys SET_ERROR(kmfh, ckrv);
19903089Swyllys /* Report authentication failures to the caller */
19915051Swyllys if (ckrv == CKR_PIN_EXPIRED || ckrv == CKR_SESSION_READ_ONLY)
19923089Swyllys rv = KMF_ERR_AUTH_FAILED;
19933089Swyllys else
19943089Swyllys rv = KMF_ERR_INTERNAL;
19953089Swyllys }
19963089Swyllys return (rv);
19973089Swyllys }
19983089Swyllys
19993089Swyllys KMF_RETURN
KMFPK11_SignData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * keyp,KMF_OID * algOID,KMF_DATA * tobesigned,KMF_DATA * output)20003089Swyllys KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp,
20013089Swyllys KMF_OID *algOID,
20023089Swyllys KMF_DATA *tobesigned,
20033089Swyllys KMF_DATA *output)
20043089Swyllys {
200511973Swyllys.ingersoll@sun.com KMF_RETURN rv = KMF_OK;
20063089Swyllys CK_RV ckrv;
20073089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
20083089Swyllys CK_SESSION_HANDLE hSession = kmfh->pk11handle;
20093089Swyllys CK_MECHANISM mechanism;
201011973Swyllys.ingersoll@sun.com CK_MECHANISM_TYPE mechtype, hashmech;
201111973Swyllys.ingersoll@sun.com CK_KEY_TYPE keytype;
20125051Swyllys KMF_ALGORITHM_INDEX AlgId;
201311973Swyllys.ingersoll@sun.com KMF_DATA hashData = {NULL, 0};
201411973Swyllys.ingersoll@sun.com uchar_t digest[1024];
201511973Swyllys.ingersoll@sun.com CK_ATTRIBUTE subprime = { CKA_SUBPRIME, NULL, 0 };
20165051Swyllys
20175051Swyllys if (kmfh == NULL)
20183089Swyllys return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
20193089Swyllys
20203089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
20213089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
20223089Swyllys
20233089Swyllys if (keyp == NULL || algOID == NULL ||
20243089Swyllys tobesigned == NULL || output == NULL)
20253089Swyllys return (KMF_ERR_BAD_PARAMETER);
20263089Swyllys
20273089Swyllys /* These functions are available to the plugin from libkmf */
20285051Swyllys AlgId = x509_algoid_to_algid(algOID);
20293089Swyllys if (AlgId == KMF_ALGID_NONE)
20303089Swyllys return (KMF_ERR_BAD_PARAMETER);
20313089Swyllys
203211973Swyllys.ingersoll@sun.com /* Get the PKCS11 signing key type and mechtype */
203311973Swyllys.ingersoll@sun.com if (get_pk11_data(AlgId, &keytype, &mechtype, &hashmech, 0))
20343089Swyllys return (KMF_ERR_BAD_PARAMETER);
20353089Swyllys
203611973Swyllys.ingersoll@sun.com (void) memset(digest, 0, sizeof (digest));
203711973Swyllys.ingersoll@sun.com hashData.Data = digest;
203811973Swyllys.ingersoll@sun.com hashData.Length = sizeof (digest);
203911973Swyllys.ingersoll@sun.com rv = PKCS_DigestData(handle, hSession, hashmech, tobesigned, &hashData,
204011973Swyllys.ingersoll@sun.com (mechtype == CKM_RSA_PKCS));
204111973Swyllys.ingersoll@sun.com if (rv)
204211973Swyllys.ingersoll@sun.com return (rv);
204311973Swyllys.ingersoll@sun.com
204411973Swyllys.ingersoll@sun.com if (mechtype == CKM_DSA && hashmech == CKM_SHA256) {
204511973Swyllys.ingersoll@sun.com /*
204611973Swyllys.ingersoll@sun.com * FIPS 186-3 says that when signing with DSA
204711973Swyllys.ingersoll@sun.com * the hash must be truncated to the size of the
204811973Swyllys.ingersoll@sun.com * subprime.
204911973Swyllys.ingersoll@sun.com */
205011973Swyllys.ingersoll@sun.com ckrv = C_GetAttributeValue(hSession,
205111973Swyllys.ingersoll@sun.com (CK_OBJECT_HANDLE)keyp->keyp,
205211973Swyllys.ingersoll@sun.com &subprime, 1);
205311973Swyllys.ingersoll@sun.com if (ckrv != CKR_OK) {
205411973Swyllys.ingersoll@sun.com SET_ERROR(kmfh, ckrv);
205511973Swyllys.ingersoll@sun.com return (KMF_ERR_INTERNAL);
205611973Swyllys.ingersoll@sun.com }
205711973Swyllys.ingersoll@sun.com hashData.Length = subprime.ulValueLen;
205811973Swyllys.ingersoll@sun.com }
205911973Swyllys.ingersoll@sun.com
206011973Swyllys.ingersoll@sun.com /* the mechtype from the 'get_pk11_info' refers to the signing */
206111973Swyllys.ingersoll@sun.com mechanism.mechanism = mechtype;
20623089Swyllys mechanism.pParameter = NULL;
20633089Swyllys mechanism.ulParameterLen = 0;
20643089Swyllys
20653089Swyllys ckrv = C_SignInit(hSession, &mechanism, (CK_OBJECT_HANDLE)keyp->keyp);
20663089Swyllys if (ckrv != CKR_OK) {
20673089Swyllys SET_ERROR(kmfh, ckrv);
20683089Swyllys return (KMF_ERR_INTERNAL);
20693089Swyllys }
20703089Swyllys
207111973Swyllys.ingersoll@sun.com ckrv = C_Sign(hSession, hashData.Data, hashData.Length,
20725051Swyllys output->Data, (CK_ULONG *)&output->Length);
20733089Swyllys
20743089Swyllys if (ckrv != CKR_OK) {
20753089Swyllys SET_ERROR(kmfh, ckrv);
20763089Swyllys return (KMF_ERR_INTERNAL);
20773089Swyllys }
20783089Swyllys
20793089Swyllys return (KMF_OK);
20803089Swyllys }
20813089Swyllys
20823089Swyllys KMF_RETURN
KMFPK11_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)20833089Swyllys KMFPK11_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
20843089Swyllys {
20853089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
20863089Swyllys
20873089Swyllys *msgstr = NULL;
20883089Swyllys if (kmfh->lasterr.errcode != 0) {
20893089Swyllys char *e = pkcs11_strerror(kmfh->lasterr.errcode);
20903089Swyllys if (e == NULL || (*msgstr = (char *)strdup(e)) == NULL) {
20913089Swyllys return (KMF_ERR_MEMORY);
20923089Swyllys }
20933089Swyllys }
20943089Swyllys
20953089Swyllys return (KMF_OK);
20963089Swyllys }
20973089Swyllys
20983089Swyllys static CK_RV
getObjectKeytype(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,CK_ULONG * keytype)20993089Swyllys getObjectKeytype(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
21003089Swyllys CK_ULONG *keytype)
21013089Swyllys {
21023089Swyllys CK_RV rv = CKR_OK;
21033089Swyllys CK_ATTRIBUTE templ;
21043089Swyllys CK_ULONG len = sizeof (CK_ULONG);
21053089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
21063089Swyllys
21073089Swyllys templ.type = CKA_KEY_TYPE;
21083089Swyllys templ.pValue = keytype;
21093089Swyllys templ.ulValueLen = len;
21103089Swyllys
21113089Swyllys rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
21123089Swyllys
21133089Swyllys return (rv);
21143089Swyllys
21153089Swyllys }
21165128Swyllys
21173089Swyllys static CK_RV
getObjectLabel(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,char ** outlabel)21183089Swyllys getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
21193089Swyllys char **outlabel)
21203089Swyllys {
21213089Swyllys CK_RV rv = CKR_OK;
21223089Swyllys CK_ATTRIBUTE templ;
21233089Swyllys char Label[BUFSIZ];
21243089Swyllys CK_ULONG len = sizeof (Label);
21253089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
21263089Swyllys
21273089Swyllys (void) memset(Label, 0, len);
21283089Swyllys templ.type = CKA_LABEL;
21293089Swyllys templ.pValue = Label;
21303089Swyllys templ.ulValueLen = len;
21313089Swyllys
21323089Swyllys rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
21333089Swyllys if (rv == CKR_OK) {
21343089Swyllys *outlabel = (char *)strdup(Label);
21353089Swyllys } else {
21363089Swyllys *outlabel = NULL;
21373089Swyllys }
21383089Swyllys return (rv);
21393089Swyllys }
21403089Swyllys
21415128Swyllys static CK_RV
getObjectKeyclass(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,KMF_KEY_CLASS * keyclass)21425128Swyllys getObjectKeyclass(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
21435128Swyllys KMF_KEY_CLASS *keyclass)
21445128Swyllys {
21455128Swyllys CK_RV rv = CKR_OK;
21465128Swyllys CK_ATTRIBUTE templ;
21475128Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
21485128Swyllys CK_OBJECT_CLASS class;
21495128Swyllys
21505128Swyllys templ.type = CKA_CLASS;
21515128Swyllys templ.pValue = &class;
21525128Swyllys templ.ulValueLen = sizeof (CK_OBJECT_CLASS);
21535128Swyllys
21545128Swyllys rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
21555128Swyllys if (rv == CKR_OK) {
21565128Swyllys if (class == CKO_PUBLIC_KEY) {
21575128Swyllys *keyclass = KMF_ASYM_PUB;
21585128Swyllys } else if (class == CKO_PRIVATE_KEY) {
21595128Swyllys *keyclass = KMF_ASYM_PRI;
21605128Swyllys } else if (class == CKO_SECRET_KEY) {
21615128Swyllys *keyclass = KMF_SYMMETRIC;
21625128Swyllys }
21635128Swyllys } else {
21645128Swyllys *keyclass = KMF_KEYCLASS_NONE;
21655128Swyllys }
21665128Swyllys return (rv);
21675128Swyllys }
21685051Swyllys
21693089Swyllys KMF_RETURN
KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)21705051Swyllys KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
21715051Swyllys KMF_ATTRIBUTE *attrlist)
21723089Swyllys {
21733089Swyllys KMF_X509_SPKI *pubkey;
21743089Swyllys KMF_X509_CERTIFICATE *SignerCert = NULL;
21753089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
21763089Swyllys KMF_RETURN rv = KMF_OK;
21773089Swyllys CK_RV ckrv = CKR_OK;
21783089Swyllys CK_ATTRIBUTE templ[4];
21793089Swyllys CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE;
21803089Swyllys CK_ULONG obj_count;
2181*12234Swyllys.ingersoll@sun.com CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
21823089Swyllys CK_BBOOL true = TRUE;
21833089Swyllys KMF_DATA Id = { NULL, 0 };
21845051Swyllys KMF_KEY_HANDLE *key = NULL;
21855051Swyllys KMF_DATA *cert = NULL;
21865051Swyllys KMF_CREDENTIAL cred;
21875051Swyllys KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF;
21885051Swyllys CK_ULONG keytype;
21895051Swyllys
21905051Swyllys /* Get the key handle */
21915051Swyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
21925051Swyllys if (key == NULL)
21935051Swyllys return (KMF_ERR_BAD_PARAMETER);
21945051Swyllys
21955051Swyllys /* Get the optional encoded format */
21965051Swyllys (void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
21975051Swyllys (void *)&format, NULL);
21983089Swyllys
21993089Swyllys /* Decode the signer cert so we can get the SPKI data */
22005051Swyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
22015051Swyllys if (cert == NULL || cert->Data == NULL)
22025051Swyllys return (KMF_ERR_BAD_PARAMETER);
22035051Swyllys
22045051Swyllys if ((rv = DerDecodeSignedCertificate(cert,
22053089Swyllys &SignerCert)) != KMF_OK)
22063089Swyllys return (rv);
22073089Swyllys
22083089Swyllys /* Get the public key info from the signer certificate */
22093089Swyllys pubkey = &SignerCert->certificate.subjectPublicKeyInfo;
22103089Swyllys
22113089Swyllys /* Generate an ID from the SPKI data */
22123089Swyllys rv = GetIDFromSPKI(pubkey, &Id);
22133089Swyllys if (rv != KMF_OK) {
22143089Swyllys goto errout;
22153089Swyllys }
22163089Swyllys
22175051Swyllys /* Get the credential and login */
22185051Swyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
22195051Swyllys (void *)&cred, NULL);
22205051Swyllys if (rv != KMF_OK)
22215051Swyllys return (KMF_ERR_BAD_PARAMETER);
22225051Swyllys
22235051Swyllys rv = pk11_authenticate(handle, &cred);
22245051Swyllys if (rv != KMF_OK) {
22255051Swyllys return (rv);
22265051Swyllys }
22275051Swyllys
22285051Swyllys /* Start searching */
2229*12234Swyllys.ingersoll@sun.com SETATTR(templ, 0, CKA_CLASS, &objClass, sizeof (objClass));
22303089Swyllys SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true));
22313089Swyllys SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true));
22323089Swyllys SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length);
22333089Swyllys
22343089Swyllys if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) {
22353089Swyllys SET_ERROR(kmfh, ckrv);
22363089Swyllys rv = KMF_ERR_INTERNAL;
22373089Swyllys goto errout;
22383089Swyllys }
22393089Swyllys
22406354Swyllys if ((ckrv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1,
22413089Swyllys &obj_count)) != CKR_OK) {
22423089Swyllys SET_ERROR(kmfh, ckrv);
22433089Swyllys rv = KMF_ERR_INTERNAL;
22443089Swyllys goto errout;
22453089Swyllys }
22463089Swyllys
22473089Swyllys if (obj_count == 0) {
22483089Swyllys SET_ERROR(kmfh, ckrv);
2249*12234Swyllys.ingersoll@sun.com rv = KMF_ERR_KEY_NOT_FOUND;
22503089Swyllys goto errout;
22513089Swyllys }
22523089Swyllys
22533089Swyllys key->kstype = KMF_KEYSTORE_PK11TOKEN;
22543089Swyllys key->keyclass = KMF_ASYM_PRI;
22553089Swyllys key->keyp = (void *)pri_obj;
22565051Swyllys key->israw = FALSE;
22573089Swyllys
22583089Swyllys (void) C_FindObjectsFinal(kmfh->pk11handle);
22593089Swyllys
22603089Swyllys ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp,
22615051Swyllys &key->keylabel);
22623089Swyllys if (ckrv != CKR_OK) {
22633089Swyllys SET_ERROR(handle, ckrv);
22643089Swyllys rv = KMF_ERR_INTERNAL;
22653089Swyllys } else {
22663089Swyllys rv = KMF_OK;
22673089Swyllys }
22683089Swyllys
22695051Swyllys /*
22705051Swyllys * The key->keyalg value is needed if we need to convert the key
22715051Swyllys * to raw key. However, the key->keyalg value will not be set if
22725051Swyllys * this function is not called thru the kmf_find_prikey_by_cert()
22735051Swyllys * framework function. To be safe, we will get the keytype from
22745051Swyllys * the key object and set key->keyalg value here.
22755051Swyllys */
22765051Swyllys ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp,
22775051Swyllys &keytype);
22785051Swyllys if (ckrv != CKR_OK) {
22795051Swyllys SET_ERROR(handle, ckrv);
22805051Swyllys rv = KMF_ERR_INTERNAL;
22815051Swyllys } else {
22825051Swyllys rv = KMF_OK;
22835051Swyllys }
22845051Swyllys
22855051Swyllys if (keytype == CKK_RSA)
22865051Swyllys key->keyalg = KMF_RSA;
22875051Swyllys else if (keytype == CKK_DSA)
22885051Swyllys key->keyalg = KMF_DSA;
228911973Swyllys.ingersoll@sun.com else if (keytype == CKK_EC)
229011973Swyllys.ingersoll@sun.com key->keyalg = KMF_ECDSA;
22915051Swyllys else {
22925051Swyllys /* For asymmetric keys, we only support RSA and DSA */
22935051Swyllys rv = KMF_ERR_KEY_NOT_FOUND;
22945051Swyllys goto errout;
22955051Swyllys }
22965051Swyllys
22975051Swyllys if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) {
22983089Swyllys KMF_RAW_KEY_DATA *rkey = NULL;
22993089Swyllys rv = keyObj2RawKey(handle, key, &rkey);
23003089Swyllys if (rv == KMF_OK) {
23013089Swyllys key->keyp = rkey;
23023089Swyllys key->israw = TRUE;
23033089Swyllys }
23043089Swyllys }
23053089Swyllys
23063089Swyllys errout:
23073089Swyllys if (Id.Data != NULL)
23083089Swyllys free(Id.Data);
23093089Swyllys
23103089Swyllys if (SignerCert != NULL) {
23115051Swyllys kmf_free_signed_cert(SignerCert);
23123089Swyllys free(SignerCert);
23133089Swyllys }
23143089Swyllys return (rv);
23153089Swyllys }
23163089Swyllys
23173089Swyllys KMF_RETURN
KMFPK11_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * algOID,KMF_DATA * ciphertext,KMF_DATA * output)23183089Swyllys KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
23193089Swyllys KMF_OID *algOID, KMF_DATA *ciphertext,
23203089Swyllys KMF_DATA *output)
23213089Swyllys {
23223089Swyllys CK_RV ckrv;
23233089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
23243089Swyllys CK_SESSION_HANDLE hSession = kmfh->pk11handle;
23253089Swyllys CK_MECHANISM mechanism;
232611973Swyllys.ingersoll@sun.com CK_MECHANISM_TYPE mechtype;
232711973Swyllys.ingersoll@sun.com CK_KEY_TYPE keytype;
23283089Swyllys KMF_ALGORITHM_INDEX AlgId;
23293089Swyllys CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0;
23303089Swyllys uint8_t *in_data, *out_data;
23313089Swyllys int i, blocks;
23323089Swyllys CK_ATTRIBUTE ckTemplate[1];
23333089Swyllys
23345051Swyllys if (kmfh == NULL)
23353089Swyllys return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
23363089Swyllys
23373089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
23383089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
23393089Swyllys
23403089Swyllys if (key == NULL || algOID == NULL ||
23413089Swyllys ciphertext == NULL || output == NULL)
23423089Swyllys return (KMF_ERR_BAD_PARAMETER);
23433089Swyllys
23445051Swyllys AlgId = x509_algoid_to_algid(algOID);
23453089Swyllys if (AlgId == KMF_ALGID_NONE)
23463089Swyllys return (KMF_ERR_BAD_PARAMETER);
23473089Swyllys
23483089Swyllys /* Map the Algorithm ID to a PKCS#11 mechanism */
234911973Swyllys.ingersoll@sun.com if (get_pk11_data(AlgId, &keytype, &mechtype, NULL, 0))
23503089Swyllys return (KMF_ERR_BAD_PARAMETER);
23513089Swyllys
235211973Swyllys.ingersoll@sun.com mechanism.mechanism = mechtype;
23533089Swyllys mechanism.pParameter = NULL;
23543089Swyllys mechanism.ulParameterLen = 0;
23553089Swyllys
23563089Swyllys SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL,
23573089Swyllys sizeof (CK_ULONG));
23583089Swyllys
23593089Swyllys /* Get the modulus length */
23603089Swyllys ckrv = C_GetAttributeValue(hSession,
23613089Swyllys (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1);
23623089Swyllys
23633089Swyllys if (ckrv != CKR_OK) {
23643089Swyllys SET_ERROR(kmfh, ckrv);
23653089Swyllys return (KMF_ERR_INTERNAL);
23663089Swyllys }
23673089Swyllys
23683089Swyllys block_len = ckTemplate[0].ulValueLen;
23693089Swyllys
23703089Swyllys /* Compute the number of times to do single-part decryption */
23713089Swyllys blocks = ciphertext->Length/block_len;
23723089Swyllys
23733089Swyllys out_data = output->Data;
23743089Swyllys in_data = ciphertext->Data;
23753089Swyllys out_len = block_len - 11;
23763089Swyllys
23773089Swyllys for (i = 0; i < blocks; i++) {
23783089Swyllys ckrv = C_DecryptInit(hSession, &mechanism,
23795051Swyllys (CK_OBJECT_HANDLE)key->keyp);
23803089Swyllys
23813089Swyllys if (ckrv != CKR_OK) {
23823089Swyllys SET_ERROR(kmfh, ckrv);
23833089Swyllys return (KMF_ERR_INTERNAL);
23843089Swyllys }
23853089Swyllys
23863089Swyllys ckrv = C_Decrypt(hSession, in_data, block_len,
23873089Swyllys out_data, (CK_ULONG *)&out_len);
23883089Swyllys
23893089Swyllys if (ckrv != CKR_OK) {
23903089Swyllys SET_ERROR(kmfh, ckrv);
23913089Swyllys return (KMF_ERR_INTERNAL);
23923089Swyllys }
23933089Swyllys
23943089Swyllys out_data += out_len;
23953089Swyllys total_decrypted += out_len;
23963089Swyllys in_data += block_len;
23973089Swyllys
23983089Swyllys }
23993089Swyllys
24003089Swyllys output->Length = total_decrypted;
24013089Swyllys return (KMF_OK);
24023089Swyllys }
24033089Swyllys
24043089Swyllys static void
attr2bigint(CK_ATTRIBUTE_PTR attr,KMF_BIGINT * big)24053089Swyllys attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big)
24063089Swyllys {
24073089Swyllys big->val = attr->pValue;
24083089Swyllys big->len = attr->ulValueLen;
24093089Swyllys }
24103089Swyllys
24115637Swyllys static KMF_RETURN
get_bigint_attr(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE_TYPE attrtype,KMF_BIGINT * bigint)24125637Swyllys get_bigint_attr(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj,
24135637Swyllys CK_ATTRIBUTE_TYPE attrtype, KMF_BIGINT *bigint)
24145637Swyllys {
24155637Swyllys CK_RV ckrv;
24165637Swyllys CK_ATTRIBUTE attr;
24175637Swyllys
24185637Swyllys attr.type = attrtype;
24195637Swyllys attr.pValue = NULL;
24205637Swyllys attr.ulValueLen = 0;
24215637Swyllys
24225637Swyllys if ((ckrv = C_GetAttributeValue(sess, obj,
24235637Swyllys &attr, 1)) != CKR_OK) {
24245637Swyllys /* Mask this error so the caller can continue */
24255637Swyllys if (ckrv == CKR_ATTRIBUTE_TYPE_INVALID)
24265637Swyllys return (KMF_OK);
24275637Swyllys else
24285637Swyllys return (KMF_ERR_INTERNAL);
24295637Swyllys }
24305637Swyllys if (attr.ulValueLen > 0 && bigint != NULL) {
24315637Swyllys attr.pValue = malloc(attr.ulValueLen);
24325637Swyllys if (attr.pValue == NULL)
24335637Swyllys return (KMF_ERR_MEMORY);
24345637Swyllys
24355637Swyllys if ((ckrv = C_GetAttributeValue(sess, obj,
24365637Swyllys &attr, 1)) != CKR_OK)
24375637Swyllys if (ckrv != CKR_OK) {
24385637Swyllys free(attr.pValue);
24395637Swyllys return (KMF_ERR_INTERNAL);
24405637Swyllys }
24415637Swyllys
24425637Swyllys bigint->val = attr.pValue;
24435637Swyllys bigint->len = attr.ulValueLen;
24445637Swyllys }
24455637Swyllys return (KMF_OK);
24465637Swyllys }
24473089Swyllys
24483089Swyllys static KMF_RETURN
get_raw_rsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_RSA_KEY * rawrsa)24493089Swyllys get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa)
24503089Swyllys {
24513089Swyllys KMF_RETURN rv = KMF_OK;
24523408Swyllys CK_RV ckrv;
24533089Swyllys CK_SESSION_HANDLE sess = kmfh->pk11handle;
24545637Swyllys CK_ATTRIBUTE rsa_pri_attrs[2] = {
24553089Swyllys { CKA_MODULUS, NULL, 0 },
24565637Swyllys { CKA_PUBLIC_EXPONENT, NULL, 0 }
24575637Swyllys };
24585051Swyllys CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
24595051Swyllys int i;
24603089Swyllys
24615637Swyllys if (rawrsa == NULL)
24625637Swyllys return (KMF_ERR_BAD_PARAMETER);
24635637Swyllys
24645637Swyllys (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
24653408Swyllys if ((ckrv = C_GetAttributeValue(sess, obj,
24665051Swyllys rsa_pri_attrs, count)) != CKR_OK) {
24673408Swyllys SET_ERROR(kmfh, ckrv);
24683408Swyllys /* Tell the caller know why the key data cannot be retrieved. */
24693408Swyllys if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
24703408Swyllys return (KMF_ERR_SENSITIVE_KEY);
24713408Swyllys else if (ckrv == CKR_KEY_UNEXTRACTABLE)
24723408Swyllys return (KMF_ERR_UNEXTRACTABLE_KEY);
24733408Swyllys else
24743408Swyllys return (KMF_ERR_INTERNAL);
24753089Swyllys }
24763089Swyllys
24773089Swyllys /* Allocate memory for each attribute. */
24783089Swyllys for (i = 0; i < count; i++) {
24793089Swyllys if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
24803089Swyllys rsa_pri_attrs[i].ulValueLen == 0) {
24813089Swyllys rsa_pri_attrs[i].ulValueLen = 0;
24823089Swyllys continue;
24833089Swyllys }
24843089Swyllys if ((rsa_pri_attrs[i].pValue =
24853089Swyllys malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) {
24863089Swyllys rv = KMF_ERR_MEMORY;
24873089Swyllys goto end;
24883089Swyllys }
24893089Swyllys }
24903089Swyllys /* Now that we have space, really get the attributes */
24916354Swyllys if ((ckrv = C_GetAttributeValue(sess, obj,
24925051Swyllys rsa_pri_attrs, count)) != CKR_OK) {
24936354Swyllys SET_ERROR(kmfh, ckrv);
24943089Swyllys rv = KMF_ERR_INTERNAL;
24953089Swyllys goto end;
24963089Swyllys }
24973089Swyllys i = 0;
24983089Swyllys attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod);
24993089Swyllys attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp);
25003089Swyllys
25015637Swyllys /* Now get the optional parameters */
25025637Swyllys rv = get_bigint_attr(sess, obj, CKA_PRIVATE_EXPONENT, &rawrsa->priexp);
25035637Swyllys if (rv != KMF_OK)
25045637Swyllys goto end;
25055637Swyllys rv = get_bigint_attr(sess, obj, CKA_PRIME_1, &rawrsa->prime1);
25065637Swyllys if (rv != KMF_OK)
25075637Swyllys goto end;
25085637Swyllys rv = get_bigint_attr(sess, obj, CKA_PRIME_2, &rawrsa->prime2);
25095637Swyllys if (rv != KMF_OK)
25105637Swyllys goto end;
25115637Swyllys rv = get_bigint_attr(sess, obj, CKA_EXPONENT_1, &rawrsa->exp1);
25125637Swyllys if (rv != KMF_OK)
25135637Swyllys goto end;
25145637Swyllys rv = get_bigint_attr(sess, obj, CKA_EXPONENT_2, &rawrsa->exp2);
25155637Swyllys if (rv != KMF_OK)
25165637Swyllys goto end;
25175637Swyllys rv = get_bigint_attr(sess, obj, CKA_COEFFICIENT, &rawrsa->coef);
25185637Swyllys if (rv != KMF_OK)
25195637Swyllys goto end;
25203089Swyllys
25213089Swyllys end:
25223089Swyllys if (rv != KMF_OK) {
25233089Swyllys for (i = 0; i < count; i++) {
25243089Swyllys if (rsa_pri_attrs[i].pValue != NULL)
25253089Swyllys free(rsa_pri_attrs[i].pValue);
25263089Swyllys }
25275637Swyllys if (rawrsa->priexp.val)
25285637Swyllys free(rawrsa->priexp.val);
25295637Swyllys if (rawrsa->prime1.val)
25305637Swyllys free(rawrsa->prime1.val);
25315637Swyllys if (rawrsa->prime2.val)
25325637Swyllys free(rawrsa->prime2.val);
25335637Swyllys if (rawrsa->exp1.val)
25345637Swyllys free(rawrsa->exp1.val);
25355637Swyllys if (rawrsa->exp2.val)
25365637Swyllys free(rawrsa->exp2.val);
25375637Swyllys if (rawrsa->coef.val)
25385637Swyllys free(rawrsa->coef.val);
25393089Swyllys (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
25403089Swyllys }
25413089Swyllys return (rv);
25423089Swyllys }
25433089Swyllys
25446557Sfr41279 #define DSA_PRIME_BUFSIZE CHARLEN2BIGNUMLEN(1024) /* 8192 bits */
25456557Sfr41279 #define DSA_PRIVATE_BUFSIZE BIG_CHUNKS_FOR_160BITS /* 160 bits */
25465051Swyllys
25475051Swyllys /*
25485051Swyllys * This function calculates the pubkey value from the prime,
25495051Swyllys * base and private key values of a DSA key.
25505051Swyllys */
25515051Swyllys static KMF_RETURN
compute_dsa_pubvalue(KMF_RAW_DSA_KEY * rawdsa)25525051Swyllys compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa)
25535051Swyllys {
25545051Swyllys KMF_RETURN rv = KMF_OK;
25555051Swyllys BIGNUM p, g, x, y;
25565051Swyllys BIG_ERR_CODE err;
25575051Swyllys uchar_t *pubvalue;
25585051Swyllys uint32_t pubvalue_len;
25595051Swyllys
25605051Swyllys if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
25615051Swyllys rv = KMF_ERR_MEMORY;
25625051Swyllys return (rv);
25635051Swyllys }
25645051Swyllys bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len);
25655051Swyllys
25665051Swyllys if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
25675051Swyllys rv = KMF_ERR_MEMORY;
25685051Swyllys goto ret1;
25695051Swyllys }
25705051Swyllys bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len);
25715051Swyllys
25725051Swyllys if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) {
25735051Swyllys rv = KMF_ERR_MEMORY;
25745051Swyllys goto ret2;
25755051Swyllys }
25765051Swyllys bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len);
25775051Swyllys
25785051Swyllys if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
25795051Swyllys rv = KMF_ERR_MEMORY;
25805051Swyllys goto ret3;
25815051Swyllys }
25825051Swyllys
25835051Swyllys err = big_modexp(&y, &g, &x, &p, NULL);
25845051Swyllys if (err != BIG_OK) {
25855051Swyllys rv = KMF_ERR_INTERNAL;
25865051Swyllys goto ret3;
25875051Swyllys }
25885051Swyllys
25895051Swyllys pubvalue_len = y.len * (int)sizeof (uint32_t);
25905051Swyllys if ((pubvalue = malloc(pubvalue_len)) == NULL) {
25915051Swyllys rv = KMF_ERR_MEMORY;
25925051Swyllys goto ret4;
25935051Swyllys }
25945051Swyllys bignum2bytestring(pubvalue, &y, pubvalue_len);
25955051Swyllys
25965051Swyllys rawdsa->pubvalue.val = pubvalue;
25975051Swyllys rawdsa->pubvalue.len = pubvalue_len;
25985051Swyllys
25995051Swyllys ret4:
26005051Swyllys big_finish(&y);
26015051Swyllys ret3:
26025051Swyllys big_finish(&x);
26035051Swyllys ret2:
26045051Swyllys big_finish(&g);
26055051Swyllys ret1:
26065051Swyllys big_finish(&p);
26075051Swyllys return (rv);
26085051Swyllys }
26095051Swyllys
261011973Swyllys.ingersoll@sun.com static KMF_RETURN
get_raw_ec(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_EC_KEY * rawec)261111973Swyllys.ingersoll@sun.com get_raw_ec(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_EC_KEY *rawec)
261211973Swyllys.ingersoll@sun.com {
261311973Swyllys.ingersoll@sun.com KMF_RETURN rv = KMF_OK;
261411973Swyllys.ingersoll@sun.com CK_RV ckrv;
261511973Swyllys.ingersoll@sun.com CK_SESSION_HANDLE sess = kmfh->pk11handle;
261611973Swyllys.ingersoll@sun.com CK_ATTRIBUTE ec_attrs[2] = {
261711973Swyllys.ingersoll@sun.com { CKA_EC_PARAMS, NULL, 0},
261811973Swyllys.ingersoll@sun.com { CKA_VALUE, NULL, 0}
261911973Swyllys.ingersoll@sun.com };
262011973Swyllys.ingersoll@sun.com CK_ULONG count = sizeof (ec_attrs) / sizeof (CK_ATTRIBUTE);
262111973Swyllys.ingersoll@sun.com int i;
262211973Swyllys.ingersoll@sun.com
262311973Swyllys.ingersoll@sun.com if ((ckrv = C_GetAttributeValue(sess, obj,
262411973Swyllys.ingersoll@sun.com ec_attrs, 2)) != CKR_OK) {
262511973Swyllys.ingersoll@sun.com SET_ERROR(kmfh, ckrv);
262611973Swyllys.ingersoll@sun.com
262711973Swyllys.ingersoll@sun.com /* Tell the caller know why the key data cannot be retrieved. */
262811973Swyllys.ingersoll@sun.com if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
262911973Swyllys.ingersoll@sun.com return (KMF_ERR_SENSITIVE_KEY);
263011973Swyllys.ingersoll@sun.com else if (ckrv == CKR_KEY_UNEXTRACTABLE)
263111973Swyllys.ingersoll@sun.com return (KMF_ERR_UNEXTRACTABLE_KEY);
263211973Swyllys.ingersoll@sun.com return (KMF_ERR_INTERNAL);
263311973Swyllys.ingersoll@sun.com }
263411973Swyllys.ingersoll@sun.com for (i = 0; i < count; i++) {
263511973Swyllys.ingersoll@sun.com if (ec_attrs[i].ulValueLen == (CK_ULONG)-1 ||
263611973Swyllys.ingersoll@sun.com ec_attrs[i].ulValueLen == 0) {
263711973Swyllys.ingersoll@sun.com ec_attrs[i].ulValueLen = 0;
263811973Swyllys.ingersoll@sun.com continue;
263911973Swyllys.ingersoll@sun.com }
264011973Swyllys.ingersoll@sun.com if ((ec_attrs[i].pValue =
264111973Swyllys.ingersoll@sun.com malloc(ec_attrs[i].ulValueLen)) == NULL) {
264211973Swyllys.ingersoll@sun.com rv = KMF_ERR_MEMORY;
264311973Swyllys.ingersoll@sun.com goto end;
264411973Swyllys.ingersoll@sun.com }
264511973Swyllys.ingersoll@sun.com }
264611973Swyllys.ingersoll@sun.com if ((ckrv = C_GetAttributeValue(sess, obj,
264711973Swyllys.ingersoll@sun.com ec_attrs, count)) != CKR_OK) {
264811973Swyllys.ingersoll@sun.com SET_ERROR(kmfh, ckrv);
264911973Swyllys.ingersoll@sun.com rv = KMF_ERR_INTERNAL;
265011973Swyllys.ingersoll@sun.com goto end;
265111973Swyllys.ingersoll@sun.com }
265211973Swyllys.ingersoll@sun.com
265311973Swyllys.ingersoll@sun.com rawec->params.Data = ec_attrs[0].pValue;
265411973Swyllys.ingersoll@sun.com rawec->params.Length = ec_attrs[0].ulValueLen;
265511973Swyllys.ingersoll@sun.com rawec->value.val = ec_attrs[1].pValue;
265611973Swyllys.ingersoll@sun.com rawec->value.len = ec_attrs[1].ulValueLen;
265711973Swyllys.ingersoll@sun.com
265811973Swyllys.ingersoll@sun.com end:
265911973Swyllys.ingersoll@sun.com if (rv != KMF_OK) {
266011973Swyllys.ingersoll@sun.com for (i = 0; i < count; i++) {
266111973Swyllys.ingersoll@sun.com if (ec_attrs[i].pValue != NULL)
266211973Swyllys.ingersoll@sun.com free(ec_attrs[i].pValue);
266311973Swyllys.ingersoll@sun.com }
266411973Swyllys.ingersoll@sun.com (void) memset(rawec, 0, sizeof (KMF_RAW_EC_KEY));
266511973Swyllys.ingersoll@sun.com }
266611973Swyllys.ingersoll@sun.com return (rv);
266711973Swyllys.ingersoll@sun.com }
26685051Swyllys
26693089Swyllys static KMF_RETURN
get_raw_dsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_DSA_KEY * rawdsa)26703089Swyllys get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa)
26713089Swyllys {
26723089Swyllys KMF_RETURN rv = KMF_OK;
26735051Swyllys CK_RV ckrv;
26743089Swyllys CK_SESSION_HANDLE sess = kmfh->pk11handle;
26753089Swyllys CK_ATTRIBUTE dsa_pri_attrs[8] = {
26763089Swyllys { CKA_PRIME, NULL, 0 },
26773089Swyllys { CKA_SUBPRIME, NULL, 0 },
26783089Swyllys { CKA_BASE, NULL, 0 },
26793089Swyllys { CKA_VALUE, NULL, 0 }
26803089Swyllys };
26813089Swyllys CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
26823089Swyllys int i;
26833089Swyllys
26845051Swyllys if ((ckrv = C_GetAttributeValue(sess, obj,
26855051Swyllys dsa_pri_attrs, count)) != CKR_OK) {
26865051Swyllys SET_ERROR(kmfh, ckrv);
26875051Swyllys
26885051Swyllys /* Tell the caller know why the key data cannot be retrieved. */
26895051Swyllys if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
26905051Swyllys return (KMF_ERR_SENSITIVE_KEY);
26915051Swyllys else if (ckrv == CKR_KEY_UNEXTRACTABLE)
26925051Swyllys return (KMF_ERR_UNEXTRACTABLE_KEY);
26933089Swyllys return (KMF_ERR_INTERNAL);
26943089Swyllys }
26953089Swyllys
26963089Swyllys /* Allocate memory for each attribute. */
26973089Swyllys for (i = 0; i < count; i++) {
26983089Swyllys if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
26993089Swyllys dsa_pri_attrs[i].ulValueLen == 0) {
27003089Swyllys dsa_pri_attrs[i].ulValueLen = 0;
27013089Swyllys continue;
27023089Swyllys }
27033089Swyllys if ((dsa_pri_attrs[i].pValue =
27043089Swyllys malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) {
27053089Swyllys rv = KMF_ERR_MEMORY;
27063089Swyllys goto end;
27073089Swyllys }
27083089Swyllys }
27096354Swyllys if ((ckrv = C_GetAttributeValue(sess, obj,
27105051Swyllys dsa_pri_attrs, count)) != CKR_OK) {
27116354Swyllys SET_ERROR(kmfh, ckrv);
27123089Swyllys rv = KMF_ERR_INTERNAL;
27133089Swyllys goto end;
27143089Swyllys }
27153089Swyllys
27163089Swyllys /* Fill in all the temp variables. They are all required. */
27173089Swyllys i = 0;
27183089Swyllys attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime);
27193089Swyllys attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime);
27203089Swyllys attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base);
27213089Swyllys attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value);
27223089Swyllys
27235051Swyllys /* Compute the public key value and store it */
27245051Swyllys rv = compute_dsa_pubvalue(rawdsa);
27255051Swyllys
27263089Swyllys end:
27273089Swyllys if (rv != KMF_OK) {
27283089Swyllys for (i = 0; i < count; i++) {
27293089Swyllys if (dsa_pri_attrs[i].pValue != NULL)
27303089Swyllys free(dsa_pri_attrs[i].pValue);
27313089Swyllys }
27323089Swyllys (void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY));
27333089Swyllys }
27343089Swyllys return (rv);
27353089Swyllys }
27363089Swyllys
27373089Swyllys static KMF_RETURN
get_raw_sym(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_SYM_KEY * rawsym)27383089Swyllys get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym)
27393089Swyllys {
27403089Swyllys KMF_RETURN rv = KMF_OK;
27413089Swyllys CK_RV ckrv;
27423089Swyllys CK_SESSION_HANDLE sess = kmfh->pk11handle;
27433089Swyllys CK_ATTRIBUTE sym_attr[1];
27443089Swyllys CK_ULONG value_len = 0;
27453089Swyllys
27463089Swyllys /* find the key length first */
27473089Swyllys sym_attr[0].type = CKA_VALUE;
27483089Swyllys sym_attr[0].pValue = NULL;
27493089Swyllys sym_attr[0].ulValueLen = value_len;
27503089Swyllys if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
27515051Swyllys rawsym->keydata.val = NULL;
27525051Swyllys rawsym->keydata.len = 0;
27533089Swyllys if (ckrv == CKR_ATTRIBUTE_SENSITIVE) {
27545051Swyllys return (KMF_ERR_SENSITIVE_KEY);
27555051Swyllys } else if (ckrv == CKR_KEY_UNEXTRACTABLE) {
27565051Swyllys return (KMF_ERR_UNEXTRACTABLE_KEY);
27575051Swyllys } else {
27585051Swyllys SET_ERROR(kmfh, ckrv);
27595051Swyllys return (KMF_ERR_INTERNAL);
27603089Swyllys }
27613089Swyllys }
27623089Swyllys
27633089Swyllys /* Allocate memory for pValue */
27643089Swyllys sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen);
27653089Swyllys if (sym_attr[0].pValue == NULL) {
27663089Swyllys return (KMF_ERR_MEMORY);
27673089Swyllys }
27683089Swyllys
27693089Swyllys /* get the key data */
27706354Swyllys if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
27716354Swyllys SET_ERROR(kmfh, ckrv);
27723089Swyllys free(sym_attr[0].pValue);
27733089Swyllys return (KMF_ERR_INTERNAL);
27743089Swyllys }
27753089Swyllys
27763089Swyllys rawsym->keydata.val = sym_attr[0].pValue;
27773089Swyllys rawsym->keydata.len = sym_attr[0].ulValueLen;
27783089Swyllys return (rv);
27793089Swyllys }
27803089Swyllys
27813089Swyllys static KMF_RETURN
keyObj2RawKey(KMF_HANDLE_T handle,KMF_KEY_HANDLE * inkey,KMF_RAW_KEY_DATA ** outkey)27823089Swyllys keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey,
27833089Swyllys KMF_RAW_KEY_DATA **outkey)
27843089Swyllys {
27853089Swyllys KMF_RETURN rv = KMF_OK;
27863089Swyllys KMF_RAW_KEY_DATA *rkey;
27873089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
27883089Swyllys
27893089Swyllys rkey = malloc(sizeof (KMF_RAW_KEY_DATA));
27903089Swyllys if (rkey == NULL)
27913089Swyllys return (KMF_ERR_MEMORY);
27923089Swyllys
27933089Swyllys (void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA));
27943089Swyllys
27953089Swyllys rkey->keytype = inkey->keyalg;
27963089Swyllys
27973089Swyllys if (inkey->keyalg == KMF_RSA) {
27983089Swyllys rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
27995051Swyllys &rkey->rawdata.rsa);
28003089Swyllys } else if (inkey->keyalg == KMF_DSA) {
28013089Swyllys rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
28025051Swyllys &rkey->rawdata.dsa);
28033089Swyllys } else if (inkey->keyalg == KMF_AES ||
28043089Swyllys inkey->keyalg == KMF_RC4 ||
28053089Swyllys inkey->keyalg == KMF_DES ||
28063812Shylee inkey->keyalg == KMF_DES3 ||
28073812Shylee inkey->keyalg == KMF_GENERIC_SECRET) {
28083089Swyllys rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
28093089Swyllys &rkey->rawdata.sym);
28105051Swyllys /*
28115051Swyllys * If sensitive or non-extractable, mark them as such
28125051Swyllys * but return "OK" status so the keys get counted
28135051Swyllys * when doing FindKey operations.
28145051Swyllys */
28155051Swyllys if (rv == KMF_ERR_SENSITIVE_KEY) {
28165051Swyllys rkey->sensitive = B_TRUE;
28175051Swyllys rv = KMF_OK;
28185051Swyllys } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
28195051Swyllys rkey->not_extractable = B_TRUE;
28205051Swyllys rv = KMF_OK;
28215051Swyllys }
282211973Swyllys.ingersoll@sun.com } else if (inkey->keyalg == KMF_ECDSA) {
282311973Swyllys.ingersoll@sun.com rv = get_raw_ec(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
282411973Swyllys.ingersoll@sun.com &rkey->rawdata.ec);
28253089Swyllys } else {
28263089Swyllys rv = KMF_ERR_BAD_PARAMETER;
28273089Swyllys }
28283089Swyllys
28293089Swyllys if (rv == KMF_OK) {
28303089Swyllys *outkey = rkey;
28313089Swyllys } else if (rkey != NULL) {
28323089Swyllys free(rkey);
28333089Swyllys *outkey = NULL;
28343089Swyllys }
28353089Swyllys
28363089Swyllys return (rv);
28373089Swyllys }
28383089Swyllys
28393089Swyllys
28403089Swyllys static KMF_RETURN
kmf2pk11keytype(KMF_KEY_ALG keyalg,CK_KEY_TYPE * type)28413089Swyllys kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type)
28423089Swyllys {
28433089Swyllys switch (keyalg) {
28443089Swyllys case KMF_RSA:
28453089Swyllys *type = CKK_RSA;
28463089Swyllys break;
28473089Swyllys case KMF_DSA:
28483089Swyllys *type = CKK_DSA;
28493089Swyllys break;
285011973Swyllys.ingersoll@sun.com case KMF_ECDSA:
285111973Swyllys.ingersoll@sun.com *type = CKK_EC;
285211973Swyllys.ingersoll@sun.com break;
28533089Swyllys case KMF_AES:
28543089Swyllys *type = CKK_AES;
28553089Swyllys break;
28563089Swyllys case KMF_RC4:
28573089Swyllys *type = CKK_RC4;
28583089Swyllys break;
28593089Swyllys case KMF_DES:
28603089Swyllys *type = CKK_DES;
28613089Swyllys break;
28623089Swyllys case KMF_DES3:
28633089Swyllys *type = CKK_DES3;
28643089Swyllys break;
28653812Shylee case KMF_GENERIC_SECRET:
28663812Shylee *type = CKK_GENERIC_SECRET;
28673812Shylee break;
28683089Swyllys default:
28693089Swyllys return (KMF_ERR_BAD_KEY_TYPE);
28703089Swyllys }
28713089Swyllys
28723089Swyllys return (KMF_OK);
28733089Swyllys }
28743089Swyllys
28753089Swyllys static int
IDStringToData(char * idstr,KMF_DATA * iddata)28763089Swyllys IDStringToData(char *idstr, KMF_DATA *iddata)
28773089Swyllys {
28783089Swyllys int len, i;
28793089Swyllys char *iddup, *byte;
28803089Swyllys uint_t lvalue;
28813089Swyllys
28823089Swyllys if (idstr == NULL || !strlen(idstr))
28833089Swyllys return (-1);
28843089Swyllys
28853089Swyllys iddup = (char *)strdup(idstr);
28863089Swyllys if (iddup == NULL)
28873089Swyllys return (KMF_ERR_MEMORY);
28883089Swyllys
28893089Swyllys len = strlen(iddup) / 3 + 1;
28903089Swyllys iddata->Data = malloc(len);
28913089Swyllys if (iddata->Data == NULL)
28923089Swyllys return (KMF_ERR_MEMORY);
28933089Swyllys (void) memset(iddata->Data, 0, len);
28943089Swyllys iddata->Length = len;
28953089Swyllys
28963089Swyllys byte = strtok(iddup, ":");
28973089Swyllys if (byte == NULL) {
28983089Swyllys free(iddup);
28993089Swyllys free(iddata->Data);
29003089Swyllys iddata->Data = NULL;
29013089Swyllys iddata->Length = 0;
29023089Swyllys return (-1);
29033089Swyllys }
29043089Swyllys
29053089Swyllys i = 0;
29063089Swyllys do {
29073089Swyllys (void) sscanf(byte, "%x", &lvalue);
29083089Swyllys iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF);
29093089Swyllys byte = strtok(NULL, ":");
29103089Swyllys } while (byte != NULL && i < len);
29113089Swyllys
29123089Swyllys iddata->Length = i;
29133089Swyllys free(iddup);
29143089Swyllys return (0);
29153089Swyllys }
29163089Swyllys
29173089Swyllys KMF_RETURN
KMFPK11_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)29185051Swyllys KMFPK11_FindKey(KMF_HANDLE_T handle,
29195051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
29203089Swyllys {
29213089Swyllys KMF_RETURN rv = KMF_OK;
29223089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
29233089Swyllys uint32_t want_keys, i;
29243089Swyllys CK_RV ckrv;
29253089Swyllys CK_ATTRIBUTE pTmpl[10];
29263089Swyllys CK_OBJECT_CLASS class;
29273089Swyllys CK_BBOOL true = TRUE;
29283089Swyllys CK_ULONG alg;
29295637Swyllys boolean_t is_token = B_TRUE, is_private = B_FALSE;
29305051Swyllys KMF_KEY_HANDLE *keys;
29315051Swyllys uint32_t *numkeys;
29326051Swyllys KMF_CREDENTIAL *cred = NULL;
29335051Swyllys KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE;
29345051Swyllys char *findLabel, *idstr;
29355051Swyllys KMF_KEY_ALG keytype = KMF_KEYALG_NONE;
29365051Swyllys KMF_ENCODE_FORMAT format;
29375051Swyllys
29385051Swyllys if (kmfh == NULL)
29393089Swyllys return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
29403089Swyllys
29413089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
29423089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
29433089Swyllys
29445051Swyllys numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
29455051Swyllys if (numkeys == NULL)
29463089Swyllys return (KMF_ERR_BAD_PARAMETER);
29473089Swyllys
29485051Swyllys if (*numkeys > 0)
29493089Swyllys want_keys = *numkeys;
29503089Swyllys else
29513089Swyllys want_keys = MAXINT; /* count them all */
29523089Swyllys
29535051Swyllys /* keyclass is optional */
29545051Swyllys (void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
29555051Swyllys (void *)&keyclass, NULL);
29565051Swyllys
29575051Swyllys if (keyclass == KMF_ASYM_PUB) {
29583089Swyllys class = CKO_PUBLIC_KEY;
29595051Swyllys } else if (keyclass == KMF_ASYM_PRI) {
29603089Swyllys class = CKO_PRIVATE_KEY;
29615051Swyllys } else if (keyclass == KMF_SYMMETRIC) {
29623089Swyllys class = CKO_SECRET_KEY;
29633089Swyllys }
29643089Swyllys
29655051Swyllys rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr,
29665051Swyllys (void *)&is_token, NULL);
29675051Swyllys if (rv != KMF_OK)
29685051Swyllys return (rv);
29695051Swyllys
29703089Swyllys i = 0;
29715051Swyllys if (is_token) {
29725051Swyllys SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true));
29735051Swyllys i++;
29745051Swyllys }
29755051Swyllys
29765051Swyllys if (keyclass != KMF_KEYCLASS_NONE) {
29775051Swyllys SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class));
29783089Swyllys i++;
29793089Swyllys }
29803089Swyllys
29815051Swyllys findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
29825051Swyllys
29835051Swyllys if (findLabel != NULL && strlen(findLabel)) {
29845051Swyllys SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel));
29855051Swyllys i++;
29865051Swyllys }
29875051Swyllys /* keytype is optional */
29885051Swyllys (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
29895051Swyllys (void *)&keytype, NULL);
29905051Swyllys
29915051Swyllys if (keytype != 0) {
29925051Swyllys rv = kmf2pk11keytype(keytype, &alg);
29933089Swyllys if (rv != KMF_OK) {
29943089Swyllys return (KMF_ERR_BAD_KEY_TYPE);
29953089Swyllys }
29965051Swyllys SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg));
29973089Swyllys i++;
29983089Swyllys }
29993089Swyllys
30005051Swyllys idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr);
30015051Swyllys
30025051Swyllys if (idstr != NULL) {
30033089Swyllys KMF_DATA iddata = { NULL, 0 };
30043089Swyllys
30053089Swyllys /*
30063089Swyllys * ID String parameter is assumed to be of form:
30073089Swyllys * XX:XX:XX:XX:XX ... :XX
30083089Swyllys * where XX is a hex number.
30093089Swyllys *
30103089Swyllys * We must convert this back to binary in order to
30113089Swyllys * use it in a search.
30123089Swyllys */
30135051Swyllys rv = IDStringToData(idstr, &iddata);
30143089Swyllys if (rv == KMF_OK) {
30155051Swyllys SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length);
30163089Swyllys i++;
30173089Swyllys } else {
30183089Swyllys return (rv);
30193089Swyllys }
30203089Swyllys }
30213089Swyllys
30225051Swyllys /* is_private is optional */
30235051Swyllys (void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
30245051Swyllys (void *)&is_private, NULL);
30255051Swyllys
30265051Swyllys if (is_private) {
30275051Swyllys SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true));
30283089Swyllys i++;
30293089Swyllys }
30303089Swyllys
30313408Swyllys /*
30323408Swyllys * Authenticate if the object is a token object,
30333408Swyllys * a private or secred key, or if the user passed in credentials.
30343408Swyllys */
30356051Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
30366354Swyllys if (cred != NULL) {
30376051Swyllys rv = pk11_authenticate(handle, cred);
30386051Swyllys if (rv != KMF_OK)
30396051Swyllys return (rv);
30403089Swyllys }
30413089Swyllys
30425051Swyllys keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30435051Swyllys /* it is okay to have "keys" contains NULL */
30445051Swyllys
30453089Swyllys ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i);
30463089Swyllys if (ckrv == CKR_OK) {
30473089Swyllys CK_ULONG obj_count, n = 0;
30483089Swyllys while (ckrv == CKR_OK && n < want_keys) {
30493089Swyllys CK_OBJECT_HANDLE hObj;
30503089Swyllys
30513089Swyllys ckrv = C_FindObjects(kmfh->pk11handle, &hObj,
30525051Swyllys 1, &obj_count);
30533089Swyllys if (ckrv == CKR_OK && obj_count == 1) {
30543089Swyllys if (keys != NULL) {
30553089Swyllys CK_ULONG keytype;
30563089Swyllys keys[n].kstype = KMF_KEYSTORE_PK11TOKEN;
30573089Swyllys keys[n].israw = FALSE;
30583089Swyllys keys[n].keyp = (void *)hObj;
30593089Swyllys
30603089Swyllys ckrv = getObjectKeytype(handle,
30615051Swyllys (CK_OBJECT_HANDLE)keys[n].keyp,
30625051Swyllys &keytype);
30633089Swyllys if (ckrv != CKR_OK)
30643089Swyllys goto end;
30653089Swyllys
30663089Swyllys ckrv = getObjectLabel(handle,
30675051Swyllys (CK_OBJECT_HANDLE)keys[n].keyp,
30685051Swyllys &(keys[n].keylabel));
30693089Swyllys if (ckrv != CKR_OK)
30703089Swyllys goto end;
30713089Swyllys
30725128Swyllys if (keyclass == KMF_KEYCLASS_NONE) {
30735128Swyllys ckrv = getObjectKeyclass(handle,
30745128Swyllys (CK_OBJECT_HANDLE)
30755128Swyllys keys[n].keyp,
30765128Swyllys &(keys[n].keyclass));
30775128Swyllys if (ckrv != CKR_OK)
30785128Swyllys goto end;
30795128Swyllys } else {
30805128Swyllys keys[n].keyclass = keyclass;
30815128Swyllys }
30825051Swyllys if (keytype == CKK_RSA) {
30833089Swyllys keys[n].keyalg = KMF_RSA;
30845051Swyllys } else if (keytype == CKK_DSA) {
30853089Swyllys keys[n].keyalg = KMF_DSA;
308611973Swyllys.ingersoll@sun.com } else if (keytype == CKK_EC) {
308711973Swyllys.ingersoll@sun.com keys[n].keyalg = KMF_ECDSA;
30885051Swyllys } else if (keytype == CKK_AES) {
30893089Swyllys keys[n].keyalg = KMF_AES;
30905051Swyllys keys[n].keyclass =
30915051Swyllys KMF_SYMMETRIC;
30925051Swyllys } else if (keytype == CKK_RC4) {
30933089Swyllys keys[n].keyalg = KMF_RC4;
30945051Swyllys keys[n].keyclass =
30955051Swyllys KMF_SYMMETRIC;
30965051Swyllys } else if (keytype == CKK_DES) {
30973089Swyllys keys[n].keyalg = KMF_DES;
30985051Swyllys keys[n].keyclass =
30995051Swyllys KMF_SYMMETRIC;
31005051Swyllys } else if (keytype == CKK_DES3) {
31013089Swyllys keys[n].keyalg = KMF_DES3;
31025051Swyllys keys[n].keyclass =
31035051Swyllys KMF_SYMMETRIC;
31045051Swyllys } else if (keytype ==
31055051Swyllys CKK_GENERIC_SECRET) {
31063812Shylee keys[n].keyalg =
31073812Shylee KMF_GENERIC_SECRET;
31085051Swyllys keys[n].keyclass =
31095051Swyllys KMF_SYMMETRIC;
31105051Swyllys }
31113089Swyllys
31123089Swyllys }
31133089Swyllys n++;
31143089Swyllys } else {
31153089Swyllys break;
31163089Swyllys }
31173089Swyllys }
31183089Swyllys ckrv = C_FindObjectsFinal(kmfh->pk11handle);
31193089Swyllys
31203089Swyllys /* "numkeys" indicates the number that were actually found */
31213089Swyllys *numkeys = n;
31223089Swyllys }
31235051Swyllys
31243408Swyllys if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) {
31255051Swyllys if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist,
31265051Swyllys numattr, (void *)&format, NULL)) == KMF_OK) {
31275051Swyllys if (format == KMF_FORMAT_RAWKEY ||
31285051Swyllys format == KMF_FORMAT_PEM) {
31295051Swyllys /* Convert keys to "rawkey" format */
31305051Swyllys for (i = 0; i < (*numkeys); i++) {
31315051Swyllys KMF_RAW_KEY_DATA *rkey = NULL;
31325051Swyllys rv = keyObj2RawKey(handle, &keys[i],
31335051Swyllys &rkey);
31345051Swyllys if (rv == KMF_OK) {
31355051Swyllys keys[i].keyp = rkey;
31365051Swyllys keys[i].israw = TRUE;
31375051Swyllys } else {
31385051Swyllys break;
31395051Swyllys }
31403408Swyllys }
31413089Swyllys }
31425051Swyllys } else {
31435051Swyllys rv = KMF_OK; /* format is optional */
31443089Swyllys }
31453089Swyllys }
31465051Swyllys
31473089Swyllys end:
31483089Swyllys if (ckrv != CKR_OK) {
31493089Swyllys SET_ERROR(kmfh, ckrv);
31503089Swyllys /* Report authentication failures to the caller */
31513089Swyllys if (ckrv == CKR_USER_NOT_LOGGED_IN ||
31523089Swyllys ckrv == CKR_PIN_INCORRECT ||
31533089Swyllys ckrv == CKR_PIN_INVALID ||
31543089Swyllys ckrv == CKR_PIN_EXPIRED ||
31553089Swyllys ckrv == CKR_PIN_LOCKED ||
31563089Swyllys ckrv == CKR_SESSION_READ_ONLY)
31573089Swyllys rv = KMF_ERR_AUTH_FAILED;
31583089Swyllys else
31593089Swyllys rv = KMF_ERR_INTERNAL;
31603089Swyllys } else if ((*numkeys) == 0) {
31613089Swyllys rv = KMF_ERR_KEY_NOT_FOUND;
31623089Swyllys }
31633089Swyllys
31643089Swyllys return (rv);
31653089Swyllys }
31663089Swyllys
31673089Swyllys static char *
convertDate(char * fulldate)31683089Swyllys convertDate(char *fulldate)
31693089Swyllys {
31703089Swyllys struct tm tms;
31713089Swyllys char newtime[9];
31723089Swyllys
31733089Swyllys (void) strptime(fulldate, "%b %d %T %Y %Z", &tms);
31743089Swyllys
31753089Swyllys if (tms.tm_year < 69)
31763089Swyllys tms.tm_year += 100;
31773089Swyllys
31783089Swyllys (void) strftime(newtime, sizeof (newtime), "m%d", &tms);
31793089Swyllys
31803089Swyllys newtime[8] = 0;
31813089Swyllys
31823089Swyllys /* memory returned must be freed by the caller */
31833089Swyllys return ((char *)strdup(newtime));
31843089Swyllys }
31853089Swyllys
31865051Swyllys static KMF_RETURN
store_raw_key(KMF_HANDLE_T handle,KMF_ATTRIBUTE * attrlist,int numattr,KMF_RAW_KEY_DATA * rawkey)31875051Swyllys store_raw_key(KMF_HANDLE_T handle,
31885051Swyllys KMF_ATTRIBUTE *attrlist, int numattr,
31893089Swyllys KMF_RAW_KEY_DATA *rawkey)
31903089Swyllys {
31913089Swyllys KMF_RETURN rv = KMF_OK;
31923089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
31933089Swyllys int i;
31943089Swyllys CK_RV ckrv = CKR_OK;
31953089Swyllys CK_ATTRIBUTE templ[32];
31963089Swyllys CK_OBJECT_HANDLE keyobj;
31973089Swyllys CK_KEY_TYPE keytype;
31983089Swyllys CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
31993089Swyllys CK_BBOOL cktrue = TRUE;
32003089Swyllys CK_DATE startdate, enddate;
32013089Swyllys KMF_DATA id = {NULL, 0};
32023089Swyllys KMF_DATA subject = {NULL, 0};
32033089Swyllys KMF_X509EXT_KEY_USAGE kuext;
32043089Swyllys KMF_X509_CERTIFICATE *x509 = NULL;
32055051Swyllys CK_BBOOL kufound = B_FALSE;
32065051Swyllys KMF_DATA *cert = NULL;
32073089Swyllys char *notbefore = NULL, *start = NULL;
32083089Swyllys char *notafter = NULL, *end = NULL;
32095051Swyllys char *keylabel = NULL;
32106354Swyllys KMF_CREDENTIAL *cred = NULL;
32115051Swyllys
32125051Swyllys if (kmfh == NULL)
32133089Swyllys return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
32143089Swyllys
32153089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
32163089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
32173089Swyllys
32183089Swyllys if (rawkey->keytype == KMF_RSA)
32193089Swyllys keytype = CKK_RSA;
32203089Swyllys else if (rawkey->keytype == KMF_DSA)
32213089Swyllys keytype = CKK_DSA;
322211973Swyllys.ingersoll@sun.com else if (rawkey->keytype == KMF_ECDSA)
322311973Swyllys.ingersoll@sun.com keytype = CKK_EC;
32243089Swyllys else
32253089Swyllys return (KMF_ERR_BAD_PARAMETER);
32263089Swyllys
32276354Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
32286354Swyllys if (cred != NULL) {
32296354Swyllys rv = pk11_authenticate(handle, cred);
32306354Swyllys if (rv != KMF_OK)
32316354Swyllys return (rv);
32326354Swyllys }
32336354Swyllys
32345051Swyllys keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
32355536Swyllys /*
32365536Swyllys * If the caller did not specify a label, see if the raw key
32375536Swyllys * came with one (possible if it came from a PKCS#12 file).
32385536Swyllys */
32395536Swyllys if (keylabel == NULL) {
32405536Swyllys keylabel = rawkey->label;
32415536Swyllys }
32423089Swyllys
32433089Swyllys i = 0;
32443089Swyllys SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++;
32453089Swyllys SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++;
32463089Swyllys SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++;
32473089Swyllys SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++;
324811973Swyllys.ingersoll@sun.com if (keytype != CKK_EC)
324911973Swyllys.ingersoll@sun.com SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++;
32503089Swyllys
32515051Swyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
32525051Swyllys if (cert != NULL) {
32535051Swyllys id.Data = NULL;
32545051Swyllys id.Length = 0;
32555051Swyllys rv = kmf_get_cert_id_data(cert, &id);
32565051Swyllys if (rv != KMF_OK) {
32575051Swyllys goto cleanup;
32585051Swyllys }
32595051Swyllys
32605051Swyllys rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509);
32615051Swyllys if (rv != KMF_OK) {
32625051Swyllys goto cleanup;
32635051Swyllys }
32645051Swyllys
32655051Swyllys rv = DerEncodeName(&x509->certificate.subject, &subject);
32665051Swyllys if (rv != KMF_OK) {
32675051Swyllys goto cleanup;
32685051Swyllys }
32695051Swyllys SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length);
32705051Swyllys i++;
32715051Swyllys
32725051Swyllys rv = kmf_get_cert_start_date_str(handle, cert, ¬before);
32735051Swyllys if (rv != KMF_OK) {
32745051Swyllys goto cleanup;
32755051Swyllys }
32765051Swyllys start = convertDate(notbefore);
32775536Swyllys free(notbefore);
32785051Swyllys
32795051Swyllys rv = kmf_get_cert_end_date_str(handle, cert, ¬after);
32805051Swyllys if (rv != KMF_OK) {
32815051Swyllys goto cleanup;
32825051Swyllys }
32835051Swyllys end = convertDate(notafter);
32845536Swyllys free(notafter);
32855051Swyllys if (id.Data != NULL && id.Data != NULL && id.Length > 0) {
32865051Swyllys SETATTR(templ, i, CKA_ID, id.Data, id.Length);
32875051Swyllys i++;
32885051Swyllys }
32895051Swyllys if (start != NULL) {
32905051Swyllys /*
32915051Swyllys * This makes some potentially dangerous assumptions:
32925051Swyllys * 1. that the startdate in the parameter block is
32935051Swyllys * properly formatted as YYYYMMDD
32945051Swyllys * 2. That the CK_DATE structure is always the same.
32955051Swyllys */
32965051Swyllys (void) memcpy(&startdate, start, sizeof (CK_DATE));
32975051Swyllys SETATTR(templ, i, CKA_START_DATE, &startdate,
32985051Swyllys sizeof (startdate));
32995051Swyllys i++;
33005051Swyllys }
33015051Swyllys if (end != NULL) {
33025051Swyllys (void) memcpy(&enddate, end, sizeof (CK_DATE));
33035051Swyllys SETATTR(templ, i, CKA_END_DATE, &enddate,
33045051Swyllys sizeof (enddate));
33055051Swyllys i++;
33065051Swyllys }
33075051Swyllys
33085051Swyllys if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK &&
33095051Swyllys rv != KMF_ERR_EXTENSION_NOT_FOUND)
33105051Swyllys goto cleanup;
33115051Swyllys
33125051Swyllys kufound = (rv == KMF_OK);
33135051Swyllys rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */
33145051Swyllys }
33155051Swyllys
33163089Swyllys /*
33173089Swyllys * Only set the KeyUsage stuff if the KU extension was present.
33183089Swyllys */
33193089Swyllys if (kufound) {
33203089Swyllys CK_BBOOL condition;
33213089Swyllys
33223089Swyllys condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ?
33235051Swyllys B_TRUE : B_FALSE;
33245051Swyllys SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL));
33255051Swyllys i++;
33263089Swyllys condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ?
33275051Swyllys B_TRUE : B_FALSE;
33285051Swyllys SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL));
33295051Swyllys i++;
33303089Swyllys condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
33315051Swyllys B_TRUE : B_FALSE;
33325051Swyllys SETATTR(templ, i, CKA_SIGN, &condition, sizeof (CK_BBOOL));
33335051Swyllys i++;
33343089Swyllys condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
33355051Swyllys B_TRUE : B_FALSE;
33363089Swyllys SETATTR(templ, i, CKA_SIGN_RECOVER, &condition,
33375051Swyllys sizeof (CK_BBOOL));
33383089Swyllys i++;
33395051Swyllys
33403089Swyllys }
33415051Swyllys
33425051Swyllys if (keylabel != NULL) {
33435051Swyllys SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
33443089Swyllys i++;
33453089Swyllys }
33465536Swyllys if (id.Data == NULL && rawkey->id.Data != NULL) {
33475536Swyllys SETATTR(templ, i, CKA_ID, rawkey->id.Data,
33485536Swyllys rawkey->id.Length);
33495536Swyllys i++;
33505536Swyllys }
33513089Swyllys if (keytype == CKK_RSA) {
33523089Swyllys SETATTR(templ, i, CKA_MODULUS,
33535051Swyllys rawkey->rawdata.rsa.mod.val,
33545051Swyllys rawkey->rawdata.rsa.mod.len);
33553089Swyllys i++;
33563089Swyllys SETATTR(templ, i, CKA_PUBLIC_EXPONENT,
33575051Swyllys rawkey->rawdata.rsa.pubexp.val,
33585051Swyllys rawkey->rawdata.rsa.pubexp.len);
33593089Swyllys i++;
33603089Swyllys if (rawkey->rawdata.rsa.priexp.val != NULL) {
33613089Swyllys SETATTR(templ, i, CKA_PRIVATE_EXPONENT,
33625051Swyllys rawkey->rawdata.rsa.priexp.val,
33635051Swyllys rawkey->rawdata.rsa.priexp.len);
33643089Swyllys i++;
33653089Swyllys }
33663089Swyllys if (rawkey->rawdata.rsa.prime1.val != NULL) {
33673089Swyllys SETATTR(templ, i, CKA_PRIME_1,
33685051Swyllys rawkey->rawdata.rsa.prime1.val,
33695051Swyllys rawkey->rawdata.rsa.prime1.len);
33703089Swyllys i++;
33713089Swyllys }
33723089Swyllys if (rawkey->rawdata.rsa.prime2.val != NULL) {
33733089Swyllys SETATTR(templ, i, CKA_PRIME_2,
33745051Swyllys rawkey->rawdata.rsa.prime2.val,
33755051Swyllys rawkey->rawdata.rsa.prime2.len);
33763089Swyllys i++;
33773089Swyllys }
33783089Swyllys if (rawkey->rawdata.rsa.exp1.val != NULL) {
33793089Swyllys SETATTR(templ, i, CKA_EXPONENT_1,
33805051Swyllys rawkey->rawdata.rsa.exp1.val,
33815051Swyllys rawkey->rawdata.rsa.exp1.len);
33823089Swyllys i++;
33833089Swyllys }
33843089Swyllys if (rawkey->rawdata.rsa.exp2.val != NULL) {
33853089Swyllys SETATTR(templ, i, CKA_EXPONENT_2,
33865051Swyllys rawkey->rawdata.rsa.exp2.val,
33875051Swyllys rawkey->rawdata.rsa.exp2.len);
33883089Swyllys i++;
33893089Swyllys }
33903089Swyllys if (rawkey->rawdata.rsa.coef.val != NULL) {
33913089Swyllys SETATTR(templ, i, CKA_COEFFICIENT,
33925051Swyllys rawkey->rawdata.rsa.coef.val,
33935051Swyllys rawkey->rawdata.rsa.coef.len);
33943089Swyllys i++;
33953089Swyllys }
339611973Swyllys.ingersoll@sun.com } else if (keytype == CKK_DSA) {
33973089Swyllys SETATTR(templ, i, CKA_PRIME,
33985051Swyllys rawkey->rawdata.dsa.prime.val,
33995051Swyllys rawkey->rawdata.dsa.prime.len);
34003089Swyllys i++;
34013089Swyllys SETATTR(templ, i, CKA_SUBPRIME,
34025051Swyllys rawkey->rawdata.dsa.subprime.val,
34035051Swyllys rawkey->rawdata.dsa.subprime.len);
34043089Swyllys i++;
34053089Swyllys SETATTR(templ, i, CKA_BASE,
34065051Swyllys rawkey->rawdata.dsa.base.val,
34075051Swyllys rawkey->rawdata.dsa.base.len);
34083089Swyllys i++;
34093089Swyllys SETATTR(templ, i, CKA_VALUE,
34105051Swyllys rawkey->rawdata.dsa.value.val,
34115051Swyllys rawkey->rawdata.dsa.value.len);
34123089Swyllys i++;
341311973Swyllys.ingersoll@sun.com } else if (keytype == CKK_EC) {
341411973Swyllys.ingersoll@sun.com SETATTR(templ, i, CKA_SIGN, &cktrue, sizeof (cktrue));
341511973Swyllys.ingersoll@sun.com i++;
341611973Swyllys.ingersoll@sun.com SETATTR(templ, i, CKA_DERIVE, &cktrue, sizeof (cktrue));
341711973Swyllys.ingersoll@sun.com i++;
341811973Swyllys.ingersoll@sun.com SETATTR(templ, i, CKA_VALUE,
341911973Swyllys.ingersoll@sun.com rawkey->rawdata.ec.value.val,
342011973Swyllys.ingersoll@sun.com rawkey->rawdata.ec.value.len);
342111973Swyllys.ingersoll@sun.com i++;
342211973Swyllys.ingersoll@sun.com SETATTR(templ, i, CKA_EC_PARAMS,
342311973Swyllys.ingersoll@sun.com rawkey->rawdata.ec.params.Data,
342411973Swyllys.ingersoll@sun.com rawkey->rawdata.ec.params.Length);
342511973Swyllys.ingersoll@sun.com i++;
34263089Swyllys }
34273089Swyllys
34283089Swyllys ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj);
34293089Swyllys if (ckrv != CKR_OK) {
34303089Swyllys SET_ERROR(kmfh, ckrv);
34313089Swyllys
34323089Swyllys /* Report authentication failures to the caller */
34333089Swyllys if (ckrv == CKR_USER_NOT_LOGGED_IN ||
34343089Swyllys ckrv == CKR_PIN_INCORRECT ||
34353089Swyllys ckrv == CKR_PIN_INVALID ||
34363089Swyllys ckrv == CKR_PIN_EXPIRED ||
34373089Swyllys ckrv == CKR_PIN_LOCKED ||
34383089Swyllys ckrv == CKR_SESSION_READ_ONLY)
34393089Swyllys rv = KMF_ERR_AUTH_FAILED;
34403089Swyllys else
34413089Swyllys rv = KMF_ERR_INTERNAL;
34423089Swyllys }
34433089Swyllys cleanup:
34445536Swyllys if (start != NULL)
34455536Swyllys free(start);
34465536Swyllys if (end != NULL)
34475536Swyllys free(end);
34485051Swyllys kmf_free_data(&id);
34495051Swyllys kmf_free_data(&subject);
34505051Swyllys kmf_free_signed_cert(x509);
34513089Swyllys free(x509);
34523089Swyllys
34533089Swyllys return (rv);
34543089Swyllys }
34553089Swyllys
34563089Swyllys KMF_RETURN
KMFPK11_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)34575051Swyllys KMFPK11_CreateSymKey(KMF_HANDLE_T handle,
34585051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
34593089Swyllys {
34603089Swyllys KMF_RETURN rv = KMF_OK;
34613089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
34623089Swyllys CK_RV ckrv;
34633089Swyllys CK_SESSION_HANDLE hSession = kmfh->pk11handle;
34643089Swyllys CK_OBJECT_HANDLE keyhandle;
34653089Swyllys CK_MECHANISM keyGenMech;
34663089Swyllys CK_OBJECT_CLASS class = CKO_SECRET_KEY;
34673089Swyllys CK_ULONG secKeyType;
34683089Swyllys CK_ULONG secKeyLen; /* for RC4 and AES */
34693089Swyllys CK_BBOOL true = TRUE;
34703089Swyllys CK_BBOOL false = FALSE;
34713089Swyllys CK_ATTRIBUTE templ[15];
34725051Swyllys CK_BYTE *keydata = NULL;
34735051Swyllys int i = 0;
34745051Swyllys KMF_KEY_HANDLE *symkey;
34755051Swyllys KMF_KEY_ALG keytype;
34765051Swyllys uint32_t keylen = 0;
34775051Swyllys uint32_t attrkeylen = 0;
34785051Swyllys uint32_t keylen_size = sizeof (uint32_t);
34795051Swyllys char *keylabel = NULL;
34806051Swyllys KMF_CREDENTIAL *cred = NULL;
34815051Swyllys uint32_t is_sensitive = B_FALSE;
34825051Swyllys uint32_t is_not_extractable = B_FALSE;
34833089Swyllys
34843089Swyllys if (kmfh == NULL)
34853089Swyllys return (KMF_ERR_UNINITIALIZED);
34863089Swyllys
34873089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
34883089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
34893089Swyllys
34905051Swyllys symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
34915051Swyllys if (symkey == NULL)
34925051Swyllys return (KMF_ERR_BAD_PARAMETER);
34935051Swyllys
34945051Swyllys rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
34955051Swyllys (void *)&keytype, NULL);
34965051Swyllys if (rv != KMF_OK)
34975051Swyllys return (KMF_ERR_BAD_PARAMETER);
34985051Swyllys
34995051Swyllys keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
35005051Swyllys if (keylabel == NULL)
35013089Swyllys return (KMF_ERR_BAD_PARAMETER);
35025051Swyllys
35035051Swyllys rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
35045051Swyllys (void *)&is_sensitive, NULL);
35055051Swyllys if (rv != KMF_OK)
35065051Swyllys return (KMF_ERR_BAD_PARAMETER);
35075051Swyllys
35085051Swyllys rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
35095051Swyllys (void *)&is_not_extractable, NULL);
35105051Swyllys if (rv != KMF_OK)
35115051Swyllys return (KMF_ERR_BAD_PARAMETER);
35125051Swyllys
35133812Shylee /*
35143812Shylee * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key.
35153812Shylee *
35163812Shylee * For a generic secret key, because it may not be supported in
35173812Shylee * C_GenerateKey() for some PKCS11 providers, we will handle it
35183812Shylee * differently.
35193812Shylee */
35205051Swyllys if (keytype == KMF_GENERIC_SECRET) {
35215051Swyllys rv = create_generic_secret_key(handle, numattr,
35225051Swyllys attrlist, &keyhandle);
35233812Shylee if (rv != KMF_OK)
35243812Shylee goto out;
35253812Shylee else
35263812Shylee goto setup;
35273812Shylee }
35283812Shylee
35295051Swyllys rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
35305051Swyllys NULL, &attrkeylen);
35315051Swyllys if (rv == KMF_OK && attrkeylen > 0) {
35325051Swyllys keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
35335051Swyllys numattr);
35345051Swyllys } else {
35355051Swyllys keydata = NULL;
35365051Swyllys attrkeylen = 0;
35375051Swyllys rv = KMF_OK;
35385051Swyllys }
35395051Swyllys if (keydata != NULL) {
35405051Swyllys if (keytype == KMF_DES && attrkeylen != 8) {
35415051Swyllys rv = KMF_ERR_BAD_KEY_SIZE;
35425051Swyllys goto out;
35435051Swyllys }
35445051Swyllys if (keytype == KMF_DES3 && attrkeylen != 24) {
35455051Swyllys rv = KMF_ERR_BAD_KEY_SIZE;
35465051Swyllys goto out;
35475051Swyllys }
35485051Swyllys /*
35495051Swyllys * This may override what the user gave on the
35505051Swyllys * command line.
35515051Swyllys */
35525051Swyllys keylen = attrkeylen * 8; /* bytes to bits */
35535051Swyllys } else {
35545051Swyllys /*
35555051Swyllys * If keydata was not given, key length must be
35565051Swyllys * provided.
35575051Swyllys */
35585051Swyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
35595051Swyllys &keylen, &keylen_size);
35605051Swyllys if (rv == KMF_ERR_ATTR_NOT_FOUND &&
35615051Swyllys (keytype == KMF_DES || keytype == KMF_DES3))
35625051Swyllys /* keylength is not required for DES and 3DES */
35635051Swyllys rv = KMF_OK;
35645051Swyllys if (rv != KMF_OK)
35655051Swyllys return (KMF_ERR_BAD_PARAMETER);
35665051Swyllys }
35675051Swyllys
35685051Swyllys if ((keylen % 8) != 0) {
35695051Swyllys return (KMF_ERR_BAD_KEY_SIZE);
35705051Swyllys }
35715051Swyllys secKeyLen = keylen / 8; /* in bytes for RC4/AES */
35725051Swyllys
35735051Swyllys /*
35745051Swyllys * Only set CKA_VALUE_LEN if the key data was not given and
35755051Swyllys * we are creating an RC4 or AES key.
35765051Swyllys */
35775051Swyllys if (keydata == NULL &&
35785051Swyllys (keytype == KMF_AES || keytype == KMF_RC4)) {
35795051Swyllys SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen,
35805051Swyllys sizeof (secKeyLen));
35815051Swyllys i++;
35825051Swyllys }
35835051Swyllys
35843812Shylee /* Other keytypes */
35853089Swyllys keyGenMech.pParameter = NULL_PTR;
35863089Swyllys keyGenMech.ulParameterLen = 0;
35875051Swyllys switch (keytype) {
35885051Swyllys case KMF_AES:
35895051Swyllys keyGenMech.mechanism = CKM_AES_KEY_GEN;
35905051Swyllys secKeyType = CKK_AES;
35915051Swyllys break;
35925051Swyllys case KMF_RC4:
35935051Swyllys keyGenMech.mechanism = CKM_RC4_KEY_GEN;
35945051Swyllys secKeyType = CKK_RC4;
35955051Swyllys break;
35965051Swyllys case KMF_DES:
35975051Swyllys keyGenMech.mechanism = CKM_DES_KEY_GEN;
35985051Swyllys secKeyType = CKK_DES;
35995051Swyllys break;
36005051Swyllys case KMF_DES3:
36015051Swyllys keyGenMech.mechanism = CKM_DES3_KEY_GEN;
36025051Swyllys secKeyType = CKK_DES3;
36035051Swyllys break;
36045051Swyllys default:
36055051Swyllys return (KMF_ERR_BAD_KEY_TYPE);
36063089Swyllys }
36075051Swyllys if (keydata != NULL) {
36085051Swyllys SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen);
36095051Swyllys i++;
36105051Swyllys }
36113089Swyllys SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
36123089Swyllys i++;
36133089Swyllys SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
36143089Swyllys i++;
36153089Swyllys
36165051Swyllys if (keylabel != NULL) {
36175051Swyllys SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
36183089Swyllys i++;
36193089Swyllys }
36203089Swyllys
36215051Swyllys if (is_sensitive == B_TRUE) {
36223089Swyllys SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
36233089Swyllys } else {
36243089Swyllys SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
36253089Swyllys }
36263089Swyllys i++;
36273089Swyllys
36285051Swyllys if (is_not_extractable == B_TRUE) {
36293089Swyllys SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
36303089Swyllys } else {
36313089Swyllys SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
36323089Swyllys }
36333089Swyllys i++;
36343089Swyllys
36353089Swyllys SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
36363089Swyllys i++;
36373089Swyllys SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
36383089Swyllys i++;
36393089Swyllys SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true));
36403089Swyllys i++;
36413089Swyllys SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true));
36423089Swyllys i++;
36433089Swyllys SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
36443089Swyllys i++;
36453089Swyllys SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true));
36463089Swyllys i++;
36473089Swyllys
36486051Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
36496051Swyllys if (cred == NULL)
36505051Swyllys return (KMF_ERR_BAD_PARAMETER);
36515051Swyllys
36526051Swyllys rv = pk11_authenticate(handle, cred);
36533089Swyllys if (rv != KMF_OK) {
36543089Swyllys return (rv);
36553089Swyllys }
36563089Swyllys
36575051Swyllys /* If the key data was given, use C_CreateObject */
36585051Swyllys if (keydata != NULL) {
36595051Swyllys ckrv = C_CreateObject(hSession, templ, i, &keyhandle);
36605051Swyllys } else {
36615051Swyllys ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i,
36625051Swyllys &keyhandle);
36635051Swyllys }
36643089Swyllys if (ckrv != CKR_OK) {
36656354Swyllys if (ckrv == CKR_USER_NOT_LOGGED_IN ||
36666354Swyllys ckrv == CKR_PIN_INCORRECT ||
36676354Swyllys ckrv == CKR_PIN_INVALID ||
36686354Swyllys ckrv == CKR_PIN_EXPIRED ||
36696354Swyllys ckrv == CKR_PIN_LOCKED ||
36706354Swyllys ckrv == CKR_SESSION_READ_ONLY)
36716354Swyllys rv = KMF_ERR_AUTH_FAILED;
36726354Swyllys else
36736354Swyllys rv = KMF_ERR_KEYGEN_FAILED;
36743089Swyllys SET_ERROR(kmfh, ckrv);
36753089Swyllys goto out;
36763089Swyllys }
36773089Swyllys
36783812Shylee setup:
36793089Swyllys symkey->kstype = KMF_KEYSTORE_PK11TOKEN;
36805051Swyllys symkey->keyalg = keytype;
36813089Swyllys symkey->keyclass = KMF_SYMMETRIC;
36823089Swyllys symkey->israw = FALSE;
36833089Swyllys symkey->keyp = (void *)keyhandle;
36843089Swyllys
36853089Swyllys out:
36863089Swyllys return (rv);
36873089Swyllys }
36883089Swyllys
36893089Swyllys KMF_RETURN
KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)36903089Swyllys KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
36913089Swyllys KMF_RAW_SYM_KEY *rkey)
36923089Swyllys {
36933089Swyllys KMF_RETURN rv = KMF_OK;
36943089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
36953089Swyllys
36963089Swyllys if (kmfh == NULL)
36973089Swyllys return (KMF_ERR_UNINITIALIZED);
36983089Swyllys
36993089Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
37003089Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
37013089Swyllys
37023089Swyllys if (symkey == NULL || rkey == NULL)
37033089Swyllys return (KMF_ERR_BAD_PARAMETER);
37043089Swyllys else if (symkey->keyclass != KMF_SYMMETRIC)
37053089Swyllys return (KMF_ERR_BAD_KEY_CLASS);
37063089Swyllys
37075051Swyllys /*
37085051Swyllys * If the key is already in "raw" format, copy the data
37095051Swyllys * to the new record if possible.
37105051Swyllys */
37113089Swyllys if (symkey->israw) {
37123089Swyllys KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
37133089Swyllys
37145051Swyllys if (rawkey == NULL)
37155051Swyllys return (KMF_ERR_BAD_KEYHANDLE);
37165051Swyllys if (rawkey->sensitive)
37175051Swyllys return (KMF_ERR_SENSITIVE_KEY);
37185051Swyllys if (rawkey->not_extractable)
37195051Swyllys return (KMF_ERR_UNEXTRACTABLE_KEY);
37205051Swyllys
37215051Swyllys if (rawkey->rawdata.sym.keydata.val == NULL ||
37223089Swyllys rawkey->rawdata.sym.keydata.len == 0)
37235051Swyllys return (KMF_ERR_GETKEYVALUE_FAILED);
37243089Swyllys
37253089Swyllys rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
37263089Swyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
37273089Swyllys return (KMF_ERR_MEMORY);
37283089Swyllys (void) memcpy(rkey->keydata.val,
37295051Swyllys rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
37303089Swyllys } else {
37313089Swyllys rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey);
37323089Swyllys }
37333089Swyllys
37343089Swyllys return (rv);
37353089Swyllys }
37363089Swyllys
37373089Swyllys KMF_RETURN
KMFPK11_SetTokenPin(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)37385051Swyllys KMFPK11_SetTokenPin(KMF_HANDLE_T handle,
37395051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
37403089Swyllys {
37413089Swyllys KMF_RETURN ret = KMF_OK;
37423089Swyllys CK_RV rv = CKR_OK;
37433089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
37443089Swyllys CK_SESSION_HANDLE session = NULL;
37456051Swyllys KMF_CREDENTIAL *oldcred;
37466051Swyllys KMF_CREDENTIAL *newcred;
37475051Swyllys CK_SLOT_ID slotid;
37489126SWyllys.Ingersoll@Sun.COM CK_USER_TYPE user = CKU_USER;
37495051Swyllys
37505051Swyllys if (handle == NULL || attrlist == NULL || numattr == 0)
37515051Swyllys return (KMF_ERR_BAD_PARAMETER);
37525051Swyllys
37536051Swyllys oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
37546051Swyllys if (oldcred == NULL)
37555051Swyllys return (KMF_ERR_BAD_PARAMETER);
37565051Swyllys
37576051Swyllys newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr);
37586051Swyllys if (newcred == NULL)
37593089Swyllys return (KMF_ERR_BAD_PARAMETER);
37603089Swyllys
37615051Swyllys rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr,
37625051Swyllys (void *)&slotid, NULL);
37635051Swyllys if (rv != KMF_OK) {
37645051Swyllys char *tokenlabel = NULL;
37655051Swyllys /*
37665051Swyllys * If a slot wasn't given, the user must pass
37675051Swyllys * a token label so we can find the slot here.
37685051Swyllys */
37696051Swyllys tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
37706051Swyllys numattr);
37716051Swyllys if (tokenlabel == NULL)
37726051Swyllys return (KMF_ERR_BAD_PARAMETER);
37735051Swyllys
37745051Swyllys rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid);
37755051Swyllys if (rv != KMF_OK)
37765051Swyllys return (rv);
37775051Swyllys }
37789126SWyllys.Ingersoll@Sun.COM rv = kmf_get_attr(KMF_PK11_USER_TYPE_ATTR, attrlist, numattr,
37799126SWyllys.Ingersoll@Sun.COM (void *)&user, NULL);
37809126SWyllys.Ingersoll@Sun.COM if (rv != CKR_OK)
37819126SWyllys.Ingersoll@Sun.COM user = CKU_USER;
37825051Swyllys
37835051Swyllys rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION,
37845051Swyllys NULL, NULL, &session);
37853089Swyllys if (rv != CKR_OK) {
37863089Swyllys SET_ERROR(kmfh, rv);
37873089Swyllys ret = KMF_ERR_UNINITIALIZED;
37883089Swyllys goto end;
37893089Swyllys }
37903089Swyllys
37919126SWyllys.Ingersoll@Sun.COM rv = C_Login(session, user, (CK_BYTE *)oldcred->cred,
37929126SWyllys.Ingersoll@Sun.COM oldcred->credlen);
37939126SWyllys.Ingersoll@Sun.COM if (rv != CKR_OK) {
37949126SWyllys.Ingersoll@Sun.COM SET_ERROR(kmfh, rv);
37959126SWyllys.Ingersoll@Sun.COM if (rv == CKR_PIN_INCORRECT ||
37969126SWyllys.Ingersoll@Sun.COM rv == CKR_PIN_INVALID ||
37979126SWyllys.Ingersoll@Sun.COM rv == CKR_PIN_EXPIRED ||
37989126SWyllys.Ingersoll@Sun.COM rv == CKR_PIN_LOCKED)
37999126SWyllys.Ingersoll@Sun.COM ret = KMF_ERR_AUTH_FAILED;
38009126SWyllys.Ingersoll@Sun.COM else
38019126SWyllys.Ingersoll@Sun.COM ret = KMF_ERR_INTERNAL;
38029126SWyllys.Ingersoll@Sun.COM
38039126SWyllys.Ingersoll@Sun.COM goto end;
38049126SWyllys.Ingersoll@Sun.COM }
38059126SWyllys.Ingersoll@Sun.COM
38063089Swyllys rv = C_SetPIN(session,
38076051Swyllys (CK_BYTE *)oldcred->cred, oldcred->credlen,
38086051Swyllys (CK_BYTE *)newcred->cred, newcred->credlen);
38093089Swyllys
38103089Swyllys if (rv != CKR_OK) {
38113089Swyllys SET_ERROR(kmfh, rv);
38123089Swyllys if (rv == CKR_PIN_INCORRECT ||
38133089Swyllys rv == CKR_PIN_INVALID ||
38143089Swyllys rv == CKR_PIN_EXPIRED ||
38153089Swyllys rv == CKR_PIN_LOCKED)
38163089Swyllys ret = KMF_ERR_AUTH_FAILED;
38173089Swyllys else
38183089Swyllys ret = KMF_ERR_INTERNAL;
38193089Swyllys }
38203089Swyllys end:
38213089Swyllys if (session != NULL)
38223089Swyllys (void) C_CloseSession(session);
38233089Swyllys return (ret);
38243089Swyllys }
38253754Swyllys
38263754Swyllys static KMF_RETURN
create_generic_secret_key(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist,CK_OBJECT_HANDLE * key)38273812Shylee create_generic_secret_key(KMF_HANDLE_T handle,
38285051Swyllys int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key)
38293812Shylee {
38303812Shylee KMF_RETURN rv = KMF_OK;
38313812Shylee KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
38323812Shylee CK_RV ckrv;
38333812Shylee CK_SESSION_HANDLE hSession = kmfh->pk11handle;
38343812Shylee CK_OBJECT_CLASS class = CKO_SECRET_KEY;
38353812Shylee CK_ULONG secKeyType = CKK_GENERIC_SECRET;
38363812Shylee CK_ULONG secKeyLen;
38373812Shylee CK_BBOOL true = TRUE;
38383812Shylee CK_BBOOL false = FALSE;
38393812Shylee CK_ATTRIBUTE templ[15];
38403812Shylee int i;
38413812Shylee int random_fd = -1;
38423812Shylee int nread;
38435051Swyllys int freebuf = 0;
38443812Shylee char *buf = NULL;
38455051Swyllys uint32_t keylen = 0, attrkeylen = 0;
38465051Swyllys char *keylabel = NULL;
38475051Swyllys KMF_CREDENTIAL *cred;
38485051Swyllys uint32_t is_sensitive, is_not_extractable;
38495051Swyllys
38505051Swyllys keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
38515051Swyllys if (keylabel == NULL)
38525051Swyllys return (KMF_ERR_BAD_PARAMETER);
38535051Swyllys
38545051Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
38555051Swyllys if (cred == NULL)
38565051Swyllys return (KMF_ERR_BAD_PARAMETER);
38575051Swyllys
38585051Swyllys rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
38595051Swyllys (void *)&is_sensitive, NULL);
38605051Swyllys if (rv != KMF_OK)
38615051Swyllys return (KMF_ERR_BAD_PARAMETER);
38625051Swyllys
38635051Swyllys rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
38645051Swyllys (void *)&is_not_extractable, NULL);
38655051Swyllys if (rv != KMF_OK)
38665051Swyllys return (KMF_ERR_BAD_PARAMETER);
38675051Swyllys
38685051Swyllys rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
38695051Swyllys NULL, &attrkeylen);
38705051Swyllys if (rv == KMF_OK && attrkeylen > 0) {
38715051Swyllys buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
38725051Swyllys numattr);
38735051Swyllys secKeyLen = attrkeylen;
38743812Shylee } else {
38755051Swyllys buf = NULL;
38765051Swyllys rv = KMF_OK;
38773812Shylee }
38785051Swyllys if (buf == NULL) {
38795051Swyllys /*
38805051Swyllys * If the key data was not given, key length must
38815051Swyllys * be provided.
38825051Swyllys */
38835051Swyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
38845051Swyllys &keylen, NULL);
38855051Swyllys if (rv != KMF_OK)
38865051Swyllys return (KMF_ERR_BAD_PARAMETER);
38875051Swyllys
38885051Swyllys /*
38895051Swyllys * Check the key size.
38905051Swyllys */
38915051Swyllys if ((keylen % 8) != 0) {
38925051Swyllys return (KMF_ERR_BAD_KEY_SIZE);
38935051Swyllys } else {
38945051Swyllys secKeyLen = keylen/8; /* in bytes */
38955051Swyllys }
38965051Swyllys
38975051Swyllys /*
38985051Swyllys * Generate a random number with the key size first.
38995051Swyllys */
39005051Swyllys buf = malloc(secKeyLen);
39015051Swyllys if (buf == NULL)
39025051Swyllys return (KMF_ERR_MEMORY);
39035051Swyllys
39045051Swyllys freebuf = 1;
39055051Swyllys while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) {
39065051Swyllys if (errno != EINTR)
39075051Swyllys break;
39085051Swyllys }
39095051Swyllys
39105051Swyllys if (random_fd < 0) {
39115051Swyllys rv = KMF_ERR_KEYGEN_FAILED;
39125051Swyllys goto out;
39135051Swyllys }
39145051Swyllys
39155051Swyllys nread = read(random_fd, buf, secKeyLen);
39165051Swyllys if (nread <= 0 || nread != secKeyLen) {
39175051Swyllys rv = KMF_ERR_KEYGEN_FAILED;
39185051Swyllys goto out;
39195051Swyllys }
39203812Shylee }
39213812Shylee
39223812Shylee /*
39233812Shylee * Authenticate into the token and call C_CreateObject to generate
39243812Shylee * a generic secret token key.
39253812Shylee */
39265051Swyllys rv = pk11_authenticate(handle, cred);
39273812Shylee if (rv != KMF_OK) {
39283812Shylee goto out;
39293812Shylee }
39303812Shylee
39313812Shylee i = 0;
39323812Shylee SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
39333812Shylee i++;
39343812Shylee SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
39353812Shylee i++;
39363812Shylee SETATTR(templ, i, CKA_VALUE, buf, secKeyLen);
39373812Shylee i++;
39383812Shylee
39395051Swyllys if (keylabel != NULL) {
39405051Swyllys SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
39413812Shylee i++;
39423812Shylee }
39433812Shylee
39445051Swyllys if (is_sensitive == B_TRUE) {
39453812Shylee SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
39463812Shylee } else {
39473812Shylee SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
39483812Shylee }
39493812Shylee i++;
39503812Shylee
39515051Swyllys if (is_not_extractable == B_TRUE) {
39523812Shylee SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
39533812Shylee } else {
39543812Shylee SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
39553812Shylee }
39563812Shylee i++;
39573812Shylee
39583812Shylee SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
39593812Shylee i++;
39603812Shylee SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
39613812Shylee i++;
39623812Shylee SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
39633812Shylee i++;
39643812Shylee
39653812Shylee ckrv = C_CreateObject(hSession, templ, i, key);
39663812Shylee if (ckrv != CKR_OK) {
39676354Swyllys if (ckrv == CKR_USER_NOT_LOGGED_IN ||
39686354Swyllys ckrv == CKR_PIN_INCORRECT ||
39696354Swyllys ckrv == CKR_PIN_INVALID ||
39706354Swyllys ckrv == CKR_PIN_EXPIRED ||
39716354Swyllys ckrv == CKR_PIN_LOCKED ||
39726354Swyllys ckrv == CKR_SESSION_READ_ONLY)
39736354Swyllys rv = KMF_ERR_AUTH_FAILED;
39746354Swyllys else
39756354Swyllys rv = KMF_ERR_KEYGEN_FAILED;
39763812Shylee SET_ERROR(kmfh, ckrv);
39773812Shylee }
39783812Shylee
39793812Shylee out:
39805051Swyllys if (buf != NULL && freebuf)
39813812Shylee free(buf);
39823812Shylee
39833812Shylee if (random_fd != -1)
39843812Shylee (void) close(random_fd);
39853812Shylee
39863812Shylee return (rv);
39873812Shylee }
39885051Swyllys
39895051Swyllys KMF_RETURN
KMFPK11_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)39905051Swyllys KMFPK11_StoreKey(KMF_HANDLE_T handle,
39915051Swyllys int numattr,
39925051Swyllys KMF_ATTRIBUTE *attlist)
39935051Swyllys {
39945051Swyllys KMF_RETURN rv = KMF_OK;
39955051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
39965051Swyllys KMF_CREDENTIAL cred = {NULL, 0};
39975051Swyllys KMF_KEY_HANDLE *key;
39985814Swyllys KMF_RAW_KEY_DATA *rawkey = NULL;
39995051Swyllys CK_BBOOL btrue = TRUE;
40005051Swyllys CK_ATTRIBUTE tokenattr[1];
40015051Swyllys CK_OBJECT_HANDLE newobj;
40025051Swyllys CK_RV ckrv;
40035051Swyllys
40045051Swyllys if (kmfh == NULL)
40055051Swyllys return (KMF_ERR_UNINITIALIZED);
40065051Swyllys
40075051Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
40085051Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
40095051Swyllys
40105051Swyllys rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr,
40115051Swyllys (void *)&cred, NULL);
40125051Swyllys if (rv != KMF_OK)
40135051Swyllys return (KMF_ERR_BAD_PARAMETER);
40145051Swyllys
40155051Swyllys rv = pk11_authenticate(handle, &cred);
40165051Swyllys if (rv != KMF_OK)
40175051Swyllys return (rv);
40185051Swyllys
40195051Swyllys key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
40205051Swyllys if (key == NULL) {
40215051Swyllys key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist,
40225051Swyllys numattr);
40235051Swyllys if (key == NULL)
40245051Swyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist,
40255051Swyllys numattr);
40265051Swyllys }
40275051Swyllys if (key == NULL && rawkey == NULL)
40285051Swyllys return (KMF_ERR_ATTR_NOT_FOUND);
40295051Swyllys
40305051Swyllys if (rawkey != NULL) {
40315051Swyllys rv = store_raw_key(handle, attlist, numattr, rawkey);
40325051Swyllys } else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) {
40335051Swyllys
40345051Swyllys SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue));
40355051Swyllys /* Copy the key object to the token */
40365051Swyllys ckrv = C_CopyObject(kmfh->pk11handle,
40375051Swyllys (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj);
40385051Swyllys if (ckrv != CKR_OK) {
40395051Swyllys SET_ERROR(kmfh, ckrv);
40405051Swyllys return (KMF_ERR_INTERNAL);
40415051Swyllys }
40425051Swyllys
40435051Swyllys /* Replace the object handle with the new token-based one */
40445051Swyllys ckrv = C_DestroyObject(kmfh->pk11handle,
40455051Swyllys (CK_OBJECT_HANDLE)key->keyp);
40465051Swyllys if (ckrv != CKR_OK) {
40475051Swyllys SET_ERROR(kmfh, ckrv);
40485051Swyllys return (KMF_ERR_INTERNAL);
40495051Swyllys }
40505051Swyllys key->keyp = (void *)newobj;
40515051Swyllys } else {
40525051Swyllys rv = KMF_ERR_BAD_PARAMETER;
40535051Swyllys }
40545051Swyllys
40555051Swyllys return (rv);
40565051Swyllys }
40575051Swyllys
40585051Swyllys
40595051Swyllys KMF_RETURN
KMFPK11_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)40605051Swyllys KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
40615051Swyllys {
40625051Swyllys KMF_RETURN rv = KMF_OK;
40635051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
40645051Swyllys KMF_CREDENTIAL *cred = NULL;
40655051Swyllys KMF_CREDENTIAL *p12cred = NULL;
40665051Swyllys char *filename = NULL;
40675051Swyllys KMF_X509_DER_CERT *certlist = NULL;
40685051Swyllys KMF_KEY_HANDLE *keylist = NULL;
40695051Swyllys uint32_t numcerts;
40705051Swyllys uint32_t numkeys;
40715051Swyllys char *certlabel = NULL;
40725051Swyllys char *issuer = NULL;
40735051Swyllys char *subject = NULL;
40745051Swyllys KMF_BIGINT *serial = NULL;
40755051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
40765051Swyllys KMF_ATTRIBUTE fc_attrlist[16];
40775051Swyllys int i;
40785051Swyllys
40795051Swyllys if (kmfh == NULL)
40805051Swyllys return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
40815051Swyllys
40825051Swyllys if (kmfh->pk11handle == CK_INVALID_HANDLE)
40835051Swyllys return (KMF_ERR_NO_TOKEN_SELECTED);
40845051Swyllys
40855051Swyllys /* First get the required attributes */
40865051Swyllys cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
40875051Swyllys if (cred == NULL)
40885051Swyllys return (KMF_ERR_BAD_PARAMETER);
40895051Swyllys
40905051Swyllys p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
40915051Swyllys if (p12cred == NULL)
40925051Swyllys return (KMF_ERR_BAD_PARAMETER);
40935051Swyllys
40945051Swyllys filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
40955051Swyllys numattr);
40965051Swyllys if (filename == NULL)
40975051Swyllys return (KMF_ERR_BAD_PARAMETER);
40985051Swyllys
40995051Swyllys /* Find all the certificates that match the searching criteria */
41005051Swyllys i = 0;
41015051Swyllys kmf_set_attr_at_index(fc_attrlist, i,
41025051Swyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
41035051Swyllys i++;
41045051Swyllys
41055051Swyllys kmf_set_attr_at_index(fc_attrlist, i,
41065051Swyllys KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
41075051Swyllys i++;
41085051Swyllys
41095051Swyllys certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
41105051Swyllys if (certlabel != NULL) {
41115051Swyllys kmf_set_attr_at_index(fc_attrlist, i,
41125051Swyllys KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
41135051Swyllys i++;
41145051Swyllys }
41155051Swyllys
41165051Swyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
41175051Swyllys if (issuer != NULL) {
41185051Swyllys kmf_set_attr_at_index(fc_attrlist, i,
41195051Swyllys KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
41205051Swyllys i++;
41215051Swyllys }
41225051Swyllys
41235051Swyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
41245051Swyllys if (subject != NULL) {
41255051Swyllys kmf_set_attr_at_index(fc_attrlist, i,
41265051Swyllys KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
41275051Swyllys i++;
41285051Swyllys }
41295051Swyllys
41305051Swyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
41315051Swyllys if (serial != NULL) {
41325051Swyllys kmf_set_attr_at_index(fc_attrlist, i,
41335051Swyllys KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
41345051Swyllys i++;
41355051Swyllys }
41365051Swyllys
41375051Swyllys rv = KMFPK11_FindCert(handle, i, fc_attrlist);
41385051Swyllys
41395051Swyllys if (rv == KMF_OK && numcerts > 0) {
41405051Swyllys certlist = (KMF_X509_DER_CERT *)malloc(numcerts *
41415051Swyllys sizeof (KMF_X509_DER_CERT));
41425051Swyllys if (certlist == NULL)
41435051Swyllys return (KMF_ERR_MEMORY);
41445051Swyllys
41455051Swyllys (void) memset(certlist, 0, numcerts *
41465051Swyllys sizeof (KMF_X509_DER_CERT));
41475051Swyllys
41485051Swyllys kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR,
41495051Swyllys certlist, sizeof (KMF_X509_DER_CERT));
41505051Swyllys i++;
41515051Swyllys
41525051Swyllys rv = kmf_find_cert(handle, i, fc_attrlist);
41535051Swyllys if (rv != KMF_OK) {
41545051Swyllys free(certlist);
41555051Swyllys return (rv);
41565051Swyllys }
41575051Swyllys } else {
41585051Swyllys return (rv);
41595051Swyllys }
41605051Swyllys
41615051Swyllys /* For each certificate, find the matching private key */
41625051Swyllys numkeys = 0;
41635051Swyllys for (i = 0; i < numcerts; i++) {
41645051Swyllys KMF_ATTRIBUTE fk_attrlist[16];
41655051Swyllys int j = 0;
41665051Swyllys KMF_KEY_HANDLE newkey;
41675051Swyllys KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY;
41685051Swyllys
41695051Swyllys kmf_set_attr_at_index(fk_attrlist, j,
41705051Swyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
41715051Swyllys j++;
41725051Swyllys
41735051Swyllys kmf_set_attr_at_index(fk_attrlist, j,
41745051Swyllys KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format));
41755051Swyllys j++;
41765051Swyllys
41775051Swyllys kmf_set_attr_at_index(fk_attrlist, j,
41785051Swyllys KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
41795051Swyllys j++;
41805051Swyllys
41815051Swyllys kmf_set_attr_at_index(fk_attrlist, j,
41825051Swyllys KMF_CERT_DATA_ATTR, &certlist[i].certificate,
41835051Swyllys sizeof (KMF_DATA));
41845051Swyllys j++;
41855051Swyllys
41865051Swyllys kmf_set_attr_at_index(fk_attrlist, j,
41875051Swyllys KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE));
41885051Swyllys j++;
41895051Swyllys
41905051Swyllys rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist);
41915051Swyllys if (rv == KMF_OK) {
41925051Swyllys numkeys++;
41935051Swyllys keylist = realloc(keylist,
41945051Swyllys numkeys * sizeof (KMF_KEY_HANDLE));
41955051Swyllys if (keylist == NULL) {
41965051Swyllys rv = KMF_ERR_MEMORY;
41975051Swyllys goto out;
41985051Swyllys }
41995051Swyllys keylist[numkeys - 1] = newkey;
42005051Swyllys } else if (rv == KMF_ERR_KEY_NOT_FOUND) {
42015051Swyllys /* it is OK if a key is not found */
42025051Swyllys rv = KMF_OK;
42035051Swyllys }
42045051Swyllys }
42055051Swyllys
42065051Swyllys if (rv != KMF_OK)
42075051Swyllys goto out;
42085051Swyllys
42095051Swyllys rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist,
42105051Swyllys p12cred, filename);
42115051Swyllys
42125051Swyllys out:
42135051Swyllys if (certlist != NULL) {
42145051Swyllys for (i = 0; i < numcerts; i++)
42155051Swyllys kmf_free_kmf_cert(handle, &certlist[i]);
42165051Swyllys free(certlist);
42175051Swyllys }
42185051Swyllys if (keylist != NULL) {
42195051Swyllys for (i = 0; i < numkeys; i++)
42205051Swyllys kmf_free_kmf_key(handle, &keylist[i]);
42215051Swyllys free(keylist);
42225051Swyllys }
42235051Swyllys
42245051Swyllys return (rv);
42255051Swyllys }
4226