PageRenderTime 329ms CodeModel.GetById 101ms app.highlight 175ms RepoModel.GetById 16ms app.codeStats 2ms

/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c

https://bitbucket.org/nexenta/illumos-nexenta
C | 4225 lines | 3368 code | 563 blank | 294 comment | 1167 complexity | dcbe07d60444ede06d478e15ac2f7ed2 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * CDDL HEADER START
   3 *
   4 * The contents of this file are subject to the terms of the
   5 * Common Development and Distribution License (the "License").
   6 * You may not use this file except in compliance with the License.
   7 *
   8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9 * or http://www.opensolaris.org/os/licensing.
  10 * See the License for the specific language governing permissions
  11 * and limitations under the License.
  12 *
  13 * When distributing Covered Code, include this CDDL HEADER in each
  14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15 * If applicable, add the following below this CDDL HEADER, with the
  16 * fields enclosed by brackets "[]" replaced with your own identifying
  17 * information: Portions Copyright [yyyy] [name of copyright owner]
  18 *
  19 * CDDL HEADER END
  20 *
  21 * PKCS11 token KMF Plugin
  22 *
  23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24 */
  25
  26#include <stdio.h> /* debugging only */
  27#include <errno.h>
  28#include <values.h>
  29
  30#include <kmfapiP.h>
  31#include <ber_der.h>
  32#include <fcntl.h>
  33#include <sha1.h>
  34#include <bignum.h>
  35
  36#include <cryptoutil.h>
  37#include <security/cryptoki.h>
  38#include <security/pkcs11.h>
  39
  40#define	DEV_RANDOM	"/dev/random"
  41
  42#define	SETATTR(t, n, atype, value, size) \
  43	t[n].type = atype; \
  44	t[n].pValue = (CK_BYTE *)value; \
  45	t[n].ulValueLen = (CK_ULONG)size;
  46
  47#define	SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \
  48	h->lasterr.errcode = c;
  49
  50typedef struct _objlist {
  51	CK_OBJECT_HANDLE handle;
  52	struct _objlist *next;
  53} OBJLIST;
  54
  55static KMF_RETURN
  56search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *,
  57	boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *);
  58
  59static CK_RV
  60getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **);
  61
  62static KMF_RETURN
  63keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **);
  64
  65static KMF_RETURN
  66create_generic_secret_key(KMF_HANDLE_T,
  67	int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *);
  68
  69KMF_RETURN
  70KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  71
  72KMF_RETURN
  73KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  74
  75void
  76KMFPK11_FreeKMFCert(KMF_HANDLE_T,
  77	KMF_X509_DER_CERT *kmf_cert);
  78
  79KMF_RETURN
  80KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  81
  82KMF_RETURN
  83KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  84
  85KMF_RETURN
  86KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  87
  88KMF_RETURN
  89KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  90
  91KMF_RETURN
  92KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  93
  94KMF_RETURN
  95KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  96
  97KMF_RETURN
  98KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
  99
 100KMF_RETURN
 101KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
 102	KMF_DATA *, KMF_DATA *);
 103
 104KMF_RETURN
 105KMFPK11_GetErrorString(KMF_HANDLE_T, char **);
 106
 107KMF_RETURN
 108KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 109
 110KMF_RETURN
 111KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
 112	KMF_DATA *, KMF_DATA *);
 113
 114KMF_RETURN
 115KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 116
 117KMF_RETURN
 118KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 119
 120KMF_RETURN
 121KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
 122
 123KMF_RETURN
 124KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 125
 126KMF_RETURN
 127KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 128
 129
 130static
 131KMF_PLUGIN_FUNCLIST pk11token_plugin_table =
 132{
 133	1,			/* Version */
 134	KMFPK11_ConfigureKeystore,
 135	KMFPK11_FindCert,
 136	KMFPK11_FreeKMFCert,
 137	KMFPK11_StoreCert,
 138	KMFPK11_ImportCert,
 139	NULL,			/* ImportCRL */
 140	KMFPK11_DeleteCert,
 141	NULL,			/* DeleteCRL */
 142	KMFPK11_CreateKeypair,
 143	KMFPK11_FindKey,
 144	KMFPK11_EncodePubKeyData,
 145	KMFPK11_SignData,
 146	KMFPK11_DeleteKey,
 147	NULL,			/* ListCRL */
 148	NULL,			/* FindCRL */
 149	NULL,			/* FindCertInCRL */
 150	KMFPK11_GetErrorString,
 151	KMFPK11_FindPrikeyByCert,
 152	KMFPK11_DecryptData,
 153	KMFPK11_ExportPK12,
 154	KMFPK11_CreateSymKey,
 155	KMFPK11_GetSymKeyValue,
 156	KMFPK11_SetTokenPin,
 157	KMFPK11_StoreKey,
 158	NULL			/* Finalize */
 159};
 160
 161KMF_PLUGIN_FUNCLIST *
 162KMF_Plugin_Initialize()
 163{
 164	return (&pk11token_plugin_table);
 165}
 166
 167KMF_RETURN
 168KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,
 169	int numattr, KMF_ATTRIBUTE *attrlist)
 170{
 171	KMF_RETURN rv = KMF_OK;
 172	char *label;
 173	boolean_t readonly = B_TRUE;
 174
 175	label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
 176	if (label == NULL) {
 177		return (KMF_ERR_BAD_PARAMETER);
 178	}
 179
 180	/* "readonly" is optional. Default is TRUE */
 181	(void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr,
 182	    (void *)&readonly, NULL);
 183
 184	rv = kmf_select_token(handle, label, readonly);
 185
 186	return (rv);
 187}
 188
 189static KMF_RETURN
 190pk11_authenticate(KMF_HANDLE_T handle,
 191	KMF_CREDENTIAL *cred)
 192{
 193
 194	CK_RV ck_rv = CKR_OK;
 195	CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle;
 196
 197	if (hSession == NULL)
 198		return (KMF_ERR_NO_TOKEN_SELECTED);
 199
 200	if (cred == NULL || cred->cred == NULL) {
 201		return (KMF_ERR_BAD_PARAMETER);
 202	}
 203
 204	if ((ck_rv = C_Login(hSession, CKU_USER, (uchar_t *)cred->cred,
 205	    cred->credlen)) != CKR_OK) {
 206		if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) {
 207			handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
 208			handle->lasterr.errcode = ck_rv;
 209			return (KMF_ERR_AUTH_FAILED);
 210		}
 211	}
 212
 213	return (KMF_OK);
 214}
 215
 216static KMF_RETURN
 217PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
 218		KMF_X509_DER_CERT *kmfcert)
 219{
 220	KMF_RETURN rv = 0;
 221	CK_RV ckrv = CKR_OK;
 222
 223	CK_CERTIFICATE_TYPE cktype;
 224	CK_OBJECT_CLASS	class;
 225	CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len;
 226	CK_BYTE *subject = NULL, *value = NULL;
 227	char *label = NULL;
 228	CK_ATTRIBUTE templ[10];
 229
 230	(void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE));
 231	SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class));
 232
 233	/*  Is this a certificate object ? */
 234	ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
 235	if (ckrv != CKR_OK || class != CKO_CERTIFICATE)  {
 236		SET_ERROR(kmfh, ckrv);
 237		return (KMF_ERR_INTERNAL);
 238	}
 239
 240	SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype));
 241	ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
 242
 243	if (ckrv != CKR_OK || cktype != CKC_X_509)  {
 244		SET_ERROR(kmfh, ckrv);
 245		return (ckrv);
 246	} else {
 247		int i = 0;
 248		/* What attributes are available and how big are they? */
 249		subject_len = issuer_len = serno_len = id_len = value_len = 0;
 250
 251		SETATTR(templ, i, CKA_SUBJECT,	NULL, subject_len);
 252		i++;
 253		SETATTR(templ, i, CKA_ISSUER,	NULL, issuer_len);
 254		i++;
 255		SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len);
 256		i++;
 257		SETATTR(templ, i, CKA_ID, NULL, id_len);
 258		i++;
 259		SETATTR(templ, i, CKA_VALUE, NULL, value_len);
 260		i++;
 261
 262		/*
 263		 * Query the object with NULL values in the pValue spot
 264		 * so we know how much space to allocate for each field.
 265		 */
 266		ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i);
 267		if (ckrv != CKR_OK)  {
 268			SET_ERROR(kmfh, ckrv);
 269			return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */
 270		}
 271
 272		subject_len	= templ[0].ulValueLen;
 273		issuer_len	= templ[1].ulValueLen;
 274		serno_len	= templ[2].ulValueLen;
 275		id_len		= templ[3].ulValueLen;
 276		value_len	= templ[4].ulValueLen;
 277
 278		/*
 279		 * For PKCS#11 CKC_X_509 certificate objects,
 280		 * the following attributes must be defined.
 281		 * CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER,
 282		 * CKA_VALUE.
 283		 */
 284		if (subject_len == 0 || issuer_len == 0 ||
 285		    serno_len == 0 || value_len == 0) {
 286			return (KMF_ERR_INTERNAL);
 287		}
 288
 289		/* Only fetch the value field if we are saving the data */
 290		if (kmfcert != NULL) {
 291			int i = 0;
 292			value = malloc(value_len);
 293			if (value == NULL) {
 294				rv = KMF_ERR_MEMORY;
 295				goto errout;
 296			}
 297
 298			SETATTR(templ, i, CKA_VALUE, value, value_len);
 299			i++;
 300
 301			/* re-query the object with room for the value attr */
 302			ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj,
 303			    templ, i);
 304
 305			if (ckrv != CKR_OK)  {
 306				SET_ERROR(kmfh, ckrv);
 307				rv = KMF_ERR_INTERNAL;
 308				goto errout;
 309			}
 310
 311			kmfcert->certificate.Data = value;
 312			kmfcert->certificate.Length = value_len;
 313			kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED;
 314			kmfcert->kmf_private.keystore_type =
 315			    KMF_KEYSTORE_PK11TOKEN;
 316
 317			ckrv = getObjectLabel(kmfh, hObj, &label);
 318			if (ckrv == CKR_OK && label != NULL) {
 319				kmfcert->kmf_private.label = (char *)label;
 320			}
 321
 322			rv = KMF_OK;
 323		}
 324	}
 325
 326errout:
 327	if (rv != KMF_OK) {
 328		if (subject)
 329			free(subject);
 330		if (value)
 331			free(value);
 332
 333		if (kmfcert) {
 334			kmfcert->certificate.Data = NULL;
 335			kmfcert->certificate.Length = 0;
 336		}
 337	}
 338	return (rv);
 339}
 340
 341static void
 342free_objlist(OBJLIST *head)
 343{
 344	OBJLIST *temp = head;
 345
 346	while (temp != NULL) {
 347		head = head->next;
 348		free(temp);
 349		temp = head;
 350	}
 351}
 352
 353/*
 354 * The caller should make sure that the templ->pValue is NULL since
 355 * it will be overwritten below.
 356 */
 357static KMF_RETURN
 358get_attr(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
 359	CK_ATTRIBUTE *templ)
 360{
 361	CK_RV rv;
 362
 363	rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
 364	if (rv != CKR_OK) {
 365		SET_ERROR(kmfh, rv);
 366		return (KMF_ERR_INTERNAL);
 367	}
 368
 369	if (templ->ulValueLen > 0) {
 370		templ->pValue = malloc(templ->ulValueLen);
 371		if (templ->pValue == NULL)
 372			return (KMF_ERR_MEMORY);
 373
 374		rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
 375		if (rv != CKR_OK) {
 376			SET_ERROR(kmfh, rv);
 377			return (KMF_ERR_INTERNAL);
 378		}
 379	}
 380
 381	return (KMF_OK);
 382}
 383
 384/*
 385 * Match a certificate with an issuer and/or subject name.
 386 * This is tricky because we cannot reliably compare DER encodings
 387 * because RDNs may have their AV-pairs in different orders even
 388 * if the values are the same.  You must compare individual
 389 * AV pairs for the RDNs.
 390 *
 391 * RETURN: 0 for a match, non-zero for a non-match.
 392 */
 393static KMF_RETURN
 394matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
 395	KMF_X509_NAME *issuer, KMF_X509_NAME *subject)
 396{
 397	KMF_RETURN rv = KMF_OK;
 398	CK_ATTRIBUTE certattr;
 399	KMF_DATA name;
 400	KMF_X509_NAME dn;
 401
 402	if (issuer->numberOfRDNs > 0) {
 403		certattr.type = CKA_ISSUER;
 404		certattr.pValue = NULL;
 405		certattr.ulValueLen = 0;
 406
 407		rv = get_attr(kmfh, obj, &certattr);
 408
 409		if (rv == KMF_OK) {
 410			name.Data = certattr.pValue;
 411			name.Length = certattr.ulValueLen;
 412			rv = DerDecodeName(&name, &dn);
 413			if (rv == KMF_OK) {
 414				rv = kmf_compare_rdns(issuer, &dn);
 415				kmf_free_dn(&dn);
 416			}
 417			free(certattr.pValue);
 418		}
 419
 420		if (rv != KMF_OK)
 421			return (rv);
 422	}
 423	if (subject->numberOfRDNs > 0) {
 424		certattr.type = CKA_SUBJECT;
 425		certattr.pValue = NULL;
 426		certattr.ulValueLen = 0;
 427
 428		rv = get_attr(kmfh, obj, &certattr);
 429
 430		if (rv == KMF_OK) {
 431			name.Data = certattr.pValue;
 432			name.Length = certattr.ulValueLen;
 433			rv = DerDecodeName(&name, &dn);
 434			if (rv == KMF_OK) {
 435				rv = kmf_compare_rdns(subject, &dn);
 436				kmf_free_dn(&dn);
 437			}
 438			free(certattr.pValue);
 439		}
 440	}
 441
 442	return (rv);
 443}
 444
 445/*
 446 * delete "curr" node from the "newlist".
 447 */
 448static void
 449pk11_delete_obj_from_list(OBJLIST **newlist,
 450	OBJLIST **prev, OBJLIST **curr)
 451{
 452
 453	if (*curr == *newlist) {
 454		/* first node in the list */
 455		*newlist = (*curr)->next;
 456		*prev = (*curr)->next;
 457		free(*curr);
 458		*curr = *newlist;
 459	} else {
 460		(*prev)->next = (*curr)->next;
 461		free(*curr);
 462		*curr = (*prev)->next;
 463	}
 464}
 465
 466/*
 467 * search_certs
 468 *
 469 * Because this code is shared by the FindCert and
 470 * DeleteCert functions, put it in a separate routine
 471 * to save some work and make code easier to debug and
 472 * read.
 473 */
 474static KMF_RETURN
 475search_certs(KMF_HANDLE_T handle,
 476	char *label, char *issuer, char *subject, KMF_BIGINT *serial,
 477	boolean_t private, KMF_CERT_VALIDITY validity,
 478	OBJLIST **objlist, uint32_t *numobj)
 479{
 480	KMF_RETURN rv = KMF_OK;
 481	CK_RV ckrv = CKR_OK;
 482	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
 483	CK_ATTRIBUTE templ[10];
 484	CK_BBOOL true = TRUE;
 485	CK_OBJECT_CLASS	oclass = CKO_CERTIFICATE;
 486	CK_CERTIFICATE_TYPE ctype = CKC_X_509;
 487	KMF_X509_NAME subjectDN, issuerDN;
 488	int i;
 489	OBJLIST *newlist, *tail;
 490	CK_ULONG num = 0;
 491	uint32_t num_ok_certs = 0; /* number of non-expired or expired certs */
 492
 493	(void) memset(&templ, 0, 10 * sizeof (CK_ATTRIBUTE));
 494	(void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
 495	(void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
 496	i = 0;
 497	SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
 498	SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++;
 499	SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype,	sizeof (ctype)); i++;
 500
 501	if (label != NULL && strlen(label)) {
 502		SETATTR(templ, i, CKA_LABEL, label, strlen(label));
 503		i++;
 504	}
 505	if (private) {
 506		SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); i++;
 507	}
 508
 509	if (issuer != NULL && strlen(issuer)) {
 510		if ((rv = kmf_dn_parser(issuer, &issuerDN)) != KMF_OK)
 511			return (rv);
 512	}
 513	if (subject != NULL && strlen(subject)) {
 514		if ((rv = kmf_dn_parser(subject, &subjectDN)) != KMF_OK)
 515			return (rv);
 516	}
 517
 518	if (serial != NULL && serial->val != NULL && serial->len > 0) {
 519		SETATTR(templ, i, CKA_SERIAL_NUMBER, serial->val, serial->len);
 520		i++;
 521	}
 522
 523	(*numobj) = 0;
 524	*objlist = NULL;
 525	newlist = NULL;
 526
 527	ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, i);
 528	if (ckrv != CKR_OK)
 529		goto cleanup;
 530
 531	tail = newlist = NULL;
 532	while (ckrv == CKR_OK) {
 533		CK_OBJECT_HANDLE tObj;
 534		ckrv = C_FindObjects(kmfh->pk11handle, &tObj, 1, &num);
 535		if (ckrv != CKR_OK || num == 0)
 536			break;
 537
 538		/*
 539		 * 'matchcert' returns 0 if subject/issuer match
 540		 *
 541		 * If no match, move on to the next one
 542		 */
 543		if (matchcert(kmfh, tObj, &issuerDN, &subjectDN))
 544			continue;
 545
 546		if (newlist == NULL) {
 547			newlist = malloc(sizeof (OBJLIST));
 548			if (newlist == NULL) {
 549				rv = KMF_ERR_MEMORY;
 550				break;
 551			}
 552			newlist->handle = tObj;
 553			newlist->next = NULL;
 554			tail = newlist;
 555		} else {
 556			tail->next = malloc(sizeof (OBJLIST));
 557			if (tail->next != NULL) {
 558				tail = tail->next;
 559			} else {
 560				rv = KMF_ERR_MEMORY;
 561				break;
 562			}
 563			tail->handle = tObj;
 564			tail->next = NULL;
 565		}
 566		(*numobj)++;
 567	}
 568	ckrv = C_FindObjectsFinal(kmfh->pk11handle);
 569
 570cleanup:
 571	if (ckrv != CKR_OK) {
 572		SET_ERROR(kmfh, ckrv);
 573		rv = KMF_ERR_INTERNAL;
 574		if (newlist != NULL) {
 575			free_objlist(newlist);
 576			*numobj = 0;
 577			newlist = NULL;
 578		}
 579	} else {
 580		if (validity == KMF_ALL_CERTS) {
 581			*objlist = newlist;
 582		} else {
 583			OBJLIST *node, *prev;
 584			KMF_X509_DER_CERT  tmp_kmf_cert;
 585			uint32_t i = 0;
 586
 587			node = prev = newlist;
 588			/*
 589			 * Now check to see if any found certificate is expired
 590			 * or valid.
 591			 */
 592			while (node != NULL && i < (*numobj)) {
 593				(void) memset(&tmp_kmf_cert, 0,
 594				    sizeof (KMF_X509_DER_CERT));
 595				rv = PK11Cert2KMFCert(kmfh, node->handle,
 596				    &tmp_kmf_cert);
 597				if (rv != KMF_OK) {
 598					goto cleanup1;
 599				}
 600
 601				rv = kmf_check_cert_date(handle,
 602				    &tmp_kmf_cert.certificate);
 603
 604				if (validity == KMF_NONEXPIRED_CERTS) {
 605					if (rv == KMF_OK)  {
 606						num_ok_certs++;
 607						prev = node;
 608						node = node->next;
 609					} else if (rv ==
 610					    KMF_ERR_VALIDITY_PERIOD) {
 611						/*
 612						 * expired - remove it from list
 613						 */
 614						pk11_delete_obj_from_list(
 615						    &newlist, &prev, &node);
 616					} else {
 617						goto cleanup1;
 618					}
 619				}
 620
 621				if (validity == KMF_EXPIRED_CERTS) {
 622					if (rv == KMF_ERR_VALIDITY_PERIOD)  {
 623						num_ok_certs++;
 624						prev = node;
 625						node = node->next;
 626						rv = KMF_OK;
 627					} else if (rv == KMF_OK) {
 628						/*
 629						 * valid - remove it from list
 630						 */
 631						pk11_delete_obj_from_list(
 632						    &newlist, &prev, &node);
 633					} else {
 634						goto cleanup1;
 635					}
 636				}
 637				i++;
 638				kmf_free_kmf_cert(handle, &tmp_kmf_cert);
 639			}
 640			*numobj = num_ok_certs;
 641			*objlist = newlist;
 642		}
 643	}
 644
 645cleanup1:
 646	if (rv != KMF_OK && newlist != NULL) {
 647		free_objlist(newlist);
 648		*numobj = 0;
 649		*objlist = NULL;
 650	}
 651
 652	if (issuer != NULL)
 653		kmf_free_dn(&issuerDN);
 654
 655	if (subject != NULL)
 656		kmf_free_dn(&subjectDN);
 657
 658	return (rv);
 659}
 660
 661/*
 662 * The caller may pass a NULL value for kmf_cert below and the function will
 663 * just return the number of certs found (in num_certs).
 664 */
 665KMF_RETURN
 666KMFPK11_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
 667{
 668	KMF_RETURN rv = 0;
 669	uint32_t want_certs;
 670	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
 671	OBJLIST *objlist = NULL;
 672	uint32_t *num_certs;
 673	KMF_X509_DER_CERT *kmf_cert = NULL;
 674	char *certlabel = NULL;
 675	char *issuer = NULL;
 676	char *subject = NULL;
 677	KMF_BIGINT *serial = NULL;
 678	KMF_CERT_VALIDITY validity;
 679	KMF_CREDENTIAL *cred = NULL;
 680	boolean_t private;
 681
 682	if (kmfh == NULL)
 683		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
 684
 685	if (kmfh->pk11handle == CK_INVALID_HANDLE)
 686		return (KMF_ERR_NO_TOKEN_SELECTED);
 687
 688	num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
 689	if (num_certs == NULL)
 690		return (KMF_ERR_BAD_PARAMETER);
 691
 692	if (*num_certs > 0)
 693		want_certs = *num_certs;
 694	else
 695		want_certs = MAXINT; /* count them all */
 696
 697	*num_certs = 0;
 698
 699	/* Get the optional returned certificate list */
 700	kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
 701	    numattr);
 702
 703	/* Get optional search criteria attributes */
 704	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
 705	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
 706	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
 707	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
 708
 709	rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
 710	    &validity, NULL);
 711	if (rv != KMF_OK) {
 712		validity = KMF_ALL_CERTS;
 713		rv = KMF_OK;
 714	}
 715
 716	rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
 717	    (void *)&private, NULL);
 718	if (rv != KMF_OK) {
 719		private = B_FALSE;
 720		rv = KMF_OK;
 721	}
 722
 723	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
 724	if (cred != NULL) {
 725		rv = pk11_authenticate(handle, cred);
 726		if (rv != KMF_OK)
 727			return (rv);
 728	}
 729
 730	/* Start searching */
 731	rv = search_certs(handle, certlabel, issuer, subject, serial, private,
 732	    validity, &objlist, num_certs);
 733
 734	if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) {
 735		OBJLIST *node = objlist;
 736		int i = 0;
 737		while (node != NULL && i < want_certs) {
 738			rv = PK11Cert2KMFCert(kmfh, node->handle,
 739			    &kmf_cert[i]);
 740			i++;
 741			node = node->next;
 742		}
 743	}
 744
 745	if (objlist != NULL)
 746		free_objlist(objlist);
 747
 748	if (*num_certs == 0)
 749		rv = KMF_ERR_CERT_NOT_FOUND;
 750
 751	return (rv);
 752}
 753
 754/*ARGSUSED*/
 755void
 756KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert)
 757{
 758	if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) {
 759		free(kmf_cert->certificate.Data);
 760		kmf_cert->certificate.Data = NULL;
 761		kmf_cert->certificate.Length = 0;
 762
 763		if (kmf_cert->kmf_private.label != NULL) {
 764			free(kmf_cert->kmf_private.label);
 765			kmf_cert->kmf_private.label = NULL;
 766		}
 767	}
 768}
 769
 770KMF_RETURN
 771KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey,
 772	KMF_DATA *eData)
 773{
 774	KMF_RETURN ret = KMF_OK;
 775	CK_RV rv;
 776	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
 777	CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY;
 778	CK_KEY_TYPE ckKeyType;
 779	KMF_DATA Modulus, Exponent, Prime, Subprime, Base, Value;
 780	KMF_OID *Algorithm;
 781	BerElement *asn1 = NULL;
 782	BerValue *PubKeyParams = NULL, *EncodedKey = NULL;
 783	KMF_X509_SPKI spki;
 784	CK_BYTE ec_params[256], ec_point[256];
 785
 786	CK_ATTRIBUTE rsaTemplate[4];
 787	CK_ATTRIBUTE dsaTemplate[6];
 788	CK_ATTRIBUTE ecdsaTemplate[6];
 789
 790	if (kmfh == NULL)
 791		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
 792
 793	if (kmfh->pk11handle == CK_INVALID_HANDLE)
 794		return (KMF_ERR_NO_TOKEN_SELECTED);
 795
 796	if (pKey == NULL || pKey->keyp == CK_INVALID_HANDLE)
 797		return (KMF_ERR_BAD_PARAMETER);
 798
 799	(void) memset(&Modulus, 0, sizeof (Modulus));
 800	(void) memset(&Exponent, 0, sizeof (Exponent));
 801	(void) memset(&Prime, 0, sizeof (Prime));
 802	(void) memset(&Subprime, 0, sizeof (Subprime));
 803	(void) memset(&Base, 0, sizeof (Base));
 804	(void) memset(&Value, 0, sizeof (Value));
 805
 806	switch (pKey->keyalg) {
 807		case KMF_RSA:
 808			SETATTR(rsaTemplate, 0, CKA_CLASS, &ckObjClass,
 809			    sizeof (ckObjClass));
 810			SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
 811			    sizeof (ckKeyType));
 812			SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
 813			    Modulus.Length);
 814			SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
 815			    Exponent.Data, Exponent.Length);
 816			/* Get the length of the fields */
 817			rv = C_GetAttributeValue(kmfh->pk11handle,
 818			    (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
 819			if (rv != CKR_OK) {
 820				SET_ERROR(kmfh, rv);
 821				return (KMF_ERR_BAD_PARAMETER);
 822			}
 823
 824			Modulus.Length = rsaTemplate[2].ulValueLen;
 825			Modulus.Data = malloc(Modulus.Length);
 826			if (Modulus.Data == NULL)
 827				return (KMF_ERR_MEMORY);
 828
 829			Exponent.Length = rsaTemplate[3].ulValueLen;
 830			Exponent.Data = malloc(Exponent.Length);
 831			if (Exponent.Data == NULL) {
 832				free(Modulus.Data);
 833				return (KMF_ERR_MEMORY);
 834			}
 835
 836			SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
 837			    Modulus.Length);
 838			SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
 839			    Exponent.Data, Exponent.Length);
 840			/* Now get the values */
 841			rv = C_GetAttributeValue(kmfh->pk11handle,
 842			    (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
 843			if (rv != CKR_OK) {
 844				SET_ERROR(kmfh, rv);
 845				free(Modulus.Data);
 846				free(Exponent.Data);
 847				return (KMF_ERR_BAD_PARAMETER);
 848			}
 849
 850			/*
 851			 * This is the KEY algorithm, not the
 852			 * signature algorithm.
 853			 */
 854			Algorithm = x509_algid_to_algoid(KMF_ALGID_RSA);
 855			if (Algorithm != NULL) {
 856
 857				/* Encode the RSA Key Data */
 858				if ((asn1 = kmfder_alloc()) == NULL) {
 859					free(Modulus.Data);
 860					free(Exponent.Data);
 861					return (KMF_ERR_MEMORY);
 862				}
 863				if (kmfber_printf(asn1, "{II}",	Modulus.Data,
 864				    Modulus.Length, Exponent.Data,
 865				    Exponent.Length) == -1) {
 866					kmfber_free(asn1, 1);
 867					free(Modulus.Data);
 868					free(Exponent.Data);
 869					return (KMF_ERR_ENCODING);
 870				}
 871				if (kmfber_flatten(asn1, &EncodedKey) == -1) {
 872					kmfber_free(asn1, 1);
 873					free(Modulus.Data);
 874					free(Exponent.Data);
 875					return (KMF_ERR_ENCODING);
 876				}
 877				kmfber_free(asn1, 1);
 878			}
 879
 880			free(Exponent.Data);
 881			free(Modulus.Data);
 882
 883			break;
 884		case KMF_DSA:
 885			SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass,
 886			    sizeof (ckObjClass));
 887			SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
 888			    sizeof (ckKeyType));
 889			SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
 890			    Prime.Length);
 891			SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
 892			    Subprime.Length);
 893			SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
 894			    Base.Length);
 895			SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
 896			    Value.Length);
 897
 898			/* Get the length of the fields */
 899			rv = C_GetAttributeValue(kmfh->pk11handle,
 900			    (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
 901			if (rv != CKR_OK) {
 902				SET_ERROR(kmfh, rv);
 903				return (KMF_ERR_BAD_PARAMETER);
 904			}
 905			Prime.Length = dsaTemplate[2].ulValueLen;
 906			Prime.Data = malloc(Prime.Length);
 907			if (Prime.Data == NULL) {
 908				return (KMF_ERR_MEMORY);
 909			}
 910
 911			Subprime.Length = dsaTemplate[3].ulValueLen;
 912			Subprime.Data = malloc(Subprime.Length);
 913			if (Subprime.Data == NULL) {
 914				free(Prime.Data);
 915				return (KMF_ERR_MEMORY);
 916			}
 917
 918			Base.Length = dsaTemplate[4].ulValueLen;
 919			Base.Data = malloc(Base.Length);
 920			if (Base.Data == NULL) {
 921				free(Prime.Data);
 922				free(Subprime.Data);
 923				return (KMF_ERR_MEMORY);
 924			}
 925
 926			Value.Length = dsaTemplate[5].ulValueLen;
 927			Value.Data = malloc(Value.Length);
 928			if (Value.Data == NULL) {
 929				free(Prime.Data);
 930				free(Subprime.Data);
 931				free(Base.Data);
 932				return (KMF_ERR_MEMORY);
 933			}
 934			SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
 935			    Prime.Length);
 936			SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
 937			    Subprime.Length);
 938			SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
 939			    Base.Length);
 940			SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
 941			    Value.Length);
 942
 943			/* Now get the values */
 944			rv = C_GetAttributeValue(kmfh->pk11handle,
 945			    (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
 946			if (rv != CKR_OK) {
 947				free(Prime.Data);
 948				free(Subprime.Data);
 949				free(Base.Data);
 950				free(Value.Data);
 951				SET_ERROR(kmfh, rv);
 952				return (KMF_ERR_BAD_PARAMETER);
 953			}
 954			/*
 955			 * This is the KEY algorithm, not the
 956			 * signature algorithm.
 957			 */
 958			Algorithm = x509_algid_to_algoid(KMF_ALGID_DSA);
 959
 960			/* Encode the DSA Algorithm Parameters */
 961			if ((asn1 = kmfder_alloc()) == NULL) {
 962				free(Prime.Data);
 963				free(Subprime.Data);
 964				free(Base.Data);
 965				free(Value.Data);
 966				return (KMF_ERR_MEMORY);
 967			}
 968
 969			if (kmfber_printf(asn1, "{III}", Prime.Data,
 970			    Prime.Length, Subprime.Data, Subprime.Length,
 971			    Base.Data, Base.Length) == -1) {
 972
 973				kmfber_free(asn1, 1);
 974				free(Prime.Data);
 975				free(Subprime.Data);
 976				free(Base.Data);
 977				free(Value.Data);
 978				return (KMF_ERR_ENCODING);
 979			}
 980			if (kmfber_flatten(asn1, &PubKeyParams) == -1) {
 981				kmfber_free(asn1, 1);
 982				free(Prime.Data);
 983				free(Subprime.Data);
 984				free(Base.Data);
 985				free(Value.Data);
 986				return (KMF_ERR_ENCODING);
 987			}
 988			kmfber_free(asn1, 1);
 989			free(Prime.Data);
 990			free(Subprime.Data);
 991			free(Base.Data);
 992
 993			/* Encode the DSA Key Value */
 994			if ((asn1 = kmfder_alloc()) == NULL) {
 995				free(Value.Data);
 996				return (KMF_ERR_MEMORY);
 997			}
 998
 999			if (kmfber_printf(asn1, "I",
1000			    Value.Data, Value.Length) == -1) {
1001				kmfber_free(asn1, 1);
1002				free(Value.Data);
1003				return (KMF_ERR_ENCODING);
1004			}
1005			if (kmfber_flatten(asn1, &EncodedKey) == -1) {
1006				kmfber_free(asn1, 1);
1007				free(Value.Data);
1008				return (KMF_ERR_ENCODING);
1009			}
1010			kmfber_free(asn1, 1);
1011			free(Value.Data);
1012			break;
1013		case KMF_ECDSA:
1014			/* The EC_PARAMS are the PubKey algorithm parameters */
1015			PubKeyParams = calloc(1, sizeof (BerValue));
1016			if (PubKeyParams == NULL)
1017				return (KMF_ERR_MEMORY);
1018			EncodedKey = calloc(1, sizeof (BerValue));
1019			if (EncodedKey == NULL) {
1020				free(PubKeyParams);
1021				return (KMF_ERR_MEMORY);
1022			}
1023			SETATTR(ecdsaTemplate, 0, CKA_EC_PARAMS,
1024			    &ec_params, sizeof (ec_params));
1025			SETATTR(ecdsaTemplate, 1, CKA_EC_POINT,
1026			    &ec_point, sizeof (ec_point));
1027
1028			/* Get the length of the fields */
1029			rv = C_GetAttributeValue(kmfh->pk11handle,
1030			    (CK_OBJECT_HANDLE)pKey->keyp,
1031			    ecdsaTemplate, 2);
1032			if (rv != CKR_OK) {
1033				SET_ERROR(kmfh, rv);
1034				return (KMF_ERR_BAD_PARAMETER);
1035			}
1036			/* The params are to be used as algorithm parameters */
1037			PubKeyParams->bv_val = (char *)ec_params;
1038			PubKeyParams->bv_len = ecdsaTemplate[0].ulValueLen;
1039			/*
1040			 * The EC_POINT is to be used as the subject pub key.
1041			 */
1042			EncodedKey->bv_val = (char *)ec_point;
1043			EncodedKey->bv_len = ecdsaTemplate[1].ulValueLen;
1044
1045			/* Use the EC_PUBLIC_KEY OID */
1046			Algorithm = (KMF_OID *)&KMFOID_EC_PUBLIC_KEY;
1047			break;
1048		default:
1049			return (KMF_ERR_BAD_PARAMETER);
1050	}
1051
1052	/* Now, build an SPKI structure for the final encoding step */
1053	spki.algorithm.algorithm = *Algorithm;
1054	if (PubKeyParams != NULL) {
1055		spki.algorithm.parameters.Data =
1056		    (uchar_t *)PubKeyParams->bv_val;
1057		spki.algorithm.parameters.Length = PubKeyParams->bv_len;
1058	} else {
1059		spki.algorithm.parameters.Data = NULL;
1060		spki.algorithm.parameters.Length = 0;
1061	}
1062
1063	if (EncodedKey != NULL) {
1064		spki.subjectPublicKey.Data = (uchar_t *)EncodedKey->bv_val;
1065		spki.subjectPublicKey.Length = EncodedKey->bv_len;
1066	} else {
1067		spki.subjectPublicKey.Data = NULL;
1068		spki.subjectPublicKey.Length = 0;
1069	}
1070
1071	/* Finally, encode the entire SPKI record */
1072	ret = DerEncodeSPKI(&spki, eData);
1073
1074cleanup:
1075	if (EncodedKey) {
1076		if (pKey->keyalg != KMF_ECDSA)
1077			free(EncodedKey->bv_val);
1078		free(EncodedKey);
1079	}
1080
1081	if (PubKeyParams) {
1082		if (pKey->keyalg != KMF_ECDSA)
1083			free(PubKeyParams->bv_val);
1084		free(PubKeyParams);
1085	}
1086
1087	return (ret);
1088}
1089
1090static KMF_RETURN
1091CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
1092{
1093	KMF_RETURN rv = 0;
1094	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1095
1096	KMF_X509_CERTIFICATE *signed_cert_ptr = NULL;
1097	KMF_DATA data;
1098	KMF_DATA Id;
1099
1100	CK_RV ckrv;
1101	CK_ULONG subject_len, issuer_len, serno_len;
1102	CK_BYTE *subject, *issuer, *serial, nullserno;
1103	CK_BBOOL true = TRUE;
1104	CK_CERTIFICATE_TYPE certtype = CKC_X_509;
1105	CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
1106	CK_ATTRIBUTE x509templ[11];
1107	CK_OBJECT_HANDLE hCert = NULL;
1108	int i;
1109
1110	if (kmfh == NULL)
1111		return (KMF_ERR_INTERNAL); /* should not happen */
1112
1113	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1114		return (KMF_ERR_INTERNAL); /* should not happen */
1115
1116	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0)
1117		return (KMF_ERR_INTERNAL);  /* should not happen */
1118
1119	/*
1120	 * The data *must* be a DER encoded X.509 certificate.
1121	 * Convert it to a CSSM cert and then parse the fields so
1122	 * the PKCS#11 attributes can be filled in correctly.
1123	 */
1124	rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert,
1125	    &signed_cert_ptr);
1126	if (rv != KMF_OK) {
1127		return (KMF_ERR_ENCODING);
1128	}
1129
1130	/*
1131	 * Encode fields into PKCS#11 attributes.
1132	 */
1133
1134	/* Get the subject name */
1135	rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data);
1136	if (rv == KMF_OK) {
1137		subject = data.Data;
1138		subject_len = data.Length;
1139	} else {
1140		rv = KMF_ERR_ENCODING;
1141		goto cleanup;
1142	}
1143
1144	/* Encode the issuer */
1145	rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data);
1146	if (rv == KMF_OK) {
1147		issuer = data.Data;
1148		issuer_len = data.Length;
1149	} else {
1150		rv = KMF_ERR_ENCODING;
1151		goto cleanup;
1152	}
1153
1154	/* Encode serial number */
1155	if (signed_cert_ptr->certificate.serialNumber.len > 0 &&
1156	    signed_cert_ptr->certificate.serialNumber.val != NULL) {
1157		serial = signed_cert_ptr->certificate.serialNumber.val;
1158		serno_len = signed_cert_ptr->certificate.serialNumber.len;
1159	} else {
1160		/*
1161		 * RFC3280 says to gracefully handle certs with serial numbers
1162		 * of 0.
1163		 */
1164		nullserno = '\0';
1165		serial  = &nullserno;
1166		serno_len = 1;
1167	}
1168
1169	/* Generate an ID from the SPKI data */
1170	rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo,
1171	    &Id);
1172
1173	if (rv != KMF_OK) {
1174		goto cleanup;
1175	}
1176
1177	i = 0;
1178	SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++;
1179	SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype,
1180	    sizeof (certtype));
1181	i++;
1182	SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
1183	SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++;
1184	SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++;
1185	SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++;
1186	SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++;
1187	SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++;
1188	if (label != NULL && strlen(label)) {
1189		SETATTR(x509templ, i, CKA_LABEL, label, strlen(label));	i++;
1190	}
1191	/*
1192	 * The cert object handle is actually "leaked" here.  If the app
1193	 * really wants to clean up the data space, it will have to call
1194	 * KMF_DeleteCert and specify the softtoken keystore.
1195	 */
1196	ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert);
1197	if (ckrv != CKR_OK) {
1198		/* Report authentication failures to the caller */
1199		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
1200		    ckrv == CKR_PIN_INCORRECT ||
1201		    ckrv == CKR_PIN_INVALID ||
1202		    ckrv == CKR_PIN_EXPIRED ||
1203		    ckrv == CKR_PIN_LOCKED ||
1204		    ckrv == CKR_SESSION_READ_ONLY)
1205			rv = KMF_ERR_AUTH_FAILED;
1206		else
1207			rv = KMF_ERR_INTERNAL;
1208		SET_ERROR(kmfh, ckrv);
1209	}
1210	free(subject);
1211	free(issuer);
1212
1213cleanup:
1214	if (Id.Data != NULL)
1215		free(Id.Data);
1216
1217	if (signed_cert_ptr) {
1218		kmf_free_signed_cert(signed_cert_ptr);
1219		free(signed_cert_ptr);
1220	}
1221	return (rv);
1222}
1223
1224
1225KMF_RETURN
1226KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1227{
1228	KMF_RETURN rv = 0;
1229	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1230	KMF_DATA *cert = NULL;
1231	KMF_CREDENTIAL *cred = NULL;
1232	char *label = NULL;
1233
1234	if (kmfh == NULL)
1235		return (KMF_ERR_UNINITIALIZED);
1236
1237	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1238		return (KMF_ERR_NO_TOKEN_SELECTED);
1239
1240	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
1241	if (cert == NULL || cert->Data == NULL || cert->Length == 0)
1242		return (KMF_ERR_BAD_PARAMETER);
1243
1244	/* label attribute is optional */
1245	label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1246
1247	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
1248	if (cred != NULL) {
1249		rv = pk11_authenticate(handle, cred);
1250		if (rv != KMF_OK)
1251			return (rv);
1252	}
1253
1254	rv = CreateCertObject(handle, label, cert);
1255	return (rv);
1256}
1257
1258KMF_RETURN
1259KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1260{
1261	KMF_RETURN rv = 0;
1262	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1263	char *certfile = NULL;
1264	char *label = NULL;
1265	KMF_ENCODE_FORMAT format;
1266	KMF_CREDENTIAL *cred = NULL;
1267	KMF_DATA  cert1 = { NULL, 0};
1268	KMF_DATA  cert2 = { NULL, 0};
1269
1270	if (kmfh == NULL)
1271		return (KMF_ERR_UNINITIALIZED);
1272
1273	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1274		return (KMF_ERR_NO_TOKEN_SELECTED);
1275
1276	/*
1277	 * Get the input cert filename attribute, check if it is a valid
1278	 * certificate and auto-detect the file format of it.
1279	 */
1280	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
1281	if (certfile == NULL)
1282		return (KMF_ERR_BAD_PARAMETER);
1283
1284	rv = kmf_is_cert_file(handle, certfile, &format);
1285	if (rv != KMF_OK)
1286		return (rv);
1287
1288	/* Read in the CERT file */
1289	rv = kmf_read_input_file(handle, certfile, &cert1);
1290	if (rv != KMF_OK) {
1291		return (rv);
1292	}
1293
1294	/* The label attribute is optional */
1295	label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1296
1297	/*
1298	 * If the input certificate is in PEM format, we need to convert
1299	 * it to DER first.
1300	 */
1301	if (format == KMF_FORMAT_PEM) {
1302		int derlen;
1303		rv = kmf_pem_to_der(cert1.Data, cert1.Length,
1304		    &cert2.Data, &derlen);
1305		if (rv != KMF_OK) {
1306			goto out;
1307		}
1308		cert2.Length = (size_t)derlen;
1309	}
1310
1311	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
1312	if (cred != NULL) {
1313		rv = pk11_authenticate(handle, cred);
1314		if (rv != KMF_OK)
1315			return (rv);
1316	}
1317
1318	rv = CreateCertObject(handle, label,
1319	    format == KMF_FORMAT_ASN1 ? &cert1 : &cert2);
1320
1321out:
1322	if (cert1.Data != NULL) {
1323		free(cert1.Data);
1324	}
1325
1326	if (cert2.Data != NULL) {
1327		free(cert2.Data);
1328	}
1329
1330	return (rv);
1331}
1332
1333KMF_RETURN
1334KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1335{
1336	KMF_RETURN rv = 0;
1337	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1338	OBJLIST *objlist;
1339	uint32_t numObjects = 0;
1340	char *certlabel = NULL;
1341	char *issuer = NULL;
1342	char *subject = NULL;
1343	KMF_BIGINT *serial = NULL;
1344	KMF_CERT_VALIDITY validity;
1345	boolean_t private;
1346
1347	if (kmfh == NULL)
1348		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1349
1350	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1351		return (KMF_ERR_NO_TOKEN_SELECTED);
1352
1353
1354	/* Get the search criteria attributes. They are all optional. */
1355	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1356	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1357	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1358	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1359
1360	rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1361	    &validity, NULL);
1362	if (rv != KMF_OK) {
1363		validity = KMF_ALL_CERTS;
1364		rv = KMF_OK;
1365	}
1366
1367	rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
1368	    (void *)&private, NULL);
1369	if (rv != KMF_OK) {
1370		private = B_FALSE;
1371		rv = KMF_OK;
1372	}
1373
1374	/*
1375	 * Start searching for certificates that match the criteria and
1376	 * delete them.
1377	 */
1378	objlist = NULL;
1379	rv = search_certs(handle, certlabel, issuer, subject, serial,
1380	    private, validity, &objlist, &numObjects);
1381
1382	if (rv == KMF_OK && objlist != NULL) {
1383		OBJLIST *node = objlist;
1384
1385		while (node != NULL) {
1386			CK_RV ckrv;
1387			ckrv = C_DestroyObject(kmfh->pk11handle, node->handle);
1388			if (ckrv != CKR_OK) {
1389				SET_ERROR(kmfh, ckrv);
1390				rv = KMF_ERR_INTERNAL;
1391				break;
1392			}
1393			node = node->next;
1394		}
1395		free_objlist(objlist);
1396	}
1397
1398	if (rv == KMF_OK && numObjects == 0)
1399		rv = KMF_ERR_CERT_NOT_FOUND;
1400
1401out:
1402	return (rv);
1403}
1404
1405static CK_RV
1406gendsa_keypair(KMF_HANDLE *kmfh, boolean_t storekey,
1407	CK_OBJECT_HANDLE *pubKey,
1408	CK_OBJECT_HANDLE *priKey)
1409{
1410	CK_RV ckrv = CKR_OK;
1411	CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1412	static CK_ULONG	dsaKeyType = CKK_DSA;
1413	static CK_BBOOL	true = TRUE;
1414	static CK_BBOOL	false = FALSE;
1415	static CK_OBJECT_CLASS	priClass = CKO_PRIVATE_KEY;
1416	static CK_OBJECT_CLASS	pubClass = CKO_PUBLIC_KEY;
1417
1418	static CK_BYTE ckDsaPrime[128] = {
1419	0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2,
1420	0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c,
1421	0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3,
1422	0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc,
1423	0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c,
1424	0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8,
1425	0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8,
1426	0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3,
1427	0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09,
1428	0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c,
1429	0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5,
1430	0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb,
1431	0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b,
1432	0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11,
1433	0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27,
1434	0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b};
1435
1436	static CK_BYTE ckDsaSubPrime[20] = {
1437	0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe,
1438	0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc,
1439	0x78, 0x47, 0xb0, 0xd5};
1440
1441	static CK_BYTE ckDsaBase[128] = {
1442	0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b,
1443	0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5,
1444	0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3,
1445	0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c,
1446	0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2,
1447	0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd,
1448	0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3,
1449	0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a,
1450	0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05,
1451	0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a,
1452	0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67,
1453	0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73,
1454	0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f,
1455	0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19,
1456	0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce,
1457	0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 };
1458
1459	static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = {
1460	{ CKA_CLASS, &pubClass, sizeof (pubClass) },
1461	{ CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) },
1462	{ CKA_TOKEN, &true, sizeof (true)},
1463	{ CKA_PRIVATE, &false, sizeof (false)},
1464	{ CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) },
1465	{ CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)},
1466	{ CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) },
1467	{ CKA_VERIFY, &true, sizeof (true) },
1468};
1469
1470#define	NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
1471					sizeof (CK_ATTRIBUTE))
1472#define	MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
1473				    sizeof (CK_ATTRIBUTE))
1474
1475	static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = {
1476	{CKA_CLASS, &priClass, sizeof (priClass)},
1477	{CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)},
1478	{CKA_TOKEN, &true, sizeof (true)},
1479	{CKA_PRIVATE, &true, sizeof (true)},
1480	{CKA_SIGN, &true, sizeof (true)},
1481	};
1482
1483#define	NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
1484					sizeof (CK_ATTRIBUTE))
1485#define	MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
1486				sizeof (CK_ATTRIBUTE))
1487	CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0};
1488
1489	SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN,
1490	    (storekey ? &true : &false), sizeof (CK_BBOOL));
1491
1492	ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1493	    ckDsaPubKeyTemplate,
1494	    (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)),
1495	    ckDsaPriKeyTemplate,
1496	    (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)),
1497	    pubKey, priKey);
1498	if (ckrv != CKR_OK) {
1499		SET_ERROR(kmfh, ckrv);
1500		return (KMF_ERR_KEYGEN_FAILED);
1501	}
1502
1503	return (ckrv);
1504}
1505
1506static CK_RV
1507genrsa_keypair(KMF_HANDLE *kmfh, CK_ULONG modulusBits,
1508	boolean_t storekey, KMF_BIGINT *rsaexp,
1509	CK_OBJECT_HANDLE *pubKey,
1510	CK_OBJECT_HANDLE *priKey)
1511{
1512	CK_RV ckrv = CKR_OK;
1513	CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1514	CK_ATTRIBUTE rsaPubKeyTemplate[16];
1515	CK_ATTRIBUTE rsaPriKeyTemplate[16];
1516	CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
1517	int numpubattr = 0, numpriattr = 0;
1518	static CK_BYTE	PubExpo[3] = {0x01, 0x00, 0x01};
1519	static CK_BBOOL	true = TRUE;
1520	static CK_BBOOL	false = FALSE;
1521
1522	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN,
1523	    (storekey ? &true : &false), sizeof (CK_BBOOL));
1524	numpubattr++;
1525
1526	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS,
1527	    &modulusBits, sizeof (modulusBits));
1528	numpubattr++;
1529
1530	if (rsaexp != NULL && (rsaexp->len > 0 && rsaexp->val != NULL)) {
1531		SETATTR(rsaPubKeyTemplate, numpubattr,
1532		    CKA_PUBLIC_EXPONENT,
1533		    rsaexp->val, rsaexp->len);
1534		numpubattr++;
1535	} else {
1536		SETATTR(rsaPubKeyTemplate, numpubattr,
1537		    CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo));
1538		numpubattr++;
1539	}
1540	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT,
1541	    &true, sizeof (true));
1542	numpubattr++;
1543	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY,
1544	    &true, sizeof (true));
1545	numpubattr++;
1546	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_WRAP,
1547	    &true, sizeof (true));
1548	numpubattr++;
1549
1550	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN,
1551	    (storekey ? &true : &false), sizeof (CK_BBOOL));
1552	numpriattr++;
1553	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true,
1554	    sizeof (true));
1555	numpriattr++;
1556	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true,
1557	    sizeof (true));
1558	numpriattr++;
1559	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true,
1560	    sizeof (true));
1561	numpriattr++;
1562	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_UNWRAP, &true,
1563	    sizeof (true));
1564	numpriattr++;
1565
1566	ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1567	    rsaPubKeyTemplate, numpubattr,
1568	    rsaPriKeyTemplate, numpriattr,
1569	    pubKey, priKey);
1570	if (ckrv != CKR_OK) {
1571		SET_ERROR(kmfh, ckrv);
1572		return (ckrv);
1573	}
1574
1575	return (ckrv);
1576}
1577
1578static CK_RV
1579genecc_keypair(KMF_HANDLE *kmfh,
1580	boolean_t ontoken,
1581	KMF_OID *curveoid,
1582	CK_OBJECT_HANDLE *pubKey,
1583	CK_OBJECT_HANDLE *priKey)
1584{
1585	CK_RV ckrv;
1586	CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1587	CK_MECHANISM keyGenMech = {CKM_EC_KEY_PAIR_GEN, NULL, 0};
1588	const ulong_t publicKey = CKO_PUBLIC_KEY;
1589	const ulong_t privateKey = CKO_PRIVATE_KEY;
1590	const ulong_t keytype = CKK_EC;
1591	static CK_BBOOL	true = TRUE;
1592	static CK_BBOOL	false = FALSE;
1593	CK_ATTRIBUTE public_template[6];
1594	CK_ATTRIBUTE private_template[6];
1595	int numpubattr, numpriattr;
1596
1597	numpubattr = 0;
1598	SETATTR(public_template, numpubattr, CKA_CLASS,
1599	    &publicKey, sizeof (publicKey));
1600	numpubattr++;
1601	SETATTR(public_template, numpubattr, CKA_KEY_TYPE,
1602	    &keytype, sizeof (keytype));
1603	numpubattr++;
1604	SETATTR(public_template, numpubattr, CKA_EC_PARAMS,
1605	    curveoid->Data, curveoid->Length);
1606	numpubattr++;
1607	SETATTR(public_template, numpubattr, CKA_TOKEN,
1608	    ontoken ? &true : &false, sizeof (true));
1609	numpubattr++;
1610	SETATTR(public_template, numpubattr, CKA_VERIFY,
1611	    &true, sizeof (true));
1612	numpubattr++;
1613	SETATTR(public_template, numpubattr, CKA_PRIVATE,
1614	    &false, sizeof (false));
1615	numpubattr++;
1616
1617	numpriattr = 0;
1618	SETATTR(private_template, numpriattr, CKA_CLASS,
1619	    &privateKey, sizeof (privateKey));
1620	numpriattr++;
1621	SETATTR(private_template, numpriattr, CKA_KEY_TYPE,
1622	    &keytype, sizeof (keytype));
1623	numpriattr++;
1624	SETATTR(private_template, numpriattr, CKA_TOKEN,
1625	    ontoken ? &true : &false, sizeof (true));
1626	numpriattr++;
1627	SETATTR(private_template, numpriattr, CKA_PRIVATE,
1628	    &true, sizeof (true));
1629	numpriattr++;
1630	SETATTR(private_template, numpriattr, CKA_SIGN,
1631	    &true, sizeof (true));
1632	numpriattr++;
1633	SETATTR(private_template, numpriattr, CKA_DERIVE,
1634	    &true, sizeof (true));
1635	numpriattr++;
1636
1637	ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1638	    public_template, numpubattr,
1639	    private_template, numpriattr,
1640	    pubKey, priKey);
1641	if (ckrv != CKR_OK) {
1642		SET_ERROR(kmfh, ckrv);
1643		return (ckrv);
1644	}
1645
1646	return (ckrv);
1647}
1648
1649KMF_RETURN
1650KMFPK11_CreateKeypair(KMF_HANDLE_T handle,
1651	int numattr,
1652	KMF_ATTRIBUTE *attlist)
1653{
1654	KMF_RETURN rv = KMF_OK;
1655	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1656	KMF_DATA IDInput, IDOutput;
1657	KMF_CREDENTIAL *cred;
1658	KMF_KEY_ALG keytype = KMF_RSA;
1659	KMF_KEY_HANDLE *pubkey, *privkey;
1660
1661	CK_RV			ckrv = 0;
1662	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
1663	CK_ATTRIBUTE labelattr[1];
1664	CK_ATTRIBUTE idattr[1];
1665	CK_OBJECT_HANDLE pubKey, priKey;
1666
1667	char IDHashData[SHA1_HASH_LENGTH];
1668	static CK_ULONG	modulusBits = 1024;
1669	uint32_t	modulusBits_size = sizeof (CK_ULONG);
1670	SHA1_CTX ctx;
1671	boolean_t storekey = TRUE;
1672	char *keylabel = NULL;
1673
1674	if (kmfh == NULL)
1675		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1676
1677	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1678		return (KMF_ERR_NO_TOKEN_SELECTED);
1679
1680	/* "storekey" is optional. Default is TRUE */
1681	(void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr,
1682	    &storekey, NULL);
1683
1684	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr);
1685	if (cred == NULL)
1686		return (KMF_ERR_BAD_PARAMETER);
1687
1688	rv = pk11_authenticate(handle, cred);
1689	if (rv != KMF_OK)
1690		return (rv);
1691
1692	/* keytype is optional.  KMF_RSA is default */
1693	(void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr,
1694	    (void *)&keytype, NULL);
1695
1696	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
1697	if (pubkey == NULL)
1698		return (KMF_ERR_BAD_PARAMETER);
1699
1700	privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr);
1701	if (privkey == NULL)
1702		return (KMF_ERR_BAD_PARAMETER);
1703
1704	(void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
1705	(void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
1706	if (keytype == KMF_RSA) {
1707		CK_BYTE *modulus = NULL;
1708		CK_ULONG modulusLength = 0;
1709		KMF_BIGINT *rsaexp = NULL;
1710		CK_ATTRIBUTE modattr[1];
1711
1712		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr,
1713		    &modulusBits, &modulusBits_size);
1714		if (rv == KMF_ERR_ATTR_NOT_FOUND)
1715			/* Default modulusBits = 1024 */
1716			rv = KMF_OK;
1717		if (rv != KMF_OK)
1718			return (KMF_ERR_BAD_PARAMETER);
1719
1720		rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, numattr);
1721
1722		/* Generate the RSA keypair */
1723		ckrv = genrsa_keypair(kmfh, modulusBits, storekey,
1724		    rsaexp, &pubKey, &priKey);
1725
1726		if (ckrv != CKR_OK)
1727			return (KMF_ERR_BAD_PARAMETER);
1728
1729		privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1730		privkey->keyalg = KMF_RSA;
1731		privkey->keyclass = KMF_ASYM_PRI;
1732		privkey->keyp = (void *)priKey;
1733
1734		pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1735		pubkey->keyalg = KMF_RSA;
1736		pubkey->keyclass = KMF_ASYM_PUB;
1737		pubkey->keyp = (void *)pubKey;
1738
1739		SETATTR(modattr, 0, CKA_MODULUS, NULL, modulusLength);
1740		/* Get the Modulus field to use as input for creating the ID */
1741		ckrv = C_GetAttributeValue(kmfh->pk11handle,
1742		    (CK_OBJECT_HANDLE)pubKey, modattr, 1);
1743		if (ckrv != CKR_OK) {
1744			SET_ERROR(kmfh, ckrv);
1745			return (KMF_ERR_BAD_PARAMETER);
1746		}
1747
1748		modulusLength = modattr[0].ulValueLen;
1749		modulus = malloc(modulusLength);
1750		if (modulus == NULL)
1751			return (KMF_ERR_MEMORY);
1752
1753		modattr[0].pValue = modulus;
1754		ckrv = C_GetAttributeValue(kmfh->pk11handle,
1755		    (CK_OBJECT_HANDLE)pubKey, modattr, 1);
1756		if (ckrv != CKR_OK) {
1757			SET_ERROR(kmfh, ckrv);
1758			free(modulus);
1759			return (KMF_ERR_BAD_PARAMETER);
1760		}
1761
1762		IDInput.Data = modulus;
1763		IDInput.Length = modulusLength;
1764
1765	} else if (keytype == KMF_DSA) {
1766		CK_BYTE *keyvalue;
1767		CK_ULONG valueLen;
1768		CK_ATTRIBUTE valattr[1];
1769
1770		/* Generate the DSA keypair */
1771		ckrv = gendsa_keypair(kmfh, storekey, &pubKey, &priKey);
1772		if (ckrv != CKR_OK)
1773			return (KMF_ERR_BAD_PARAMETER);
1774
1775		privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1776		privkey->keyalg = KMF_DSA;
1777		privkey->keyclass = KMF_ASYM_PRI;
1778		privkey->keyp = (void *)priKey;
1779
1780		pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1781		pubkey->keyalg = KMF_DSA;
1782		pubkey->keyclass = KMF_ASYM_PUB;
1783		pubkey->keyp = (void *)pubKey;
1784
1785		/* Get the Public Value to use as input for creating the ID */
1786		SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen);
1787
1788		ckrv = C_GetAttributeValue(hSession,
1789		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1790		if (ckrv != CKR_OK) {
1791			SET_ERROR(kmfh, ckrv);
1792			return (KMF_ERR_BAD_PARAMETER);
1793		}
1794
1795		valueLen = valattr[0].ulValueLen;
1796		keyvalue = malloc(valueLen);
1797		if (keyvalue == NULL)
1798			return (KMF_ERR_MEMORY);
1799
1800		valattr[0].pValue = keyvalue;
1801		ckrv = C_GetAttributeValue(hSession,
1802		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1803		if (ckrv != CKR_OK) {
1804			SET_ERROR(kmfh, ckrv);
1805			free(keyvalue);
1806			return (KMF_ERR_BAD_PARAMETER);
1807		}
1808
1809		IDInput.Data = keyvalue;
1810		IDInput.Length = valueLen;
1811	} else if (keytype == KMF_ECDSA) {
1812		CK_BYTE *keyvalue;
1813		CK_ULONG valueLen;
1814		CK_ATTRIBUTE valattr[1];
1815		KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
1816		    attlist, numattr);
1817
1818		if (eccoid == NULL)
1819			return (KMF_ERR_BAD_PARAMETER);
1820
1821		ckrv = genecc_keypair(kmfh, storekey, eccoid,
1822		    &pubKey, &priKey);
1823		if (ckrv != CKR_OK)
1824			return (KMF_ERR_BAD_PARAMETER);
1825
1826		privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1827		privkey->keyalg = KMF_ECDSA;
1828		privkey->keyclass = KMF_ASYM_PRI;
1829		privkey->keyp = (void *)priKey;
1830
1831		pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1832		pubkey->keyalg = KMF_ECDSA;
1833		pubkey->keyclass = KMF_ASYM_PUB;
1834		pubkey->keyp = (void *)pubKey;
1835
1836		/* Get the EC_POINT to use as input for creating the ID */
1837		SETATTR(valattr, 0, CKA_EC_POINT, NULL, &valueLen);
1838
1839		ckrv = C_GetAttributeValue(hSession,
1840		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1841		if (ckrv != CKR_OK) {
1842			SET_ERROR(kmfh, ckrv);
1843			return (KMF_ERR_BAD_PARAMETER);
1844		}
1845
1846		valueLen = valattr[0].ulValueLen;
1847		keyvalue = malloc(valueLen);
1848		if (keyvalue == NULL)
1849			return (KMF_ERR_MEMORY);
1850
1851		valattr[0].pValue = keyvalue;
1852		ckrv = C_GetAttributeValue(hSession,
1853		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1854		if (ckrv != CKR_OK) {
1855			SET_ERROR(kmfh, ckrv);
1856			free(keyvalue);
1857			return (KMF_ERR_BAD_PARAMETER);
1858		}
1859
1860		IDInput.Data = keyvalue;
1861		IDInput.Length = valueLen;
1862	} else {
1863		return (KMF_ERR_BAD_PARAMETER);
1864	}
1865
1866	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr);
1867	if (keylabel != NULL && strlen(keylabel)) {
1868		SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel));
1869
1870		/* Set the CKA_LABEL if one was indicated */
1871		if ((ckrv = C_SetAttributeValue(hSession, pubKey,
1872		    labelattr, 1)) != CKR_OK) {
1873			SET_ERROR(kmfh, ckrv);
1874			rv = KMF_ERR_INTERNAL;
1875			goto cleanup;
1876		}
1877		pubkey->keylabel = (char *)strdup(keylabel);
1878		if (pubkey->keylabel == NULL) {
1879			rv = KMF_ERR_MEMORY;
1880			goto cleanup;
1881		}
1882		if ((ckrv = C_SetAttributeValue(hSession, priKey,
1883		    labelattr, 1)) != CKR_OK) {
1884			SET_ERROR(kmfh, ckrv);
1885			rv = KMF_ERR_INTERNAL;
1886			goto cleanup;
1887		}
1888		privkey->keylabel = (char *)strdup(keylabel);
1889		if (privkey->keylabel == NULL) {
1890			rv = KMF_ERR_MEMORY;
1891			goto cleanup;
1892		}
1893	} else {
1894		rv = KMF_OK;
1895	}
1896
1897	/* Now, assign a CKA_ID value so it can be searched */
1898	/* ID_Input was assigned above in the RSA or DSA keygen section */
1899	IDOutput.Data = (uchar_t *)IDHashData;
1900	IDOutput.Length = sizeof (IDHashData);
1901
1902	SHA1Init(&ctx);
1903	SHA1Update

Large files files are truncated, but you can click here to view the full file