xref: /illumos-gate/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c (revision 33efde4275d24731ef87927237b0ffb0630b6b2d)
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 	if (EncodedKey) {
1075 		if (pKey->keyalg != KMF_ECDSA)
1076 			free(EncodedKey->bv_val);
1077 		free(EncodedKey);
1078 	}
1079 
1080 	if (PubKeyParams) {
1081 		if (pKey->keyalg != KMF_ECDSA)
1082 			free(PubKeyParams->bv_val);
1083 		free(PubKeyParams);
1084 	}
1085 
1086 	return (ret);
1087 }
1088 
1089 static KMF_RETURN
CreateCertObject(KMF_HANDLE_T handle,char * label,KMF_DATA * pcert)1090 CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
1091 {
1092 	KMF_RETURN rv = 0;
1093 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1094 
1095 	KMF_X509_CERTIFICATE *signed_cert_ptr = NULL;
1096 	KMF_DATA data;
1097 	KMF_DATA Id;
1098 
1099 	CK_RV ckrv;
1100 	CK_ULONG subject_len, issuer_len, serno_len;
1101 	CK_BYTE *subject, *issuer, *serial, nullserno;
1102 	CK_BBOOL true = TRUE;
1103 	CK_CERTIFICATE_TYPE certtype = CKC_X_509;
1104 	CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
1105 	CK_ATTRIBUTE x509templ[11];
1106 	CK_OBJECT_HANDLE hCert = 0;
1107 	int i;
1108 
1109 	if (kmfh == NULL)
1110 		return (KMF_ERR_INTERNAL); /* should not happen */
1111 
1112 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1113 		return (KMF_ERR_INTERNAL); /* should not happen */
1114 
1115 	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0)
1116 		return (KMF_ERR_INTERNAL);  /* should not happen */
1117 
1118 	/*
1119 	 * The data *must* be a DER encoded X.509 certificate.
1120 	 * Convert it to a CSSM cert and then parse the fields so
1121 	 * the PKCS#11 attributes can be filled in correctly.
1122 	 */
1123 	rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert,
1124 	    &signed_cert_ptr);
1125 	if (rv != KMF_OK) {
1126 		return (KMF_ERR_ENCODING);
1127 	}
1128 
1129 	/*
1130 	 * Encode fields into PKCS#11 attributes.
1131 	 */
1132 
1133 	/* Get the subject name */
1134 	rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data);
1135 	if (rv == KMF_OK) {
1136 		subject = data.Data;
1137 		subject_len = data.Length;
1138 	} else {
1139 		rv = KMF_ERR_ENCODING;
1140 		goto cleanup;
1141 	}
1142 
1143 	/* Encode the issuer */
1144 	rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data);
1145 	if (rv == KMF_OK) {
1146 		issuer = data.Data;
1147 		issuer_len = data.Length;
1148 	} else {
1149 		rv = KMF_ERR_ENCODING;
1150 		goto cleanup;
1151 	}
1152 
1153 	/* Encode serial number */
1154 	if (signed_cert_ptr->certificate.serialNumber.len > 0 &&
1155 	    signed_cert_ptr->certificate.serialNumber.val != NULL) {
1156 		serial = signed_cert_ptr->certificate.serialNumber.val;
1157 		serno_len = signed_cert_ptr->certificate.serialNumber.len;
1158 	} else {
1159 		/*
1160 		 * RFC3280 says to gracefully handle certs with serial numbers
1161 		 * of 0.
1162 		 */
1163 		nullserno = '\0';
1164 		serial  = &nullserno;
1165 		serno_len = 1;
1166 	}
1167 
1168 	/* Generate an ID from the SPKI data */
1169 	rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo,
1170 	    &Id);
1171 
1172 	if (rv != KMF_OK) {
1173 		goto cleanup;
1174 	}
1175 
1176 	i = 0;
1177 	SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++;
1178 	SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype,
1179 	    sizeof (certtype));
1180 	i++;
1181 	SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
1182 	SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++;
1183 	SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++;
1184 	SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++;
1185 	SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++;
1186 	SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++;
1187 	if (label != NULL && strlen(label)) {
1188 		SETATTR(x509templ, i, CKA_LABEL, label, strlen(label));	i++;
1189 	}
1190 	/*
1191 	 * The cert object handle is actually "leaked" here.  If the app
1192 	 * really wants to clean up the data space, it will have to call
1193 	 * KMF_DeleteCert and specify the softtoken keystore.
1194 	 */
1195 	ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert);
1196 	if (ckrv != CKR_OK) {
1197 		/* Report authentication failures to the caller */
1198 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
1199 		    ckrv == CKR_PIN_INCORRECT ||
1200 		    ckrv == CKR_PIN_INVALID ||
1201 		    ckrv == CKR_PIN_EXPIRED ||
1202 		    ckrv == CKR_PIN_LOCKED ||
1203 		    ckrv == CKR_SESSION_READ_ONLY)
1204 			rv = KMF_ERR_AUTH_FAILED;
1205 		else
1206 			rv = KMF_ERR_INTERNAL;
1207 		SET_ERROR(kmfh, ckrv);
1208 	}
1209 	free(subject);
1210 	free(issuer);
1211 
1212 cleanup:
1213 	if (Id.Data != NULL)
1214 		free(Id.Data);
1215 
1216 	if (signed_cert_ptr) {
1217 		kmf_free_signed_cert(signed_cert_ptr);
1218 		free(signed_cert_ptr);
1219 	}
1220 	return (rv);
1221 }
1222 
1223 
1224 KMF_RETURN
KMFPK11_StoreCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1225 KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1226 {
1227 	KMF_RETURN rv = 0;
1228 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1229 	KMF_DATA *cert = NULL;
1230 	KMF_CREDENTIAL *cred = NULL;
1231 	char *label = NULL;
1232 
1233 	if (kmfh == NULL)
1234 		return (KMF_ERR_UNINITIALIZED);
1235 
1236 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1237 		return (KMF_ERR_NO_TOKEN_SELECTED);
1238 
1239 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
1240 	if (cert == NULL || cert->Data == NULL || cert->Length == 0)
1241 		return (KMF_ERR_BAD_PARAMETER);
1242 
1243 	/* label attribute is optional */
1244 	label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1245 
1246 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
1247 	if (cred != NULL) {
1248 		rv = pk11_authenticate(handle, cred);
1249 		if (rv != KMF_OK)
1250 			return (rv);
1251 	}
1252 
1253 	rv = CreateCertObject(handle, label, cert);
1254 	return (rv);
1255 }
1256 
1257 KMF_RETURN
KMFPK11_ImportCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1258 KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1259 {
1260 	KMF_RETURN rv = 0;
1261 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1262 	char *certfile = NULL;
1263 	char *label = NULL;
1264 	KMF_ENCODE_FORMAT format;
1265 	KMF_CREDENTIAL *cred = NULL;
1266 	KMF_DATA  cert1 = { 0, NULL };
1267 	KMF_DATA  cert2 = { 0, NULL };
1268 
1269 	if (kmfh == NULL)
1270 		return (KMF_ERR_UNINITIALIZED);
1271 
1272 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1273 		return (KMF_ERR_NO_TOKEN_SELECTED);
1274 
1275 	/*
1276 	 * Get the input cert filename attribute, check if it is a valid
1277 	 * certificate and auto-detect the file format of it.
1278 	 */
1279 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
1280 	if (certfile == NULL)
1281 		return (KMF_ERR_BAD_PARAMETER);
1282 
1283 	rv = kmf_is_cert_file(handle, certfile, &format);
1284 	if (rv != KMF_OK)
1285 		return (rv);
1286 
1287 	/* Read in the CERT file */
1288 	rv = kmf_read_input_file(handle, certfile, &cert1);
1289 	if (rv != KMF_OK) {
1290 		return (rv);
1291 	}
1292 
1293 	/* The label attribute is optional */
1294 	label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1295 
1296 	/*
1297 	 * If the input certificate is in PEM format, we need to convert
1298 	 * it to DER first.
1299 	 */
1300 	if (format == KMF_FORMAT_PEM) {
1301 		int derlen;
1302 		rv = kmf_pem_to_der(cert1.Data, cert1.Length,
1303 		    &cert2.Data, &derlen);
1304 		if (rv != KMF_OK) {
1305 			goto out;
1306 		}
1307 		cert2.Length = (size_t)derlen;
1308 	}
1309 
1310 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
1311 	if (cred != NULL) {
1312 		rv = pk11_authenticate(handle, cred);
1313 		if (rv != KMF_OK)
1314 			return (rv);
1315 	}
1316 
1317 	rv = CreateCertObject(handle, label,
1318 	    format == KMF_FORMAT_ASN1 ? &cert1 : &cert2);
1319 
1320 out:
1321 	if (cert1.Data != NULL) {
1322 		free(cert1.Data);
1323 	}
1324 
1325 	if (cert2.Data != NULL) {
1326 		free(cert2.Data);
1327 	}
1328 
1329 	return (rv);
1330 }
1331 
1332 KMF_RETURN
KMFPK11_DeleteCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1333 KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1334 {
1335 	KMF_RETURN rv = 0;
1336 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1337 	OBJLIST *objlist;
1338 	uint32_t numObjects = 0;
1339 	char *certlabel = NULL;
1340 	char *issuer = NULL;
1341 	char *subject = NULL;
1342 	KMF_BIGINT *serial = NULL;
1343 	KMF_CERT_VALIDITY validity;
1344 	boolean_t private;
1345 
1346 	if (kmfh == NULL)
1347 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1348 
1349 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1350 		return (KMF_ERR_NO_TOKEN_SELECTED);
1351 
1352 
1353 	/* Get the search criteria attributes. They are all optional. */
1354 	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1355 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1356 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1357 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1358 
1359 	rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1360 	    &validity, NULL);
1361 	if (rv != KMF_OK) {
1362 		validity = KMF_ALL_CERTS;
1363 		rv = KMF_OK;
1364 	}
1365 
1366 	rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
1367 	    (void *)&private, NULL);
1368 	if (rv != KMF_OK) {
1369 		private = B_FALSE;
1370 		rv = KMF_OK;
1371 	}
1372 
1373 	/*
1374 	 * Start searching for certificates that match the criteria and
1375 	 * delete them.
1376 	 */
1377 	objlist = NULL;
1378 	rv = search_certs(handle, certlabel, issuer, subject, serial,
1379 	    private, validity, &objlist, &numObjects);
1380 
1381 	if (rv == KMF_OK && objlist != NULL) {
1382 		OBJLIST *node = objlist;
1383 
1384 		while (node != NULL) {
1385 			CK_RV ckrv;
1386 			ckrv = C_DestroyObject(kmfh->pk11handle, node->handle);
1387 			if (ckrv != CKR_OK) {
1388 				SET_ERROR(kmfh, ckrv);
1389 				rv = KMF_ERR_INTERNAL;
1390 				break;
1391 			}
1392 			node = node->next;
1393 		}
1394 		free_objlist(objlist);
1395 	}
1396 
1397 	if (rv == KMF_OK && numObjects == 0)
1398 		rv = KMF_ERR_CERT_NOT_FOUND;
1399 
1400 	return (rv);
1401 }
1402 
1403 static CK_RV
gendsa_keypair(KMF_HANDLE * kmfh,boolean_t storekey,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)1404 gendsa_keypair(KMF_HANDLE *kmfh, boolean_t storekey,
1405 	CK_OBJECT_HANDLE *pubKey,
1406 	CK_OBJECT_HANDLE *priKey)
1407 {
1408 	CK_RV ckrv = CKR_OK;
1409 	CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1410 	static CK_ULONG	dsaKeyType = CKK_DSA;
1411 	static CK_BBOOL	true = TRUE;
1412 	static CK_BBOOL	false = FALSE;
1413 	static CK_OBJECT_CLASS	priClass = CKO_PRIVATE_KEY;
1414 	static CK_OBJECT_CLASS	pubClass = CKO_PUBLIC_KEY;
1415 
1416 	static CK_BYTE ckDsaPrime[128] = {
1417 	0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2,
1418 	0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c,
1419 	0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3,
1420 	0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc,
1421 	0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c,
1422 	0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8,
1423 	0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8,
1424 	0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3,
1425 	0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09,
1426 	0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c,
1427 	0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5,
1428 	0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb,
1429 	0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b,
1430 	0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11,
1431 	0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27,
1432 	0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b};
1433 
1434 	static CK_BYTE ckDsaSubPrime[20] = {
1435 	0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe,
1436 	0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc,
1437 	0x78, 0x47, 0xb0, 0xd5};
1438 
1439 	static CK_BYTE ckDsaBase[128] = {
1440 	0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b,
1441 	0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5,
1442 	0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3,
1443 	0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c,
1444 	0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2,
1445 	0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd,
1446 	0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3,
1447 	0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a,
1448 	0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05,
1449 	0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a,
1450 	0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67,
1451 	0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73,
1452 	0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f,
1453 	0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19,
1454 	0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce,
1455 	0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 };
1456 
1457 	static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = {
1458 	{ CKA_CLASS, &pubClass, sizeof (pubClass) },
1459 	{ CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) },
1460 	{ CKA_TOKEN, &true, sizeof (true)},
1461 	{ CKA_PRIVATE, &false, sizeof (false)},
1462 	{ CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) },
1463 	{ CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)},
1464 	{ CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) },
1465 	{ CKA_VERIFY, &true, sizeof (true) },
1466 };
1467 
1468 #define	NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
1469 					sizeof (CK_ATTRIBUTE))
1470 #define	MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
1471 				    sizeof (CK_ATTRIBUTE))
1472 
1473 	static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = {
1474 	{CKA_CLASS, &priClass, sizeof (priClass)},
1475 	{CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)},
1476 	{CKA_TOKEN, &true, sizeof (true)},
1477 	{CKA_PRIVATE, &true, sizeof (true)},
1478 	{CKA_SIGN, &true, sizeof (true)},
1479 	};
1480 
1481 #define	NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
1482 					sizeof (CK_ATTRIBUTE))
1483 #define	MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
1484 				sizeof (CK_ATTRIBUTE))
1485 	CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0};
1486 
1487 	SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN,
1488 	    (storekey ? &true : &false), sizeof (CK_BBOOL));
1489 
1490 	ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1491 	    ckDsaPubKeyTemplate,
1492 	    (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)),
1493 	    ckDsaPriKeyTemplate,
1494 	    (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)),
1495 	    pubKey, priKey);
1496 	if (ckrv != CKR_OK) {
1497 		SET_ERROR(kmfh, ckrv);
1498 		return (KMF_ERR_KEYGEN_FAILED);
1499 	}
1500 
1501 	return (ckrv);
1502 }
1503 
1504 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)1505 genrsa_keypair(KMF_HANDLE *kmfh, CK_ULONG modulusBits,
1506 	boolean_t storekey, KMF_BIGINT *rsaexp,
1507 	CK_OBJECT_HANDLE *pubKey,
1508 	CK_OBJECT_HANDLE *priKey)
1509 {
1510 	CK_RV ckrv = CKR_OK;
1511 	CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1512 	CK_ATTRIBUTE rsaPubKeyTemplate[16];
1513 	CK_ATTRIBUTE rsaPriKeyTemplate[16];
1514 	CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
1515 	int numpubattr = 0, numpriattr = 0;
1516 	static CK_BYTE	PubExpo[3] = {0x01, 0x00, 0x01};
1517 	static CK_BBOOL	true = TRUE;
1518 	static CK_BBOOL	false = FALSE;
1519 
1520 	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN,
1521 	    (storekey ? &true : &false), sizeof (CK_BBOOL));
1522 	numpubattr++;
1523 
1524 	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS,
1525 	    &modulusBits, sizeof (modulusBits));
1526 	numpubattr++;
1527 
1528 	if (rsaexp != NULL && (rsaexp->len > 0 && rsaexp->val != NULL)) {
1529 		SETATTR(rsaPubKeyTemplate, numpubattr,
1530 		    CKA_PUBLIC_EXPONENT,
1531 		    rsaexp->val, rsaexp->len);
1532 		numpubattr++;
1533 	} else {
1534 		SETATTR(rsaPubKeyTemplate, numpubattr,
1535 		    CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo));
1536 		numpubattr++;
1537 	}
1538 	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT,
1539 	    &true, sizeof (true));
1540 	numpubattr++;
1541 	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY,
1542 	    &true, sizeof (true));
1543 	numpubattr++;
1544 	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_WRAP,
1545 	    &true, sizeof (true));
1546 	numpubattr++;
1547 
1548 	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN,
1549 	    (storekey ? &true : &false), sizeof (CK_BBOOL));
1550 	numpriattr++;
1551 	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true,
1552 	    sizeof (true));
1553 	numpriattr++;
1554 	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true,
1555 	    sizeof (true));
1556 	numpriattr++;
1557 	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true,
1558 	    sizeof (true));
1559 	numpriattr++;
1560 	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_UNWRAP, &true,
1561 	    sizeof (true));
1562 	numpriattr++;
1563 
1564 	ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1565 	    rsaPubKeyTemplate, numpubattr,
1566 	    rsaPriKeyTemplate, numpriattr,
1567 	    pubKey, priKey);
1568 	if (ckrv != CKR_OK) {
1569 		SET_ERROR(kmfh, ckrv);
1570 		return (ckrv);
1571 	}
1572 
1573 	return (ckrv);
1574 }
1575 
1576 static CK_RV
genecc_keypair(KMF_HANDLE * kmfh,boolean_t ontoken,KMF_OID * curveoid,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)1577 genecc_keypair(KMF_HANDLE *kmfh,
1578 	boolean_t ontoken,
1579 	KMF_OID *curveoid,
1580 	CK_OBJECT_HANDLE *pubKey,
1581 	CK_OBJECT_HANDLE *priKey)
1582 {
1583 	CK_RV ckrv;
1584 	CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1585 	CK_MECHANISM keyGenMech = {CKM_EC_KEY_PAIR_GEN, NULL, 0};
1586 	const ulong_t publicKey = CKO_PUBLIC_KEY;
1587 	const ulong_t privateKey = CKO_PRIVATE_KEY;
1588 	const ulong_t keytype = CKK_EC;
1589 	static CK_BBOOL	true = TRUE;
1590 	static CK_BBOOL	false = FALSE;
1591 	CK_ATTRIBUTE public_template[6];
1592 	CK_ATTRIBUTE private_template[6];
1593 	int numpubattr, numpriattr;
1594 
1595 	numpubattr = 0;
1596 	SETATTR(public_template, numpubattr, CKA_CLASS,
1597 	    &publicKey, sizeof (publicKey));
1598 	numpubattr++;
1599 	SETATTR(public_template, numpubattr, CKA_KEY_TYPE,
1600 	    &keytype, sizeof (keytype));
1601 	numpubattr++;
1602 	SETATTR(public_template, numpubattr, CKA_EC_PARAMS,
1603 	    curveoid->Data, curveoid->Length);
1604 	numpubattr++;
1605 	SETATTR(public_template, numpubattr, CKA_TOKEN,
1606 	    ontoken ? &true : &false, sizeof (true));
1607 	numpubattr++;
1608 	SETATTR(public_template, numpubattr, CKA_VERIFY,
1609 	    &true, sizeof (true));
1610 	numpubattr++;
1611 	SETATTR(public_template, numpubattr, CKA_PRIVATE,
1612 	    &false, sizeof (false));
1613 	numpubattr++;
1614 
1615 	numpriattr = 0;
1616 	SETATTR(private_template, numpriattr, CKA_CLASS,
1617 	    &privateKey, sizeof (privateKey));
1618 	numpriattr++;
1619 	SETATTR(private_template, numpriattr, CKA_KEY_TYPE,
1620 	    &keytype, sizeof (keytype));
1621 	numpriattr++;
1622 	SETATTR(private_template, numpriattr, CKA_TOKEN,
1623 	    ontoken ? &true : &false, sizeof (true));
1624 	numpriattr++;
1625 	SETATTR(private_template, numpriattr, CKA_PRIVATE,
1626 	    &true, sizeof (true));
1627 	numpriattr++;
1628 	SETATTR(private_template, numpriattr, CKA_SIGN,
1629 	    &true, sizeof (true));
1630 	numpriattr++;
1631 	SETATTR(private_template, numpriattr, CKA_DERIVE,
1632 	    &true, sizeof (true));
1633 	numpriattr++;
1634 
1635 	ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1636 	    public_template, numpubattr,
1637 	    private_template, numpriattr,
1638 	    pubKey, priKey);
1639 	if (ckrv != CKR_OK) {
1640 		SET_ERROR(kmfh, ckrv);
1641 		return (ckrv);
1642 	}
1643 
1644 	return (ckrv);
1645 }
1646 
1647 KMF_RETURN
KMFPK11_CreateKeypair(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)1648 KMFPK11_CreateKeypair(KMF_HANDLE_T handle,
1649 	int numattr,
1650 	KMF_ATTRIBUTE *attlist)
1651 {
1652 	KMF_RETURN rv = KMF_OK;
1653 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1654 	KMF_DATA IDInput, IDOutput;
1655 	KMF_CREDENTIAL *cred;
1656 	KMF_KEY_ALG keytype = KMF_RSA;
1657 	KMF_KEY_HANDLE *pubkey, *privkey;
1658 
1659 	CK_RV			ckrv = 0;
1660 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
1661 	CK_ATTRIBUTE labelattr[1];
1662 	CK_ATTRIBUTE idattr[1];
1663 	CK_OBJECT_HANDLE pubKey, priKey;
1664 
1665 	char IDHashData[SHA1_HASH_LENGTH];
1666 	static CK_ULONG	modulusBits = 1024;
1667 	uint32_t	modulusBits_size = sizeof (CK_ULONG);
1668 	SHA1_CTX ctx;
1669 	boolean_t storekey = TRUE;
1670 	char *keylabel = NULL;
1671 
1672 	if (kmfh == NULL)
1673 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1674 
1675 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1676 		return (KMF_ERR_NO_TOKEN_SELECTED);
1677 
1678 	/* "storekey" is optional. Default is TRUE */
1679 	(void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr,
1680 	    &storekey, NULL);
1681 
1682 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr);
1683 	if (cred == NULL)
1684 		return (KMF_ERR_BAD_PARAMETER);
1685 
1686 	rv = pk11_authenticate(handle, cred);
1687 	if (rv != KMF_OK)
1688 		return (rv);
1689 
1690 	/* keytype is optional.  KMF_RSA is default */
1691 	(void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr,
1692 	    (void *)&keytype, NULL);
1693 
1694 	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
1695 	if (pubkey == NULL)
1696 		return (KMF_ERR_BAD_PARAMETER);
1697 
1698 	privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr);
1699 	if (privkey == NULL)
1700 		return (KMF_ERR_BAD_PARAMETER);
1701 
1702 	(void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
1703 	(void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
1704 	if (keytype == KMF_RSA) {
1705 		CK_BYTE *modulus = NULL;
1706 		CK_ULONG modulusLength = 0;
1707 		KMF_BIGINT *rsaexp = NULL;
1708 		CK_ATTRIBUTE modattr[1];
1709 
1710 		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr,
1711 		    &modulusBits, &modulusBits_size);
1712 		if (rv == KMF_ERR_ATTR_NOT_FOUND)
1713 			/* Default modulusBits = 1024 */
1714 			rv = KMF_OK;
1715 		if (rv != KMF_OK)
1716 			return (KMF_ERR_BAD_PARAMETER);
1717 
1718 		rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, numattr);
1719 
1720 		/* Generate the RSA keypair */
1721 		ckrv = genrsa_keypair(kmfh, modulusBits, storekey,
1722 		    rsaexp, &pubKey, &priKey);
1723 
1724 		if (ckrv != CKR_OK)
1725 			return (KMF_ERR_BAD_PARAMETER);
1726 
1727 		privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1728 		privkey->keyalg = KMF_RSA;
1729 		privkey->keyclass = KMF_ASYM_PRI;
1730 		privkey->keyp = (void *)priKey;
1731 
1732 		pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1733 		pubkey->keyalg = KMF_RSA;
1734 		pubkey->keyclass = KMF_ASYM_PUB;
1735 		pubkey->keyp = (void *)pubKey;
1736 
1737 		SETATTR(modattr, 0, CKA_MODULUS, NULL, modulusLength);
1738 		/* Get the Modulus field to use as input for creating the ID */
1739 		ckrv = C_GetAttributeValue(kmfh->pk11handle,
1740 		    (CK_OBJECT_HANDLE)pubKey, modattr, 1);
1741 		if (ckrv != CKR_OK) {
1742 			SET_ERROR(kmfh, ckrv);
1743 			return (KMF_ERR_BAD_PARAMETER);
1744 		}
1745 
1746 		modulusLength = modattr[0].ulValueLen;
1747 		modulus = malloc(modulusLength);
1748 		if (modulus == NULL)
1749 			return (KMF_ERR_MEMORY);
1750 
1751 		modattr[0].pValue = modulus;
1752 		ckrv = C_GetAttributeValue(kmfh->pk11handle,
1753 		    (CK_OBJECT_HANDLE)pubKey, modattr, 1);
1754 		if (ckrv != CKR_OK) {
1755 			SET_ERROR(kmfh, ckrv);
1756 			free(modulus);
1757 			return (KMF_ERR_BAD_PARAMETER);
1758 		}
1759 
1760 		IDInput.Data = modulus;
1761 		IDInput.Length = modulusLength;
1762 
1763 	} else if (keytype == KMF_DSA) {
1764 		CK_BYTE *keyvalue;
1765 		CK_ULONG valueLen;
1766 		CK_ATTRIBUTE valattr[1];
1767 
1768 		/* Generate the DSA keypair */
1769 		ckrv = gendsa_keypair(kmfh, storekey, &pubKey, &priKey);
1770 		if (ckrv != CKR_OK)
1771 			return (KMF_ERR_BAD_PARAMETER);
1772 
1773 		privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1774 		privkey->keyalg = KMF_DSA;
1775 		privkey->keyclass = KMF_ASYM_PRI;
1776 		privkey->keyp = (void *)priKey;
1777 
1778 		pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1779 		pubkey->keyalg = KMF_DSA;
1780 		pubkey->keyclass = KMF_ASYM_PUB;
1781 		pubkey->keyp = (void *)pubKey;
1782 
1783 		/* Get the Public Value to use as input for creating the ID */
1784 		SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen);
1785 
1786 		ckrv = C_GetAttributeValue(hSession,
1787 		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1788 		if (ckrv != CKR_OK) {
1789 			SET_ERROR(kmfh, ckrv);
1790 			return (KMF_ERR_BAD_PARAMETER);
1791 		}
1792 
1793 		valueLen = valattr[0].ulValueLen;
1794 		keyvalue = malloc(valueLen);
1795 		if (keyvalue == NULL)
1796 			return (KMF_ERR_MEMORY);
1797 
1798 		valattr[0].pValue = keyvalue;
1799 		ckrv = C_GetAttributeValue(hSession,
1800 		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1801 		if (ckrv != CKR_OK) {
1802 			SET_ERROR(kmfh, ckrv);
1803 			free(keyvalue);
1804 			return (KMF_ERR_BAD_PARAMETER);
1805 		}
1806 
1807 		IDInput.Data = keyvalue;
1808 		IDInput.Length = valueLen;
1809 	} else if (keytype == KMF_ECDSA) {
1810 		CK_BYTE *keyvalue;
1811 		CK_ULONG valueLen;
1812 		CK_ATTRIBUTE valattr[1];
1813 		KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
1814 		    attlist, numattr);
1815 
1816 		if (eccoid == NULL)
1817 			return (KMF_ERR_BAD_PARAMETER);
1818 
1819 		ckrv = genecc_keypair(kmfh, storekey, eccoid,
1820 		    &pubKey, &priKey);
1821 		if (ckrv != CKR_OK)
1822 			return (KMF_ERR_BAD_PARAMETER);
1823 
1824 		privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1825 		privkey->keyalg = KMF_ECDSA;
1826 		privkey->keyclass = KMF_ASYM_PRI;
1827 		privkey->keyp = (void *)priKey;
1828 
1829 		pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1830 		pubkey->keyalg = KMF_ECDSA;
1831 		pubkey->keyclass = KMF_ASYM_PUB;
1832 		pubkey->keyp = (void *)pubKey;
1833 
1834 		/* Get the EC_POINT to use as input for creating the ID */
1835 		SETATTR(valattr, 0, CKA_EC_POINT, NULL, &valueLen);
1836 
1837 		ckrv = C_GetAttributeValue(hSession,
1838 		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1839 		if (ckrv != CKR_OK) {
1840 			SET_ERROR(kmfh, ckrv);
1841 			return (KMF_ERR_BAD_PARAMETER);
1842 		}
1843 
1844 		valueLen = valattr[0].ulValueLen;
1845 		keyvalue = malloc(valueLen);
1846 		if (keyvalue == NULL)
1847 			return (KMF_ERR_MEMORY);
1848 
1849 		valattr[0].pValue = keyvalue;
1850 		ckrv = C_GetAttributeValue(hSession,
1851 		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1852 		if (ckrv != CKR_OK) {
1853 			SET_ERROR(kmfh, ckrv);
1854 			free(keyvalue);
1855 			return (KMF_ERR_BAD_PARAMETER);
1856 		}
1857 
1858 		IDInput.Data = keyvalue;
1859 		IDInput.Length = valueLen;
1860 	} else {
1861 		return (KMF_ERR_BAD_PARAMETER);
1862 	}
1863 
1864 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr);
1865 	if (keylabel != NULL && strlen(keylabel)) {
1866 		SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel));
1867 
1868 		/* Set the CKA_LABEL if one was indicated */
1869 		if ((ckrv = C_SetAttributeValue(hSession, pubKey,
1870 		    labelattr, 1)) != CKR_OK) {
1871 			SET_ERROR(kmfh, ckrv);
1872 			rv = KMF_ERR_INTERNAL;
1873 			goto cleanup;
1874 		}
1875 		pubkey->keylabel = (char *)strdup(keylabel);
1876 		if (pubkey->keylabel == NULL) {
1877 			rv = KMF_ERR_MEMORY;
1878 			goto cleanup;
1879 		}
1880 		if ((ckrv = C_SetAttributeValue(hSession, priKey,
1881 		    labelattr, 1)) != CKR_OK) {
1882 			SET_ERROR(kmfh, ckrv);
1883 			rv = KMF_ERR_INTERNAL;
1884 			goto cleanup;
1885 		}
1886 		privkey->keylabel = (char *)strdup(keylabel);
1887 		if (privkey->keylabel == NULL) {
1888 			rv = KMF_ERR_MEMORY;
1889 			goto cleanup;
1890 		}
1891 	} else {
1892 		rv = KMF_OK;
1893 	}
1894 
1895 	/* Now, assign a CKA_ID value so it can be searched */
1896 	/* ID_Input was assigned above in the RSA or DSA keygen section */
1897 	IDOutput.Data = (uchar_t *)IDHashData;
1898 	IDOutput.Length = sizeof (IDHashData);
1899 
1900 	SHA1Init(&ctx);
1901 	SHA1Update(&ctx, IDInput.Data, IDInput.Length);
1902 	SHA1Final(IDOutput.Data, &ctx);
1903 
1904 	IDOutput.Length = SHA1_DIGEST_LENGTH;
1905 
1906 	free(IDInput.Data);
1907 
1908 	if (rv != CKR_OK) {
1909 		goto cleanup;
1910 	}
1911 	SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length);
1912 	if ((ckrv = C_SetAttributeValue(hSession, pubKey,
1913 	    idattr, 1)) != CKR_OK) {
1914 		SET_ERROR(kmfh, ckrv);
1915 		rv = KMF_ERR_INTERNAL;
1916 		goto cleanup;
1917 	}
1918 	if ((ckrv = C_SetAttributeValue(hSession, priKey,
1919 	    idattr, 1)) != CKR_OK) {
1920 		SET_ERROR(kmfh, ckrv);
1921 		rv = KMF_ERR_INTERNAL;
1922 		goto cleanup;
1923 	}
1924 
1925 cleanup:
1926 	if (rv != KMF_OK) {
1927 		if (pubKey != CK_INVALID_HANDLE)
1928 			(void) C_DestroyObject(hSession, pubKey);
1929 		if (priKey != CK_INVALID_HANDLE)
1930 			(void) C_DestroyObject(hSession, priKey);
1931 
1932 		if (privkey->keylabel)
1933 			free(privkey->keylabel);
1934 		if (pubkey->keylabel)
1935 			free(pubkey->keylabel);
1936 	}
1937 	return (rv);
1938 }
1939 
1940 KMF_RETURN
KMFPK11_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1941 KMFPK11_DeleteKey(KMF_HANDLE_T handle,
1942 	int numattr, KMF_ATTRIBUTE *attrlist)
1943 {
1944 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1945 	CK_RV ckrv = CKR_OK;
1946 	KMF_RETURN rv = KMF_OK;
1947 	KMF_KEY_HANDLE *key;
1948 	KMF_CREDENTIAL cred;
1949 	boolean_t destroy = B_TRUE;
1950 
1951 	if (kmfh == NULL)
1952 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1953 
1954 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
1955 		return (KMF_ERR_NO_TOKEN_SELECTED);
1956 
1957 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1958 	if (key == NULL || key->keyp == NULL)
1959 		return (KMF_ERR_BAD_PARAMETER);
1960 
1961 	if (key->keyclass != KMF_ASYM_PUB &&
1962 	    key->keyclass != KMF_ASYM_PRI &&
1963 	    key->keyclass != KMF_SYMMETRIC)
1964 		return (KMF_ERR_BAD_KEY_CLASS);
1965 
1966 	/* "destroy" is optional. Default is TRUE */
1967 	(void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1968 	    (void *)&destroy, NULL);
1969 
1970 	if (destroy) {
1971 		rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
1972 		    (void *)&cred, NULL);
1973 		if (rv != KMF_OK)
1974 			return (KMF_ERR_BAD_PARAMETER);
1975 
1976 		rv = pk11_authenticate(handle, &cred);
1977 		if (rv != KMF_OK) {
1978 			return (rv);
1979 		}
1980 	}
1981 
1982 	if (!key->israw && destroy)
1983 		ckrv = C_DestroyObject(kmfh->pk11handle,
1984 		    (CK_OBJECT_HANDLE)key->keyp);
1985 
1986 	if (ckrv != CKR_OK) {
1987 		SET_ERROR(kmfh, ckrv);
1988 		/* Report authentication failures to the caller */
1989 		if (ckrv == CKR_PIN_EXPIRED || ckrv == CKR_SESSION_READ_ONLY)
1990 			rv = KMF_ERR_AUTH_FAILED;
1991 		else
1992 			rv = KMF_ERR_INTERNAL;
1993 	}
1994 	return (rv);
1995 }
1996 
1997 KMF_RETURN
KMFPK11_SignData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * keyp,KMF_OID * algOID,KMF_DATA * tobesigned,KMF_DATA * output)1998 KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp,
1999 	KMF_OID *algOID,
2000 	KMF_DATA *tobesigned,
2001 	KMF_DATA *output)
2002 {
2003 	KMF_RETURN		rv = KMF_OK;
2004 	CK_RV			ckrv;
2005 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
2006 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
2007 	CK_MECHANISM		mechanism;
2008 	CK_MECHANISM_TYPE	mechtype, hashmech;
2009 	CK_KEY_TYPE		keytype;
2010 	KMF_ALGORITHM_INDEX	AlgId;
2011 	KMF_DATA		hashData = { 0, NULL };
2012 	uchar_t			digest[1024];
2013 	CK_ATTRIBUTE		subprime = { CKA_SUBPRIME, NULL, 0 };
2014 
2015 	if (kmfh == NULL)
2016 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2017 
2018 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
2019 		return (KMF_ERR_NO_TOKEN_SELECTED);
2020 
2021 	if (keyp == NULL || algOID == NULL ||
2022 	    tobesigned == NULL || output == NULL)
2023 		return (KMF_ERR_BAD_PARAMETER);
2024 
2025 	/* These functions are available to the plugin from libkmf */
2026 	AlgId = x509_algoid_to_algid(algOID);
2027 	if (AlgId == KMF_ALGID_NONE)
2028 		return (KMF_ERR_BAD_PARAMETER);
2029 
2030 	/* Get the PKCS11 signing key type and mechtype */
2031 	if (get_pk11_data(AlgId, &keytype, &mechtype, &hashmech, 0))
2032 		return (KMF_ERR_BAD_PARAMETER);
2033 
2034 	(void) memset(digest, 0, sizeof (digest));
2035 	hashData.Data = digest;
2036 	hashData.Length = sizeof (digest);
2037 	rv = PKCS_DigestData(handle, hSession, hashmech, tobesigned, &hashData,
2038 	    (mechtype == CKM_RSA_PKCS));
2039 	if (rv)
2040 		return (rv);
2041 
2042 	if (mechtype == CKM_DSA && hashmech == CKM_SHA256) {
2043 		/*
2044 		 * FIPS 186-3 says that when signing with DSA
2045 		 * the hash must be truncated to the size of the
2046 		 * subprime.
2047 		 */
2048 		ckrv = C_GetAttributeValue(hSession,
2049 		    (CK_OBJECT_HANDLE)keyp->keyp,
2050 		    &subprime, 1);
2051 		if (ckrv != CKR_OK)  {
2052 			SET_ERROR(kmfh, ckrv);
2053 			return (KMF_ERR_INTERNAL);
2054 		}
2055 		hashData.Length = subprime.ulValueLen;
2056 	}
2057 
2058 	/* the mechtype from the 'get_pk11_info' refers to the signing */
2059 	mechanism.mechanism = mechtype;
2060 	mechanism.pParameter = NULL;
2061 	mechanism.ulParameterLen = 0;
2062 
2063 	ckrv = C_SignInit(hSession, &mechanism, (CK_OBJECT_HANDLE)keyp->keyp);
2064 	if (ckrv != CKR_OK) {
2065 		SET_ERROR(kmfh, ckrv);
2066 		return (KMF_ERR_INTERNAL);
2067 	}
2068 
2069 	ckrv = C_Sign(hSession,	hashData.Data, hashData.Length,
2070 	    output->Data, (CK_ULONG *)&output->Length);
2071 
2072 	if (ckrv != CKR_OK) {
2073 		SET_ERROR(kmfh, ckrv);
2074 		return (KMF_ERR_INTERNAL);
2075 	}
2076 
2077 	return (KMF_OK);
2078 }
2079 
2080 KMF_RETURN
KMFPK11_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)2081 KMFPK11_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
2082 {
2083 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2084 
2085 	*msgstr = NULL;
2086 	if (kmfh->lasterr.errcode != 0) {
2087 		char *e = pkcs11_strerror(kmfh->lasterr.errcode);
2088 		if (e == NULL || (*msgstr = (char *)strdup(e)) == NULL) {
2089 			return (KMF_ERR_MEMORY);
2090 		}
2091 	}
2092 
2093 	return (KMF_OK);
2094 }
2095 
2096 static CK_RV
getObjectKeytype(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,CK_ULONG * keytype)2097 getObjectKeytype(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2098 	CK_ULONG *keytype)
2099 {
2100 	CK_RV rv = CKR_OK;
2101 	CK_ATTRIBUTE templ;
2102 	CK_ULONG len = sizeof (CK_ULONG);
2103 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2104 
2105 	templ.type = CKA_KEY_TYPE;
2106 	templ.pValue = keytype;
2107 	templ.ulValueLen = len;
2108 
2109 	rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2110 
2111 	return (rv);
2112 
2113 }
2114 
2115 static CK_RV
getObjectLabel(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,char ** outlabel)2116 getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2117 	char **outlabel)
2118 {
2119 	CK_RV rv = CKR_OK;
2120 	CK_ATTRIBUTE templ;
2121 	char	Label[BUFSIZ];
2122 	CK_ULONG len = sizeof (Label);
2123 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2124 
2125 	(void) memset(Label, 0, len);
2126 	templ.type = CKA_LABEL;
2127 	templ.pValue = Label;
2128 	templ.ulValueLen = len;
2129 
2130 	rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2131 	if (rv == CKR_OK) {
2132 		*outlabel = (char *)strdup(Label);
2133 	} else {
2134 		*outlabel = NULL;
2135 	}
2136 	return (rv);
2137 }
2138 
2139 static CK_RV
getObjectKeyclass(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,KMF_KEY_CLASS * keyclass)2140 getObjectKeyclass(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2141 	KMF_KEY_CLASS *keyclass)
2142 {
2143 	CK_RV rv = CKR_OK;
2144 	CK_ATTRIBUTE templ;
2145 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2146 	CK_OBJECT_CLASS class;
2147 
2148 	templ.type = CKA_CLASS;
2149 	templ.pValue = &class;
2150 	templ.ulValueLen = sizeof (CK_OBJECT_CLASS);
2151 
2152 	rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2153 	if (rv == CKR_OK) {
2154 		if (class == CKO_PUBLIC_KEY) {
2155 			*keyclass = KMF_ASYM_PUB;
2156 		} else if (class == CKO_PRIVATE_KEY) {
2157 			*keyclass = KMF_ASYM_PRI;
2158 		} else if (class == CKO_SECRET_KEY) {
2159 			*keyclass = KMF_SYMMETRIC;
2160 		}
2161 	} else {
2162 		*keyclass = KMF_KEYCLASS_NONE;
2163 	}
2164 	return (rv);
2165 }
2166 
2167 KMF_RETURN
KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2168 KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2169     KMF_ATTRIBUTE *attrlist)
2170 {
2171 	KMF_X509_SPKI *pubkey;
2172 	KMF_X509_CERTIFICATE *SignerCert = NULL;
2173 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2174 	KMF_RETURN rv = KMF_OK;
2175 	CK_RV ckrv = CKR_OK;
2176 	CK_ATTRIBUTE templ[4];
2177 	CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE;
2178 	CK_ULONG obj_count;
2179 	CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
2180 	CK_BBOOL true = TRUE;
2181 	KMF_DATA Id = { 0, NULL };
2182 	KMF_KEY_HANDLE *key = NULL;
2183 	KMF_DATA *cert = NULL;
2184 	KMF_CREDENTIAL cred;
2185 	KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF;
2186 	CK_ULONG keytype;
2187 
2188 	/* Get the key handle */
2189 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2190 	if (key == NULL)
2191 		return (KMF_ERR_BAD_PARAMETER);
2192 
2193 	/* Get the optional encoded format */
2194 	(void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
2195 	    (void *)&format, NULL);
2196 
2197 	/* Decode the signer cert so we can get the SPKI data */
2198 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
2199 	if (cert == NULL || cert->Data == NULL)
2200 		return (KMF_ERR_BAD_PARAMETER);
2201 
2202 	if ((rv = DerDecodeSignedCertificate(cert,
2203 	    &SignerCert)) != KMF_OK)
2204 		return (rv);
2205 
2206 	/* Get the public key info from the signer certificate */
2207 	pubkey = &SignerCert->certificate.subjectPublicKeyInfo;
2208 
2209 	/* Generate an ID from the SPKI data */
2210 	rv = GetIDFromSPKI(pubkey, &Id);
2211 	if (rv != KMF_OK) {
2212 		goto errout;
2213 	}
2214 
2215 	/* Get the credential and login */
2216 	rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
2217 	    (void *)&cred, NULL);
2218 	if (rv != KMF_OK)
2219 		return (KMF_ERR_BAD_PARAMETER);
2220 
2221 	rv = pk11_authenticate(handle, &cred);
2222 	if (rv != KMF_OK) {
2223 		return (rv);
2224 	}
2225 
2226 	/* Start searching */
2227 	SETATTR(templ, 0, CKA_CLASS, &objClass, sizeof (objClass));
2228 	SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true));
2229 	SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true));
2230 	SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length);
2231 
2232 	if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) {
2233 		SET_ERROR(kmfh, ckrv);
2234 		rv = KMF_ERR_INTERNAL;
2235 		goto errout;
2236 	}
2237 
2238 	if ((ckrv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1,
2239 	    &obj_count)) != CKR_OK) {
2240 		SET_ERROR(kmfh, ckrv);
2241 		rv = KMF_ERR_INTERNAL;
2242 		goto errout;
2243 	}
2244 
2245 	if (obj_count == 0) {
2246 		SET_ERROR(kmfh, ckrv);
2247 		rv = KMF_ERR_KEY_NOT_FOUND;
2248 		goto errout;
2249 	}
2250 
2251 	key->kstype = KMF_KEYSTORE_PK11TOKEN;
2252 	key->keyclass = KMF_ASYM_PRI;
2253 	key->keyp = (void *)pri_obj;
2254 	key->israw = FALSE;
2255 
2256 	(void) C_FindObjectsFinal(kmfh->pk11handle);
2257 
2258 	ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp,
2259 	    &key->keylabel);
2260 	if (ckrv != CKR_OK) {
2261 		SET_ERROR(handle, ckrv);
2262 		rv = KMF_ERR_INTERNAL;
2263 	} else {
2264 		rv = KMF_OK;
2265 	}
2266 
2267 	/*
2268 	 * The key->keyalg value is needed if we need to convert the key
2269 	 * to raw key.  However, the key->keyalg value will not be set if
2270 	 * this function is not called thru the kmf_find_prikey_by_cert()
2271 	 * framework function. To be safe, we will get the keytype from
2272 	 * the key object and set key->keyalg value here.
2273 	 */
2274 	ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp,
2275 	    &keytype);
2276 	if (ckrv != CKR_OK) {
2277 		SET_ERROR(handle, ckrv);
2278 		rv = KMF_ERR_INTERNAL;
2279 	} else {
2280 		rv = KMF_OK;
2281 	}
2282 
2283 	if (keytype == CKK_RSA)
2284 		key->keyalg = KMF_RSA;
2285 	else if (keytype == CKK_DSA)
2286 		key->keyalg = KMF_DSA;
2287 	else if (keytype == CKK_EC)
2288 		key->keyalg = KMF_ECDSA;
2289 	else {
2290 		/* For asymmetric keys, we only support RSA and DSA */
2291 		rv = KMF_ERR_KEY_NOT_FOUND;
2292 		goto errout;
2293 	}
2294 
2295 	if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) {
2296 		KMF_RAW_KEY_DATA *rkey = NULL;
2297 		rv = keyObj2RawKey(handle, key, &rkey);
2298 		if (rv == KMF_OK) {
2299 			key->keyp = rkey;
2300 			key->israw = TRUE;
2301 		}
2302 	}
2303 
2304 errout:
2305 	if (Id.Data != NULL)
2306 		free(Id.Data);
2307 
2308 	if (SignerCert != NULL) {
2309 		kmf_free_signed_cert(SignerCert);
2310 		free(SignerCert);
2311 	}
2312 	return (rv);
2313 }
2314 
2315 KMF_RETURN
KMFPK11_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * algOID,KMF_DATA * ciphertext,KMF_DATA * output)2316 KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2317 	KMF_OID *algOID, KMF_DATA *ciphertext,
2318 	KMF_DATA *output)
2319 {
2320 	CK_RV			ckrv;
2321 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
2322 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
2323 	CK_MECHANISM		mechanism;
2324 	CK_MECHANISM_TYPE	mechtype;
2325 	CK_KEY_TYPE		keytype;
2326 	KMF_ALGORITHM_INDEX	AlgId;
2327 	CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0;
2328 	uint8_t *in_data, *out_data;
2329 	int i, blocks;
2330 	CK_ATTRIBUTE ckTemplate[1];
2331 
2332 	if (kmfh == NULL)
2333 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2334 
2335 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
2336 		return (KMF_ERR_NO_TOKEN_SELECTED);
2337 
2338 	if (key == NULL || algOID == NULL ||
2339 	    ciphertext == NULL || output == NULL)
2340 		return (KMF_ERR_BAD_PARAMETER);
2341 
2342 	AlgId = x509_algoid_to_algid(algOID);
2343 	if (AlgId == KMF_ALGID_NONE)
2344 		return (KMF_ERR_BAD_PARAMETER);
2345 
2346 	/* Map the Algorithm ID to a PKCS#11 mechanism */
2347 	if (get_pk11_data(AlgId, &keytype, &mechtype, NULL, 0))
2348 		return (KMF_ERR_BAD_PARAMETER);
2349 
2350 	mechanism.mechanism = mechtype;
2351 	mechanism.pParameter = NULL;
2352 	mechanism.ulParameterLen = 0;
2353 
2354 	SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL,
2355 	    sizeof (CK_ULONG));
2356 
2357 	/* Get the modulus length */
2358 	ckrv = C_GetAttributeValue(hSession,
2359 	    (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1);
2360 
2361 	if (ckrv != CKR_OK)  {
2362 		SET_ERROR(kmfh, ckrv);
2363 		return (KMF_ERR_INTERNAL);
2364 	}
2365 
2366 	block_len = ckTemplate[0].ulValueLen;
2367 
2368 	/* Compute the number of times to do single-part decryption */
2369 	blocks = ciphertext->Length/block_len;
2370 
2371 	out_data = output->Data;
2372 	in_data = ciphertext->Data;
2373 	out_len = block_len - 11;
2374 
2375 	for (i = 0; i < blocks; i++) {
2376 		ckrv = C_DecryptInit(hSession, &mechanism,
2377 		    (CK_OBJECT_HANDLE)key->keyp);
2378 
2379 		if (ckrv != CKR_OK) {
2380 			SET_ERROR(kmfh, ckrv);
2381 			return (KMF_ERR_INTERNAL);
2382 		}
2383 
2384 		ckrv = C_Decrypt(hSession, in_data, block_len,
2385 		    out_data, (CK_ULONG *)&out_len);
2386 
2387 		if (ckrv != CKR_OK) {
2388 			SET_ERROR(kmfh, ckrv);
2389 			return (KMF_ERR_INTERNAL);
2390 		}
2391 
2392 		out_data += out_len;
2393 		total_decrypted += out_len;
2394 		in_data += block_len;
2395 
2396 	}
2397 
2398 	output->Length = total_decrypted;
2399 	return (KMF_OK);
2400 }
2401 
2402 static void
attr2bigint(CK_ATTRIBUTE_PTR attr,KMF_BIGINT * big)2403 attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big)
2404 {
2405 	big->val = attr->pValue;
2406 	big->len = attr->ulValueLen;
2407 }
2408 
2409 static KMF_RETURN
get_bigint_attr(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE_TYPE attrtype,KMF_BIGINT * bigint)2410 get_bigint_attr(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj,
2411 	CK_ATTRIBUTE_TYPE attrtype, KMF_BIGINT *bigint)
2412 {
2413 	CK_RV ckrv;
2414 	CK_ATTRIBUTE attr;
2415 
2416 	attr.type = attrtype;
2417 	attr.pValue = NULL;
2418 	attr.ulValueLen = 0;
2419 
2420 	if ((ckrv = C_GetAttributeValue(sess, obj,
2421 	    &attr, 1)) != CKR_OK) {
2422 		/* Mask this error so the caller can continue */
2423 		if (ckrv == CKR_ATTRIBUTE_TYPE_INVALID)
2424 			return (KMF_OK);
2425 		else
2426 			return (KMF_ERR_INTERNAL);
2427 	}
2428 	if (attr.ulValueLen > 0 && bigint != NULL) {
2429 		attr.pValue = malloc(attr.ulValueLen);
2430 		if (attr.pValue == NULL)
2431 			return (KMF_ERR_MEMORY);
2432 
2433 		if ((ckrv = C_GetAttributeValue(sess, obj,
2434 		    &attr, 1)) != CKR_OK)
2435 		if (ckrv != CKR_OK) {
2436 			free(attr.pValue);
2437 			return (KMF_ERR_INTERNAL);
2438 		}
2439 
2440 		bigint->val = attr.pValue;
2441 		bigint->len = attr.ulValueLen;
2442 	}
2443 	return (KMF_OK);
2444 }
2445 
2446 static KMF_RETURN
get_raw_rsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_RSA_KEY * rawrsa)2447 get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa)
2448 {
2449 	KMF_RETURN rv = KMF_OK;
2450 	CK_RV ckrv;
2451 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
2452 	CK_ATTRIBUTE rsa_pri_attrs[2] = {
2453 		{ CKA_MODULUS, NULL, 0 },
2454 		{ CKA_PUBLIC_EXPONENT, NULL, 0 }
2455 	};
2456 	CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
2457 	int i;
2458 
2459 	if (rawrsa == NULL)
2460 		return (KMF_ERR_BAD_PARAMETER);
2461 
2462 	(void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
2463 	if ((ckrv = C_GetAttributeValue(sess, obj,
2464 	    rsa_pri_attrs, count)) != CKR_OK) {
2465 		SET_ERROR(kmfh, ckrv);
2466 		/* Tell the caller know why the key data cannot be retrieved. */
2467 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2468 			return (KMF_ERR_SENSITIVE_KEY);
2469 		else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2470 			return (KMF_ERR_UNEXTRACTABLE_KEY);
2471 		else
2472 			return (KMF_ERR_INTERNAL);
2473 	}
2474 
2475 	/* Allocate memory for each attribute. */
2476 	for (i = 0; i < count; i++) {
2477 		if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2478 		    rsa_pri_attrs[i].ulValueLen == 0) {
2479 			rsa_pri_attrs[i].ulValueLen = 0;
2480 			continue;
2481 		}
2482 		if ((rsa_pri_attrs[i].pValue =
2483 		    malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) {
2484 			rv = KMF_ERR_MEMORY;
2485 			goto end;
2486 		}
2487 	}
2488 	/* Now that we have space, really get the attributes */
2489 	if ((ckrv = C_GetAttributeValue(sess, obj,
2490 	    rsa_pri_attrs, count)) != CKR_OK) {
2491 		SET_ERROR(kmfh, ckrv);
2492 		rv = KMF_ERR_INTERNAL;
2493 		goto end;
2494 	}
2495 	i = 0;
2496 	attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod);
2497 	attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp);
2498 
2499 	/* Now get the optional parameters */
2500 	rv = get_bigint_attr(sess, obj, CKA_PRIVATE_EXPONENT, &rawrsa->priexp);
2501 	if (rv != KMF_OK)
2502 		goto end;
2503 	rv = get_bigint_attr(sess, obj, CKA_PRIME_1, &rawrsa->prime1);
2504 	if (rv != KMF_OK)
2505 		goto end;
2506 	rv = get_bigint_attr(sess, obj, CKA_PRIME_2, &rawrsa->prime2);
2507 	if (rv != KMF_OK)
2508 		goto end;
2509 	rv = get_bigint_attr(sess, obj, CKA_EXPONENT_1, &rawrsa->exp1);
2510 	if (rv != KMF_OK)
2511 		goto end;
2512 	rv = get_bigint_attr(sess, obj, CKA_EXPONENT_2, &rawrsa->exp2);
2513 	if (rv != KMF_OK)
2514 		goto end;
2515 	rv = get_bigint_attr(sess, obj, CKA_COEFFICIENT, &rawrsa->coef);
2516 	if (rv != KMF_OK)
2517 		goto end;
2518 
2519 end:
2520 	if (rv != KMF_OK) {
2521 		for (i = 0; i < count; i++) {
2522 			if (rsa_pri_attrs[i].pValue != NULL)
2523 				free(rsa_pri_attrs[i].pValue);
2524 		}
2525 		if (rawrsa->priexp.val)
2526 			free(rawrsa->priexp.val);
2527 		if (rawrsa->prime1.val)
2528 			free(rawrsa->prime1.val);
2529 		if (rawrsa->prime2.val)
2530 			free(rawrsa->prime2.val);
2531 		if (rawrsa->exp1.val)
2532 			free(rawrsa->exp1.val);
2533 		if (rawrsa->exp2.val)
2534 			free(rawrsa->exp2.val);
2535 		if (rawrsa->coef.val)
2536 			free(rawrsa->coef.val);
2537 		(void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
2538 	}
2539 	return (rv);
2540 }
2541 
2542 #define	DSA_PRIME_BUFSIZE	CHARLEN2BIGNUMLEN(1024)	/* 8192 bits */
2543 #define	DSA_PRIVATE_BUFSIZE	BIG_CHUNKS_FOR_160BITS	/* 160 bits */
2544 
2545 /*
2546  * This function calculates the pubkey value from the prime,
2547  * base and private key values of a DSA key.
2548  */
2549 static KMF_RETURN
compute_dsa_pubvalue(KMF_RAW_DSA_KEY * rawdsa)2550 compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa)
2551 {
2552 	KMF_RETURN rv = KMF_OK;
2553 	BIGNUM p, g, x, y;
2554 	BIG_ERR_CODE err;
2555 	uchar_t *pubvalue;
2556 	uint32_t pubvalue_len;
2557 
2558 	if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2559 		rv = KMF_ERR_MEMORY;
2560 		return (rv);
2561 	}
2562 	bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len);
2563 
2564 	if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2565 		rv = KMF_ERR_MEMORY;
2566 		goto ret1;
2567 	}
2568 	bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len);
2569 
2570 	if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) {
2571 		rv = KMF_ERR_MEMORY;
2572 		goto ret2;
2573 	}
2574 	bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len);
2575 
2576 	if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2577 		rv = KMF_ERR_MEMORY;
2578 		goto ret3;
2579 	}
2580 
2581 	err = big_modexp(&y, &g, &x, &p, NULL);
2582 	if (err != BIG_OK) {
2583 		rv = KMF_ERR_INTERNAL;
2584 		goto ret3;
2585 	}
2586 
2587 	pubvalue_len = y.len * (int)sizeof (uint32_t);
2588 	if ((pubvalue = malloc(pubvalue_len)) == NULL) {
2589 		rv = KMF_ERR_MEMORY;
2590 		goto ret4;
2591 	}
2592 	bignum2bytestring(pubvalue, &y, pubvalue_len);
2593 
2594 	rawdsa->pubvalue.val = pubvalue;
2595 	rawdsa->pubvalue.len = pubvalue_len;
2596 
2597 ret4:
2598 	big_finish(&y);
2599 ret3:
2600 	big_finish(&x);
2601 ret2:
2602 	big_finish(&g);
2603 ret1:
2604 	big_finish(&p);
2605 	return (rv);
2606 }
2607 
2608 static KMF_RETURN
get_raw_ec(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_EC_KEY * rawec)2609 get_raw_ec(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_EC_KEY *rawec)
2610 {
2611 	KMF_RETURN rv = KMF_OK;
2612 	CK_RV ckrv;
2613 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
2614 	CK_ATTRIBUTE	ec_attrs[2] = {
2615 		{ CKA_EC_PARAMS, NULL, 0},
2616 		{ CKA_VALUE, NULL, 0}
2617 	};
2618 	CK_ULONG	count = sizeof (ec_attrs) / sizeof (CK_ATTRIBUTE);
2619 	int		i;
2620 
2621 	if ((ckrv = C_GetAttributeValue(sess, obj,
2622 	    ec_attrs, 2)) != CKR_OK) {
2623 		SET_ERROR(kmfh, ckrv);
2624 
2625 		/* Tell the caller know why the key data cannot be retrieved. */
2626 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2627 			return (KMF_ERR_SENSITIVE_KEY);
2628 		else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2629 			return (KMF_ERR_UNEXTRACTABLE_KEY);
2630 		return (KMF_ERR_INTERNAL);
2631 	}
2632 	for (i = 0; i < count; i++) {
2633 		if (ec_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2634 		    ec_attrs[i].ulValueLen == 0) {
2635 			ec_attrs[i].ulValueLen = 0;
2636 			continue;
2637 		}
2638 		if ((ec_attrs[i].pValue =
2639 		    malloc(ec_attrs[i].ulValueLen)) == NULL) {
2640 			rv = KMF_ERR_MEMORY;
2641 			goto end;
2642 		}
2643 	}
2644 	if ((ckrv = C_GetAttributeValue(sess, obj,
2645 	    ec_attrs, count)) != CKR_OK) {
2646 		SET_ERROR(kmfh, ckrv);
2647 		rv = KMF_ERR_INTERNAL;
2648 		goto end;
2649 	}
2650 
2651 	rawec->params.Data = ec_attrs[0].pValue;
2652 	rawec->params.Length = ec_attrs[0].ulValueLen;
2653 	rawec->value.val = ec_attrs[1].pValue;
2654 	rawec->value.len = ec_attrs[1].ulValueLen;
2655 
2656 end:
2657 	if (rv != KMF_OK) {
2658 		for (i = 0; i < count; i++) {
2659 			if (ec_attrs[i].pValue != NULL)
2660 				free(ec_attrs[i].pValue);
2661 		}
2662 		(void) memset(rawec, 0, sizeof (KMF_RAW_EC_KEY));
2663 	}
2664 	return (rv);
2665 }
2666 
2667 static KMF_RETURN
get_raw_dsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_DSA_KEY * rawdsa)2668 get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa)
2669 {
2670 	KMF_RETURN rv = KMF_OK;
2671 	CK_RV ckrv;
2672 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
2673 	CK_ATTRIBUTE	dsa_pri_attrs[8] = {
2674 		{ CKA_PRIME, NULL, 0 },
2675 		{ CKA_SUBPRIME, NULL, 0 },
2676 		{ CKA_BASE, NULL, 0 },
2677 		{ CKA_VALUE, NULL, 0 }
2678 	};
2679 	CK_ULONG	count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
2680 	int		i;
2681 
2682 	if ((ckrv = C_GetAttributeValue(sess, obj,
2683 	    dsa_pri_attrs, count)) != CKR_OK) {
2684 		SET_ERROR(kmfh, ckrv);
2685 
2686 		/* Tell the caller know why the key data cannot be retrieved. */
2687 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2688 			return (KMF_ERR_SENSITIVE_KEY);
2689 		else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2690 			return (KMF_ERR_UNEXTRACTABLE_KEY);
2691 		return (KMF_ERR_INTERNAL);
2692 	}
2693 
2694 	/* Allocate memory for each attribute. */
2695 	for (i = 0; i < count; i++) {
2696 		if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2697 		    dsa_pri_attrs[i].ulValueLen == 0) {
2698 			dsa_pri_attrs[i].ulValueLen = 0;
2699 			continue;
2700 		}
2701 		if ((dsa_pri_attrs[i].pValue =
2702 		    malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) {
2703 			rv = KMF_ERR_MEMORY;
2704 			goto end;
2705 		}
2706 	}
2707 	if ((ckrv = C_GetAttributeValue(sess, obj,
2708 	    dsa_pri_attrs, count)) != CKR_OK) {
2709 		SET_ERROR(kmfh, ckrv);
2710 		rv = KMF_ERR_INTERNAL;
2711 		goto end;
2712 	}
2713 
2714 	/* Fill in all the temp variables.  They are all required. */
2715 	i = 0;
2716 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime);
2717 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime);
2718 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base);
2719 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value);
2720 
2721 	/* Compute the public key value and store it */
2722 	rv = compute_dsa_pubvalue(rawdsa);
2723 
2724 end:
2725 	if (rv != KMF_OK) {
2726 		for (i = 0; i < count; i++) {
2727 			if (dsa_pri_attrs[i].pValue != NULL)
2728 				free(dsa_pri_attrs[i].pValue);
2729 		}
2730 		(void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY));
2731 	}
2732 	return (rv);
2733 }
2734 
2735 static KMF_RETURN
get_raw_sym(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_SYM_KEY * rawsym)2736 get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym)
2737 {
2738 	KMF_RETURN rv = KMF_OK;
2739 	CK_RV	ckrv;
2740 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
2741 	CK_ATTRIBUTE	sym_attr[1];
2742 	CK_ULONG	value_len = 0;
2743 
2744 	/* find the key length first */
2745 	sym_attr[0].type = CKA_VALUE;
2746 	sym_attr[0].pValue = NULL;
2747 	sym_attr[0].ulValueLen = value_len;
2748 	if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
2749 		rawsym->keydata.val = NULL;
2750 		rawsym->keydata.len = 0;
2751 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE) {
2752 			return (KMF_ERR_SENSITIVE_KEY);
2753 		} else if (ckrv == CKR_KEY_UNEXTRACTABLE) {
2754 			return (KMF_ERR_UNEXTRACTABLE_KEY);
2755 		} else {
2756 			SET_ERROR(kmfh, ckrv);
2757 			return (KMF_ERR_INTERNAL);
2758 		}
2759 	}
2760 
2761 	/* Allocate memory for pValue */
2762 	sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen);
2763 	if (sym_attr[0].pValue == NULL) {
2764 		return (KMF_ERR_MEMORY);
2765 	}
2766 
2767 	/* get the key data */
2768 	if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
2769 		SET_ERROR(kmfh, ckrv);
2770 		free(sym_attr[0].pValue);
2771 		return (KMF_ERR_INTERNAL);
2772 	}
2773 
2774 	rawsym->keydata.val = sym_attr[0].pValue;
2775 	rawsym->keydata.len = sym_attr[0].ulValueLen;
2776 	return (rv);
2777 }
2778 
2779 static KMF_RETURN
keyObj2RawKey(KMF_HANDLE_T handle,KMF_KEY_HANDLE * inkey,KMF_RAW_KEY_DATA ** outkey)2780 keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey,
2781 	KMF_RAW_KEY_DATA **outkey)
2782 {
2783 	KMF_RETURN rv = KMF_OK;
2784 	KMF_RAW_KEY_DATA *rkey;
2785 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2786 
2787 	rkey = malloc(sizeof (KMF_RAW_KEY_DATA));
2788 	if (rkey == NULL)
2789 		return (KMF_ERR_MEMORY);
2790 
2791 	(void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA));
2792 
2793 	rkey->keytype = inkey->keyalg;
2794 
2795 	if (inkey->keyalg == KMF_RSA) {
2796 		rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2797 		    &rkey->rawdata.rsa);
2798 	} else if (inkey->keyalg == KMF_DSA) {
2799 		rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2800 		    &rkey->rawdata.dsa);
2801 	} else if (inkey->keyalg == KMF_AES ||
2802 	    inkey->keyalg == KMF_RC4 ||
2803 	    inkey->keyalg == KMF_DES ||
2804 	    inkey->keyalg == KMF_DES3 ||
2805 	    inkey->keyalg == KMF_GENERIC_SECRET) {
2806 		rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2807 		    &rkey->rawdata.sym);
2808 		/*
2809 		 * If sensitive or non-extractable, mark them as such
2810 		 * but return "OK" status so the keys get counted
2811 		 * when doing FindKey operations.
2812 		 */
2813 		if (rv == KMF_ERR_SENSITIVE_KEY) {
2814 			rkey->sensitive = B_TRUE;
2815 			rv = KMF_OK;
2816 		} else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
2817 			rkey->not_extractable = B_TRUE;
2818 			rv = KMF_OK;
2819 		}
2820 	} else if (inkey->keyalg == KMF_ECDSA) {
2821 		rv = get_raw_ec(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2822 		    &rkey->rawdata.ec);
2823 	} else {
2824 		rv = KMF_ERR_BAD_PARAMETER;
2825 	}
2826 
2827 	if (rv == KMF_OK) {
2828 		*outkey = rkey;
2829 	} else if (rkey != NULL) {
2830 		free(rkey);
2831 		*outkey = NULL;
2832 	}
2833 
2834 	return (rv);
2835 }
2836 
2837 
2838 static KMF_RETURN
kmf2pk11keytype(KMF_KEY_ALG keyalg,CK_KEY_TYPE * type)2839 kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type)
2840 {
2841 	switch (keyalg) {
2842 	case KMF_RSA:
2843 		*type = CKK_RSA;
2844 		break;
2845 	case KMF_DSA:
2846 		*type = CKK_DSA;
2847 		break;
2848 	case KMF_ECDSA:
2849 		*type = CKK_EC;
2850 		break;
2851 	case KMF_AES:
2852 		*type = CKK_AES;
2853 		break;
2854 	case KMF_RC4:
2855 		*type = CKK_RC4;
2856 		break;
2857 	case KMF_DES:
2858 		*type = CKK_DES;
2859 		break;
2860 	case KMF_DES3:
2861 		*type = CKK_DES3;
2862 		break;
2863 	case KMF_GENERIC_SECRET:
2864 		*type = CKK_GENERIC_SECRET;
2865 		break;
2866 	default:
2867 		return (KMF_ERR_BAD_KEY_TYPE);
2868 	}
2869 
2870 	return (KMF_OK);
2871 }
2872 
2873 static int
IDStringToData(char * idstr,KMF_DATA * iddata)2874 IDStringToData(char *idstr, KMF_DATA *iddata)
2875 {
2876 	int len, i;
2877 	char *iddup, *byte;
2878 	uint_t lvalue;
2879 
2880 	if (idstr == NULL || !strlen(idstr))
2881 		return (-1);
2882 
2883 	iddup = (char *)strdup(idstr);
2884 	if (iddup == NULL)
2885 		return (KMF_ERR_MEMORY);
2886 
2887 	len = strlen(iddup) / 3  + 1;
2888 	iddata->Data = malloc(len);
2889 	if (iddata->Data == NULL)
2890 		return (KMF_ERR_MEMORY);
2891 	(void) memset(iddata->Data, 0, len);
2892 	iddata->Length = len;
2893 
2894 	byte = strtok(iddup, ":");
2895 	if (byte == NULL) {
2896 		free(iddup);
2897 		free(iddata->Data);
2898 		iddata->Data = NULL;
2899 		iddata->Length = 0;
2900 		return (-1);
2901 	}
2902 
2903 	i = 0;
2904 	do {
2905 		(void) sscanf(byte, "%x", &lvalue);
2906 		iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF);
2907 		byte = strtok(NULL, ":");
2908 	} while (byte != NULL && i < len);
2909 
2910 	iddata->Length = i;
2911 	free(iddup);
2912 	return (0);
2913 }
2914 
2915 KMF_RETURN
KMFPK11_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2916 KMFPK11_FindKey(KMF_HANDLE_T handle,
2917 	int numattr, KMF_ATTRIBUTE *attrlist)
2918 {
2919 	KMF_RETURN rv = KMF_OK;
2920 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2921 	uint32_t want_keys, i;
2922 	CK_RV ckrv;
2923 	CK_ATTRIBUTE pTmpl[10];
2924 	CK_OBJECT_CLASS class;
2925 	CK_BBOOL true = TRUE;
2926 	CK_ULONG alg;
2927 	boolean_t is_token = B_TRUE, is_private = B_FALSE;
2928 	KMF_KEY_HANDLE *keys;
2929 	uint32_t *numkeys;
2930 	KMF_CREDENTIAL *cred = NULL;
2931 	KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE;
2932 	char *findLabel, *idstr;
2933 	KMF_KEY_ALG keytype = KMF_KEYALG_NONE;
2934 	KMF_ENCODE_FORMAT format;
2935 
2936 	if (kmfh == NULL)
2937 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2938 
2939 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
2940 		return (KMF_ERR_NO_TOKEN_SELECTED);
2941 
2942 	numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2943 	if (numkeys == NULL)
2944 		return (KMF_ERR_BAD_PARAMETER);
2945 
2946 	if (*numkeys > 0)
2947 		want_keys = *numkeys;
2948 	else
2949 		want_keys = MAXINT; /* count them all */
2950 
2951 	/* keyclass is optional */
2952 	(void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2953 	    (void *)&keyclass, NULL);
2954 
2955 	if (keyclass == KMF_ASYM_PUB) {
2956 		class = CKO_PUBLIC_KEY;
2957 	} else if (keyclass == KMF_ASYM_PRI) {
2958 		class = CKO_PRIVATE_KEY;
2959 	} else if (keyclass == KMF_SYMMETRIC) {
2960 		class = CKO_SECRET_KEY;
2961 	}
2962 
2963 	rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr,
2964 	    (void *)&is_token, NULL);
2965 	if (rv != KMF_OK)
2966 		return (rv);
2967 
2968 	i = 0;
2969 	if (is_token) {
2970 		SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true));
2971 		i++;
2972 	}
2973 
2974 	if (keyclass != KMF_KEYCLASS_NONE) {
2975 		SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class));
2976 		i++;
2977 	}
2978 
2979 	findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
2980 
2981 	if (findLabel != NULL && strlen(findLabel)) {
2982 		SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel));
2983 		i++;
2984 	}
2985 	/* keytype is optional */
2986 	(void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
2987 	    (void *)&keytype, NULL);
2988 
2989 	if (keytype != 0) {
2990 		rv = kmf2pk11keytype(keytype, &alg);
2991 		if (rv != KMF_OK) {
2992 			return (KMF_ERR_BAD_KEY_TYPE);
2993 		}
2994 		SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg));
2995 		i++;
2996 	}
2997 
2998 	idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr);
2999 
3000 	if (idstr != NULL) {
3001 		KMF_DATA iddata = { 0, NULL };
3002 
3003 		/*
3004 		 * ID String parameter is assumed to be of form:
3005 		 * XX:XX:XX:XX:XX ... :XX
3006 		 * where XX is a hex number.
3007 		 *
3008 		 * We must convert this back to binary in order to
3009 		 * use it in a search.
3010 		 */
3011 		rv = IDStringToData(idstr, &iddata);
3012 		if (rv == KMF_OK) {
3013 			SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length);
3014 			i++;
3015 		} else {
3016 			return (rv);
3017 		}
3018 	}
3019 
3020 	/* is_private is optional */
3021 	(void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
3022 	    (void *)&is_private, NULL);
3023 
3024 	if (is_private) {
3025 		SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true));
3026 		i++;
3027 	}
3028 
3029 	/*
3030 	 * Authenticate if the object is a token object,
3031 	 * a private or secred key, or if the user passed in credentials.
3032 	 */
3033 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3034 	if (cred != NULL) {
3035 		rv = pk11_authenticate(handle, cred);
3036 		if (rv != KMF_OK)
3037 			return (rv);
3038 	}
3039 
3040 	keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
3041 	/* it is okay to have "keys" contains NULL */
3042 
3043 	ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i);
3044 	if (ckrv == CKR_OK) {
3045 		CK_ULONG obj_count, n = 0;
3046 		while (ckrv == CKR_OK && n < want_keys) {
3047 			CK_OBJECT_HANDLE hObj;
3048 
3049 			ckrv = C_FindObjects(kmfh->pk11handle, &hObj,
3050 			    1, &obj_count);
3051 			if (ckrv == CKR_OK && obj_count == 1) {
3052 				if (keys != NULL) {
3053 					CK_ULONG keytype;
3054 					keys[n].kstype = KMF_KEYSTORE_PK11TOKEN;
3055 					keys[n].israw = FALSE;
3056 					keys[n].keyp = (void *)hObj;
3057 
3058 					ckrv = getObjectKeytype(handle,
3059 					    (CK_OBJECT_HANDLE)keys[n].keyp,
3060 					    &keytype);
3061 					if (ckrv != CKR_OK)
3062 						goto end;
3063 
3064 					ckrv = getObjectLabel(handle,
3065 					    (CK_OBJECT_HANDLE)keys[n].keyp,
3066 					    &(keys[n].keylabel));
3067 					if (ckrv != CKR_OK)
3068 						goto end;
3069 
3070 					if (keyclass == KMF_KEYCLASS_NONE) {
3071 						ckrv = getObjectKeyclass(handle,
3072 						    (CK_OBJECT_HANDLE)
3073 						    keys[n].keyp,
3074 						    &(keys[n].keyclass));
3075 						if (ckrv != CKR_OK)
3076 							goto end;
3077 					} else {
3078 						keys[n].keyclass = keyclass;
3079 					}
3080 					if (keytype == CKK_RSA) {
3081 						keys[n].keyalg = KMF_RSA;
3082 					} else if (keytype == CKK_DSA) {
3083 						keys[n].keyalg = KMF_DSA;
3084 					} else if (keytype == CKK_EC) {
3085 						keys[n].keyalg = KMF_ECDSA;
3086 					} else if (keytype == CKK_AES) {
3087 						keys[n].keyalg = KMF_AES;
3088 						keys[n].keyclass =
3089 						    KMF_SYMMETRIC;
3090 					} else if (keytype == CKK_RC4) {
3091 						keys[n].keyalg = KMF_RC4;
3092 						keys[n].keyclass =
3093 						    KMF_SYMMETRIC;
3094 					} else if (keytype == CKK_DES) {
3095 						keys[n].keyalg = KMF_DES;
3096 						keys[n].keyclass =
3097 						    KMF_SYMMETRIC;
3098 					} else if (keytype == CKK_DES3) {
3099 						keys[n].keyalg = KMF_DES3;
3100 						keys[n].keyclass =
3101 						    KMF_SYMMETRIC;
3102 					} else if (keytype ==
3103 					    CKK_GENERIC_SECRET) {
3104 						keys[n].keyalg =
3105 						    KMF_GENERIC_SECRET;
3106 						keys[n].keyclass =
3107 						    KMF_SYMMETRIC;
3108 					}
3109 
3110 				}
3111 				n++;
3112 			} else {
3113 				break;
3114 			}
3115 		}
3116 		ckrv = C_FindObjectsFinal(kmfh->pk11handle);
3117 
3118 		/* "numkeys" indicates the number that were actually found */
3119 		*numkeys = n;
3120 	}
3121 
3122 	if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) {
3123 		if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist,
3124 		    numattr, (void *)&format, NULL)) == KMF_OK) {
3125 			if (format == KMF_FORMAT_RAWKEY ||
3126 			    format == KMF_FORMAT_PEM) {
3127 				/* Convert keys to "rawkey" format */
3128 				for (i = 0; i < (*numkeys); i++) {
3129 					KMF_RAW_KEY_DATA *rkey = NULL;
3130 					rv = keyObj2RawKey(handle, &keys[i],
3131 					    &rkey);
3132 					if (rv == KMF_OK) {
3133 						keys[i].keyp = rkey;
3134 						keys[i].israw = TRUE;
3135 					} else {
3136 						break;
3137 					}
3138 				}
3139 			}
3140 		} else {
3141 			rv = KMF_OK; /* format is optional */
3142 		}
3143 	}
3144 
3145 end:
3146 	if (ckrv != CKR_OK) {
3147 		SET_ERROR(kmfh, ckrv);
3148 		/* Report authentication failures to the caller */
3149 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3150 		    ckrv == CKR_PIN_INCORRECT ||
3151 		    ckrv == CKR_PIN_INVALID ||
3152 		    ckrv == CKR_PIN_EXPIRED ||
3153 		    ckrv == CKR_PIN_LOCKED ||
3154 		    ckrv == CKR_SESSION_READ_ONLY)
3155 			rv = KMF_ERR_AUTH_FAILED;
3156 		else
3157 			rv = KMF_ERR_INTERNAL;
3158 	} else if ((*numkeys) == 0) {
3159 		rv = KMF_ERR_KEY_NOT_FOUND;
3160 	}
3161 
3162 	return (rv);
3163 }
3164 
3165 static char *
convertDate(char * fulldate)3166 convertDate(char *fulldate)
3167 {
3168 	struct tm tms;
3169 	char newtime[9];
3170 
3171 	(void) strptime(fulldate, "%b %d %T %Y %Z", &tms);
3172 
3173 	if (tms.tm_year < 69)
3174 		tms.tm_year += 100;
3175 
3176 	(void) strftime(newtime, sizeof (newtime), "m%d", &tms);
3177 
3178 	newtime[8] = 0;
3179 
3180 	/* memory returned must be freed by the caller */
3181 	return ((char *)strdup(newtime));
3182 }
3183 
3184 static KMF_RETURN
store_raw_key(KMF_HANDLE_T handle,KMF_ATTRIBUTE * attrlist,int numattr,KMF_RAW_KEY_DATA * rawkey)3185 store_raw_key(KMF_HANDLE_T handle,
3186 	KMF_ATTRIBUTE *attrlist, int numattr,
3187 	KMF_RAW_KEY_DATA *rawkey)
3188 {
3189 	KMF_RETURN rv = KMF_OK;
3190 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3191 	int i;
3192 	CK_RV		ckrv = CKR_OK;
3193 	CK_ATTRIBUTE	templ[32];
3194 	CK_OBJECT_HANDLE keyobj;
3195 	CK_KEY_TYPE	keytype;
3196 	CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
3197 	CK_BBOOL	cktrue = TRUE;
3198 	CK_DATE		startdate, enddate;
3199 	KMF_DATA	id = { 0, NULL };
3200 	KMF_DATA	subject = { 0, NULL };
3201 	KMF_X509EXT_KEY_USAGE kuext;
3202 	KMF_X509_CERTIFICATE *x509 = NULL;
3203 	CK_BBOOL	kufound = B_FALSE;
3204 	KMF_DATA	*cert = NULL;
3205 	char		*notbefore = NULL, *start = NULL;
3206 	char		*notafter = NULL, *end = NULL;
3207 	char		*keylabel = NULL;
3208 	KMF_CREDENTIAL	*cred = NULL;
3209 
3210 	if (kmfh == NULL)
3211 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
3212 
3213 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
3214 		return (KMF_ERR_NO_TOKEN_SELECTED);
3215 
3216 	if (rawkey->keytype == KMF_RSA)
3217 		keytype = CKK_RSA;
3218 	else if (rawkey->keytype == KMF_DSA)
3219 		keytype = CKK_DSA;
3220 	else if (rawkey->keytype == KMF_ECDSA)
3221 		keytype = CKK_EC;
3222 	else
3223 		return (KMF_ERR_BAD_PARAMETER);
3224 
3225 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3226 	if (cred != NULL) {
3227 		rv = pk11_authenticate(handle, cred);
3228 		if (rv != KMF_OK)
3229 			return (rv);
3230 	}
3231 
3232 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3233 	/*
3234 	 * If the caller did not specify a label, see if the raw key
3235 	 * came with one (possible if it came from a PKCS#12 file).
3236 	 */
3237 	if (keylabel == NULL) {
3238 		keylabel = rawkey->label;
3239 	}
3240 
3241 	i = 0;
3242 	SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++;
3243 	SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++;
3244 	SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++;
3245 	SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++;
3246 	if (keytype != CKK_EC) {
3247 		SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++;
3248 	}
3249 
3250 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
3251 	if (cert != NULL) {
3252 		id.Data = NULL;
3253 		id.Length = 0;
3254 		rv = kmf_get_cert_id_data(cert, &id);
3255 		if (rv != KMF_OK) {
3256 			goto cleanup;
3257 		}
3258 
3259 		rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509);
3260 		if (rv != KMF_OK) {
3261 			goto cleanup;
3262 		}
3263 
3264 		rv = DerEncodeName(&x509->certificate.subject, &subject);
3265 		if (rv != KMF_OK) {
3266 			goto cleanup;
3267 		}
3268 		SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length);
3269 		i++;
3270 
3271 		rv = kmf_get_cert_start_date_str(handle, cert, &notbefore);
3272 		if (rv != KMF_OK) {
3273 			goto cleanup;
3274 		}
3275 		start = convertDate(notbefore);
3276 		free(notbefore);
3277 
3278 		rv = kmf_get_cert_end_date_str(handle, cert, &notafter);
3279 		if (rv != KMF_OK) {
3280 			goto cleanup;
3281 		}
3282 		end = convertDate(notafter);
3283 		free(notafter);
3284 		if (id.Data != NULL && id.Data != NULL && id.Length > 0) {
3285 			SETATTR(templ, i, CKA_ID, id.Data, id.Length);
3286 			i++;
3287 		}
3288 		if (start != NULL) {
3289 			/*
3290 			 * This makes some potentially dangerous assumptions:
3291 			 *  1. that the startdate in the parameter block is
3292 			 * properly formatted as YYYYMMDD
3293 			 *  2. That the CK_DATE structure is always the same.
3294 			 */
3295 			(void) memcpy(&startdate, start, sizeof (CK_DATE));
3296 			SETATTR(templ, i, CKA_START_DATE, &startdate,
3297 			    sizeof (startdate));
3298 			i++;
3299 		}
3300 		if (end != NULL) {
3301 			(void) memcpy(&enddate, end, sizeof (CK_DATE));
3302 			SETATTR(templ, i, CKA_END_DATE, &enddate,
3303 			    sizeof (enddate));
3304 			i++;
3305 		}
3306 
3307 		if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK &&
3308 		    rv != KMF_ERR_EXTENSION_NOT_FOUND)
3309 			goto cleanup;
3310 
3311 		kufound = (rv == KMF_OK);
3312 		rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */
3313 	}
3314 
3315 	/*
3316 	 * Only set the KeyUsage stuff if the KU extension was present.
3317 	 */
3318 	if (kufound) {
3319 		CK_BBOOL	condition;
3320 
3321 		condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ?
3322 		    B_TRUE : B_FALSE;
3323 		SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL));
3324 		i++;
3325 		condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ?
3326 		    B_TRUE : B_FALSE;
3327 		SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL));
3328 		i++;
3329 		condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
3330 		    B_TRUE : B_FALSE;
3331 		SETATTR(templ, i, CKA_SIGN, &condition,	sizeof (CK_BBOOL));
3332 		i++;
3333 		condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
3334 		    B_TRUE : B_FALSE;
3335 		SETATTR(templ, i, CKA_SIGN_RECOVER, &condition,
3336 		    sizeof (CK_BBOOL));
3337 		i++;
3338 
3339 	}
3340 
3341 	if (keylabel != NULL) {
3342 		SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3343 		i++;
3344 	}
3345 	if (id.Data == NULL && rawkey->id.Data != NULL) {
3346 		SETATTR(templ, i, CKA_ID, rawkey->id.Data,
3347 		    rawkey->id.Length);
3348 		i++;
3349 	}
3350 	if (keytype == CKK_RSA) {
3351 		SETATTR(templ, i, CKA_MODULUS,
3352 		    rawkey->rawdata.rsa.mod.val,
3353 		    rawkey->rawdata.rsa.mod.len);
3354 		i++;
3355 		SETATTR(templ, i, CKA_PUBLIC_EXPONENT,
3356 		    rawkey->rawdata.rsa.pubexp.val,
3357 		    rawkey->rawdata.rsa.pubexp.len);
3358 		i++;
3359 		if (rawkey->rawdata.rsa.priexp.val != NULL) {
3360 			SETATTR(templ, i, CKA_PRIVATE_EXPONENT,
3361 			    rawkey->rawdata.rsa.priexp.val,
3362 			    rawkey->rawdata.rsa.priexp.len);
3363 			i++;
3364 		}
3365 		if (rawkey->rawdata.rsa.prime1.val != NULL) {
3366 			SETATTR(templ, i, CKA_PRIME_1,
3367 			    rawkey->rawdata.rsa.prime1.val,
3368 			    rawkey->rawdata.rsa.prime1.len);
3369 			i++;
3370 		}
3371 		if (rawkey->rawdata.rsa.prime2.val != NULL) {
3372 			SETATTR(templ, i, CKA_PRIME_2,
3373 			    rawkey->rawdata.rsa.prime2.val,
3374 			    rawkey->rawdata.rsa.prime2.len);
3375 			i++;
3376 		}
3377 		if (rawkey->rawdata.rsa.exp1.val != NULL) {
3378 			SETATTR(templ, i, CKA_EXPONENT_1,
3379 			    rawkey->rawdata.rsa.exp1.val,
3380 			    rawkey->rawdata.rsa.exp1.len);
3381 			i++;
3382 		}
3383 		if (rawkey->rawdata.rsa.exp2.val != NULL) {
3384 			SETATTR(templ, i, CKA_EXPONENT_2,
3385 			    rawkey->rawdata.rsa.exp2.val,
3386 			    rawkey->rawdata.rsa.exp2.len);
3387 			i++;
3388 		}
3389 		if (rawkey->rawdata.rsa.coef.val != NULL) {
3390 			SETATTR(templ, i, CKA_COEFFICIENT,
3391 			    rawkey->rawdata.rsa.coef.val,
3392 			    rawkey->rawdata.rsa.coef.len);
3393 			i++;
3394 		}
3395 	} else if (keytype == CKK_DSA) {
3396 		SETATTR(templ, i, CKA_PRIME,
3397 		    rawkey->rawdata.dsa.prime.val,
3398 		    rawkey->rawdata.dsa.prime.len);
3399 		i++;
3400 		SETATTR(templ, i, CKA_SUBPRIME,
3401 		    rawkey->rawdata.dsa.subprime.val,
3402 		    rawkey->rawdata.dsa.subprime.len);
3403 		i++;
3404 		SETATTR(templ, i, CKA_BASE,
3405 		    rawkey->rawdata.dsa.base.val,
3406 		    rawkey->rawdata.dsa.base.len);
3407 		i++;
3408 		SETATTR(templ, i, CKA_VALUE,
3409 		    rawkey->rawdata.dsa.value.val,
3410 		    rawkey->rawdata.dsa.value.len);
3411 		i++;
3412 	} else if (keytype == CKK_EC) {
3413 		SETATTR(templ, i, CKA_SIGN, &cktrue, sizeof (cktrue));
3414 		i++;
3415 		SETATTR(templ, i, CKA_DERIVE, &cktrue, sizeof (cktrue));
3416 		i++;
3417 		SETATTR(templ, i, CKA_VALUE,
3418 		    rawkey->rawdata.ec.value.val,
3419 		    rawkey->rawdata.ec.value.len);
3420 		i++;
3421 		SETATTR(templ, i, CKA_EC_PARAMS,
3422 		    rawkey->rawdata.ec.params.Data,
3423 		    rawkey->rawdata.ec.params.Length);
3424 		i++;
3425 	}
3426 
3427 	ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj);
3428 	if (ckrv != CKR_OK) {
3429 		SET_ERROR(kmfh, ckrv);
3430 
3431 		/* Report authentication failures to the caller */
3432 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3433 		    ckrv == CKR_PIN_INCORRECT ||
3434 		    ckrv == CKR_PIN_INVALID ||
3435 		    ckrv == CKR_PIN_EXPIRED ||
3436 		    ckrv == CKR_PIN_LOCKED ||
3437 		    ckrv == CKR_SESSION_READ_ONLY)
3438 			rv = KMF_ERR_AUTH_FAILED;
3439 		else
3440 			rv = KMF_ERR_INTERNAL;
3441 	}
3442 cleanup:
3443 	if (start != NULL)
3444 		free(start);
3445 	if (end != NULL)
3446 		free(end);
3447 	kmf_free_data(&id);
3448 	kmf_free_data(&subject);
3449 	kmf_free_signed_cert(x509);
3450 	free(x509);
3451 
3452 	return (rv);
3453 }
3454 
3455 KMF_RETURN
KMFPK11_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3456 KMFPK11_CreateSymKey(KMF_HANDLE_T handle,
3457     int numattr, KMF_ATTRIBUTE *attrlist)
3458 {
3459 	KMF_RETURN		rv = KMF_OK;
3460 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
3461 	CK_RV			ckrv;
3462 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
3463 	CK_OBJECT_HANDLE	keyhandle;
3464 	CK_MECHANISM		keyGenMech;
3465 	CK_OBJECT_CLASS		class = CKO_SECRET_KEY;
3466 	CK_ULONG		secKeyType;
3467 	CK_ULONG		secKeyLen;	/* for RC4 and AES */
3468 	CK_BBOOL		true = TRUE;
3469 	CK_BBOOL		false = FALSE;
3470 	CK_ATTRIBUTE		templ[15];
3471 	CK_BYTE			*keydata = NULL;
3472 	int			i = 0;
3473 	KMF_KEY_HANDLE		*symkey;
3474 	KMF_KEY_ALG		keytype;
3475 	uint32_t		keylen = 0;
3476 	uint32_t		attrkeylen = 0;
3477 	uint32_t		keylen_size = sizeof (uint32_t);
3478 	char			*keylabel = NULL;
3479 	KMF_CREDENTIAL		*cred = NULL;
3480 	uint32_t		is_sensitive = B_FALSE;
3481 	uint32_t		is_not_extractable = B_FALSE;
3482 
3483 	if (kmfh == NULL)
3484 		return (KMF_ERR_UNINITIALIZED);
3485 
3486 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
3487 		return (KMF_ERR_NO_TOKEN_SELECTED);
3488 
3489 	symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
3490 	if (symkey == NULL)
3491 		return (KMF_ERR_BAD_PARAMETER);
3492 
3493 	rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
3494 	    (void *)&keytype, NULL);
3495 	if (rv != KMF_OK)
3496 		return (KMF_ERR_BAD_PARAMETER);
3497 
3498 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3499 	if (keylabel == NULL)
3500 		return (KMF_ERR_BAD_PARAMETER);
3501 
3502 	rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
3503 	    (void *)&is_sensitive, NULL);
3504 	if (rv != KMF_OK)
3505 		return (KMF_ERR_BAD_PARAMETER);
3506 
3507 	rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
3508 	    (void *)&is_not_extractable, NULL);
3509 	if (rv != KMF_OK)
3510 		return (KMF_ERR_BAD_PARAMETER);
3511 
3512 	/*
3513 	 * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key.
3514 	 *
3515 	 * For a generic secret key, because it may not be supported in
3516 	 * C_GenerateKey() for some PKCS11 providers, we will handle it
3517 	 * differently.
3518 	 */
3519 	if (keytype == KMF_GENERIC_SECRET) {
3520 		rv = create_generic_secret_key(handle, numattr,
3521 		    attrlist, &keyhandle);
3522 		if (rv != KMF_OK)
3523 			goto out;
3524 		else
3525 			goto setup;
3526 	}
3527 
3528 	rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
3529 	    NULL, &attrkeylen);
3530 	if (rv == KMF_OK && attrkeylen > 0) {
3531 		keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
3532 		    numattr);
3533 	} else {
3534 		keydata = NULL;
3535 		attrkeylen = 0;
3536 		rv = KMF_OK;
3537 	}
3538 	if (keydata != NULL) {
3539 		if (keytype == KMF_DES && attrkeylen != 8) {
3540 			rv = KMF_ERR_BAD_KEY_SIZE;
3541 			goto out;
3542 		}
3543 		if (keytype == KMF_DES3 && attrkeylen != 24) {
3544 			rv = KMF_ERR_BAD_KEY_SIZE;
3545 			goto out;
3546 		}
3547 		/*
3548 		 * This may override what the user gave on the
3549 		 * command line.
3550 		 */
3551 		keylen = attrkeylen * 8; /* bytes to bits */
3552 	} else {
3553 		/*
3554 		 * If keydata was not given, key length must be
3555 		 * provided.
3556 		 */
3557 		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
3558 		    &keylen, &keylen_size);
3559 		if (rv == KMF_ERR_ATTR_NOT_FOUND &&
3560 		    (keytype == KMF_DES || keytype == KMF_DES3))
3561 			/* keylength is not required for DES and 3DES */
3562 			rv = KMF_OK;
3563 		if (rv != KMF_OK)
3564 			return (KMF_ERR_BAD_PARAMETER);
3565 	}
3566 
3567 	if ((keylen % 8) != 0) {
3568 		return (KMF_ERR_BAD_KEY_SIZE);
3569 	}
3570 	secKeyLen = keylen / 8;  /* in bytes for RC4/AES */
3571 
3572 	/*
3573 	 * Only set CKA_VALUE_LEN if the key data was not given and
3574 	 * we are creating an RC4 or AES key.
3575 	 */
3576 	if (keydata == NULL &&
3577 	    (keytype == KMF_AES || keytype == KMF_RC4)) {
3578 		SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen,
3579 		    sizeof (secKeyLen));
3580 		i++;
3581 	}
3582 
3583 	/* Other keytypes */
3584 	keyGenMech.pParameter = NULL_PTR;
3585 	keyGenMech.ulParameterLen = 0;
3586 	switch (keytype) {
3587 		case KMF_AES:
3588 			keyGenMech.mechanism = CKM_AES_KEY_GEN;
3589 			secKeyType = CKK_AES;
3590 			break;
3591 		case KMF_RC4:
3592 			keyGenMech.mechanism = CKM_RC4_KEY_GEN;
3593 			secKeyType = CKK_RC4;
3594 			break;
3595 		case KMF_DES:
3596 			keyGenMech.mechanism = CKM_DES_KEY_GEN;
3597 			secKeyType = CKK_DES;
3598 			break;
3599 		case KMF_DES3:
3600 			keyGenMech.mechanism = CKM_DES3_KEY_GEN;
3601 			secKeyType = CKK_DES3;
3602 			break;
3603 		default:
3604 			return (KMF_ERR_BAD_KEY_TYPE);
3605 	}
3606 	if (keydata != NULL) {
3607 		SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen);
3608 		i++;
3609 	}
3610 	SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
3611 	i++;
3612 	SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
3613 	i++;
3614 
3615 	if (keylabel != NULL) {
3616 		SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3617 		i++;
3618 	}
3619 
3620 	if (is_sensitive == B_TRUE) {
3621 		SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
3622 	} else {
3623 		SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
3624 	}
3625 	i++;
3626 
3627 	if (is_not_extractable == B_TRUE) {
3628 		SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
3629 	} else {
3630 		SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
3631 	}
3632 	i++;
3633 
3634 	SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
3635 	i++;
3636 	SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
3637 	i++;
3638 	SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true));
3639 	i++;
3640 	SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true));
3641 	i++;
3642 	SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
3643 	i++;
3644 	SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true));
3645 	i++;
3646 
3647 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3648 	if (cred == NULL)
3649 		return (KMF_ERR_BAD_PARAMETER);
3650 
3651 	rv = pk11_authenticate(handle, cred);
3652 	if (rv != KMF_OK) {
3653 		return (rv);
3654 	}
3655 
3656 	/* If the key data was given, use C_CreateObject */
3657 	if (keydata != NULL) {
3658 		ckrv = C_CreateObject(hSession, templ, i, &keyhandle);
3659 	} else {
3660 		ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i,
3661 		    &keyhandle);
3662 	}
3663 	if (ckrv != CKR_OK) {
3664 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3665 		    ckrv == CKR_PIN_INCORRECT ||
3666 		    ckrv == CKR_PIN_INVALID ||
3667 		    ckrv == CKR_PIN_EXPIRED ||
3668 		    ckrv == CKR_PIN_LOCKED ||
3669 		    ckrv == CKR_SESSION_READ_ONLY)
3670 			rv = KMF_ERR_AUTH_FAILED;
3671 		else
3672 			rv = KMF_ERR_KEYGEN_FAILED;
3673 		SET_ERROR(kmfh, ckrv);
3674 		goto out;
3675 	}
3676 
3677 setup:
3678 	symkey->kstype = KMF_KEYSTORE_PK11TOKEN;
3679 	symkey->keyalg = keytype;
3680 	symkey->keyclass = KMF_SYMMETRIC;
3681 	symkey->israw = FALSE;
3682 	symkey->keyp = (void *)keyhandle;
3683 
3684 out:
3685 	return (rv);
3686 }
3687 
3688 KMF_RETURN
KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)3689 KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
3690     KMF_RAW_SYM_KEY *rkey)
3691 {
3692 	KMF_RETURN		rv = KMF_OK;
3693 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
3694 
3695 	if (kmfh == NULL)
3696 		return (KMF_ERR_UNINITIALIZED);
3697 
3698 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
3699 		return (KMF_ERR_NO_TOKEN_SELECTED);
3700 
3701 	if (symkey == NULL || rkey == NULL)
3702 		return (KMF_ERR_BAD_PARAMETER);
3703 	else if (symkey->keyclass != KMF_SYMMETRIC)
3704 		return (KMF_ERR_BAD_KEY_CLASS);
3705 
3706 	/*
3707 	 * If the key is already in "raw" format, copy the data
3708 	 * to the new record if possible.
3709 	 */
3710 	if (symkey->israw) {
3711 		KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
3712 
3713 		if (rawkey == NULL)
3714 			return (KMF_ERR_BAD_KEYHANDLE);
3715 		if (rawkey->sensitive)
3716 			return (KMF_ERR_SENSITIVE_KEY);
3717 		if (rawkey->not_extractable)
3718 			return (KMF_ERR_UNEXTRACTABLE_KEY);
3719 
3720 		if (rawkey->rawdata.sym.keydata.val == NULL ||
3721 		    rawkey->rawdata.sym.keydata.len == 0)
3722 			return (KMF_ERR_GETKEYVALUE_FAILED);
3723 
3724 		rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
3725 		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
3726 			return (KMF_ERR_MEMORY);
3727 		(void) memcpy(rkey->keydata.val,
3728 		    rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
3729 	} else {
3730 		rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey);
3731 	}
3732 
3733 	return (rv);
3734 }
3735 
3736 KMF_RETURN
KMFPK11_SetTokenPin(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3737 KMFPK11_SetTokenPin(KMF_HANDLE_T handle,
3738 	int numattr, KMF_ATTRIBUTE *attrlist)
3739 {
3740 	KMF_RETURN	ret = KMF_OK;
3741 	CK_RV		rv = CKR_OK;
3742 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
3743 	CK_SESSION_HANDLE	session = 0;
3744 	KMF_CREDENTIAL	*oldcred;
3745 	KMF_CREDENTIAL	*newcred;
3746 	CK_SLOT_ID	slotid;
3747 	CK_USER_TYPE	user = CKU_USER;
3748 
3749 	if (handle == NULL || attrlist == NULL || numattr == 0)
3750 		return (KMF_ERR_BAD_PARAMETER);
3751 
3752 	oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3753 	if (oldcred == NULL)
3754 		return (KMF_ERR_BAD_PARAMETER);
3755 
3756 	newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr);
3757 	if (newcred == NULL)
3758 		return (KMF_ERR_BAD_PARAMETER);
3759 
3760 	rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr,
3761 	    (void *)&slotid, NULL);
3762 	if (rv != KMF_OK) {
3763 		char *tokenlabel = NULL;
3764 		/*
3765 		 * If a slot wasn't given, the user must pass
3766 		 * a token label so we can find the slot here.
3767 		 */
3768 		tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
3769 		    numattr);
3770 		if (tokenlabel == NULL)
3771 			return (KMF_ERR_BAD_PARAMETER);
3772 
3773 		rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid);
3774 		if (rv != KMF_OK)
3775 			return (rv);
3776 	}
3777 	rv = kmf_get_attr(KMF_PK11_USER_TYPE_ATTR, attrlist, numattr,
3778 	    (void *)&user, NULL);
3779 	if (rv != CKR_OK)
3780 		user = CKU_USER;
3781 
3782 	rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION,
3783 	    NULL, NULL, &session);
3784 	if (rv != CKR_OK) {
3785 		SET_ERROR(kmfh, rv);
3786 		ret = KMF_ERR_UNINITIALIZED;
3787 		goto end;
3788 	}
3789 
3790 	rv = C_Login(session, user, (CK_BYTE *)oldcred->cred,
3791 	    oldcred->credlen);
3792 	if (rv != CKR_OK) {
3793 		SET_ERROR(kmfh, rv);
3794 		if (rv == CKR_PIN_INCORRECT ||
3795 		    rv == CKR_PIN_INVALID ||
3796 		    rv == CKR_PIN_EXPIRED ||
3797 		    rv == CKR_PIN_LOCKED)
3798 			ret = KMF_ERR_AUTH_FAILED;
3799 		else
3800 			ret = KMF_ERR_INTERNAL;
3801 
3802 		goto end;
3803 	}
3804 
3805 	rv = C_SetPIN(session,
3806 	    (CK_BYTE *)oldcred->cred, oldcred->credlen,
3807 	    (CK_BYTE *)newcred->cred, newcred->credlen);
3808 
3809 	if (rv != CKR_OK) {
3810 		SET_ERROR(kmfh, rv);
3811 		if (rv == CKR_PIN_INCORRECT ||
3812 		    rv == CKR_PIN_INVALID ||
3813 		    rv == CKR_PIN_EXPIRED ||
3814 		    rv == CKR_PIN_LOCKED)
3815 			ret = KMF_ERR_AUTH_FAILED;
3816 		else
3817 			ret = KMF_ERR_INTERNAL;
3818 	}
3819 end:
3820 	if (session != 0)
3821 		(void) C_CloseSession(session);
3822 	return (ret);
3823 }
3824 
3825 static KMF_RETURN
create_generic_secret_key(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist,CK_OBJECT_HANDLE * key)3826 create_generic_secret_key(KMF_HANDLE_T handle,
3827 	int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key)
3828 {
3829 	KMF_RETURN		rv = KMF_OK;
3830 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
3831 	CK_RV			ckrv;
3832 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
3833 	CK_OBJECT_CLASS		class = CKO_SECRET_KEY;
3834 	CK_ULONG		secKeyType = CKK_GENERIC_SECRET;
3835 	CK_ULONG		secKeyLen;
3836 	CK_BBOOL		true = TRUE;
3837 	CK_BBOOL		false = FALSE;
3838 	CK_ATTRIBUTE		templ[15];
3839 	int			i;
3840 	int			random_fd = -1;
3841 	int			nread;
3842 	int			freebuf = 0;
3843 	char			*buf = NULL;
3844 	uint32_t		keylen = 0, attrkeylen = 0;
3845 	char			*keylabel = NULL;
3846 	KMF_CREDENTIAL		*cred;
3847 	uint32_t is_sensitive, is_not_extractable;
3848 
3849 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3850 	if (keylabel == NULL)
3851 		return (KMF_ERR_BAD_PARAMETER);
3852 
3853 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3854 	if (cred == NULL)
3855 		return (KMF_ERR_BAD_PARAMETER);
3856 
3857 	rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
3858 	    (void *)&is_sensitive, NULL);
3859 	if (rv != KMF_OK)
3860 		return (KMF_ERR_BAD_PARAMETER);
3861 
3862 	rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
3863 	    (void *)&is_not_extractable, NULL);
3864 	if (rv != KMF_OK)
3865 		return (KMF_ERR_BAD_PARAMETER);
3866 
3867 	rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
3868 	    NULL, &attrkeylen);
3869 	if (rv == KMF_OK && attrkeylen > 0) {
3870 		buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
3871 		    numattr);
3872 		secKeyLen = attrkeylen;
3873 	} else {
3874 		buf = NULL;
3875 		rv = KMF_OK;
3876 	}
3877 	if (buf == NULL) {
3878 		/*
3879 		 * If the key data was not given, key length must
3880 		 * be provided.
3881 		 */
3882 		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
3883 		    &keylen, NULL);
3884 		if (rv != KMF_OK)
3885 			return (KMF_ERR_BAD_PARAMETER);
3886 
3887 		/*
3888 		 * Check the key size.
3889 		 */
3890 		if ((keylen % 8) != 0) {
3891 			return (KMF_ERR_BAD_KEY_SIZE);
3892 		} else {
3893 			secKeyLen = keylen/8;  /* in bytes */
3894 		}
3895 
3896 		/*
3897 		 * Generate a random number with the key size first.
3898 		 */
3899 		buf = malloc(secKeyLen);
3900 		if (buf == NULL)
3901 			return (KMF_ERR_MEMORY);
3902 
3903 		freebuf = 1;
3904 		while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) {
3905 			if (errno != EINTR)
3906 				break;
3907 		}
3908 
3909 		if (random_fd < 0) {
3910 			rv = KMF_ERR_KEYGEN_FAILED;
3911 			goto out;
3912 		}
3913 
3914 		nread = read(random_fd, buf, secKeyLen);
3915 		if (nread <= 0 || nread != secKeyLen) {
3916 			rv = KMF_ERR_KEYGEN_FAILED;
3917 			goto out;
3918 		}
3919 	}
3920 
3921 	/*
3922 	 * Authenticate into the token and call C_CreateObject to generate
3923 	 * a generic secret token key.
3924 	 */
3925 	rv = pk11_authenticate(handle, cred);
3926 	if (rv != KMF_OK) {
3927 		goto out;
3928 	}
3929 
3930 	i = 0;
3931 	SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
3932 	i++;
3933 	SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
3934 	i++;
3935 	SETATTR(templ, i, CKA_VALUE, buf, secKeyLen);
3936 	i++;
3937 
3938 	if (keylabel != NULL) {
3939 		SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3940 		i++;
3941 	}
3942 
3943 	if (is_sensitive == B_TRUE) {
3944 		SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
3945 	} else {
3946 		SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
3947 	}
3948 	i++;
3949 
3950 	if (is_not_extractable == B_TRUE) {
3951 		SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
3952 	} else {
3953 		SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
3954 	}
3955 	i++;
3956 
3957 	SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
3958 	i++;
3959 	SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
3960 	i++;
3961 	SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
3962 	i++;
3963 
3964 	ckrv = C_CreateObject(hSession, templ, i, key);
3965 	if (ckrv != CKR_OK) {
3966 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3967 		    ckrv == CKR_PIN_INCORRECT ||
3968 		    ckrv == CKR_PIN_INVALID ||
3969 		    ckrv == CKR_PIN_EXPIRED ||
3970 		    ckrv == CKR_PIN_LOCKED ||
3971 		    ckrv == CKR_SESSION_READ_ONLY)
3972 			rv = KMF_ERR_AUTH_FAILED;
3973 		else
3974 			rv = KMF_ERR_KEYGEN_FAILED;
3975 		SET_ERROR(kmfh, ckrv);
3976 	}
3977 
3978 out:
3979 	if (buf != NULL && freebuf)
3980 		free(buf);
3981 
3982 	if (random_fd != -1)
3983 		(void) close(random_fd);
3984 
3985 	return (rv);
3986 }
3987 
3988 KMF_RETURN
KMFPK11_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)3989 KMFPK11_StoreKey(KMF_HANDLE_T handle,
3990 	int numattr,
3991 	KMF_ATTRIBUTE *attlist)
3992 {
3993 	KMF_RETURN rv = KMF_OK;
3994 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3995 	KMF_CREDENTIAL cred = { NULL, 0 };
3996 	KMF_KEY_HANDLE *key;
3997 	KMF_RAW_KEY_DATA *rawkey = NULL;
3998 	CK_BBOOL btrue = TRUE;
3999 	CK_ATTRIBUTE tokenattr[1];
4000 	CK_OBJECT_HANDLE newobj;
4001 	CK_RV ckrv;
4002 
4003 	if (kmfh == NULL)
4004 		return (KMF_ERR_UNINITIALIZED);
4005 
4006 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
4007 		return (KMF_ERR_NO_TOKEN_SELECTED);
4008 
4009 	rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr,
4010 	    (void *)&cred, NULL);
4011 	if (rv != KMF_OK)
4012 		return (KMF_ERR_BAD_PARAMETER);
4013 
4014 	rv = pk11_authenticate(handle, &cred);
4015 	if (rv != KMF_OK)
4016 		return (rv);
4017 
4018 	key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
4019 	if (key == NULL) {
4020 		key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist,
4021 		    numattr);
4022 		if (key == NULL)
4023 			rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist,
4024 			    numattr);
4025 	}
4026 	if (key == NULL && rawkey == NULL)
4027 		return (KMF_ERR_ATTR_NOT_FOUND);
4028 
4029 	if (rawkey != NULL) {
4030 		rv = store_raw_key(handle, attlist, numattr, rawkey);
4031 	} else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) {
4032 
4033 		SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue));
4034 		/* Copy the key object to the token */
4035 		ckrv = C_CopyObject(kmfh->pk11handle,
4036 		    (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj);
4037 		if (ckrv != CKR_OK)  {
4038 			SET_ERROR(kmfh, ckrv);
4039 			return (KMF_ERR_INTERNAL);
4040 		}
4041 
4042 		/* Replace the object handle with the new token-based one */
4043 		ckrv = C_DestroyObject(kmfh->pk11handle,
4044 		    (CK_OBJECT_HANDLE)key->keyp);
4045 		if (ckrv != CKR_OK)  {
4046 			SET_ERROR(kmfh, ckrv);
4047 			return (KMF_ERR_INTERNAL);
4048 		}
4049 		key->keyp = (void *)newobj;
4050 	} else {
4051 		rv = KMF_ERR_BAD_PARAMETER;
4052 	}
4053 
4054 	return (rv);
4055 }
4056 
4057 
4058 KMF_RETURN
KMFPK11_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)4059 KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4060 {
4061 	KMF_RETURN rv = KMF_OK;
4062 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4063 	KMF_CREDENTIAL *cred = NULL;
4064 	KMF_CREDENTIAL *p12cred = NULL;
4065 	char *filename = NULL;
4066 	KMF_X509_DER_CERT *certlist = NULL;
4067 	KMF_KEY_HANDLE *keylist = NULL;
4068 	uint32_t numcerts;
4069 	uint32_t numkeys;
4070 	char *certlabel = NULL;
4071 	char *issuer = NULL;
4072 	char *subject = NULL;
4073 	KMF_BIGINT *serial = NULL;
4074 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
4075 	KMF_ATTRIBUTE fc_attrlist[16];
4076 	int i;
4077 
4078 	if (kmfh == NULL)
4079 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
4080 
4081 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
4082 		return (KMF_ERR_NO_TOKEN_SELECTED);
4083 
4084 	/* First get the required attributes */
4085 	cred =  kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
4086 	if (cred == NULL)
4087 		return (KMF_ERR_BAD_PARAMETER);
4088 
4089 	p12cred =  kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
4090 	if (p12cred == NULL)
4091 		return (KMF_ERR_BAD_PARAMETER);
4092 
4093 	filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
4094 	    numattr);
4095 	if (filename == NULL)
4096 		return (KMF_ERR_BAD_PARAMETER);
4097 
4098 	/* Find all the certificates that match the searching criteria */
4099 	i = 0;
4100 	kmf_set_attr_at_index(fc_attrlist, i,
4101 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4102 	i++;
4103 
4104 	kmf_set_attr_at_index(fc_attrlist, i,
4105 	    KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
4106 	i++;
4107 
4108 	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
4109 	if (certlabel != NULL) {
4110 		kmf_set_attr_at_index(fc_attrlist, i,
4111 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
4112 		i++;
4113 	}
4114 
4115 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
4116 	if (issuer != NULL) {
4117 		kmf_set_attr_at_index(fc_attrlist, i,
4118 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
4119 		i++;
4120 	}
4121 
4122 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
4123 	if (subject != NULL) {
4124 		kmf_set_attr_at_index(fc_attrlist, i,
4125 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
4126 		i++;
4127 	}
4128 
4129 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
4130 	if (serial != NULL) {
4131 		kmf_set_attr_at_index(fc_attrlist, i,
4132 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
4133 		i++;
4134 	}
4135 
4136 	rv = KMFPK11_FindCert(handle, i, fc_attrlist);
4137 
4138 	if (rv == KMF_OK && numcerts > 0) {
4139 		certlist = (KMF_X509_DER_CERT *)malloc(numcerts *
4140 		    sizeof (KMF_X509_DER_CERT));
4141 		if (certlist == NULL)
4142 			return (KMF_ERR_MEMORY);
4143 
4144 		(void) memset(certlist, 0, numcerts *
4145 		    sizeof (KMF_X509_DER_CERT));
4146 
4147 		kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR,
4148 		    certlist, sizeof (KMF_X509_DER_CERT));
4149 		i++;
4150 
4151 		rv = kmf_find_cert(handle, i, fc_attrlist);
4152 		if (rv != KMF_OK) {
4153 			free(certlist);
4154 			return (rv);
4155 		}
4156 	} else {
4157 		return (rv);
4158 	}
4159 
4160 	/* For each certificate, find the matching private key */
4161 	numkeys = 0;
4162 	for (i = 0; i < numcerts; i++) {
4163 		KMF_ATTRIBUTE fk_attrlist[16];
4164 		int j = 0;
4165 		KMF_KEY_HANDLE newkey;
4166 		KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY;
4167 
4168 		kmf_set_attr_at_index(fk_attrlist, j,
4169 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4170 		j++;
4171 
4172 		kmf_set_attr_at_index(fk_attrlist, j,
4173 		    KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format));
4174 		j++;
4175 
4176 		kmf_set_attr_at_index(fk_attrlist, j,
4177 		    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
4178 		j++;
4179 
4180 		kmf_set_attr_at_index(fk_attrlist, j,
4181 		    KMF_CERT_DATA_ATTR, &certlist[i].certificate,
4182 		    sizeof (KMF_DATA));
4183 		j++;
4184 
4185 		kmf_set_attr_at_index(fk_attrlist, j,
4186 		    KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE));
4187 		j++;
4188 
4189 		rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist);
4190 		if (rv == KMF_OK) {
4191 			numkeys++;
4192 			keylist = realloc(keylist,
4193 			    numkeys * sizeof (KMF_KEY_HANDLE));
4194 			if (keylist == NULL) {
4195 				rv = KMF_ERR_MEMORY;
4196 				goto out;
4197 			}
4198 			keylist[numkeys - 1] = newkey;
4199 		} else if (rv == KMF_ERR_KEY_NOT_FOUND) {
4200 			/* it is OK if a key is not found */
4201 			rv = KMF_OK;
4202 		}
4203 	}
4204 
4205 	if (rv != KMF_OK)
4206 		goto out;
4207 
4208 	rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist,
4209 	    p12cred, filename);
4210 
4211 out:
4212 	if (certlist != NULL) {
4213 		for (i = 0; i < numcerts; i++)
4214 			kmf_free_kmf_cert(handle, &certlist[i]);
4215 		free(certlist);
4216 	}
4217 	if (keylist != NULL) {
4218 		for (i = 0; i < numkeys; i++)
4219 			kmf_free_kmf_key(handle, &keylist[i]);
4220 		free(keylist);
4221 	}
4222 
4223 	return (rv);
4224 }
4225