xref: /illumos-gate/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c (revision f810c7e5159aec14e1937d86287a006e755d3d99)
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 
50 typedef struct _objlist {
51 	CK_OBJECT_HANDLE handle;
52 	struct _objlist *next;
53 } OBJLIST;
54 
55 static KMF_RETURN
56 search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *,
57 	boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *);
58 
59 static CK_RV
60 getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **);
61 
62 static KMF_RETURN
63 keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **);
64 
65 static KMF_RETURN
66 create_generic_secret_key(KMF_HANDLE_T,
67 	int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *);
68 
69 KMF_RETURN
70 KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
71 
72 KMF_RETURN
73 KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
74 
75 void
76 KMFPK11_FreeKMFCert(KMF_HANDLE_T,
77 	KMF_X509_DER_CERT *kmf_cert);
78 
79 KMF_RETURN
80 KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
81 
82 KMF_RETURN
83 KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
84 
85 KMF_RETURN
86 KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
87 
88 KMF_RETURN
89 KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
90 
91 KMF_RETURN
92 KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
93 
94 KMF_RETURN
95 KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
96 
97 KMF_RETURN
98 KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
99 
100 KMF_RETURN
101 KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
102 	KMF_DATA *, KMF_DATA *);
103 
104 KMF_RETURN
105 KMFPK11_GetErrorString(KMF_HANDLE_T, char **);
106 
107 KMF_RETURN
108 KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
109 
110 KMF_RETURN
111 KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
112 	KMF_DATA *, KMF_DATA *);
113 
114 KMF_RETURN
115 KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
116 
117 KMF_RETURN
118 KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
119 
120 KMF_RETURN
121 KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
122 
123 KMF_RETURN
124 KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
125 
126 KMF_RETURN
127 KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
128 
129 
130 static
131 KMF_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 
161 KMF_PLUGIN_FUNCLIST *
KMF_Plugin_Initialize()162 KMF_Plugin_Initialize()
163 {
164 	return (&pk11token_plugin_table);
165 }
166 
167 KMF_RETURN
KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)168 KMFPK11_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 
189 static KMF_RETURN
pk11_authenticate(KMF_HANDLE_T handle,KMF_CREDENTIAL * cred)190 pk11_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 == 0)
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 
216 static KMF_RETURN
PK11Cert2KMFCert(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE hObj,KMF_X509_DER_CERT * kmfcert)217 PK11Cert2KMFCert(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 
326 errout:
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 
341 static void
free_objlist(OBJLIST * head)342 free_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  */
357 static KMF_RETURN
get_attr(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE * templ)358 get_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  */
393 static KMF_RETURN
matchcert(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_X509_NAME * issuer,KMF_X509_NAME * subject)394 matchcert(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  */
448 static void
pk11_delete_obj_from_list(OBJLIST ** newlist,OBJLIST ** prev,OBJLIST ** curr)449 pk11_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  */
474 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)475 search_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 
570 cleanup:
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 
645 cleanup1:
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  */
665 KMF_RETURN
KMFPK11_FindCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)666 KMFPK11_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*/
755 void
KMFPK11_FreeKMFCert(KMF_HANDLE_T handle,KMF_X509_DER_CERT * kmf_cert)756 KMFPK11_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 
770 KMF_RETURN
KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * pKey,KMF_DATA * eData)771 KMFPK11_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 
1074 cleanup:
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 
1090 static KMF_RETURN
CreateCertObject(KMF_HANDLE_T handle,char * label,KMF_DATA * pcert)1091 CreateCertObject(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 = 0;
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 
1213 cleanup:
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 
1225 KMF_RETURN
KMFPK11_StoreCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1226 KMFPK11_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 
1258 KMF_RETURN
KMFPK11_ImportCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1259 KMFPK11_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 = { 0, NULL };
1268 	KMF_DATA  cert2 = { 0, NULL };
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 
1321 out:
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 
1333 KMF_RETURN
KMFPK11_DeleteCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1334 KMFPK11_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 
1401 out:
1402 	return (rv);
1403 }
1404 
1405 static CK_RV
gendsa_keypair(KMF_HANDLE * kmfh,boolean_t storekey,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)1406 gendsa_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 
1506 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)1507 genrsa_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 
1578 static CK_RV
genecc_keypair(KMF_HANDLE * kmfh,boolean_t ontoken,KMF_OID * curveoid,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)1579 genecc_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 
1649 KMF_RETURN
KMFPK11_CreateKeypair(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)1650 KMFPK11_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(&ctx, IDInput.Data, IDInput.Length);
1904 	SHA1Final(IDOutput.Data, &ctx);
1905 
1906 	IDOutput.Length = SHA1_DIGEST_LENGTH;
1907 
1908 	free(IDInput.Data);
1909 
1910 	if (rv != CKR_OK) {
1911 		goto cleanup;
1912 	}
1913 	SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length);
1914 	if ((ckrv = C_SetAttributeValue(hSession, pubKey,
1915 	    idattr, 1)) != CKR_OK) {
1916 		SET_ERROR(kmfh, ckrv);
1917 		rv = KMF_ERR_INTERNAL;
1918 		goto cleanup;
1919 	}
1920 	if ((ckrv = C_SetAttributeValue(hSession, priKey,
1921 	    idattr, 1)) != CKR_OK) {
1922 		SET_ERROR(kmfh, ckrv);
1923 		rv = KMF_ERR_INTERNAL;
1924 		goto cleanup;
1925 	}
1926 
1927 cleanup:
1928 	if (rv != KMF_OK) {
1929 		if (pubKey != CK_INVALID_HANDLE)
1930 			(void) C_DestroyObject(hSession, pubKey);
1931 		if (priKey != CK_INVALID_HANDLE)
1932 			(void) C_DestroyObject(hSession, priKey);
1933 
1934 		if (privkey->keylabel)
1935 			free(privkey->keylabel);
1936 		if (pubkey->keylabel)
1937 			free(pubkey->keylabel);
1938 	}
1939 	return (rv);
1940 }
1941 
1942 KMF_RETURN
KMFPK11_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1943 KMFPK11_DeleteKey(KMF_HANDLE_T handle,
1944 	int numattr, KMF_ATTRIBUTE *attrlist)
1945 {
1946 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1947 	CK_RV ckrv = CKR_OK;
1948 	KMF_RETURN rv = KMF_OK;
1949 	KMF_KEY_HANDLE *key;
1950 	KMF_CREDENTIAL cred;
1951 	boolean_t destroy = B_TRUE;
1952 
1953 	if (kmfh == NULL)
1954 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1955 
1956 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1957 		return (KMF_ERR_NO_TOKEN_SELECTED);
1958 
1959 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1960 	if (key == NULL || key->keyp == NULL)
1961 		return (KMF_ERR_BAD_PARAMETER);
1962 
1963 	if (key->keyclass != KMF_ASYM_PUB &&
1964 	    key->keyclass != KMF_ASYM_PRI &&
1965 	    key->keyclass != KMF_SYMMETRIC)
1966 		return (KMF_ERR_BAD_KEY_CLASS);
1967 
1968 	/* "destroy" is optional. Default is TRUE */
1969 	(void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1970 	    (void *)&destroy, NULL);
1971 
1972 	if (destroy) {
1973 		rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
1974 		    (void *)&cred, NULL);
1975 		if (rv != KMF_OK)
1976 			return (KMF_ERR_BAD_PARAMETER);
1977 
1978 		rv = pk11_authenticate(handle, &cred);
1979 		if (rv != KMF_OK) {
1980 			return (rv);
1981 		}
1982 	}
1983 
1984 	if (!key->israw && destroy)
1985 		ckrv = C_DestroyObject(kmfh->pk11handle,
1986 		    (CK_OBJECT_HANDLE)key->keyp);
1987 
1988 	if (ckrv != CKR_OK) {
1989 		SET_ERROR(kmfh, ckrv);
1990 		/* Report authentication failures to the caller */
1991 		if (ckrv == CKR_PIN_EXPIRED || ckrv == CKR_SESSION_READ_ONLY)
1992 			rv = KMF_ERR_AUTH_FAILED;
1993 		else
1994 			rv = KMF_ERR_INTERNAL;
1995 	}
1996 	return (rv);
1997 }
1998 
1999 KMF_RETURN
KMFPK11_SignData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * keyp,KMF_OID * algOID,KMF_DATA * tobesigned,KMF_DATA * output)2000 KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp,
2001 	KMF_OID *algOID,
2002 	KMF_DATA *tobesigned,
2003 	KMF_DATA *output)
2004 {
2005 	KMF_RETURN		rv = KMF_OK;
2006 	CK_RV			ckrv;
2007 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
2008 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
2009 	CK_MECHANISM		mechanism;
2010 	CK_MECHANISM_TYPE	mechtype, hashmech;
2011 	CK_KEY_TYPE		keytype;
2012 	KMF_ALGORITHM_INDEX	AlgId;
2013 	KMF_DATA		hashData = { 0, NULL };
2014 	uchar_t			digest[1024];
2015 	CK_ATTRIBUTE		subprime = { CKA_SUBPRIME, NULL, 0 };
2016 
2017 	if (kmfh == NULL)
2018 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2019 
2020 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
2021 		return (KMF_ERR_NO_TOKEN_SELECTED);
2022 
2023 	if (keyp == NULL || algOID == NULL ||
2024 	    tobesigned == NULL || output == NULL)
2025 		return (KMF_ERR_BAD_PARAMETER);
2026 
2027 	/* These functions are available to the plugin from libkmf */
2028 	AlgId = x509_algoid_to_algid(algOID);
2029 	if (AlgId == KMF_ALGID_NONE)
2030 		return (KMF_ERR_BAD_PARAMETER);
2031 
2032 	/* Get the PKCS11 signing key type and mechtype */
2033 	if (get_pk11_data(AlgId, &keytype, &mechtype, &hashmech, 0))
2034 		return (KMF_ERR_BAD_PARAMETER);
2035 
2036 	(void) memset(digest, 0, sizeof (digest));
2037 	hashData.Data = digest;
2038 	hashData.Length = sizeof (digest);
2039 	rv = PKCS_DigestData(handle, hSession, hashmech, tobesigned, &hashData,
2040 	    (mechtype == CKM_RSA_PKCS));
2041 	if (rv)
2042 		return (rv);
2043 
2044 	if (mechtype == CKM_DSA && hashmech == CKM_SHA256) {
2045 		/*
2046 		 * FIPS 186-3 says that when signing with DSA
2047 		 * the hash must be truncated to the size of the
2048 		 * subprime.
2049 		 */
2050 		ckrv = C_GetAttributeValue(hSession,
2051 		    (CK_OBJECT_HANDLE)keyp->keyp,
2052 		    &subprime, 1);
2053 		if (ckrv != CKR_OK)  {
2054 			SET_ERROR(kmfh, ckrv);
2055 			return (KMF_ERR_INTERNAL);
2056 		}
2057 		hashData.Length = subprime.ulValueLen;
2058 	}
2059 
2060 	/* the mechtype from the 'get_pk11_info' refers to the signing */
2061 	mechanism.mechanism = mechtype;
2062 	mechanism.pParameter = NULL;
2063 	mechanism.ulParameterLen = 0;
2064 
2065 	ckrv = C_SignInit(hSession, &mechanism, (CK_OBJECT_HANDLE)keyp->keyp);
2066 	if (ckrv != CKR_OK) {
2067 		SET_ERROR(kmfh, ckrv);
2068 		return (KMF_ERR_INTERNAL);
2069 	}
2070 
2071 	ckrv = C_Sign(hSession,	hashData.Data, hashData.Length,
2072 	    output->Data, (CK_ULONG *)&output->Length);
2073 
2074 	if (ckrv != CKR_OK) {
2075 		SET_ERROR(kmfh, ckrv);
2076 		return (KMF_ERR_INTERNAL);
2077 	}
2078 
2079 	return (KMF_OK);
2080 }
2081 
2082 KMF_RETURN
KMFPK11_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)2083 KMFPK11_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
2084 {
2085 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2086 
2087 	*msgstr = NULL;
2088 	if (kmfh->lasterr.errcode != 0) {
2089 		char *e = pkcs11_strerror(kmfh->lasterr.errcode);
2090 		if (e == NULL || (*msgstr = (char *)strdup(e)) == NULL) {
2091 			return (KMF_ERR_MEMORY);
2092 		}
2093 	}
2094 
2095 	return (KMF_OK);
2096 }
2097 
2098 static CK_RV
getObjectKeytype(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,CK_ULONG * keytype)2099 getObjectKeytype(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2100 	CK_ULONG *keytype)
2101 {
2102 	CK_RV rv = CKR_OK;
2103 	CK_ATTRIBUTE templ;
2104 	CK_ULONG len = sizeof (CK_ULONG);
2105 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2106 
2107 	templ.type = CKA_KEY_TYPE;
2108 	templ.pValue = keytype;
2109 	templ.ulValueLen = len;
2110 
2111 	rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2112 
2113 	return (rv);
2114 
2115 }
2116 
2117 static CK_RV
getObjectLabel(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,char ** outlabel)2118 getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2119 	char **outlabel)
2120 {
2121 	CK_RV rv = CKR_OK;
2122 	CK_ATTRIBUTE templ;
2123 	char	Label[BUFSIZ];
2124 	CK_ULONG len = sizeof (Label);
2125 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2126 
2127 	(void) memset(Label, 0, len);
2128 	templ.type = CKA_LABEL;
2129 	templ.pValue = Label;
2130 	templ.ulValueLen = len;
2131 
2132 	rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2133 	if (rv == CKR_OK) {
2134 		*outlabel = (char *)strdup(Label);
2135 	} else {
2136 		*outlabel = NULL;
2137 	}
2138 	return (rv);
2139 }
2140 
2141 static CK_RV
getObjectKeyclass(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,KMF_KEY_CLASS * keyclass)2142 getObjectKeyclass(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2143 	KMF_KEY_CLASS *keyclass)
2144 {
2145 	CK_RV rv = CKR_OK;
2146 	CK_ATTRIBUTE templ;
2147 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2148 	CK_OBJECT_CLASS class;
2149 
2150 	templ.type = CKA_CLASS;
2151 	templ.pValue = &class;
2152 	templ.ulValueLen = sizeof (CK_OBJECT_CLASS);
2153 
2154 	rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2155 	if (rv == CKR_OK) {
2156 		if (class == CKO_PUBLIC_KEY) {
2157 			*keyclass = KMF_ASYM_PUB;
2158 		} else if (class == CKO_PRIVATE_KEY) {
2159 			*keyclass = KMF_ASYM_PRI;
2160 		} else if (class == CKO_SECRET_KEY) {
2161 			*keyclass = KMF_SYMMETRIC;
2162 		}
2163 	} else {
2164 		*keyclass = KMF_KEYCLASS_NONE;
2165 	}
2166 	return (rv);
2167 }
2168 
2169 KMF_RETURN
KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2170 KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2171     KMF_ATTRIBUTE *attrlist)
2172 {
2173 	KMF_X509_SPKI *pubkey;
2174 	KMF_X509_CERTIFICATE *SignerCert = NULL;
2175 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2176 	KMF_RETURN rv = KMF_OK;
2177 	CK_RV ckrv = CKR_OK;
2178 	CK_ATTRIBUTE templ[4];
2179 	CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE;
2180 	CK_ULONG obj_count;
2181 	CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
2182 	CK_BBOOL true = TRUE;
2183 	KMF_DATA Id = { 0, NULL };
2184 	KMF_KEY_HANDLE *key = NULL;
2185 	KMF_DATA *cert = NULL;
2186 	KMF_CREDENTIAL cred;
2187 	KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF;
2188 	CK_ULONG keytype;
2189 
2190 	/* Get the key handle */
2191 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2192 	if (key == NULL)
2193 		return (KMF_ERR_BAD_PARAMETER);
2194 
2195 	/* Get the optional encoded format */
2196 	(void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
2197 	    (void *)&format, NULL);
2198 
2199 	/* Decode the signer cert so we can get the SPKI data */
2200 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
2201 	if (cert == NULL || cert->Data == NULL)
2202 		return (KMF_ERR_BAD_PARAMETER);
2203 
2204 	if ((rv = DerDecodeSignedCertificate(cert,
2205 	    &SignerCert)) != KMF_OK)
2206 		return (rv);
2207 
2208 	/* Get the public key info from the signer certificate */
2209 	pubkey = &SignerCert->certificate.subjectPublicKeyInfo;
2210 
2211 	/* Generate an ID from the SPKI data */
2212 	rv = GetIDFromSPKI(pubkey, &Id);
2213 	if (rv != KMF_OK) {
2214 		goto errout;
2215 	}
2216 
2217 	/* Get the credential and login */
2218 	rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
2219 	    (void *)&cred, NULL);
2220 	if (rv != KMF_OK)
2221 		return (KMF_ERR_BAD_PARAMETER);
2222 
2223 	rv = pk11_authenticate(handle, &cred);
2224 	if (rv != KMF_OK) {
2225 		return (rv);
2226 	}
2227 
2228 	/* Start searching */
2229 	SETATTR(templ, 0, CKA_CLASS, &objClass, sizeof (objClass));
2230 	SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true));
2231 	SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true));
2232 	SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length);
2233 
2234 	if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) {
2235 		SET_ERROR(kmfh, ckrv);
2236 		rv = KMF_ERR_INTERNAL;
2237 		goto errout;
2238 	}
2239 
2240 	if ((ckrv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1,
2241 	    &obj_count)) != CKR_OK) {
2242 		SET_ERROR(kmfh, ckrv);
2243 		rv = KMF_ERR_INTERNAL;
2244 		goto errout;
2245 	}
2246 
2247 	if (obj_count == 0) {
2248 		SET_ERROR(kmfh, ckrv);
2249 		rv = KMF_ERR_KEY_NOT_FOUND;
2250 		goto errout;
2251 	}
2252 
2253 	key->kstype = KMF_KEYSTORE_PK11TOKEN;
2254 	key->keyclass = KMF_ASYM_PRI;
2255 	key->keyp = (void *)pri_obj;
2256 	key->israw = FALSE;
2257 
2258 	(void) C_FindObjectsFinal(kmfh->pk11handle);
2259 
2260 	ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp,
2261 	    &key->keylabel);
2262 	if (ckrv != CKR_OK) {
2263 		SET_ERROR(handle, ckrv);
2264 		rv = KMF_ERR_INTERNAL;
2265 	} else {
2266 		rv = KMF_OK;
2267 	}
2268 
2269 	/*
2270 	 * The key->keyalg value is needed if we need to convert the key
2271 	 * to raw key.  However, the key->keyalg value will not be set if
2272 	 * this function is not called thru the kmf_find_prikey_by_cert()
2273 	 * framework function. To be safe, we will get the keytype from
2274 	 * the key object and set key->keyalg value here.
2275 	 */
2276 	ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp,
2277 	    &keytype);
2278 	if (ckrv != CKR_OK) {
2279 		SET_ERROR(handle, ckrv);
2280 		rv = KMF_ERR_INTERNAL;
2281 	} else {
2282 		rv = KMF_OK;
2283 	}
2284 
2285 	if (keytype == CKK_RSA)
2286 		key->keyalg = KMF_RSA;
2287 	else if (keytype == CKK_DSA)
2288 		key->keyalg = KMF_DSA;
2289 	else if (keytype == CKK_EC)
2290 		key->keyalg = KMF_ECDSA;
2291 	else {
2292 		/* For asymmetric keys, we only support RSA and DSA */
2293 		rv = KMF_ERR_KEY_NOT_FOUND;
2294 		goto errout;
2295 	}
2296 
2297 	if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) {
2298 		KMF_RAW_KEY_DATA *rkey = NULL;
2299 		rv = keyObj2RawKey(handle, key, &rkey);
2300 		if (rv == KMF_OK) {
2301 			key->keyp = rkey;
2302 			key->israw = TRUE;
2303 		}
2304 	}
2305 
2306 errout:
2307 	if (Id.Data != NULL)
2308 		free(Id.Data);
2309 
2310 	if (SignerCert != NULL) {
2311 		kmf_free_signed_cert(SignerCert);
2312 		free(SignerCert);
2313 	}
2314 	return (rv);
2315 }
2316 
2317 KMF_RETURN
KMFPK11_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * algOID,KMF_DATA * ciphertext,KMF_DATA * output)2318 KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2319 	KMF_OID *algOID, KMF_DATA *ciphertext,
2320 	KMF_DATA *output)
2321 {
2322 	CK_RV			ckrv;
2323 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
2324 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
2325 	CK_MECHANISM		mechanism;
2326 	CK_MECHANISM_TYPE	mechtype;
2327 	CK_KEY_TYPE		keytype;
2328 	KMF_ALGORITHM_INDEX	AlgId;
2329 	CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0;
2330 	uint8_t *in_data, *out_data;
2331 	int i, blocks;
2332 	CK_ATTRIBUTE ckTemplate[1];
2333 
2334 	if (kmfh == NULL)
2335 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2336 
2337 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
2338 		return (KMF_ERR_NO_TOKEN_SELECTED);
2339 
2340 	if (key == NULL || algOID == NULL ||
2341 	    ciphertext == NULL || output == NULL)
2342 		return (KMF_ERR_BAD_PARAMETER);
2343 
2344 	AlgId = x509_algoid_to_algid(algOID);
2345 	if (AlgId == KMF_ALGID_NONE)
2346 		return (KMF_ERR_BAD_PARAMETER);
2347 
2348 	/* Map the Algorithm ID to a PKCS#11 mechanism */
2349 	if (get_pk11_data(AlgId, &keytype, &mechtype, NULL, 0))
2350 		return (KMF_ERR_BAD_PARAMETER);
2351 
2352 	mechanism.mechanism = mechtype;
2353 	mechanism.pParameter = NULL;
2354 	mechanism.ulParameterLen = 0;
2355 
2356 	SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL,
2357 	    sizeof (CK_ULONG));
2358 
2359 	/* Get the modulus length */
2360 	ckrv = C_GetAttributeValue(hSession,
2361 	    (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1);
2362 
2363 	if (ckrv != CKR_OK)  {
2364 		SET_ERROR(kmfh, ckrv);
2365 		return (KMF_ERR_INTERNAL);
2366 	}
2367 
2368 	block_len = ckTemplate[0].ulValueLen;
2369 
2370 	/* Compute the number of times to do single-part decryption */
2371 	blocks = ciphertext->Length/block_len;
2372 
2373 	out_data = output->Data;
2374 	in_data = ciphertext->Data;
2375 	out_len = block_len - 11;
2376 
2377 	for (i = 0; i < blocks; i++) {
2378 		ckrv = C_DecryptInit(hSession, &mechanism,
2379 		    (CK_OBJECT_HANDLE)key->keyp);
2380 
2381 		if (ckrv != CKR_OK) {
2382 			SET_ERROR(kmfh, ckrv);
2383 			return (KMF_ERR_INTERNAL);
2384 		}
2385 
2386 		ckrv = C_Decrypt(hSession, in_data, block_len,
2387 		    out_data, (CK_ULONG *)&out_len);
2388 
2389 		if (ckrv != CKR_OK) {
2390 			SET_ERROR(kmfh, ckrv);
2391 			return (KMF_ERR_INTERNAL);
2392 		}
2393 
2394 		out_data += out_len;
2395 		total_decrypted += out_len;
2396 		in_data += block_len;
2397 
2398 	}
2399 
2400 	output->Length = total_decrypted;
2401 	return (KMF_OK);
2402 }
2403 
2404 static void
attr2bigint(CK_ATTRIBUTE_PTR attr,KMF_BIGINT * big)2405 attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big)
2406 {
2407 	big->val = attr->pValue;
2408 	big->len = attr->ulValueLen;
2409 }
2410 
2411 static KMF_RETURN
get_bigint_attr(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE_TYPE attrtype,KMF_BIGINT * bigint)2412 get_bigint_attr(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj,
2413 	CK_ATTRIBUTE_TYPE attrtype, KMF_BIGINT *bigint)
2414 {
2415 	CK_RV ckrv;
2416 	CK_ATTRIBUTE attr;
2417 
2418 	attr.type = attrtype;
2419 	attr.pValue = NULL;
2420 	attr.ulValueLen = 0;
2421 
2422 	if ((ckrv = C_GetAttributeValue(sess, obj,
2423 	    &attr, 1)) != CKR_OK) {
2424 		/* Mask this error so the caller can continue */
2425 		if (ckrv == CKR_ATTRIBUTE_TYPE_INVALID)
2426 			return (KMF_OK);
2427 		else
2428 			return (KMF_ERR_INTERNAL);
2429 	}
2430 	if (attr.ulValueLen > 0 && bigint != NULL) {
2431 		attr.pValue = malloc(attr.ulValueLen);
2432 		if (attr.pValue == NULL)
2433 			return (KMF_ERR_MEMORY);
2434 
2435 		if ((ckrv = C_GetAttributeValue(sess, obj,
2436 		    &attr, 1)) != CKR_OK)
2437 		if (ckrv != CKR_OK) {
2438 			free(attr.pValue);
2439 			return (KMF_ERR_INTERNAL);
2440 		}
2441 
2442 		bigint->val = attr.pValue;
2443 		bigint->len = attr.ulValueLen;
2444 	}
2445 	return (KMF_OK);
2446 }
2447 
2448 static KMF_RETURN
get_raw_rsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_RSA_KEY * rawrsa)2449 get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa)
2450 {
2451 	KMF_RETURN rv = KMF_OK;
2452 	CK_RV ckrv;
2453 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
2454 	CK_ATTRIBUTE rsa_pri_attrs[2] = {
2455 		{ CKA_MODULUS, NULL, 0 },
2456 		{ CKA_PUBLIC_EXPONENT, NULL, 0 }
2457 	};
2458 	CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
2459 	int i;
2460 
2461 	if (rawrsa == NULL)
2462 		return (KMF_ERR_BAD_PARAMETER);
2463 
2464 	(void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
2465 	if ((ckrv = C_GetAttributeValue(sess, obj,
2466 	    rsa_pri_attrs, count)) != CKR_OK) {
2467 		SET_ERROR(kmfh, ckrv);
2468 		/* Tell the caller know why the key data cannot be retrieved. */
2469 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2470 			return (KMF_ERR_SENSITIVE_KEY);
2471 		else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2472 			return (KMF_ERR_UNEXTRACTABLE_KEY);
2473 		else
2474 			return (KMF_ERR_INTERNAL);
2475 	}
2476 
2477 	/* Allocate memory for each attribute. */
2478 	for (i = 0; i < count; i++) {
2479 		if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2480 		    rsa_pri_attrs[i].ulValueLen == 0) {
2481 			rsa_pri_attrs[i].ulValueLen = 0;
2482 			continue;
2483 		}
2484 		if ((rsa_pri_attrs[i].pValue =
2485 		    malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) {
2486 			rv = KMF_ERR_MEMORY;
2487 			goto end;
2488 		}
2489 	}
2490 	/* Now that we have space, really get the attributes */
2491 	if ((ckrv = C_GetAttributeValue(sess, obj,
2492 	    rsa_pri_attrs, count)) != CKR_OK) {
2493 		SET_ERROR(kmfh, ckrv);
2494 		rv = KMF_ERR_INTERNAL;
2495 		goto end;
2496 	}
2497 	i = 0;
2498 	attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod);
2499 	attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp);
2500 
2501 	/* Now get the optional parameters */
2502 	rv = get_bigint_attr(sess, obj, CKA_PRIVATE_EXPONENT, &rawrsa->priexp);
2503 	if (rv != KMF_OK)
2504 		goto end;
2505 	rv = get_bigint_attr(sess, obj, CKA_PRIME_1, &rawrsa->prime1);
2506 	if (rv != KMF_OK)
2507 		goto end;
2508 	rv = get_bigint_attr(sess, obj, CKA_PRIME_2, &rawrsa->prime2);
2509 	if (rv != KMF_OK)
2510 		goto end;
2511 	rv = get_bigint_attr(sess, obj, CKA_EXPONENT_1, &rawrsa->exp1);
2512 	if (rv != KMF_OK)
2513 		goto end;
2514 	rv = get_bigint_attr(sess, obj, CKA_EXPONENT_2, &rawrsa->exp2);
2515 	if (rv != KMF_OK)
2516 		goto end;
2517 	rv = get_bigint_attr(sess, obj, CKA_COEFFICIENT, &rawrsa->coef);
2518 	if (rv != KMF_OK)
2519 		goto end;
2520 
2521 end:
2522 	if (rv != KMF_OK) {
2523 		for (i = 0; i < count; i++) {
2524 			if (rsa_pri_attrs[i].pValue != NULL)
2525 				free(rsa_pri_attrs[i].pValue);
2526 		}
2527 		if (rawrsa->priexp.val)
2528 			free(rawrsa->priexp.val);
2529 		if (rawrsa->prime1.val)
2530 			free(rawrsa->prime1.val);
2531 		if (rawrsa->prime2.val)
2532 			free(rawrsa->prime2.val);
2533 		if (rawrsa->exp1.val)
2534 			free(rawrsa->exp1.val);
2535 		if (rawrsa->exp2.val)
2536 			free(rawrsa->exp2.val);
2537 		if (rawrsa->coef.val)
2538 			free(rawrsa->coef.val);
2539 		(void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
2540 	}
2541 	return (rv);
2542 }
2543 
2544 #define	DSA_PRIME_BUFSIZE	CHARLEN2BIGNUMLEN(1024)	/* 8192 bits */
2545 #define	DSA_PRIVATE_BUFSIZE	BIG_CHUNKS_FOR_160BITS	/* 160 bits */
2546 
2547 /*
2548  * This function calculates the pubkey value from the prime,
2549  * base and private key values of a DSA key.
2550  */
2551 static KMF_RETURN
compute_dsa_pubvalue(KMF_RAW_DSA_KEY * rawdsa)2552 compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa)
2553 {
2554 	KMF_RETURN rv = KMF_OK;
2555 	BIGNUM p, g, x, y;
2556 	BIG_ERR_CODE err;
2557 	uchar_t *pubvalue;
2558 	uint32_t pubvalue_len;
2559 
2560 	if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2561 		rv = KMF_ERR_MEMORY;
2562 		return (rv);
2563 	}
2564 	bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len);
2565 
2566 	if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2567 		rv = KMF_ERR_MEMORY;
2568 		goto ret1;
2569 	}
2570 	bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len);
2571 
2572 	if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) {
2573 		rv = KMF_ERR_MEMORY;
2574 		goto ret2;
2575 	}
2576 	bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len);
2577 
2578 	if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2579 		rv = KMF_ERR_MEMORY;
2580 		goto ret3;
2581 	}
2582 
2583 	err = big_modexp(&y, &g, &x, &p, NULL);
2584 	if (err != BIG_OK) {
2585 		rv = KMF_ERR_INTERNAL;
2586 		goto ret3;
2587 	}
2588 
2589 	pubvalue_len = y.len * (int)sizeof (uint32_t);
2590 	if ((pubvalue = malloc(pubvalue_len)) == NULL) {
2591 		rv = KMF_ERR_MEMORY;
2592 		goto ret4;
2593 	}
2594 	bignum2bytestring(pubvalue, &y, pubvalue_len);
2595 
2596 	rawdsa->pubvalue.val = pubvalue;
2597 	rawdsa->pubvalue.len = pubvalue_len;
2598 
2599 ret4:
2600 	big_finish(&y);
2601 ret3:
2602 	big_finish(&x);
2603 ret2:
2604 	big_finish(&g);
2605 ret1:
2606 	big_finish(&p);
2607 	return (rv);
2608 }
2609 
2610 static KMF_RETURN
get_raw_ec(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_EC_KEY * rawec)2611 get_raw_ec(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_EC_KEY *rawec)
2612 {
2613 	KMF_RETURN rv = KMF_OK;
2614 	CK_RV ckrv;
2615 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
2616 	CK_ATTRIBUTE	ec_attrs[2] = {
2617 		{ CKA_EC_PARAMS, NULL, 0},
2618 		{ CKA_VALUE, NULL, 0}
2619 	};
2620 	CK_ULONG	count = sizeof (ec_attrs) / sizeof (CK_ATTRIBUTE);
2621 	int		i;
2622 
2623 	if ((ckrv = C_GetAttributeValue(sess, obj,
2624 	    ec_attrs, 2)) != CKR_OK) {
2625 		SET_ERROR(kmfh, ckrv);
2626 
2627 		/* Tell the caller know why the key data cannot be retrieved. */
2628 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2629 			return (KMF_ERR_SENSITIVE_KEY);
2630 		else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2631 			return (KMF_ERR_UNEXTRACTABLE_KEY);
2632 		return (KMF_ERR_INTERNAL);
2633 	}
2634 	for (i = 0; i < count; i++) {
2635 		if (ec_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2636 		    ec_attrs[i].ulValueLen == 0) {
2637 			ec_attrs[i].ulValueLen = 0;
2638 			continue;
2639 		}
2640 		if ((ec_attrs[i].pValue =
2641 		    malloc(ec_attrs[i].ulValueLen)) == NULL) {
2642 			rv = KMF_ERR_MEMORY;
2643 			goto end;
2644 		}
2645 	}
2646 	if ((ckrv = C_GetAttributeValue(sess, obj,
2647 	    ec_attrs, count)) != CKR_OK) {
2648 		SET_ERROR(kmfh, ckrv);
2649 		rv = KMF_ERR_INTERNAL;
2650 		goto end;
2651 	}
2652 
2653 	rawec->params.Data = ec_attrs[0].pValue;
2654 	rawec->params.Length = ec_attrs[0].ulValueLen;
2655 	rawec->value.val = ec_attrs[1].pValue;
2656 	rawec->value.len = ec_attrs[1].ulValueLen;
2657 
2658 end:
2659 	if (rv != KMF_OK) {
2660 		for (i = 0; i < count; i++) {
2661 			if (ec_attrs[i].pValue != NULL)
2662 				free(ec_attrs[i].pValue);
2663 		}
2664 		(void) memset(rawec, 0, sizeof (KMF_RAW_EC_KEY));
2665 	}
2666 	return (rv);
2667 }
2668 
2669 static KMF_RETURN
get_raw_dsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_DSA_KEY * rawdsa)2670 get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa)
2671 {
2672 	KMF_RETURN rv = KMF_OK;
2673 	CK_RV ckrv;
2674 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
2675 	CK_ATTRIBUTE	dsa_pri_attrs[8] = {
2676 		{ CKA_PRIME, NULL, 0 },
2677 		{ CKA_SUBPRIME, NULL, 0 },
2678 		{ CKA_BASE, NULL, 0 },
2679 		{ CKA_VALUE, NULL, 0 }
2680 	};
2681 	CK_ULONG	count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
2682 	int		i;
2683 
2684 	if ((ckrv = C_GetAttributeValue(sess, obj,
2685 	    dsa_pri_attrs, count)) != CKR_OK) {
2686 		SET_ERROR(kmfh, ckrv);
2687 
2688 		/* Tell the caller know why the key data cannot be retrieved. */
2689 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2690 			return (KMF_ERR_SENSITIVE_KEY);
2691 		else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2692 			return (KMF_ERR_UNEXTRACTABLE_KEY);
2693 		return (KMF_ERR_INTERNAL);
2694 	}
2695 
2696 	/* Allocate memory for each attribute. */
2697 	for (i = 0; i < count; i++) {
2698 		if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2699 		    dsa_pri_attrs[i].ulValueLen == 0) {
2700 			dsa_pri_attrs[i].ulValueLen = 0;
2701 			continue;
2702 		}
2703 		if ((dsa_pri_attrs[i].pValue =
2704 		    malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) {
2705 			rv = KMF_ERR_MEMORY;
2706 			goto end;
2707 		}
2708 	}
2709 	if ((ckrv = C_GetAttributeValue(sess, obj,
2710 	    dsa_pri_attrs, count)) != CKR_OK) {
2711 		SET_ERROR(kmfh, ckrv);
2712 		rv = KMF_ERR_INTERNAL;
2713 		goto end;
2714 	}
2715 
2716 	/* Fill in all the temp variables.  They are all required. */
2717 	i = 0;
2718 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime);
2719 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime);
2720 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base);
2721 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value);
2722 
2723 	/* Compute the public key value and store it */
2724 	rv = compute_dsa_pubvalue(rawdsa);
2725 
2726 end:
2727 	if (rv != KMF_OK) {
2728 		for (i = 0; i < count; i++) {
2729 			if (dsa_pri_attrs[i].pValue != NULL)
2730 				free(dsa_pri_attrs[i].pValue);
2731 		}
2732 		(void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY));
2733 	}
2734 	return (rv);
2735 }
2736 
2737 static KMF_RETURN
get_raw_sym(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_SYM_KEY * rawsym)2738 get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym)
2739 {
2740 	KMF_RETURN rv = KMF_OK;
2741 	CK_RV	ckrv;
2742 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
2743 	CK_ATTRIBUTE	sym_attr[1];
2744 	CK_ULONG	value_len = 0;
2745 
2746 	/* find the key length first */
2747 	sym_attr[0].type = CKA_VALUE;
2748 	sym_attr[0].pValue = NULL;
2749 	sym_attr[0].ulValueLen = value_len;
2750 	if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
2751 		rawsym->keydata.val = NULL;
2752 		rawsym->keydata.len = 0;
2753 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE) {
2754 			return (KMF_ERR_SENSITIVE_KEY);
2755 		} else if (ckrv == CKR_KEY_UNEXTRACTABLE) {
2756 			return (KMF_ERR_UNEXTRACTABLE_KEY);
2757 		} else {
2758 			SET_ERROR(kmfh, ckrv);
2759 			return (KMF_ERR_INTERNAL);
2760 		}
2761 	}
2762 
2763 	/* Allocate memory for pValue */
2764 	sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen);
2765 	if (sym_attr[0].pValue == NULL) {
2766 		return (KMF_ERR_MEMORY);
2767 	}
2768 
2769 	/* get the key data */
2770 	if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
2771 		SET_ERROR(kmfh, ckrv);
2772 		free(sym_attr[0].pValue);
2773 		return (KMF_ERR_INTERNAL);
2774 	}
2775 
2776 	rawsym->keydata.val = sym_attr[0].pValue;
2777 	rawsym->keydata.len = sym_attr[0].ulValueLen;
2778 	return (rv);
2779 }
2780 
2781 static KMF_RETURN
keyObj2RawKey(KMF_HANDLE_T handle,KMF_KEY_HANDLE * inkey,KMF_RAW_KEY_DATA ** outkey)2782 keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey,
2783 	KMF_RAW_KEY_DATA **outkey)
2784 {
2785 	KMF_RETURN rv = KMF_OK;
2786 	KMF_RAW_KEY_DATA *rkey;
2787 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2788 
2789 	rkey = malloc(sizeof (KMF_RAW_KEY_DATA));
2790 	if (rkey == NULL)
2791 		return (KMF_ERR_MEMORY);
2792 
2793 	(void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA));
2794 
2795 	rkey->keytype = inkey->keyalg;
2796 
2797 	if (inkey->keyalg == KMF_RSA) {
2798 		rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2799 		    &rkey->rawdata.rsa);
2800 	} else if (inkey->keyalg == KMF_DSA) {
2801 		rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2802 		    &rkey->rawdata.dsa);
2803 	} else if (inkey->keyalg == KMF_AES ||
2804 	    inkey->keyalg == KMF_RC4 ||
2805 	    inkey->keyalg == KMF_DES ||
2806 	    inkey->keyalg == KMF_DES3 ||
2807 	    inkey->keyalg == KMF_GENERIC_SECRET) {
2808 		rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2809 		    &rkey->rawdata.sym);
2810 		/*
2811 		 * If sensitive or non-extractable, mark them as such
2812 		 * but return "OK" status so the keys get counted
2813 		 * when doing FindKey operations.
2814 		 */
2815 		if (rv == KMF_ERR_SENSITIVE_KEY) {
2816 			rkey->sensitive = B_TRUE;
2817 			rv = KMF_OK;
2818 		} else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
2819 			rkey->not_extractable = B_TRUE;
2820 			rv = KMF_OK;
2821 		}
2822 	} else if (inkey->keyalg == KMF_ECDSA) {
2823 		rv = get_raw_ec(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2824 		    &rkey->rawdata.ec);
2825 	} else {
2826 		rv = KMF_ERR_BAD_PARAMETER;
2827 	}
2828 
2829 	if (rv == KMF_OK) {
2830 		*outkey = rkey;
2831 	} else if (rkey != NULL) {
2832 		free(rkey);
2833 		*outkey = NULL;
2834 	}
2835 
2836 	return (rv);
2837 }
2838 
2839 
2840 static KMF_RETURN
kmf2pk11keytype(KMF_KEY_ALG keyalg,CK_KEY_TYPE * type)2841 kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type)
2842 {
2843 	switch (keyalg) {
2844 	case KMF_RSA:
2845 		*type = CKK_RSA;
2846 		break;
2847 	case KMF_DSA:
2848 		*type = CKK_DSA;
2849 		break;
2850 	case KMF_ECDSA:
2851 		*type = CKK_EC;
2852 		break;
2853 	case KMF_AES:
2854 		*type = CKK_AES;
2855 		break;
2856 	case KMF_RC4:
2857 		*type = CKK_RC4;
2858 		break;
2859 	case KMF_DES:
2860 		*type = CKK_DES;
2861 		break;
2862 	case KMF_DES3:
2863 		*type = CKK_DES3;
2864 		break;
2865 	case KMF_GENERIC_SECRET:
2866 		*type = CKK_GENERIC_SECRET;
2867 		break;
2868 	default:
2869 		return (KMF_ERR_BAD_KEY_TYPE);
2870 	}
2871 
2872 	return (KMF_OK);
2873 }
2874 
2875 static int
IDStringToData(char * idstr,KMF_DATA * iddata)2876 IDStringToData(char *idstr, KMF_DATA *iddata)
2877 {
2878 	int len, i;
2879 	char *iddup, *byte;
2880 	uint_t lvalue;
2881 
2882 	if (idstr == NULL || !strlen(idstr))
2883 		return (-1);
2884 
2885 	iddup = (char *)strdup(idstr);
2886 	if (iddup == NULL)
2887 		return (KMF_ERR_MEMORY);
2888 
2889 	len = strlen(iddup) / 3  + 1;
2890 	iddata->Data = malloc(len);
2891 	if (iddata->Data == NULL)
2892 		return (KMF_ERR_MEMORY);
2893 	(void) memset(iddata->Data, 0, len);
2894 	iddata->Length = len;
2895 
2896 	byte = strtok(iddup, ":");
2897 	if (byte == NULL) {
2898 		free(iddup);
2899 		free(iddata->Data);
2900 		iddata->Data = NULL;
2901 		iddata->Length = 0;
2902 		return (-1);
2903 	}
2904 
2905 	i = 0;
2906 	do {
2907 		(void) sscanf(byte, "%x", &lvalue);
2908 		iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF);
2909 		byte = strtok(NULL, ":");
2910 	} while (byte != NULL && i < len);
2911 
2912 	iddata->Length = i;
2913 	free(iddup);
2914 	return (0);
2915 }
2916 
2917 KMF_RETURN
KMFPK11_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2918 KMFPK11_FindKey(KMF_HANDLE_T handle,
2919 	int numattr, KMF_ATTRIBUTE *attrlist)
2920 {
2921 	KMF_RETURN rv = KMF_OK;
2922 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2923 	uint32_t want_keys, i;
2924 	CK_RV ckrv;
2925 	CK_ATTRIBUTE pTmpl[10];
2926 	CK_OBJECT_CLASS class;
2927 	CK_BBOOL true = TRUE;
2928 	CK_ULONG alg;
2929 	boolean_t is_token = B_TRUE, is_private = B_FALSE;
2930 	KMF_KEY_HANDLE *keys;
2931 	uint32_t *numkeys;
2932 	KMF_CREDENTIAL *cred = NULL;
2933 	KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE;
2934 	char *findLabel, *idstr;
2935 	KMF_KEY_ALG keytype = KMF_KEYALG_NONE;
2936 	KMF_ENCODE_FORMAT format;
2937 
2938 	if (kmfh == NULL)
2939 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2940 
2941 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
2942 		return (KMF_ERR_NO_TOKEN_SELECTED);
2943 
2944 	numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2945 	if (numkeys == NULL)
2946 		return (KMF_ERR_BAD_PARAMETER);
2947 
2948 	if (*numkeys > 0)
2949 		want_keys = *numkeys;
2950 	else
2951 		want_keys = MAXINT; /* count them all */
2952 
2953 	/* keyclass is optional */
2954 	(void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2955 	    (void *)&keyclass, NULL);
2956 
2957 	if (keyclass == KMF_ASYM_PUB) {
2958 		class = CKO_PUBLIC_KEY;
2959 	} else if (keyclass == KMF_ASYM_PRI) {
2960 		class = CKO_PRIVATE_KEY;
2961 	} else if (keyclass == KMF_SYMMETRIC) {
2962 		class = CKO_SECRET_KEY;
2963 	}
2964 
2965 	rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr,
2966 	    (void *)&is_token, NULL);
2967 	if (rv != KMF_OK)
2968 		return (rv);
2969 
2970 	i = 0;
2971 	if (is_token) {
2972 		SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true));
2973 		i++;
2974 	}
2975 
2976 	if (keyclass != KMF_KEYCLASS_NONE) {
2977 		SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class));
2978 		i++;
2979 	}
2980 
2981 	findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
2982 
2983 	if (findLabel != NULL && strlen(findLabel)) {
2984 		SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel));
2985 		i++;
2986 	}
2987 	/* keytype is optional */
2988 	(void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
2989 	    (void *)&keytype, NULL);
2990 
2991 	if (keytype != 0) {
2992 		rv = kmf2pk11keytype(keytype, &alg);
2993 		if (rv != KMF_OK) {
2994 			return (KMF_ERR_BAD_KEY_TYPE);
2995 		}
2996 		SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg));
2997 		i++;
2998 	}
2999 
3000 	idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr);
3001 
3002 	if (idstr != NULL) {
3003 		KMF_DATA iddata = { 0, NULL };
3004 
3005 		/*
3006 		 * ID String parameter is assumed to be of form:
3007 		 * XX:XX:XX:XX:XX ... :XX
3008 		 * where XX is a hex number.
3009 		 *
3010 		 * We must convert this back to binary in order to
3011 		 * use it in a search.
3012 		 */
3013 		rv = IDStringToData(idstr, &iddata);
3014 		if (rv == KMF_OK) {
3015 			SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length);
3016 			i++;
3017 		} else {
3018 			return (rv);
3019 		}
3020 	}
3021 
3022 	/* is_private is optional */
3023 	(void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
3024 	    (void *)&is_private, NULL);
3025 
3026 	if (is_private) {
3027 		SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true));
3028 		i++;
3029 	}
3030 
3031 	/*
3032 	 * Authenticate if the object is a token object,
3033 	 * a private or secred key, or if the user passed in credentials.
3034 	 */
3035 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3036 	if (cred != NULL) {
3037 		rv = pk11_authenticate(handle, cred);
3038 		if (rv != KMF_OK)
3039 			return (rv);
3040 	}
3041 
3042 	keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
3043 	/* it is okay to have "keys" contains NULL */
3044 
3045 	ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i);
3046 	if (ckrv == CKR_OK) {
3047 		CK_ULONG obj_count, n = 0;
3048 		while (ckrv == CKR_OK && n < want_keys) {
3049 			CK_OBJECT_HANDLE hObj;
3050 
3051 			ckrv = C_FindObjects(kmfh->pk11handle, &hObj,
3052 			    1, &obj_count);
3053 			if (ckrv == CKR_OK && obj_count == 1) {
3054 				if (keys != NULL) {
3055 					CK_ULONG keytype;
3056 					keys[n].kstype = KMF_KEYSTORE_PK11TOKEN;
3057 					keys[n].israw = FALSE;
3058 					keys[n].keyp = (void *)hObj;
3059 
3060 					ckrv = getObjectKeytype(handle,
3061 					    (CK_OBJECT_HANDLE)keys[n].keyp,
3062 					    &keytype);
3063 					if (ckrv != CKR_OK)
3064 						goto end;
3065 
3066 					ckrv = getObjectLabel(handle,
3067 					    (CK_OBJECT_HANDLE)keys[n].keyp,
3068 					    &(keys[n].keylabel));
3069 					if (ckrv != CKR_OK)
3070 						goto end;
3071 
3072 					if (keyclass == KMF_KEYCLASS_NONE) {
3073 						ckrv = getObjectKeyclass(handle,
3074 						    (CK_OBJECT_HANDLE)
3075 						    keys[n].keyp,
3076 						    &(keys[n].keyclass));
3077 						if (ckrv != CKR_OK)
3078 							goto end;
3079 					} else {
3080 						keys[n].keyclass = keyclass;
3081 					}
3082 					if (keytype == CKK_RSA) {
3083 						keys[n].keyalg = KMF_RSA;
3084 					} else if (keytype == CKK_DSA) {
3085 						keys[n].keyalg = KMF_DSA;
3086 					} else if (keytype == CKK_EC) {
3087 						keys[n].keyalg = KMF_ECDSA;
3088 					} else if (keytype == CKK_AES) {
3089 						keys[n].keyalg = KMF_AES;
3090 						keys[n].keyclass =
3091 						    KMF_SYMMETRIC;
3092 					} else if (keytype == CKK_RC4) {
3093 						keys[n].keyalg = KMF_RC4;
3094 						keys[n].keyclass =
3095 						    KMF_SYMMETRIC;
3096 					} else if (keytype == CKK_DES) {
3097 						keys[n].keyalg = KMF_DES;
3098 						keys[n].keyclass =
3099 						    KMF_SYMMETRIC;
3100 					} else if (keytype == CKK_DES3) {
3101 						keys[n].keyalg = KMF_DES3;
3102 						keys[n].keyclass =
3103 						    KMF_SYMMETRIC;
3104 					} else if (keytype ==
3105 					    CKK_GENERIC_SECRET) {
3106 						keys[n].keyalg =
3107 						    KMF_GENERIC_SECRET;
3108 						keys[n].keyclass =
3109 						    KMF_SYMMETRIC;
3110 					}
3111 
3112 				}
3113 				n++;
3114 			} else {
3115 				break;
3116 			}
3117 		}
3118 		ckrv = C_FindObjectsFinal(kmfh->pk11handle);
3119 
3120 		/* "numkeys" indicates the number that were actually found */
3121 		*numkeys = n;
3122 	}
3123 
3124 	if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) {
3125 		if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist,
3126 		    numattr, (void *)&format, NULL)) == KMF_OK) {
3127 			if (format == KMF_FORMAT_RAWKEY ||
3128 			    format == KMF_FORMAT_PEM) {
3129 				/* Convert keys to "rawkey" format */
3130 				for (i = 0; i < (*numkeys); i++) {
3131 					KMF_RAW_KEY_DATA *rkey = NULL;
3132 					rv = keyObj2RawKey(handle, &keys[i],
3133 					    &rkey);
3134 					if (rv == KMF_OK) {
3135 						keys[i].keyp = rkey;
3136 						keys[i].israw = TRUE;
3137 					} else {
3138 						break;
3139 					}
3140 				}
3141 			}
3142 		} else {
3143 			rv = KMF_OK; /* format is optional */
3144 		}
3145 	}
3146 
3147 end:
3148 	if (ckrv != CKR_OK) {
3149 		SET_ERROR(kmfh, ckrv);
3150 		/* Report authentication failures to the caller */
3151 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3152 		    ckrv == CKR_PIN_INCORRECT ||
3153 		    ckrv == CKR_PIN_INVALID ||
3154 		    ckrv == CKR_PIN_EXPIRED ||
3155 		    ckrv == CKR_PIN_LOCKED ||
3156 		    ckrv == CKR_SESSION_READ_ONLY)
3157 			rv = KMF_ERR_AUTH_FAILED;
3158 		else
3159 			rv = KMF_ERR_INTERNAL;
3160 	} else if ((*numkeys) == 0) {
3161 		rv = KMF_ERR_KEY_NOT_FOUND;
3162 	}
3163 
3164 	return (rv);
3165 }
3166 
3167 static char *
convertDate(char * fulldate)3168 convertDate(char *fulldate)
3169 {
3170 	struct tm tms;
3171 	char newtime[9];
3172 
3173 	(void) strptime(fulldate, "%b %d %T %Y %Z", &tms);
3174 
3175 	if (tms.tm_year < 69)
3176 		tms.tm_year += 100;
3177 
3178 	(void) strftime(newtime, sizeof (newtime), "m%d", &tms);
3179 
3180 	newtime[8] = 0;
3181 
3182 	/* memory returned must be freed by the caller */
3183 	return ((char *)strdup(newtime));
3184 }
3185 
3186 static KMF_RETURN
store_raw_key(KMF_HANDLE_T handle,KMF_ATTRIBUTE * attrlist,int numattr,KMF_RAW_KEY_DATA * rawkey)3187 store_raw_key(KMF_HANDLE_T handle,
3188 	KMF_ATTRIBUTE *attrlist, int numattr,
3189 	KMF_RAW_KEY_DATA *rawkey)
3190 {
3191 	KMF_RETURN rv = KMF_OK;
3192 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3193 	int i;
3194 	CK_RV		ckrv = CKR_OK;
3195 	CK_ATTRIBUTE	templ[32];
3196 	CK_OBJECT_HANDLE keyobj;
3197 	CK_KEY_TYPE	keytype;
3198 	CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
3199 	CK_BBOOL	cktrue = TRUE;
3200 	CK_DATE		startdate, enddate;
3201 	KMF_DATA	id = { 0, NULL };
3202 	KMF_DATA	subject = { 0, NULL };
3203 	KMF_X509EXT_KEY_USAGE kuext;
3204 	KMF_X509_CERTIFICATE *x509 = NULL;
3205 	CK_BBOOL	kufound = B_FALSE;
3206 	KMF_DATA	*cert = NULL;
3207 	char		*notbefore = NULL, *start = NULL;
3208 	char		*notafter = NULL, *end = NULL;
3209 	char		*keylabel = NULL;
3210 	KMF_CREDENTIAL	*cred = NULL;
3211 
3212 	if (kmfh == NULL)
3213 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
3214 
3215 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
3216 		return (KMF_ERR_NO_TOKEN_SELECTED);
3217 
3218 	if (rawkey->keytype == KMF_RSA)
3219 		keytype = CKK_RSA;
3220 	else if (rawkey->keytype == KMF_DSA)
3221 		keytype = CKK_DSA;
3222 	else if (rawkey->keytype == KMF_ECDSA)
3223 		keytype = CKK_EC;
3224 	else
3225 		return (KMF_ERR_BAD_PARAMETER);
3226 
3227 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3228 	if (cred != NULL) {
3229 		rv = pk11_authenticate(handle, cred);
3230 		if (rv != KMF_OK)
3231 			return (rv);
3232 	}
3233 
3234 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3235 	/*
3236 	 * If the caller did not specify a label, see if the raw key
3237 	 * came with one (possible if it came from a PKCS#12 file).
3238 	 */
3239 	if (keylabel == NULL) {
3240 		keylabel = rawkey->label;
3241 	}
3242 
3243 	i = 0;
3244 	SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++;
3245 	SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++;
3246 	SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++;
3247 	SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++;
3248 	if (keytype != CKK_EC) {
3249 		SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++;
3250 	}
3251 
3252 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
3253 	if (cert != NULL) {
3254 		id.Data = NULL;
3255 		id.Length = 0;
3256 		rv = kmf_get_cert_id_data(cert, &id);
3257 		if (rv != KMF_OK) {
3258 			goto cleanup;
3259 		}
3260 
3261 		rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509);
3262 		if (rv != KMF_OK) {
3263 			goto cleanup;
3264 		}
3265 
3266 		rv = DerEncodeName(&x509->certificate.subject, &subject);
3267 		if (rv != KMF_OK) {
3268 			goto cleanup;
3269 		}
3270 		SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length);
3271 		i++;
3272 
3273 		rv = kmf_get_cert_start_date_str(handle, cert, &notbefore);
3274 		if (rv != KMF_OK) {
3275 			goto cleanup;
3276 		}
3277 		start = convertDate(notbefore);
3278 		free(notbefore);
3279 
3280 		rv = kmf_get_cert_end_date_str(handle, cert, &notafter);
3281 		if (rv != KMF_OK) {
3282 			goto cleanup;
3283 		}
3284 		end = convertDate(notafter);
3285 		free(notafter);
3286 		if (id.Data != NULL && id.Data != NULL && id.Length > 0) {
3287 			SETATTR(templ, i, CKA_ID, id.Data, id.Length);
3288 			i++;
3289 		}
3290 		if (start != NULL) {
3291 			/*
3292 			 * This makes some potentially dangerous assumptions:
3293 			 *  1. that the startdate in the parameter block is
3294 			 * properly formatted as YYYYMMDD
3295 			 *  2. That the CK_DATE structure is always the same.
3296 			 */
3297 			(void) memcpy(&startdate, start, sizeof (CK_DATE));
3298 			SETATTR(templ, i, CKA_START_DATE, &startdate,
3299 			    sizeof (startdate));
3300 			i++;
3301 		}
3302 		if (end != NULL) {
3303 			(void) memcpy(&enddate, end, sizeof (CK_DATE));
3304 			SETATTR(templ, i, CKA_END_DATE, &enddate,
3305 			    sizeof (enddate));
3306 			i++;
3307 		}
3308 
3309 		if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK &&
3310 		    rv != KMF_ERR_EXTENSION_NOT_FOUND)
3311 			goto cleanup;
3312 
3313 		kufound = (rv == KMF_OK);
3314 		rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */
3315 	}
3316 
3317 	/*
3318 	 * Only set the KeyUsage stuff if the KU extension was present.
3319 	 */
3320 	if (kufound) {
3321 		CK_BBOOL	condition;
3322 
3323 		condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ?
3324 		    B_TRUE : B_FALSE;
3325 		SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL));
3326 		i++;
3327 		condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ?
3328 		    B_TRUE : B_FALSE;
3329 		SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL));
3330 		i++;
3331 		condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
3332 		    B_TRUE : B_FALSE;
3333 		SETATTR(templ, i, CKA_SIGN, &condition,	sizeof (CK_BBOOL));
3334 		i++;
3335 		condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
3336 		    B_TRUE : B_FALSE;
3337 		SETATTR(templ, i, CKA_SIGN_RECOVER, &condition,
3338 		    sizeof (CK_BBOOL));
3339 		i++;
3340 
3341 	}
3342 
3343 	if (keylabel != NULL) {
3344 		SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3345 		i++;
3346 	}
3347 	if (id.Data == NULL && rawkey->id.Data != NULL) {
3348 		SETATTR(templ, i, CKA_ID, rawkey->id.Data,
3349 		    rawkey->id.Length);
3350 		i++;
3351 	}
3352 	if (keytype == CKK_RSA) {
3353 		SETATTR(templ, i, CKA_MODULUS,
3354 		    rawkey->rawdata.rsa.mod.val,
3355 		    rawkey->rawdata.rsa.mod.len);
3356 		i++;
3357 		SETATTR(templ, i, CKA_PUBLIC_EXPONENT,
3358 		    rawkey->rawdata.rsa.pubexp.val,
3359 		    rawkey->rawdata.rsa.pubexp.len);
3360 		i++;
3361 		if (rawkey->rawdata.rsa.priexp.val != NULL) {
3362 			SETATTR(templ, i, CKA_PRIVATE_EXPONENT,
3363 			    rawkey->rawdata.rsa.priexp.val,
3364 			    rawkey->rawdata.rsa.priexp.len);
3365 			i++;
3366 		}
3367 		if (rawkey->rawdata.rsa.prime1.val != NULL) {
3368 			SETATTR(templ, i, CKA_PRIME_1,
3369 			    rawkey->rawdata.rsa.prime1.val,
3370 			    rawkey->rawdata.rsa.prime1.len);
3371 			i++;
3372 		}
3373 		if (rawkey->rawdata.rsa.prime2.val != NULL) {
3374 			SETATTR(templ, i, CKA_PRIME_2,
3375 			    rawkey->rawdata.rsa.prime2.val,
3376 			    rawkey->rawdata.rsa.prime2.len);
3377 			i++;
3378 		}
3379 		if (rawkey->rawdata.rsa.exp1.val != NULL) {
3380 			SETATTR(templ, i, CKA_EXPONENT_1,
3381 			    rawkey->rawdata.rsa.exp1.val,
3382 			    rawkey->rawdata.rsa.exp1.len);
3383 			i++;
3384 		}
3385 		if (rawkey->rawdata.rsa.exp2.val != NULL) {
3386 			SETATTR(templ, i, CKA_EXPONENT_2,
3387 			    rawkey->rawdata.rsa.exp2.val,
3388 			    rawkey->rawdata.rsa.exp2.len);
3389 			i++;
3390 		}
3391 		if (rawkey->rawdata.rsa.coef.val != NULL) {
3392 			SETATTR(templ, i, CKA_COEFFICIENT,
3393 			    rawkey->rawdata.rsa.coef.val,
3394 			    rawkey->rawdata.rsa.coef.len);
3395 			i++;
3396 		}
3397 	} else if (keytype == CKK_DSA) {
3398 		SETATTR(templ, i, CKA_PRIME,
3399 		    rawkey->rawdata.dsa.prime.val,
3400 		    rawkey->rawdata.dsa.prime.len);
3401 		i++;
3402 		SETATTR(templ, i, CKA_SUBPRIME,
3403 		    rawkey->rawdata.dsa.subprime.val,
3404 		    rawkey->rawdata.dsa.subprime.len);
3405 		i++;
3406 		SETATTR(templ, i, CKA_BASE,
3407 		    rawkey->rawdata.dsa.base.val,
3408 		    rawkey->rawdata.dsa.base.len);
3409 		i++;
3410 		SETATTR(templ, i, CKA_VALUE,
3411 		    rawkey->rawdata.dsa.value.val,
3412 		    rawkey->rawdata.dsa.value.len);
3413 		i++;
3414 	} else if (keytype == CKK_EC) {
3415 		SETATTR(templ, i, CKA_SIGN, &cktrue, sizeof (cktrue));
3416 		i++;
3417 		SETATTR(templ, i, CKA_DERIVE, &cktrue, sizeof (cktrue));
3418 		i++;
3419 		SETATTR(templ, i, CKA_VALUE,
3420 		    rawkey->rawdata.ec.value.val,
3421 		    rawkey->rawdata.ec.value.len);
3422 		i++;
3423 		SETATTR(templ, i, CKA_EC_PARAMS,
3424 		    rawkey->rawdata.ec.params.Data,
3425 		    rawkey->rawdata.ec.params.Length);
3426 		i++;
3427 	}
3428 
3429 	ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj);
3430 	if (ckrv != CKR_OK) {
3431 		SET_ERROR(kmfh, ckrv);
3432 
3433 		/* Report authentication failures to the caller */
3434 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3435 		    ckrv == CKR_PIN_INCORRECT ||
3436 		    ckrv == CKR_PIN_INVALID ||
3437 		    ckrv == CKR_PIN_EXPIRED ||
3438 		    ckrv == CKR_PIN_LOCKED ||
3439 		    ckrv == CKR_SESSION_READ_ONLY)
3440 			rv = KMF_ERR_AUTH_FAILED;
3441 		else
3442 			rv = KMF_ERR_INTERNAL;
3443 	}
3444 cleanup:
3445 	if (start != NULL)
3446 		free(start);
3447 	if (end != NULL)
3448 		free(end);
3449 	kmf_free_data(&id);
3450 	kmf_free_data(&subject);
3451 	kmf_free_signed_cert(x509);
3452 	free(x509);
3453 
3454 	return (rv);
3455 }
3456 
3457 KMF_RETURN
KMFPK11_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3458 KMFPK11_CreateSymKey(KMF_HANDLE_T handle,
3459     int numattr, KMF_ATTRIBUTE *attrlist)
3460 {
3461 	KMF_RETURN		rv = KMF_OK;
3462 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
3463 	CK_RV			ckrv;
3464 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
3465 	CK_OBJECT_HANDLE	keyhandle;
3466 	CK_MECHANISM		keyGenMech;
3467 	CK_OBJECT_CLASS		class = CKO_SECRET_KEY;
3468 	CK_ULONG		secKeyType;
3469 	CK_ULONG		secKeyLen;	/* for RC4 and AES */
3470 	CK_BBOOL		true = TRUE;
3471 	CK_BBOOL		false = FALSE;
3472 	CK_ATTRIBUTE		templ[15];
3473 	CK_BYTE			*keydata = NULL;
3474 	int			i = 0;
3475 	KMF_KEY_HANDLE		*symkey;
3476 	KMF_KEY_ALG		keytype;
3477 	uint32_t		keylen = 0;
3478 	uint32_t		attrkeylen = 0;
3479 	uint32_t		keylen_size = sizeof (uint32_t);
3480 	char			*keylabel = NULL;
3481 	KMF_CREDENTIAL		*cred = NULL;
3482 	uint32_t		is_sensitive = B_FALSE;
3483 	uint32_t		is_not_extractable = B_FALSE;
3484 
3485 	if (kmfh == NULL)
3486 		return (KMF_ERR_UNINITIALIZED);
3487 
3488 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
3489 		return (KMF_ERR_NO_TOKEN_SELECTED);
3490 
3491 	symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
3492 	if (symkey == NULL)
3493 		return (KMF_ERR_BAD_PARAMETER);
3494 
3495 	rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
3496 	    (void *)&keytype, NULL);
3497 	if (rv != KMF_OK)
3498 		return (KMF_ERR_BAD_PARAMETER);
3499 
3500 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3501 	if (keylabel == NULL)
3502 		return (KMF_ERR_BAD_PARAMETER);
3503 
3504 	rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
3505 	    (void *)&is_sensitive, NULL);
3506 	if (rv != KMF_OK)
3507 		return (KMF_ERR_BAD_PARAMETER);
3508 
3509 	rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
3510 	    (void *)&is_not_extractable, NULL);
3511 	if (rv != KMF_OK)
3512 		return (KMF_ERR_BAD_PARAMETER);
3513 
3514 	/*
3515 	 * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key.
3516 	 *
3517 	 * For a generic secret key, because it may not be supported in
3518 	 * C_GenerateKey() for some PKCS11 providers, we will handle it
3519 	 * differently.
3520 	 */
3521 	if (keytype == KMF_GENERIC_SECRET) {
3522 		rv = create_generic_secret_key(handle, numattr,
3523 		    attrlist, &keyhandle);
3524 		if (rv != KMF_OK)
3525 			goto out;
3526 		else
3527 			goto setup;
3528 	}
3529 
3530 	rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
3531 	    NULL, &attrkeylen);
3532 	if (rv == KMF_OK && attrkeylen > 0) {
3533 		keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
3534 		    numattr);
3535 	} else {
3536 		keydata = NULL;
3537 		attrkeylen = 0;
3538 		rv = KMF_OK;
3539 	}
3540 	if (keydata != NULL) {
3541 		if (keytype == KMF_DES && attrkeylen != 8) {
3542 			rv = KMF_ERR_BAD_KEY_SIZE;
3543 			goto out;
3544 		}
3545 		if (keytype == KMF_DES3 && attrkeylen != 24) {
3546 			rv = KMF_ERR_BAD_KEY_SIZE;
3547 			goto out;
3548 		}
3549 		/*
3550 		 * This may override what the user gave on the
3551 		 * command line.
3552 		 */
3553 		keylen = attrkeylen * 8; /* bytes to bits */
3554 	} else {
3555 		/*
3556 		 * If keydata was not given, key length must be
3557 		 * provided.
3558 		 */
3559 		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
3560 		    &keylen, &keylen_size);
3561 		if (rv == KMF_ERR_ATTR_NOT_FOUND &&
3562 		    (keytype == KMF_DES || keytype == KMF_DES3))
3563 			/* keylength is not required for DES and 3DES */
3564 			rv = KMF_OK;
3565 		if (rv != KMF_OK)
3566 			return (KMF_ERR_BAD_PARAMETER);
3567 	}
3568 
3569 	if ((keylen % 8) != 0) {
3570 		return (KMF_ERR_BAD_KEY_SIZE);
3571 	}
3572 	secKeyLen = keylen / 8;  /* in bytes for RC4/AES */
3573 
3574 	/*
3575 	 * Only set CKA_VALUE_LEN if the key data was not given and
3576 	 * we are creating an RC4 or AES key.
3577 	 */
3578 	if (keydata == NULL &&
3579 	    (keytype == KMF_AES || keytype == KMF_RC4)) {
3580 		SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen,
3581 		    sizeof (secKeyLen));
3582 		i++;
3583 	}
3584 
3585 	/* Other keytypes */
3586 	keyGenMech.pParameter = NULL_PTR;
3587 	keyGenMech.ulParameterLen = 0;
3588 	switch (keytype) {
3589 		case KMF_AES:
3590 			keyGenMech.mechanism = CKM_AES_KEY_GEN;
3591 			secKeyType = CKK_AES;
3592 			break;
3593 		case KMF_RC4:
3594 			keyGenMech.mechanism = CKM_RC4_KEY_GEN;
3595 			secKeyType = CKK_RC4;
3596 			break;
3597 		case KMF_DES:
3598 			keyGenMech.mechanism = CKM_DES_KEY_GEN;
3599 			secKeyType = CKK_DES;
3600 			break;
3601 		case KMF_DES3:
3602 			keyGenMech.mechanism = CKM_DES3_KEY_GEN;
3603 			secKeyType = CKK_DES3;
3604 			break;
3605 		default:
3606 			return (KMF_ERR_BAD_KEY_TYPE);
3607 	}
3608 	if (keydata != NULL) {
3609 		SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen);
3610 		i++;
3611 	}
3612 	SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
3613 	i++;
3614 	SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
3615 	i++;
3616 
3617 	if (keylabel != NULL) {
3618 		SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3619 		i++;
3620 	}
3621 
3622 	if (is_sensitive == B_TRUE) {
3623 		SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
3624 	} else {
3625 		SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
3626 	}
3627 	i++;
3628 
3629 	if (is_not_extractable == B_TRUE) {
3630 		SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
3631 	} else {
3632 		SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
3633 	}
3634 	i++;
3635 
3636 	SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
3637 	i++;
3638 	SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
3639 	i++;
3640 	SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true));
3641 	i++;
3642 	SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true));
3643 	i++;
3644 	SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
3645 	i++;
3646 	SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true));
3647 	i++;
3648 
3649 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3650 	if (cred == NULL)
3651 		return (KMF_ERR_BAD_PARAMETER);
3652 
3653 	rv = pk11_authenticate(handle, cred);
3654 	if (rv != KMF_OK) {
3655 		return (rv);
3656 	}
3657 
3658 	/* If the key data was given, use C_CreateObject */
3659 	if (keydata != NULL) {
3660 		ckrv = C_CreateObject(hSession, templ, i, &keyhandle);
3661 	} else {
3662 		ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i,
3663 		    &keyhandle);
3664 	}
3665 	if (ckrv != CKR_OK) {
3666 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3667 		    ckrv == CKR_PIN_INCORRECT ||
3668 		    ckrv == CKR_PIN_INVALID ||
3669 		    ckrv == CKR_PIN_EXPIRED ||
3670 		    ckrv == CKR_PIN_LOCKED ||
3671 		    ckrv == CKR_SESSION_READ_ONLY)
3672 			rv = KMF_ERR_AUTH_FAILED;
3673 		else
3674 			rv = KMF_ERR_KEYGEN_FAILED;
3675 		SET_ERROR(kmfh, ckrv);
3676 		goto out;
3677 	}
3678 
3679 setup:
3680 	symkey->kstype = KMF_KEYSTORE_PK11TOKEN;
3681 	symkey->keyalg = keytype;
3682 	symkey->keyclass = KMF_SYMMETRIC;
3683 	symkey->israw = FALSE;
3684 	symkey->keyp = (void *)keyhandle;
3685 
3686 out:
3687 	return (rv);
3688 }
3689 
3690 KMF_RETURN
KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)3691 KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
3692     KMF_RAW_SYM_KEY *rkey)
3693 {
3694 	KMF_RETURN		rv = KMF_OK;
3695 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
3696 
3697 	if (kmfh == NULL)
3698 		return (KMF_ERR_UNINITIALIZED);
3699 
3700 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
3701 		return (KMF_ERR_NO_TOKEN_SELECTED);
3702 
3703 	if (symkey == NULL || rkey == NULL)
3704 		return (KMF_ERR_BAD_PARAMETER);
3705 	else if (symkey->keyclass != KMF_SYMMETRIC)
3706 		return (KMF_ERR_BAD_KEY_CLASS);
3707 
3708 	/*
3709 	 * If the key is already in "raw" format, copy the data
3710 	 * to the new record if possible.
3711 	 */
3712 	if (symkey->israw) {
3713 		KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
3714 
3715 		if (rawkey == NULL)
3716 			return (KMF_ERR_BAD_KEYHANDLE);
3717 		if (rawkey->sensitive)
3718 			return (KMF_ERR_SENSITIVE_KEY);
3719 		if (rawkey->not_extractable)
3720 			return (KMF_ERR_UNEXTRACTABLE_KEY);
3721 
3722 		if (rawkey->rawdata.sym.keydata.val == NULL ||
3723 		    rawkey->rawdata.sym.keydata.len == 0)
3724 			return (KMF_ERR_GETKEYVALUE_FAILED);
3725 
3726 		rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
3727 		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
3728 			return (KMF_ERR_MEMORY);
3729 		(void) memcpy(rkey->keydata.val,
3730 		    rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
3731 	} else {
3732 		rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey);
3733 	}
3734 
3735 	return (rv);
3736 }
3737 
3738 KMF_RETURN
KMFPK11_SetTokenPin(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3739 KMFPK11_SetTokenPin(KMF_HANDLE_T handle,
3740 	int numattr, KMF_ATTRIBUTE *attrlist)
3741 {
3742 	KMF_RETURN	ret = KMF_OK;
3743 	CK_RV		rv = CKR_OK;
3744 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
3745 	CK_SESSION_HANDLE	session = 0;
3746 	KMF_CREDENTIAL	*oldcred;
3747 	KMF_CREDENTIAL	*newcred;
3748 	CK_SLOT_ID	slotid;
3749 	CK_USER_TYPE	user = CKU_USER;
3750 
3751 	if (handle == NULL || attrlist == NULL || numattr == 0)
3752 		return (KMF_ERR_BAD_PARAMETER);
3753 
3754 	oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3755 	if (oldcred == NULL)
3756 		return (KMF_ERR_BAD_PARAMETER);
3757 
3758 	newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr);
3759 	if (newcred == NULL)
3760 		return (KMF_ERR_BAD_PARAMETER);
3761 
3762 	rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr,
3763 	    (void *)&slotid, NULL);
3764 	if (rv != KMF_OK) {
3765 		char *tokenlabel = NULL;
3766 		/*
3767 		 * If a slot wasn't given, the user must pass
3768 		 * a token label so we can find the slot here.
3769 		 */
3770 		tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
3771 		    numattr);
3772 		if (tokenlabel == NULL)
3773 			return (KMF_ERR_BAD_PARAMETER);
3774 
3775 		rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid);
3776 		if (rv != KMF_OK)
3777 			return (rv);
3778 	}
3779 	rv = kmf_get_attr(KMF_PK11_USER_TYPE_ATTR, attrlist, numattr,
3780 	    (void *)&user, NULL);
3781 	if (rv != CKR_OK)
3782 		user = CKU_USER;
3783 
3784 	rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION,
3785 	    NULL, NULL, &session);
3786 	if (rv != CKR_OK) {
3787 		SET_ERROR(kmfh, rv);
3788 		ret = KMF_ERR_UNINITIALIZED;
3789 		goto end;
3790 	}
3791 
3792 	rv = C_Login(session, user, (CK_BYTE *)oldcred->cred,
3793 	    oldcred->credlen);
3794 	if (rv != CKR_OK) {
3795 		SET_ERROR(kmfh, rv);
3796 		if (rv == CKR_PIN_INCORRECT ||
3797 		    rv == CKR_PIN_INVALID ||
3798 		    rv == CKR_PIN_EXPIRED ||
3799 		    rv == CKR_PIN_LOCKED)
3800 			ret = KMF_ERR_AUTH_FAILED;
3801 		else
3802 			ret = KMF_ERR_INTERNAL;
3803 
3804 		goto end;
3805 	}
3806 
3807 	rv = C_SetPIN(session,
3808 	    (CK_BYTE *)oldcred->cred, oldcred->credlen,
3809 	    (CK_BYTE *)newcred->cred, newcred->credlen);
3810 
3811 	if (rv != CKR_OK) {
3812 		SET_ERROR(kmfh, rv);
3813 		if (rv == CKR_PIN_INCORRECT ||
3814 		    rv == CKR_PIN_INVALID ||
3815 		    rv == CKR_PIN_EXPIRED ||
3816 		    rv == CKR_PIN_LOCKED)
3817 			ret = KMF_ERR_AUTH_FAILED;
3818 		else
3819 			ret = KMF_ERR_INTERNAL;
3820 	}
3821 end:
3822 	if (session != 0)
3823 		(void) C_CloseSession(session);
3824 	return (ret);
3825 }
3826 
3827 static KMF_RETURN
create_generic_secret_key(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist,CK_OBJECT_HANDLE * key)3828 create_generic_secret_key(KMF_HANDLE_T handle,
3829 	int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key)
3830 {
3831 	KMF_RETURN		rv = KMF_OK;
3832 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
3833 	CK_RV			ckrv;
3834 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
3835 	CK_OBJECT_CLASS		class = CKO_SECRET_KEY;
3836 	CK_ULONG		secKeyType = CKK_GENERIC_SECRET;
3837 	CK_ULONG		secKeyLen;
3838 	CK_BBOOL		true = TRUE;
3839 	CK_BBOOL		false = FALSE;
3840 	CK_ATTRIBUTE		templ[15];
3841 	int			i;
3842 	int			random_fd = -1;
3843 	int			nread;
3844 	int			freebuf = 0;
3845 	char			*buf = NULL;
3846 	uint32_t		keylen = 0, attrkeylen = 0;
3847 	char			*keylabel = NULL;
3848 	KMF_CREDENTIAL		*cred;
3849 	uint32_t is_sensitive, is_not_extractable;
3850 
3851 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3852 	if (keylabel == NULL)
3853 		return (KMF_ERR_BAD_PARAMETER);
3854 
3855 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3856 	if (cred == NULL)
3857 		return (KMF_ERR_BAD_PARAMETER);
3858 
3859 	rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
3860 	    (void *)&is_sensitive, NULL);
3861 	if (rv != KMF_OK)
3862 		return (KMF_ERR_BAD_PARAMETER);
3863 
3864 	rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
3865 	    (void *)&is_not_extractable, NULL);
3866 	if (rv != KMF_OK)
3867 		return (KMF_ERR_BAD_PARAMETER);
3868 
3869 	rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
3870 	    NULL, &attrkeylen);
3871 	if (rv == KMF_OK && attrkeylen > 0) {
3872 		buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
3873 		    numattr);
3874 		secKeyLen = attrkeylen;
3875 	} else {
3876 		buf = NULL;
3877 		rv = KMF_OK;
3878 	}
3879 	if (buf == NULL) {
3880 		/*
3881 		 * If the key data was not given, key length must
3882 		 * be provided.
3883 		 */
3884 		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
3885 		    &keylen, NULL);
3886 		if (rv != KMF_OK)
3887 			return (KMF_ERR_BAD_PARAMETER);
3888 
3889 		/*
3890 		 * Check the key size.
3891 		 */
3892 		if ((keylen % 8) != 0) {
3893 			return (KMF_ERR_BAD_KEY_SIZE);
3894 		} else {
3895 			secKeyLen = keylen/8;  /* in bytes */
3896 		}
3897 
3898 		/*
3899 		 * Generate a random number with the key size first.
3900 		 */
3901 		buf = malloc(secKeyLen);
3902 		if (buf == NULL)
3903 			return (KMF_ERR_MEMORY);
3904 
3905 		freebuf = 1;
3906 		while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) {
3907 			if (errno != EINTR)
3908 				break;
3909 		}
3910 
3911 		if (random_fd < 0) {
3912 			rv = KMF_ERR_KEYGEN_FAILED;
3913 			goto out;
3914 		}
3915 
3916 		nread = read(random_fd, buf, secKeyLen);
3917 		if (nread <= 0 || nread != secKeyLen) {
3918 			rv = KMF_ERR_KEYGEN_FAILED;
3919 			goto out;
3920 		}
3921 	}
3922 
3923 	/*
3924 	 * Authenticate into the token and call C_CreateObject to generate
3925 	 * a generic secret token key.
3926 	 */
3927 	rv = pk11_authenticate(handle, cred);
3928 	if (rv != KMF_OK) {
3929 		goto out;
3930 	}
3931 
3932 	i = 0;
3933 	SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
3934 	i++;
3935 	SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
3936 	i++;
3937 	SETATTR(templ, i, CKA_VALUE, buf, secKeyLen);
3938 	i++;
3939 
3940 	if (keylabel != NULL) {
3941 		SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3942 		i++;
3943 	}
3944 
3945 	if (is_sensitive == B_TRUE) {
3946 		SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
3947 	} else {
3948 		SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
3949 	}
3950 	i++;
3951 
3952 	if (is_not_extractable == B_TRUE) {
3953 		SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
3954 	} else {
3955 		SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
3956 	}
3957 	i++;
3958 
3959 	SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
3960 	i++;
3961 	SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
3962 	i++;
3963 	SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
3964 	i++;
3965 
3966 	ckrv = C_CreateObject(hSession, templ, i, key);
3967 	if (ckrv != CKR_OK) {
3968 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3969 		    ckrv == CKR_PIN_INCORRECT ||
3970 		    ckrv == CKR_PIN_INVALID ||
3971 		    ckrv == CKR_PIN_EXPIRED ||
3972 		    ckrv == CKR_PIN_LOCKED ||
3973 		    ckrv == CKR_SESSION_READ_ONLY)
3974 			rv = KMF_ERR_AUTH_FAILED;
3975 		else
3976 			rv = KMF_ERR_KEYGEN_FAILED;
3977 		SET_ERROR(kmfh, ckrv);
3978 	}
3979 
3980 out:
3981 	if (buf != NULL && freebuf)
3982 		free(buf);
3983 
3984 	if (random_fd != -1)
3985 		(void) close(random_fd);
3986 
3987 	return (rv);
3988 }
3989 
3990 KMF_RETURN
KMFPK11_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)3991 KMFPK11_StoreKey(KMF_HANDLE_T handle,
3992 	int numattr,
3993 	KMF_ATTRIBUTE *attlist)
3994 {
3995 	KMF_RETURN rv = KMF_OK;
3996 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3997 	KMF_CREDENTIAL cred = { NULL, 0 };
3998 	KMF_KEY_HANDLE *key;
3999 	KMF_RAW_KEY_DATA *rawkey = NULL;
4000 	CK_BBOOL btrue = TRUE;
4001 	CK_ATTRIBUTE tokenattr[1];
4002 	CK_OBJECT_HANDLE newobj;
4003 	CK_RV ckrv;
4004 
4005 	if (kmfh == NULL)
4006 		return (KMF_ERR_UNINITIALIZED);
4007 
4008 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
4009 		return (KMF_ERR_NO_TOKEN_SELECTED);
4010 
4011 	rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr,
4012 	    (void *)&cred, NULL);
4013 	if (rv != KMF_OK)
4014 		return (KMF_ERR_BAD_PARAMETER);
4015 
4016 	rv = pk11_authenticate(handle, &cred);
4017 	if (rv != KMF_OK)
4018 		return (rv);
4019 
4020 	key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
4021 	if (key == NULL) {
4022 		key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist,
4023 		    numattr);
4024 		if (key == NULL)
4025 			rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist,
4026 			    numattr);
4027 	}
4028 	if (key == NULL && rawkey == NULL)
4029 		return (KMF_ERR_ATTR_NOT_FOUND);
4030 
4031 	if (rawkey != NULL) {
4032 		rv = store_raw_key(handle, attlist, numattr, rawkey);
4033 	} else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) {
4034 
4035 		SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue));
4036 		/* Copy the key object to the token */
4037 		ckrv = C_CopyObject(kmfh->pk11handle,
4038 		    (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj);
4039 		if (ckrv != CKR_OK)  {
4040 			SET_ERROR(kmfh, ckrv);
4041 			return (KMF_ERR_INTERNAL);
4042 		}
4043 
4044 		/* Replace the object handle with the new token-based one */
4045 		ckrv = C_DestroyObject(kmfh->pk11handle,
4046 		    (CK_OBJECT_HANDLE)key->keyp);
4047 		if (ckrv != CKR_OK)  {
4048 			SET_ERROR(kmfh, ckrv);
4049 			return (KMF_ERR_INTERNAL);
4050 		}
4051 		key->keyp = (void *)newobj;
4052 	} else {
4053 		rv = KMF_ERR_BAD_PARAMETER;
4054 	}
4055 
4056 	return (rv);
4057 }
4058 
4059 
4060 KMF_RETURN
KMFPK11_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)4061 KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4062 {
4063 	KMF_RETURN rv = KMF_OK;
4064 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4065 	KMF_CREDENTIAL *cred = NULL;
4066 	KMF_CREDENTIAL *p12cred = NULL;
4067 	char *filename = NULL;
4068 	KMF_X509_DER_CERT *certlist = NULL;
4069 	KMF_KEY_HANDLE *keylist = NULL;
4070 	uint32_t numcerts;
4071 	uint32_t numkeys;
4072 	char *certlabel = NULL;
4073 	char *issuer = NULL;
4074 	char *subject = NULL;
4075 	KMF_BIGINT *serial = NULL;
4076 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
4077 	KMF_ATTRIBUTE fc_attrlist[16];
4078 	int i;
4079 
4080 	if (kmfh == NULL)
4081 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
4082 
4083 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
4084 		return (KMF_ERR_NO_TOKEN_SELECTED);
4085 
4086 	/* First get the required attributes */
4087 	cred =  kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
4088 	if (cred == NULL)
4089 		return (KMF_ERR_BAD_PARAMETER);
4090 
4091 	p12cred =  kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
4092 	if (p12cred == NULL)
4093 		return (KMF_ERR_BAD_PARAMETER);
4094 
4095 	filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
4096 	    numattr);
4097 	if (filename == NULL)
4098 		return (KMF_ERR_BAD_PARAMETER);
4099 
4100 	/* Find all the certificates that match the searching criteria */
4101 	i = 0;
4102 	kmf_set_attr_at_index(fc_attrlist, i,
4103 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4104 	i++;
4105 
4106 	kmf_set_attr_at_index(fc_attrlist, i,
4107 	    KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
4108 	i++;
4109 
4110 	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
4111 	if (certlabel != NULL) {
4112 		kmf_set_attr_at_index(fc_attrlist, i,
4113 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
4114 		i++;
4115 	}
4116 
4117 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
4118 	if (issuer != NULL) {
4119 		kmf_set_attr_at_index(fc_attrlist, i,
4120 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
4121 		i++;
4122 	}
4123 
4124 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
4125 	if (subject != NULL) {
4126 		kmf_set_attr_at_index(fc_attrlist, i,
4127 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
4128 		i++;
4129 	}
4130 
4131 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
4132 	if (serial != NULL) {
4133 		kmf_set_attr_at_index(fc_attrlist, i,
4134 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
4135 		i++;
4136 	}
4137 
4138 	rv = KMFPK11_FindCert(handle, i, fc_attrlist);
4139 
4140 	if (rv == KMF_OK && numcerts > 0) {
4141 		certlist = (KMF_X509_DER_CERT *)malloc(numcerts *
4142 		    sizeof (KMF_X509_DER_CERT));
4143 		if (certlist == NULL)
4144 			return (KMF_ERR_MEMORY);
4145 
4146 		(void) memset(certlist, 0, numcerts *
4147 		    sizeof (KMF_X509_DER_CERT));
4148 
4149 		kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR,
4150 		    certlist, sizeof (KMF_X509_DER_CERT));
4151 		i++;
4152 
4153 		rv = kmf_find_cert(handle, i, fc_attrlist);
4154 		if (rv != KMF_OK) {
4155 			free(certlist);
4156 			return (rv);
4157 		}
4158 	} else {
4159 		return (rv);
4160 	}
4161 
4162 	/* For each certificate, find the matching private key */
4163 	numkeys = 0;
4164 	for (i = 0; i < numcerts; i++) {
4165 		KMF_ATTRIBUTE fk_attrlist[16];
4166 		int j = 0;
4167 		KMF_KEY_HANDLE newkey;
4168 		KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY;
4169 
4170 		kmf_set_attr_at_index(fk_attrlist, j,
4171 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4172 		j++;
4173 
4174 		kmf_set_attr_at_index(fk_attrlist, j,
4175 		    KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format));
4176 		j++;
4177 
4178 		kmf_set_attr_at_index(fk_attrlist, j,
4179 		    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
4180 		j++;
4181 
4182 		kmf_set_attr_at_index(fk_attrlist, j,
4183 		    KMF_CERT_DATA_ATTR, &certlist[i].certificate,
4184 		    sizeof (KMF_DATA));
4185 		j++;
4186 
4187 		kmf_set_attr_at_index(fk_attrlist, j,
4188 		    KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE));
4189 		j++;
4190 
4191 		rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist);
4192 		if (rv == KMF_OK) {
4193 			numkeys++;
4194 			keylist = realloc(keylist,
4195 			    numkeys * sizeof (KMF_KEY_HANDLE));
4196 			if (keylist == NULL) {
4197 				rv = KMF_ERR_MEMORY;
4198 				goto out;
4199 			}
4200 			keylist[numkeys - 1] = newkey;
4201 		} else if (rv == KMF_ERR_KEY_NOT_FOUND) {
4202 			/* it is OK if a key is not found */
4203 			rv = KMF_OK;
4204 		}
4205 	}
4206 
4207 	if (rv != KMF_OK)
4208 		goto out;
4209 
4210 	rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist,
4211 	    p12cred, filename);
4212 
4213 out:
4214 	if (certlist != NULL) {
4215 		for (i = 0; i < numcerts; i++)
4216 			kmf_free_kmf_cert(handle, &certlist[i]);
4217 		free(certlist);
4218 	}
4219 	if (keylist != NULL) {
4220 		for (i = 0; i < numkeys; i++)
4221 			kmf_free_kmf_key(handle, &keylist[i]);
4222 		free(keylist);
4223 	}
4224 
4225 	return (rv);
4226 }
4227