/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c
C | 4225 lines | 3368 code | 563 blank | 294 comment | 1167 complexity | dcbe07d60444ede06d478e15ac2f7ed2 MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause, LGPL-2.0, 0BSD, AGPL-3.0, GPL-2.0, GPL-3.0, LGPL-2.1, LGPL-3.0, BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- /*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- * PKCS11 token KMF Plugin
- *
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
- */
- #include <stdio.h> /* debugging only */
- #include <errno.h>
- #include <values.h>
- #include <kmfapiP.h>
- #include <ber_der.h>
- #include <fcntl.h>
- #include <sha1.h>
- #include <bignum.h>
- #include <cryptoutil.h>
- #include <security/cryptoki.h>
- #include <security/pkcs11.h>
- #define DEV_RANDOM "/dev/random"
- #define SETATTR(t, n, atype, value, size) \
- t[n].type = atype; \
- t[n].pValue = (CK_BYTE *)value; \
- t[n].ulValueLen = (CK_ULONG)size;
- #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \
- h->lasterr.errcode = c;
- typedef struct _objlist {
- CK_OBJECT_HANDLE handle;
- struct _objlist *next;
- } OBJLIST;
- static KMF_RETURN
- search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *,
- boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *);
- static CK_RV
- getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **);
- static KMF_RETURN
- keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **);
- static KMF_RETURN
- create_generic_secret_key(KMF_HANDLE_T,
- int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *);
- KMF_RETURN
- KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- void
- KMFPK11_FreeKMFCert(KMF_HANDLE_T,
- KMF_X509_DER_CERT *kmf_cert);
- KMF_RETURN
- KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
- KMF_RETURN
- KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
- KMF_DATA *, KMF_DATA *);
- KMF_RETURN
- KMFPK11_GetErrorString(KMF_HANDLE_T, char **);
- KMF_RETURN
- KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
- KMF_DATA *, KMF_DATA *);
- KMF_RETURN
- KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
- KMF_RETURN
- KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- KMF_RETURN
- KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
- static
- KMF_PLUGIN_FUNCLIST pk11token_plugin_table =
- {
- 1, /* Version */
- KMFPK11_ConfigureKeystore,
- KMFPK11_FindCert,
- KMFPK11_FreeKMFCert,
- KMFPK11_StoreCert,
- KMFPK11_ImportCert,
- NULL, /* ImportCRL */
- KMFPK11_DeleteCert,
- NULL, /* DeleteCRL */
- KMFPK11_CreateKeypair,
- KMFPK11_FindKey,
- KMFPK11_EncodePubKeyData,
- KMFPK11_SignData,
- KMFPK11_DeleteKey,
- NULL, /* ListCRL */
- NULL, /* FindCRL */
- NULL, /* FindCertInCRL */
- KMFPK11_GetErrorString,
- KMFPK11_FindPrikeyByCert,
- KMFPK11_DecryptData,
- KMFPK11_ExportPK12,
- KMFPK11_CreateSymKey,
- KMFPK11_GetSymKeyValue,
- KMFPK11_SetTokenPin,
- KMFPK11_StoreKey,
- NULL /* Finalize */
- };
- KMF_PLUGIN_FUNCLIST *
- KMF_Plugin_Initialize()
- {
- return (&pk11token_plugin_table);
- }
- KMF_RETURN
- KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,
- int numattr, KMF_ATTRIBUTE *attrlist)
- {
- KMF_RETURN rv = KMF_OK;
- char *label;
- boolean_t readonly = B_TRUE;
- label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
- if (label == NULL) {
- return (KMF_ERR_BAD_PARAMETER);
- }
- /* "readonly" is optional. Default is TRUE */
- (void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr,
- (void *)&readonly, NULL);
- rv = kmf_select_token(handle, label, readonly);
- return (rv);
- }
- static KMF_RETURN
- pk11_authenticate(KMF_HANDLE_T handle,
- KMF_CREDENTIAL *cred)
- {
- CK_RV ck_rv = CKR_OK;
- CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle;
- if (hSession == NULL)
- return (KMF_ERR_NO_TOKEN_SELECTED);
- if (cred == NULL || cred->cred == NULL) {
- return (KMF_ERR_BAD_PARAMETER);
- }
- if ((ck_rv = C_Login(hSession, CKU_USER, (uchar_t *)cred->cred,
- cred->credlen)) != CKR_OK) {
- if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) {
- handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
- handle->lasterr.errcode = ck_rv;
- return (KMF_ERR_AUTH_FAILED);
- }
- }
- return (KMF_OK);
- }
- static KMF_RETURN
- PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
- KMF_X509_DER_CERT *kmfcert)
- {
- KMF_RETURN rv = 0;
- CK_RV ckrv = CKR_OK;
- CK_CERTIFICATE_TYPE cktype;
- CK_OBJECT_CLASS class;
- CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len;
- CK_BYTE *subject = NULL, *value = NULL;
- char *label = NULL;
- CK_ATTRIBUTE templ[10];
- (void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE));
- SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class));
- /* Is this a certificate object ? */
- ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
- if (ckrv != CKR_OK || class != CKO_CERTIFICATE) {
- SET_ERROR(kmfh, ckrv);
- return (KMF_ERR_INTERNAL);
- }
- SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype));
- ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
- if (ckrv != CKR_OK || cktype != CKC_X_509) {
- SET_ERROR(kmfh, ckrv);
- return (ckrv);
- } else {
- int i = 0;
- /* What attributes are available and how big are they? */
- subject_len = issuer_len = serno_len = id_len = value_len = 0;
- SETATTR(templ, i, CKA_SUBJECT, NULL, subject_len);
- i++;
- SETATTR(templ, i, CKA_ISSUER, NULL, issuer_len);
- i++;
- SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len);
- i++;
- SETATTR(templ, i, CKA_ID, NULL, id_len);
- i++;
- SETATTR(templ, i, CKA_VALUE, NULL, value_len);
- i++;
- /*
- * Query the object with NULL values in the pValue spot
- * so we know how much space to allocate for each field.
- */
- ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */
- }
- subject_len = templ[0].ulValueLen;
- issuer_len = templ[1].ulValueLen;
- serno_len = templ[2].ulValueLen;
- id_len = templ[3].ulValueLen;
- value_len = templ[4].ulValueLen;
- /*
- * For PKCS#11 CKC_X_509 certificate objects,
- * the following attributes must be defined.
- * CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER,
- * CKA_VALUE.
- */
- if (subject_len == 0 || issuer_len == 0 ||
- serno_len == 0 || value_len == 0) {
- return (KMF_ERR_INTERNAL);
- }
- /* Only fetch the value field if we are saving the data */
- if (kmfcert != NULL) {
- int i = 0;
- value = malloc(value_len);
- if (value == NULL) {
- rv = KMF_ERR_MEMORY;
- goto errout;
- }
- SETATTR(templ, i, CKA_VALUE, value, value_len);
- i++;
- /* re-query the object with room for the value attr */
- ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj,
- templ, i);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- rv = KMF_ERR_INTERNAL;
- goto errout;
- }
- kmfcert->certificate.Data = value;
- kmfcert->certificate.Length = value_len;
- kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED;
- kmfcert->kmf_private.keystore_type =
- KMF_KEYSTORE_PK11TOKEN;
- ckrv = getObjectLabel(kmfh, hObj, &label);
- if (ckrv == CKR_OK && label != NULL) {
- kmfcert->kmf_private.label = (char *)label;
- }
- rv = KMF_OK;
- }
- }
- errout:
- if (rv != KMF_OK) {
- if (subject)
- free(subject);
- if (value)
- free(value);
- if (kmfcert) {
- kmfcert->certificate.Data = NULL;
- kmfcert->certificate.Length = 0;
- }
- }
- return (rv);
- }
- static void
- free_objlist(OBJLIST *head)
- {
- OBJLIST *temp = head;
- while (temp != NULL) {
- head = head->next;
- free(temp);
- temp = head;
- }
- }
- /*
- * The caller should make sure that the templ->pValue is NULL since
- * it will be overwritten below.
- */
- static KMF_RETURN
- get_attr(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
- CK_ATTRIBUTE *templ)
- {
- CK_RV rv;
- rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
- if (rv != CKR_OK) {
- SET_ERROR(kmfh, rv);
- return (KMF_ERR_INTERNAL);
- }
- if (templ->ulValueLen > 0) {
- templ->pValue = malloc(templ->ulValueLen);
- if (templ->pValue == NULL)
- return (KMF_ERR_MEMORY);
- rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
- if (rv != CKR_OK) {
- SET_ERROR(kmfh, rv);
- return (KMF_ERR_INTERNAL);
- }
- }
- return (KMF_OK);
- }
- /*
- * Match a certificate with an issuer and/or subject name.
- * This is tricky because we cannot reliably compare DER encodings
- * because RDNs may have their AV-pairs in different orders even
- * if the values are the same. You must compare individual
- * AV pairs for the RDNs.
- *
- * RETURN: 0 for a match, non-zero for a non-match.
- */
- static KMF_RETURN
- matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
- KMF_X509_NAME *issuer, KMF_X509_NAME *subject)
- {
- KMF_RETURN rv = KMF_OK;
- CK_ATTRIBUTE certattr;
- KMF_DATA name;
- KMF_X509_NAME dn;
- if (issuer->numberOfRDNs > 0) {
- certattr.type = CKA_ISSUER;
- certattr.pValue = NULL;
- certattr.ulValueLen = 0;
- rv = get_attr(kmfh, obj, &certattr);
- if (rv == KMF_OK) {
- name.Data = certattr.pValue;
- name.Length = certattr.ulValueLen;
- rv = DerDecodeName(&name, &dn);
- if (rv == KMF_OK) {
- rv = kmf_compare_rdns(issuer, &dn);
- kmf_free_dn(&dn);
- }
- free(certattr.pValue);
- }
- if (rv != KMF_OK)
- return (rv);
- }
- if (subject->numberOfRDNs > 0) {
- certattr.type = CKA_SUBJECT;
- certattr.pValue = NULL;
- certattr.ulValueLen = 0;
- rv = get_attr(kmfh, obj, &certattr);
- if (rv == KMF_OK) {
- name.Data = certattr.pValue;
- name.Length = certattr.ulValueLen;
- rv = DerDecodeName(&name, &dn);
- if (rv == KMF_OK) {
- rv = kmf_compare_rdns(subject, &dn);
- kmf_free_dn(&dn);
- }
- free(certattr.pValue);
- }
- }
- return (rv);
- }
- /*
- * delete "curr" node from the "newlist".
- */
- static void
- pk11_delete_obj_from_list(OBJLIST **newlist,
- OBJLIST **prev, OBJLIST **curr)
- {
- if (*curr == *newlist) {
- /* first node in the list */
- *newlist = (*curr)->next;
- *prev = (*curr)->next;
- free(*curr);
- *curr = *newlist;
- } else {
- (*prev)->next = (*curr)->next;
- free(*curr);
- *curr = (*prev)->next;
- }
- }
- /*
- * search_certs
- *
- * Because this code is shared by the FindCert and
- * DeleteCert functions, put it in a separate routine
- * to save some work and make code easier to debug and
- * read.
- */
- 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)
- {
- KMF_RETURN rv = KMF_OK;
- CK_RV ckrv = CKR_OK;
- KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
- CK_ATTRIBUTE templ[10];
- CK_BBOOL true = TRUE;
- CK_OBJECT_CLASS oclass = CKO_CERTIFICATE;
- CK_CERTIFICATE_TYPE ctype = CKC_X_509;
- KMF_X509_NAME subjectDN, issuerDN;
- int i;
- OBJLIST *newlist, *tail;
- CK_ULONG num = 0;
- uint32_t num_ok_certs = 0; /* number of non-expired or expired certs */
- (void) memset(&templ, 0, 10 * sizeof (CK_ATTRIBUTE));
- (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
- (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
- i = 0;
- SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
- SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++;
- SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, sizeof (ctype)); i++;
- if (label != NULL && strlen(label)) {
- SETATTR(templ, i, CKA_LABEL, label, strlen(label));
- i++;
- }
- if (private) {
- SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); i++;
- }
- if (issuer != NULL && strlen(issuer)) {
- if ((rv = kmf_dn_parser(issuer, &issuerDN)) != KMF_OK)
- return (rv);
- }
- if (subject != NULL && strlen(subject)) {
- if ((rv = kmf_dn_parser(subject, &subjectDN)) != KMF_OK)
- return (rv);
- }
- if (serial != NULL && serial->val != NULL && serial->len > 0) {
- SETATTR(templ, i, CKA_SERIAL_NUMBER, serial->val, serial->len);
- i++;
- }
- (*numobj) = 0;
- *objlist = NULL;
- newlist = NULL;
- ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, i);
- if (ckrv != CKR_OK)
- goto cleanup;
- tail = newlist = NULL;
- while (ckrv == CKR_OK) {
- CK_OBJECT_HANDLE tObj;
- ckrv = C_FindObjects(kmfh->pk11handle, &tObj, 1, &num);
- if (ckrv != CKR_OK || num == 0)
- break;
- /*
- * 'matchcert' returns 0 if subject/issuer match
- *
- * If no match, move on to the next one
- */
- if (matchcert(kmfh, tObj, &issuerDN, &subjectDN))
- continue;
- if (newlist == NULL) {
- newlist = malloc(sizeof (OBJLIST));
- if (newlist == NULL) {
- rv = KMF_ERR_MEMORY;
- break;
- }
- newlist->handle = tObj;
- newlist->next = NULL;
- tail = newlist;
- } else {
- tail->next = malloc(sizeof (OBJLIST));
- if (tail->next != NULL) {
- tail = tail->next;
- } else {
- rv = KMF_ERR_MEMORY;
- break;
- }
- tail->handle = tObj;
- tail->next = NULL;
- }
- (*numobj)++;
- }
- ckrv = C_FindObjectsFinal(kmfh->pk11handle);
- cleanup:
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- rv = KMF_ERR_INTERNAL;
- if (newlist != NULL) {
- free_objlist(newlist);
- *numobj = 0;
- newlist = NULL;
- }
- } else {
- if (validity == KMF_ALL_CERTS) {
- *objlist = newlist;
- } else {
- OBJLIST *node, *prev;
- KMF_X509_DER_CERT tmp_kmf_cert;
- uint32_t i = 0;
- node = prev = newlist;
- /*
- * Now check to see if any found certificate is expired
- * or valid.
- */
- while (node != NULL && i < (*numobj)) {
- (void) memset(&tmp_kmf_cert, 0,
- sizeof (KMF_X509_DER_CERT));
- rv = PK11Cert2KMFCert(kmfh, node->handle,
- &tmp_kmf_cert);
- if (rv != KMF_OK) {
- goto cleanup1;
- }
- rv = kmf_check_cert_date(handle,
- &tmp_kmf_cert.certificate);
- if (validity == KMF_NONEXPIRED_CERTS) {
- if (rv == KMF_OK) {
- num_ok_certs++;
- prev = node;
- node = node->next;
- } else if (rv ==
- KMF_ERR_VALIDITY_PERIOD) {
- /*
- * expired - remove it from list
- */
- pk11_delete_obj_from_list(
- &newlist, &prev, &node);
- } else {
- goto cleanup1;
- }
- }
- if (validity == KMF_EXPIRED_CERTS) {
- if (rv == KMF_ERR_VALIDITY_PERIOD) {
- num_ok_certs++;
- prev = node;
- node = node->next;
- rv = KMF_OK;
- } else if (rv == KMF_OK) {
- /*
- * valid - remove it from list
- */
- pk11_delete_obj_from_list(
- &newlist, &prev, &node);
- } else {
- goto cleanup1;
- }
- }
- i++;
- kmf_free_kmf_cert(handle, &tmp_kmf_cert);
- }
- *numobj = num_ok_certs;
- *objlist = newlist;
- }
- }
- cleanup1:
- if (rv != KMF_OK && newlist != NULL) {
- free_objlist(newlist);
- *numobj = 0;
- *objlist = NULL;
- }
- if (issuer != NULL)
- kmf_free_dn(&issuerDN);
- if (subject != NULL)
- kmf_free_dn(&subjectDN);
- return (rv);
- }
- /*
- * The caller may pass a NULL value for kmf_cert below and the function will
- * just return the number of certs found (in num_certs).
- */
- KMF_RETURN
- KMFPK11_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
- {
- KMF_RETURN rv = 0;
- uint32_t want_certs;
- KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
- OBJLIST *objlist = NULL;
- uint32_t *num_certs;
- KMF_X509_DER_CERT *kmf_cert = NULL;
- char *certlabel = NULL;
- char *issuer = NULL;
- char *subject = NULL;
- KMF_BIGINT *serial = NULL;
- KMF_CERT_VALIDITY validity;
- KMF_CREDENTIAL *cred = NULL;
- boolean_t private;
- if (kmfh == NULL)
- return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
- if (kmfh->pk11handle == CK_INVALID_HANDLE)
- return (KMF_ERR_NO_TOKEN_SELECTED);
- num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
- if (num_certs == NULL)
- return (KMF_ERR_BAD_PARAMETER);
- if (*num_certs > 0)
- want_certs = *num_certs;
- else
- want_certs = MAXINT; /* count them all */
- *num_certs = 0;
- /* Get the optional returned certificate list */
- kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
- numattr);
- /* Get optional search criteria attributes */
- certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
- issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
- subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
- serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
- rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
- &validity, NULL);
- if (rv != KMF_OK) {
- validity = KMF_ALL_CERTS;
- rv = KMF_OK;
- }
- rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
- (void *)&private, NULL);
- if (rv != KMF_OK) {
- private = B_FALSE;
- rv = KMF_OK;
- }
- cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
- if (cred != NULL) {
- rv = pk11_authenticate(handle, cred);
- if (rv != KMF_OK)
- return (rv);
- }
- /* Start searching */
- rv = search_certs(handle, certlabel, issuer, subject, serial, private,
- validity, &objlist, num_certs);
- if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) {
- OBJLIST *node = objlist;
- int i = 0;
- while (node != NULL && i < want_certs) {
- rv = PK11Cert2KMFCert(kmfh, node->handle,
- &kmf_cert[i]);
- i++;
- node = node->next;
- }
- }
- if (objlist != NULL)
- free_objlist(objlist);
- if (*num_certs == 0)
- rv = KMF_ERR_CERT_NOT_FOUND;
- return (rv);
- }
- /*ARGSUSED*/
- void
- KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert)
- {
- if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) {
- free(kmf_cert->certificate.Data);
- kmf_cert->certificate.Data = NULL;
- kmf_cert->certificate.Length = 0;
- if (kmf_cert->kmf_private.label != NULL) {
- free(kmf_cert->kmf_private.label);
- kmf_cert->kmf_private.label = NULL;
- }
- }
- }
- KMF_RETURN
- KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey,
- KMF_DATA *eData)
- {
- KMF_RETURN ret = KMF_OK;
- CK_RV rv;
- KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
- CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY;
- CK_KEY_TYPE ckKeyType;
- KMF_DATA Modulus, Exponent, Prime, Subprime, Base, Value;
- KMF_OID *Algorithm;
- BerElement *asn1 = NULL;
- BerValue *PubKeyParams = NULL, *EncodedKey = NULL;
- KMF_X509_SPKI spki;
- CK_BYTE ec_params[256], ec_point[256];
- CK_ATTRIBUTE rsaTemplate[4];
- CK_ATTRIBUTE dsaTemplate[6];
- CK_ATTRIBUTE ecdsaTemplate[6];
- if (kmfh == NULL)
- return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
- if (kmfh->pk11handle == CK_INVALID_HANDLE)
- return (KMF_ERR_NO_TOKEN_SELECTED);
- if (pKey == NULL || pKey->keyp == CK_INVALID_HANDLE)
- return (KMF_ERR_BAD_PARAMETER);
- (void) memset(&Modulus, 0, sizeof (Modulus));
- (void) memset(&Exponent, 0, sizeof (Exponent));
- (void) memset(&Prime, 0, sizeof (Prime));
- (void) memset(&Subprime, 0, sizeof (Subprime));
- (void) memset(&Base, 0, sizeof (Base));
- (void) memset(&Value, 0, sizeof (Value));
- switch (pKey->keyalg) {
- case KMF_RSA:
- SETATTR(rsaTemplate, 0, CKA_CLASS, &ckObjClass,
- sizeof (ckObjClass));
- SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
- sizeof (ckKeyType));
- SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
- Modulus.Length);
- SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
- Exponent.Data, Exponent.Length);
- /* Get the length of the fields */
- rv = C_GetAttributeValue(kmfh->pk11handle,
- (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
- if (rv != CKR_OK) {
- SET_ERROR(kmfh, rv);
- return (KMF_ERR_BAD_PARAMETER);
- }
- Modulus.Length = rsaTemplate[2].ulValueLen;
- Modulus.Data = malloc(Modulus.Length);
- if (Modulus.Data == NULL)
- return (KMF_ERR_MEMORY);
- Exponent.Length = rsaTemplate[3].ulValueLen;
- Exponent.Data = malloc(Exponent.Length);
- if (Exponent.Data == NULL) {
- free(Modulus.Data);
- return (KMF_ERR_MEMORY);
- }
- SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
- Modulus.Length);
- SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
- Exponent.Data, Exponent.Length);
- /* Now get the values */
- rv = C_GetAttributeValue(kmfh->pk11handle,
- (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
- if (rv != CKR_OK) {
- SET_ERROR(kmfh, rv);
- free(Modulus.Data);
- free(Exponent.Data);
- return (KMF_ERR_BAD_PARAMETER);
- }
- /*
- * This is the KEY algorithm, not the
- * signature algorithm.
- */
- Algorithm = x509_algid_to_algoid(KMF_ALGID_RSA);
- if (Algorithm != NULL) {
- /* Encode the RSA Key Data */
- if ((asn1 = kmfder_alloc()) == NULL) {
- free(Modulus.Data);
- free(Exponent.Data);
- return (KMF_ERR_MEMORY);
- }
- if (kmfber_printf(asn1, "{II}", Modulus.Data,
- Modulus.Length, Exponent.Data,
- Exponent.Length) == -1) {
- kmfber_free(asn1, 1);
- free(Modulus.Data);
- free(Exponent.Data);
- return (KMF_ERR_ENCODING);
- }
- if (kmfber_flatten(asn1, &EncodedKey) == -1) {
- kmfber_free(asn1, 1);
- free(Modulus.Data);
- free(Exponent.Data);
- return (KMF_ERR_ENCODING);
- }
- kmfber_free(asn1, 1);
- }
- free(Exponent.Data);
- free(Modulus.Data);
- break;
- case KMF_DSA:
- SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass,
- sizeof (ckObjClass));
- SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
- sizeof (ckKeyType));
- SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
- Prime.Length);
- SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
- Subprime.Length);
- SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
- Base.Length);
- SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
- Value.Length);
- /* Get the length of the fields */
- rv = C_GetAttributeValue(kmfh->pk11handle,
- (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
- if (rv != CKR_OK) {
- SET_ERROR(kmfh, rv);
- return (KMF_ERR_BAD_PARAMETER);
- }
- Prime.Length = dsaTemplate[2].ulValueLen;
- Prime.Data = malloc(Prime.Length);
- if (Prime.Data == NULL) {
- return (KMF_ERR_MEMORY);
- }
- Subprime.Length = dsaTemplate[3].ulValueLen;
- Subprime.Data = malloc(Subprime.Length);
- if (Subprime.Data == NULL) {
- free(Prime.Data);
- return (KMF_ERR_MEMORY);
- }
- Base.Length = dsaTemplate[4].ulValueLen;
- Base.Data = malloc(Base.Length);
- if (Base.Data == NULL) {
- free(Prime.Data);
- free(Subprime.Data);
- return (KMF_ERR_MEMORY);
- }
- Value.Length = dsaTemplate[5].ulValueLen;
- Value.Data = malloc(Value.Length);
- if (Value.Data == NULL) {
- free(Prime.Data);
- free(Subprime.Data);
- free(Base.Data);
- return (KMF_ERR_MEMORY);
- }
- SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
- Prime.Length);
- SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
- Subprime.Length);
- SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
- Base.Length);
- SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
- Value.Length);
- /* Now get the values */
- rv = C_GetAttributeValue(kmfh->pk11handle,
- (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
- if (rv != CKR_OK) {
- free(Prime.Data);
- free(Subprime.Data);
- free(Base.Data);
- free(Value.Data);
- SET_ERROR(kmfh, rv);
- return (KMF_ERR_BAD_PARAMETER);
- }
- /*
- * This is the KEY algorithm, not the
- * signature algorithm.
- */
- Algorithm = x509_algid_to_algoid(KMF_ALGID_DSA);
- /* Encode the DSA Algorithm Parameters */
- if ((asn1 = kmfder_alloc()) == NULL) {
- free(Prime.Data);
- free(Subprime.Data);
- free(Base.Data);
- free(Value.Data);
- return (KMF_ERR_MEMORY);
- }
- if (kmfber_printf(asn1, "{III}", Prime.Data,
- Prime.Length, Subprime.Data, Subprime.Length,
- Base.Data, Base.Length) == -1) {
- kmfber_free(asn1, 1);
- free(Prime.Data);
- free(Subprime.Data);
- free(Base.Data);
- free(Value.Data);
- return (KMF_ERR_ENCODING);
- }
- if (kmfber_flatten(asn1, &PubKeyParams) == -1) {
- kmfber_free(asn1, 1);
- free(Prime.Data);
- free(Subprime.Data);
- free(Base.Data);
- free(Value.Data);
- return (KMF_ERR_ENCODING);
- }
- kmfber_free(asn1, 1);
- free(Prime.Data);
- free(Subprime.Data);
- free(Base.Data);
- /* Encode the DSA Key Value */
- if ((asn1 = kmfder_alloc()) == NULL) {
- free(Value.Data);
- return (KMF_ERR_MEMORY);
- }
- if (kmfber_printf(asn1, "I",
- Value.Data, Value.Length) == -1) {
- kmfber_free(asn1, 1);
- free(Value.Data);
- return (KMF_ERR_ENCODING);
- }
- if (kmfber_flatten(asn1, &EncodedKey) == -1) {
- kmfber_free(asn1, 1);
- free(Value.Data);
- return (KMF_ERR_ENCODING);
- }
- kmfber_free(asn1, 1);
- free(Value.Data);
- break;
- case KMF_ECDSA:
- /* The EC_PARAMS are the PubKey algorithm parameters */
- PubKeyParams = calloc(1, sizeof (BerValue));
- if (PubKeyParams == NULL)
- return (KMF_ERR_MEMORY);
- EncodedKey = calloc(1, sizeof (BerValue));
- if (EncodedKey == NULL) {
- free(PubKeyParams);
- return (KMF_ERR_MEMORY);
- }
- SETATTR(ecdsaTemplate, 0, CKA_EC_PARAMS,
- &ec_params, sizeof (ec_params));
- SETATTR(ecdsaTemplate, 1, CKA_EC_POINT,
- &ec_point, sizeof (ec_point));
- /* Get the length of the fields */
- rv = C_GetAttributeValue(kmfh->pk11handle,
- (CK_OBJECT_HANDLE)pKey->keyp,
- ecdsaTemplate, 2);
- if (rv != CKR_OK) {
- SET_ERROR(kmfh, rv);
- return (KMF_ERR_BAD_PARAMETER);
- }
- /* The params are to be used as algorithm parameters */
- PubKeyParams->bv_val = (char *)ec_params;
- PubKeyParams->bv_len = ecdsaTemplate[0].ulValueLen;
- /*
- * The EC_POINT is to be used as the subject pub key.
- */
- EncodedKey->bv_val = (char *)ec_point;
- EncodedKey->bv_len = ecdsaTemplate[1].ulValueLen;
- /* Use the EC_PUBLIC_KEY OID */
- Algorithm = (KMF_OID *)&KMFOID_EC_PUBLIC_KEY;
- break;
- default:
- return (KMF_ERR_BAD_PARAMETER);
- }
- /* Now, build an SPKI structure for the final encoding step */
- spki.algorithm.algorithm = *Algorithm;
- if (PubKeyParams != NULL) {
- spki.algorithm.parameters.Data =
- (uchar_t *)PubKeyParams->bv_val;
- spki.algorithm.parameters.Length = PubKeyParams->bv_len;
- } else {
- spki.algorithm.parameters.Data = NULL;
- spki.algorithm.parameters.Length = 0;
- }
- if (EncodedKey != NULL) {
- spki.subjectPublicKey.Data = (uchar_t *)EncodedKey->bv_val;
- spki.subjectPublicKey.Length = EncodedKey->bv_len;
- } else {
- spki.subjectPublicKey.Data = NULL;
- spki.subjectPublicKey.Length = 0;
- }
- /* Finally, encode the entire SPKI record */
- ret = DerEncodeSPKI(&spki, eData);
- cleanup:
- if (EncodedKey) {
- if (pKey->keyalg != KMF_ECDSA)
- free(EncodedKey->bv_val);
- free(EncodedKey);
- }
- if (PubKeyParams) {
- if (pKey->keyalg != KMF_ECDSA)
- free(PubKeyParams->bv_val);
- free(PubKeyParams);
- }
- return (ret);
- }
- static KMF_RETURN
- CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
- {
- KMF_RETURN rv = 0;
- KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
- KMF_X509_CERTIFICATE *signed_cert_ptr = NULL;
- KMF_DATA data;
- KMF_DATA Id;
- CK_RV ckrv;
- CK_ULONG subject_len, issuer_len, serno_len;
- CK_BYTE *subject, *issuer, *serial, nullserno;
- CK_BBOOL true = TRUE;
- CK_CERTIFICATE_TYPE certtype = CKC_X_509;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_ATTRIBUTE x509templ[11];
- CK_OBJECT_HANDLE hCert = NULL;
- int i;
- if (kmfh == NULL)
- return (KMF_ERR_INTERNAL); /* should not happen */
- if (kmfh->pk11handle == CK_INVALID_HANDLE)
- return (KMF_ERR_INTERNAL); /* should not happen */
- if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0)
- return (KMF_ERR_INTERNAL); /* should not happen */
- /*
- * The data *must* be a DER encoded X.509 certificate.
- * Convert it to a CSSM cert and then parse the fields so
- * the PKCS#11 attributes can be filled in correctly.
- */
- rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert,
- &signed_cert_ptr);
- if (rv != KMF_OK) {
- return (KMF_ERR_ENCODING);
- }
- /*
- * Encode fields into PKCS#11 attributes.
- */
- /* Get the subject name */
- rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data);
- if (rv == KMF_OK) {
- subject = data.Data;
- subject_len = data.Length;
- } else {
- rv = KMF_ERR_ENCODING;
- goto cleanup;
- }
- /* Encode the issuer */
- rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data);
- if (rv == KMF_OK) {
- issuer = data.Data;
- issuer_len = data.Length;
- } else {
- rv = KMF_ERR_ENCODING;
- goto cleanup;
- }
- /* Encode serial number */
- if (signed_cert_ptr->certificate.serialNumber.len > 0 &&
- signed_cert_ptr->certificate.serialNumber.val != NULL) {
- serial = signed_cert_ptr->certificate.serialNumber.val;
- serno_len = signed_cert_ptr->certificate.serialNumber.len;
- } else {
- /*
- * RFC3280 says to gracefully handle certs with serial numbers
- * of 0.
- */
- nullserno = '\0';
- serial = &nullserno;
- serno_len = 1;
- }
- /* Generate an ID from the SPKI data */
- rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo,
- &Id);
- if (rv != KMF_OK) {
- goto cleanup;
- }
- i = 0;
- SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++;
- SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype,
- sizeof (certtype));
- i++;
- SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
- SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++;
- SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++;
- SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++;
- SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++;
- SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++;
- if (label != NULL && strlen(label)) {
- SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); i++;
- }
- /*
- * The cert object handle is actually "leaked" here. If the app
- * really wants to clean up the data space, it will have to call
- * KMF_DeleteCert and specify the softtoken keystore.
- */
- ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert);
- if (ckrv != CKR_OK) {
- /* Report authentication failures to the caller */
- if (ckrv == CKR_USER_NOT_LOGGED_IN ||
- ckrv == CKR_PIN_INCORRECT ||
- ckrv == CKR_PIN_INVALID ||
- ckrv == CKR_PIN_EXPIRED ||
- ckrv == CKR_PIN_LOCKED ||
- ckrv == CKR_SESSION_READ_ONLY)
- rv = KMF_ERR_AUTH_FAILED;
- else
- rv = KMF_ERR_INTERNAL;
- SET_ERROR(kmfh, ckrv);
- }
- free(subject);
- free(issuer);
- cleanup:
- if (Id.Data != NULL)
- free(Id.Data);
- if (signed_cert_ptr) {
- kmf_free_signed_cert(signed_cert_ptr);
- free(signed_cert_ptr);
- }
- return (rv);
- }
- KMF_RETURN
- KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
- {
- KMF_RETURN rv = 0;
- KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
- KMF_DATA *cert = NULL;
- KMF_CREDENTIAL *cred = NULL;
- char *label = NULL;
- if (kmfh == NULL)
- return (KMF_ERR_UNINITIALIZED);
- if (kmfh->pk11handle == CK_INVALID_HANDLE)
- return (KMF_ERR_NO_TOKEN_SELECTED);
- cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
- if (cert == NULL || cert->Data == NULL || cert->Length == 0)
- return (KMF_ERR_BAD_PARAMETER);
- /* label attribute is optional */
- label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
- cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
- if (cred != NULL) {
- rv = pk11_authenticate(handle, cred);
- if (rv != KMF_OK)
- return (rv);
- }
- rv = CreateCertObject(handle, label, cert);
- return (rv);
- }
- KMF_RETURN
- KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
- {
- KMF_RETURN rv = 0;
- KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
- char *certfile = NULL;
- char *label = NULL;
- KMF_ENCODE_FORMAT format;
- KMF_CREDENTIAL *cred = NULL;
- KMF_DATA cert1 = { NULL, 0};
- KMF_DATA cert2 = { NULL, 0};
- if (kmfh == NULL)
- return (KMF_ERR_UNINITIALIZED);
- if (kmfh->pk11handle == CK_INVALID_HANDLE)
- return (KMF_ERR_NO_TOKEN_SELECTED);
- /*
- * Get the input cert filename attribute, check if it is a valid
- * certificate and auto-detect the file format of it.
- */
- certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
- if (certfile == NULL)
- return (KMF_ERR_BAD_PARAMETER);
- rv = kmf_is_cert_file(handle, certfile, &format);
- if (rv != KMF_OK)
- return (rv);
- /* Read in the CERT file */
- rv = kmf_read_input_file(handle, certfile, &cert1);
- if (rv != KMF_OK) {
- return (rv);
- }
- /* The label attribute is optional */
- label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
- /*
- * If the input certificate is in PEM format, we need to convert
- * it to DER first.
- */
- if (format == KMF_FORMAT_PEM) {
- int derlen;
- rv = kmf_pem_to_der(cert1.Data, cert1.Length,
- &cert2.Data, &derlen);
- if (rv != KMF_OK) {
- goto out;
- }
- cert2.Length = (size_t)derlen;
- }
- cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
- if (cred != NULL) {
- rv = pk11_authenticate(handle, cred);
- if (rv != KMF_OK)
- return (rv);
- }
- rv = CreateCertObject(handle, label,
- format == KMF_FORMAT_ASN1 ? &cert1 : &cert2);
- out:
- if (cert1.Data != NULL) {
- free(cert1.Data);
- }
- if (cert2.Data != NULL) {
- free(cert2.Data);
- }
- return (rv);
- }
- KMF_RETURN
- KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
- {
- KMF_RETURN rv = 0;
- KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
- OBJLIST *objlist;
- uint32_t numObjects = 0;
- char *certlabel = NULL;
- char *issuer = NULL;
- char *subject = NULL;
- KMF_BIGINT *serial = NULL;
- KMF_CERT_VALIDITY validity;
- boolean_t private;
- if (kmfh == NULL)
- return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
- if (kmfh->pk11handle == CK_INVALID_HANDLE)
- return (KMF_ERR_NO_TOKEN_SELECTED);
- /* Get the search criteria attributes. They are all optional. */
- certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
- issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
- subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
- serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
- rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
- &validity, NULL);
- if (rv != KMF_OK) {
- validity = KMF_ALL_CERTS;
- rv = KMF_OK;
- }
- rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
- (void *)&private, NULL);
- if (rv != KMF_OK) {
- private = B_FALSE;
- rv = KMF_OK;
- }
- /*
- * Start searching for certificates that match the criteria and
- * delete them.
- */
- objlist = NULL;
- rv = search_certs(handle, certlabel, issuer, subject, serial,
- private, validity, &objlist, &numObjects);
- if (rv == KMF_OK && objlist != NULL) {
- OBJLIST *node = objlist;
- while (node != NULL) {
- CK_RV ckrv;
- ckrv = C_DestroyObject(kmfh->pk11handle, node->handle);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- rv = KMF_ERR_INTERNAL;
- break;
- }
- node = node->next;
- }
- free_objlist(objlist);
- }
- if (rv == KMF_OK && numObjects == 0)
- rv = KMF_ERR_CERT_NOT_FOUND;
- out:
- return (rv);
- }
- static CK_RV
- gendsa_keypair(KMF_HANDLE *kmfh, boolean_t storekey,
- CK_OBJECT_HANDLE *pubKey,
- CK_OBJECT_HANDLE *priKey)
- {
- CK_RV ckrv = CKR_OK;
- CK_SESSION_HANDLE hSession = kmfh->pk11handle;
- static CK_ULONG dsaKeyType = CKK_DSA;
- static CK_BBOOL true = TRUE;
- static CK_BBOOL false = FALSE;
- static CK_OBJECT_CLASS priClass = CKO_PRIVATE_KEY;
- static CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
- static CK_BYTE ckDsaPrime[128] = {
- 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2,
- 0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c,
- 0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3,
- 0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc,
- 0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c,
- 0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8,
- 0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8,
- 0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3,
- 0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09,
- 0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c,
- 0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5,
- 0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb,
- 0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b,
- 0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11,
- 0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27,
- 0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b};
- static CK_BYTE ckDsaSubPrime[20] = {
- 0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe,
- 0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc,
- 0x78, 0x47, 0xb0, 0xd5};
- static CK_BYTE ckDsaBase[128] = {
- 0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b,
- 0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5,
- 0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3,
- 0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c,
- 0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2,
- 0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd,
- 0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3,
- 0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a,
- 0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05,
- 0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a,
- 0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67,
- 0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73,
- 0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f,
- 0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19,
- 0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce,
- 0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 };
- static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = {
- { CKA_CLASS, &pubClass, sizeof (pubClass) },
- { CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) },
- { CKA_TOKEN, &true, sizeof (true)},
- { CKA_PRIVATE, &false, sizeof (false)},
- { CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) },
- { CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)},
- { CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) },
- { CKA_VERIFY, &true, sizeof (true) },
- };
- #define NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
- sizeof (CK_ATTRIBUTE))
- #define MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
- sizeof (CK_ATTRIBUTE))
- static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = {
- {CKA_CLASS, &priClass, sizeof (priClass)},
- {CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)},
- {CKA_TOKEN, &true, sizeof (true)},
- {CKA_PRIVATE, &true, sizeof (true)},
- {CKA_SIGN, &true, sizeof (true)},
- };
- #define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
- sizeof (CK_ATTRIBUTE))
- #define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
- sizeof (CK_ATTRIBUTE))
- CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0};
- SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN,
- (storekey ? &true : &false), sizeof (CK_BBOOL));
- ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
- ckDsaPubKeyTemplate,
- (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)),
- ckDsaPriKeyTemplate,
- (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)),
- pubKey, priKey);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- return (KMF_ERR_KEYGEN_FAILED);
- }
- return (ckrv);
- }
- 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)
- {
- CK_RV ckrv = CKR_OK;
- CK_SESSION_HANDLE hSession = kmfh->pk11handle;
- CK_ATTRIBUTE rsaPubKeyTemplate[16];
- CK_ATTRIBUTE rsaPriKeyTemplate[16];
- CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
- int numpubattr = 0, numpriattr = 0;
- static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01};
- static CK_BBOOL true = TRUE;
- static CK_BBOOL false = FALSE;
- SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN,
- (storekey ? &true : &false), sizeof (CK_BBOOL));
- numpubattr++;
- SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS,
- &modulusBits, sizeof (modulusBits));
- numpubattr++;
- if (rsaexp != NULL && (rsaexp->len > 0 && rsaexp->val != NULL)) {
- SETATTR(rsaPubKeyTemplate, numpubattr,
- CKA_PUBLIC_EXPONENT,
- rsaexp->val, rsaexp->len);
- numpubattr++;
- } else {
- SETATTR(rsaPubKeyTemplate, numpubattr,
- CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo));
- numpubattr++;
- }
- SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT,
- &true, sizeof (true));
- numpubattr++;
- SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY,
- &true, sizeof (true));
- numpubattr++;
- SETATTR(rsaPubKeyTemplate, numpubattr, CKA_WRAP,
- &true, sizeof (true));
- numpubattr++;
- SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN,
- (storekey ? &true : &false), sizeof (CK_BBOOL));
- numpriattr++;
- SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true,
- sizeof (true));
- numpriattr++;
- SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true,
- sizeof (true));
- numpriattr++;
- SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true,
- sizeof (true));
- numpriattr++;
- SETATTR(rsaPriKeyTemplate, numpriattr, CKA_UNWRAP, &true,
- sizeof (true));
- numpriattr++;
- ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
- rsaPubKeyTemplate, numpubattr,
- rsaPriKeyTemplate, numpriattr,
- pubKey, priKey);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- return (ckrv);
- }
- return (ckrv);
- }
- static CK_RV
- genecc_keypair(KMF_HANDLE *kmfh,
- boolean_t ontoken,
- KMF_OID *curveoid,
- CK_OBJECT_HANDLE *pubKey,
- CK_OBJECT_HANDLE *priKey)
- {
- CK_RV ckrv;
- CK_SESSION_HANDLE hSession = kmfh->pk11handle;
- CK_MECHANISM keyGenMech = {CKM_EC_KEY_PAIR_GEN, NULL, 0};
- const ulong_t publicKey = CKO_PUBLIC_KEY;
- const ulong_t privateKey = CKO_PRIVATE_KEY;
- const ulong_t keytype = CKK_EC;
- static CK_BBOOL true = TRUE;
- static CK_BBOOL false = FALSE;
- CK_ATTRIBUTE public_template[6];
- CK_ATTRIBUTE private_template[6];
- int numpubattr, numpriattr;
- numpubattr = 0;
- SETATTR(public_template, numpubattr, CKA_CLASS,
- &publicKey, sizeof (publicKey));
- numpubattr++;
- SETATTR(public_template, numpubattr, CKA_KEY_TYPE,
- &keytype, sizeof (keytype));
- numpubattr++;
- SETATTR(public_template, numpubattr, CKA_EC_PARAMS,
- curveoid->Data, curveoid->Length);
- numpubattr++;
- SETATTR(public_template, numpubattr, CKA_TOKEN,
- ontoken ? &true : &false, sizeof (true));
- numpubattr++;
- SETATTR(public_template, numpubattr, CKA_VERIFY,
- &true, sizeof (true));
- numpubattr++;
- SETATTR(public_template, numpubattr, CKA_PRIVATE,
- &false, sizeof (false));
- numpubattr++;
- numpriattr = 0;
- SETATTR(private_template, numpriattr, CKA_CLASS,
- &privateKey, sizeof (privateKey));
- numpriattr++;
- SETATTR(private_template, numpriattr, CKA_KEY_TYPE,
- &keytype, sizeof (keytype));
- numpriattr++;
- SETATTR(private_template, numpriattr, CKA_TOKEN,
- ontoken ? &true : &false, sizeof (true));
- numpriattr++;
- SETATTR(private_template, numpriattr, CKA_PRIVATE,
- &true, sizeof (true));
- numpriattr++;
- SETATTR(private_template, numpriattr, CKA_SIGN,
- &true, sizeof (true));
- numpriattr++;
- SETATTR(private_template, numpriattr, CKA_DERIVE,
- &true, sizeof (true));
- numpriattr++;
- ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
- public_template, numpubattr,
- private_template, numpriattr,
- pubKey, priKey);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- return (ckrv);
- }
- return (ckrv);
- }
- KMF_RETURN
- KMFPK11_CreateKeypair(KMF_HANDLE_T handle,
- int numattr,
- KMF_ATTRIBUTE *attlist)
- {
- KMF_RETURN rv = KMF_OK;
- KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
- KMF_DATA IDInput, IDOutput;
- KMF_CREDENTIAL *cred;
- KMF_KEY_ALG keytype = KMF_RSA;
- KMF_KEY_HANDLE *pubkey, *privkey;
- CK_RV ckrv = 0;
- CK_SESSION_HANDLE hSession = kmfh->pk11handle;
- CK_ATTRIBUTE labelattr[1];
- CK_ATTRIBUTE idattr[1];
- CK_OBJECT_HANDLE pubKey, priKey;
- char IDHashData[SHA1_HASH_LENGTH];
- static CK_ULONG modulusBits = 1024;
- uint32_t modulusBits_size = sizeof (CK_ULONG);
- SHA1_CTX ctx;
- boolean_t storekey = TRUE;
- char *keylabel = NULL;
- if (kmfh == NULL)
- return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
- if (kmfh->pk11handle == CK_INVALID_HANDLE)
- return (KMF_ERR_NO_TOKEN_SELECTED);
- /* "storekey" is optional. Default is TRUE */
- (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr,
- &storekey, NULL);
- cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr);
- if (cred == NULL)
- return (KMF_ERR_BAD_PARAMETER);
- rv = pk11_authenticate(handle, cred);
- if (rv != KMF_OK)
- return (rv);
- /* keytype is optional. KMF_RSA is default */
- (void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr,
- (void *)&keytype, NULL);
- pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
- if (pubkey == NULL)
- return (KMF_ERR_BAD_PARAMETER);
- privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr);
- if (privkey == NULL)
- return (KMF_ERR_BAD_PARAMETER);
- (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
- (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
- if (keytype == KMF_RSA) {
- CK_BYTE *modulus = NULL;
- CK_ULONG modulusLength = 0;
- KMF_BIGINT *rsaexp = NULL;
- CK_ATTRIBUTE modattr[1];
- rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr,
- &modulusBits, &modulusBits_size);
- if (rv == KMF_ERR_ATTR_NOT_FOUND)
- /* Default modulusBits = 1024 */
- rv = KMF_OK;
- if (rv != KMF_OK)
- return (KMF_ERR_BAD_PARAMETER);
- rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, numattr);
- /* Generate the RSA keypair */
- ckrv = genrsa_keypair(kmfh, modulusBits, storekey,
- rsaexp, &pubKey, &priKey);
- if (ckrv != CKR_OK)
- return (KMF_ERR_BAD_PARAMETER);
- privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
- privkey->keyalg = KMF_RSA;
- privkey->keyclass = KMF_ASYM_PRI;
- privkey->keyp = (void *)priKey;
- pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
- pubkey->keyalg = KMF_RSA;
- pubkey->keyclass = KMF_ASYM_PUB;
- pubkey->keyp = (void *)pubKey;
- SETATTR(modattr, 0, CKA_MODULUS, NULL, modulusLength);
- /* Get the Modulus field to use as input for creating the ID */
- ckrv = C_GetAttributeValue(kmfh->pk11handle,
- (CK_OBJECT_HANDLE)pubKey, modattr, 1);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- return (KMF_ERR_BAD_PARAMETER);
- }
- modulusLength = modattr[0].ulValueLen;
- modulus = malloc(modulusLength);
- if (modulus == NULL)
- return (KMF_ERR_MEMORY);
- modattr[0].pValue = modulus;
- ckrv = C_GetAttributeValue(kmfh->pk11handle,
- (CK_OBJECT_HANDLE)pubKey, modattr, 1);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- free(modulus);
- return (KMF_ERR_BAD_PARAMETER);
- }
- IDInput.Data = modulus;
- IDInput.Length = modulusLength;
- } else if (keytype == KMF_DSA) {
- CK_BYTE *keyvalue;
- CK_ULONG valueLen;
- CK_ATTRIBUTE valattr[1];
- /* Generate the DSA keypair */
- ckrv = gendsa_keypair(kmfh, storekey, &pubKey, &priKey);
- if (ckrv != CKR_OK)
- return (KMF_ERR_BAD_PARAMETER);
- privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
- privkey->keyalg = KMF_DSA;
- privkey->keyclass = KMF_ASYM_PRI;
- privkey->keyp = (void *)priKey;
- pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
- pubkey->keyalg = KMF_DSA;
- pubkey->keyclass = KMF_ASYM_PUB;
- pubkey->keyp = (void *)pubKey;
- /* Get the Public Value to use as input for creating the ID */
- SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen);
- ckrv = C_GetAttributeValue(hSession,
- (CK_OBJECT_HANDLE)pubKey, valattr, 1);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- return (KMF_ERR_BAD_PARAMETER);
- }
- valueLen = valattr[0].ulValueLen;
- keyvalue = malloc(valueLen);
- if (keyvalue == NULL)
- return (KMF_ERR_MEMORY);
- valattr[0].pValue = keyvalue;
- ckrv = C_GetAttributeValue(hSession,
- (CK_OBJECT_HANDLE)pubKey, valattr, 1);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- free(keyvalue);
- return (KMF_ERR_BAD_PARAMETER);
- }
- IDInput.Data = keyvalue;
- IDInput.Length = valueLen;
- } else if (keytype == KMF_ECDSA) {
- CK_BYTE *keyvalue;
- CK_ULONG valueLen;
- CK_ATTRIBUTE valattr[1];
- KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
- attlist, numattr);
- if (eccoid == NULL)
- return (KMF_ERR_BAD_PARAMETER);
- ckrv = genecc_keypair(kmfh, storekey, eccoid,
- &pubKey, &priKey);
- if (ckrv != CKR_OK)
- return (KMF_ERR_BAD_PARAMETER);
- privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
- privkey->keyalg = KMF_ECDSA;
- privkey->keyclass = KMF_ASYM_PRI;
- privkey->keyp = (void *)priKey;
- pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
- pubkey->keyalg = KMF_ECDSA;
- pubkey->keyclass = KMF_ASYM_PUB;
- pubkey->keyp = (void *)pubKey;
- /* Get the EC_POINT to use as input for creating the ID */
- SETATTR(valattr, 0, CKA_EC_POINT, NULL, &valueLen);
- ckrv = C_GetAttributeValue(hSession,
- (CK_OBJECT_HANDLE)pubKey, valattr, 1);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- return (KMF_ERR_BAD_PARAMETER);
- }
- valueLen = valattr[0].ulValueLen;
- keyvalue = malloc(valueLen);
- if (keyvalue == NULL)
- return (KMF_ERR_MEMORY);
- valattr[0].pValue = keyvalue;
- ckrv = C_GetAttributeValue(hSession,
- (CK_OBJECT_HANDLE)pubKey, valattr, 1);
- if (ckrv != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- free(keyvalue);
- return (KMF_ERR_BAD_PARAMETER);
- }
- IDInput.Data = keyvalue;
- IDInput.Length = valueLen;
- } else {
- return (KMF_ERR_BAD_PARAMETER);
- }
- keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr);
- if (keylabel != NULL && strlen(keylabel)) {
- SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel));
- /* Set the CKA_LABEL if one was indicated */
- if ((ckrv = C_SetAttributeValue(hSession, pubKey,
- labelattr, 1)) != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- rv = KMF_ERR_INTERNAL;
- goto cleanup;
- }
- pubkey->keylabel = (char *)strdup(keylabel);
- if (pubkey->keylabel == NULL) {
- rv = KMF_ERR_MEMORY;
- goto cleanup;
- }
- if ((ckrv = C_SetAttributeValue(hSession, priKey,
- labelattr, 1)) != CKR_OK) {
- SET_ERROR(kmfh, ckrv);
- rv = KMF_ERR_INTERNAL;
- goto cleanup;
- }
- privkey->keylabel = (char *)strdup(keylabel);
- if (privkey->keylabel == NULL) {
- rv = KMF_ERR_MEMORY;
- goto cleanup;
- }
- } else {
- rv = KMF_OK;
- }
- /* Now, assign a CKA_ID value so it can be searched */
- /* ID_Input was assigned above in the RSA or DSA keygen section */
- IDOutput.Data = (uchar_t *)IDHashData;
- IDOutput.Length = sizeof (IDHashData);
- SHA1Init(&ctx);
- SHA1Update…
Large files files are truncated, but you can click here to view the full file