xref: /titanic_51/usr/src/lib/libkmf/libkmf/common/certop.c (revision 6b35cb3cf158584a9408d44b9b6796564e8e1882)
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  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
22  */
23 
24 #include <stdio.h>
25 #include <link.h>
26 #include <fcntl.h>
27 #include <ctype.h>
28 #include <sys/param.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/socket.h>
32 #include <ber_der.h>
33 #include <kmfapiP.h>
34 #include <pem_encode.h>
35 #include <libgen.h>
36 #include <cryptoutil.h>
37 
38 #define	CERTFILE_TEMPNAME	"/tmp/user.certXXXXXX"
39 #define	CRLFILE_TEMPNAME	"/tmp/crlXXXXXX"
40 #define	X509_FORMAT_VERSION 2
41 
42 static KMF_RETURN
43 sign_cert(KMF_HANDLE_T, const KMF_DATA *, KMF_KEY_HANDLE *,
44     KMF_OID *, KMF_DATA *);
45 
46 static KMF_RETURN
47 verify_cert_with_key(KMF_HANDLE_T, KMF_DATA *, const KMF_DATA *);
48 
49 static KMF_RETURN
50 verify_cert_with_cert(KMF_HANDLE_T, const KMF_DATA *, const KMF_DATA *);
51 
52 static KMF_RETURN
53 get_keyalg_from_cert(KMF_DATA *cert, KMF_KEY_ALG *keyalg)
54 {
55 	KMF_RETURN rv;
56 	KMF_X509_CERTIFICATE *SignerCert = NULL;
57 	KMF_ALGORITHM_INDEX AlgorithmId;
58 
59 	rv = DerDecodeSignedCertificate(cert, &SignerCert);
60 
61 	if (rv != KMF_OK)
62 		return (rv);
63 
64 	/* Get the algorithm info from the signer certificate */
65 	AlgorithmId = x509_algoid_to_algid(
66 	    &SignerCert->signature.algorithmIdentifier.algorithm);
67 
68 	switch (AlgorithmId) {
69 		case KMF_ALGID_MD5WithRSA:
70 		case KMF_ALGID_SHA1WithRSA:
71 		case KMF_ALGID_SHA256WithRSA:
72 		case KMF_ALGID_SHA384WithRSA:
73 		case KMF_ALGID_SHA512WithRSA:
74 			*keyalg = KMF_RSA;
75 			break;
76 		case KMF_ALGID_SHA1WithDSA:
77 		case KMF_ALGID_SHA256WithDSA:
78 			*keyalg = KMF_DSA;
79 			break;
80 		case KMF_ALGID_SHA1WithECDSA:
81 		case KMF_ALGID_SHA256WithECDSA:
82 		case KMF_ALGID_SHA384WithECDSA:
83 		case KMF_ALGID_SHA512WithECDSA:
84 		case KMF_ALGID_ECDSA:
85 			*keyalg = KMF_ECDSA;
86 			break;
87 		default:
88 			rv = KMF_ERR_BAD_ALGORITHM;
89 	}
90 
91 	kmf_free_signed_cert(SignerCert);
92 	free(SignerCert);
93 	return (rv);
94 }
95 
96 /*
97  * Name: kmf_find_prikey_by_cert
98  *
99  * Description:
100  *   This function finds the corresponding private key in keystore
101  *   for a certificate
102  */
103 KMF_RETURN
104 kmf_find_prikey_by_cert(KMF_HANDLE_T handle, int numattr,
105     KMF_ATTRIBUTE *attrlist)
106 {
107 	KMF_PLUGIN *plugin;
108 	KMF_RETURN ret = KMF_OK;
109 	KMF_KEYSTORE_TYPE kstype;
110 	KMF_KEY_ALG keyalg;
111 	KMF_KEY_HANDLE *key = NULL;
112 	KMF_DATA *cert = NULL;
113 
114 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
115 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
116 	    {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
117 	    {KMF_KEY_HANDLE_ATTR, TRUE, sizeof (KMF_KEY_HANDLE),
118 	    sizeof (KMF_KEY_HANDLE)}
119 	};
120 
121 	int num_req_attrs = sizeof (required_attrs) /
122 	    sizeof (KMF_ATTRIBUTE_TESTER);
123 
124 	if (handle == NULL)
125 		return (KMF_ERR_BAD_PARAMETER);
126 
127 	CLEAR_ERROR(handle, ret);
128 
129 	ret = test_attributes(num_req_attrs, required_attrs,
130 	    0, NULL, numattr, attrlist);
131 	if (ret != KMF_OK)
132 		return (ret);
133 
134 	/*
135 	 * First, get the key algorithm info from the certificate and saves it
136 	 * in the returned key handle.
137 	 */
138 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
139 	if (cert == NULL)
140 		return (KMF_ERR_BAD_PARAMETER);
141 
142 	ret = get_keyalg_from_cert(cert, &keyalg);
143 	if (ret != KMF_OK)
144 		return (ret);
145 
146 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
147 	if (key == NULL)
148 		return (KMF_ERR_BAD_PARAMETER);
149 	key->keyalg = keyalg;
150 
151 	/* Call the plugin to do the work. */
152 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
153 	    &kstype, NULL);
154 	if (ret != KMF_OK)
155 		return (ret);
156 
157 	plugin = FindPlugin(handle, kstype);
158 	if (plugin == NULL || plugin->funclist->FindPrikeyByCert == NULL)
159 		return (KMF_ERR_PLUGIN_NOTFOUND);
160 
161 	return (plugin->funclist->FindPrikeyByCert(handle, numattr, attrlist));
162 }
163 
164 
165 KMF_RETURN
166 check_key_usage(void *handle,
167 	const KMF_DATA *cert,
168 	const KMF_KU_PURPOSE purpose)
169 {
170 	KMF_X509EXT_BASICCONSTRAINTS constraint;
171 	KMF_BOOL	critical = B_FALSE;
172 	KMF_X509EXT_KEY_USAGE keyusage;
173 	KMF_RETURN ret = KMF_OK;
174 
175 	if (handle == NULL || cert == NULL)
176 		return (KMF_ERR_BAD_PARAMETER);
177 
178 	(void) memset(&constraint, 0, sizeof (KMF_X509EXT_BASICCONSTRAINTS));
179 	(void) memset(&keyusage, 0, sizeof (KMF_X509EXT_KEY_USAGE));
180 
181 	ret = kmf_get_cert_ku(cert, &keyusage);
182 	if (ret != KMF_OK)
183 		/*
184 		 * If absent or error, the cert is assumed to be invalid
185 		 * for all key usage checking.
186 		 */
187 		return (ret);
188 
189 	switch (purpose) {
190 	case KMF_KU_SIGN_CERT:
191 		/*
192 		 * RFC 3280:
193 		 * The keyCertSign bit is asserted when the subject
194 		 * public key is used for verifying a signature on
195 		 * public key certificates.  If the keyCertSign bit
196 		 * is asserted, then the cA bit in the basic constraints
197 		 * extension (section 4.2.1.10) MUST also be asserted.
198 		 * The basic constraints extension MUST appear as a
199 		 * critical extension in all CA certificates that
200 		 * contain public keys used to validate digital
201 		 * signatures on certificates.
202 		 */
203 		if (keyusage.KeyUsageBits & KMF_keyCertSign) {
204 			ret = kmf_get_cert_basic_constraint(cert,
205 			    &critical, &constraint);
206 
207 			if (ret != KMF_OK)
208 				return (ret);
209 
210 			if ((!critical) || (!constraint.cA))
211 				return (KMF_ERR_KEYUSAGE);
212 		} else {
213 			return (KMF_ERR_KEYUSAGE);
214 		}
215 		break;
216 	case KMF_KU_SIGN_DATA:
217 		/*
218 		 * RFC 3280:
219 		 * The digitalSignature bit is asserted when the subject
220 		 * public key is used with a digital signature mechanism
221 		 * to support security services other than certificate
222 		 * signing(bit 5), or CRL signing(bit 6).
223 		 */
224 		if (!(keyusage.KeyUsageBits & KMF_digitalSignature))
225 			return (KMF_ERR_KEYUSAGE);
226 		break;
227 	case KMF_KU_ENCRYPT_DATA:
228 		/*
229 		 * RFC 3280:
230 		 * The dataEncipherment bit is asserted when the subject
231 		 * public key is used for enciphering user data, other than
232 		 * cryptographic keys.
233 		 */
234 		if (!(keyusage.KeyUsageBits & KMF_dataEncipherment))
235 			return (KMF_ERR_KEYUSAGE);
236 		break;
237 	default:
238 		return (KMF_ERR_BAD_PARAMETER);
239 	}
240 
241 	return (KMF_OK);
242 }
243 
244 KMF_RETURN
245 kmf_find_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
246 {
247 	KMF_PLUGIN *plugin;
248 	KMF_RETURN ret = KMF_OK;
249 	KMF_KEYSTORE_TYPE kstype;
250 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
251 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
252 	    {KMF_COUNT_ATTR, FALSE, sizeof (uint32_t), sizeof (uint32_t)}
253 	};
254 	int num_req_attrs = sizeof (required_attrs) /
255 	    sizeof (KMF_ATTRIBUTE_TESTER);
256 
257 	if (handle == NULL)
258 		return (KMF_ERR_BAD_PARAMETER);
259 
260 	CLEAR_ERROR(handle, ret);
261 
262 	ret = test_attributes(num_req_attrs, required_attrs,
263 	    0, NULL, numattr, attrlist);
264 	if (ret != KMF_OK)
265 		return (ret);
266 
267 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
268 	    &kstype, NULL);
269 	if (ret != KMF_OK)
270 		return (ret);
271 
272 	plugin = FindPlugin(handle, kstype);
273 	if (plugin == NULL || plugin->funclist->FindCert == NULL)
274 		return (KMF_ERR_PLUGIN_NOTFOUND);
275 
276 	return (plugin->funclist->FindCert(handle, numattr, attrlist));
277 }
278 
279 #define	NODATA(d) (d.Data == NULL || d.Length == NULL)
280 
281 KMF_RETURN
282 kmf_encode_cert_record(KMF_X509_CERTIFICATE *CertData, KMF_DATA *encodedCert)
283 {
284 	KMF_RETURN ret;
285 	KMF_X509_TBS_CERT *tbs_cert;
286 
287 	if (CertData == NULL || encodedCert == NULL)
288 		return (KMF_ERR_BAD_PARAMETER);
289 
290 	/*
291 	 * Validate that all required fields are present.
292 	 */
293 	tbs_cert = &(CertData->certificate);
294 	if (NODATA(tbs_cert->version) ||
295 	    NODATA(tbs_cert->signature.algorithm) ||
296 	    NODATA(tbs_cert->subjectPublicKeyInfo.subjectPublicKey) ||
297 	    tbs_cert->serialNumber.val == NULL ||
298 	    tbs_cert->serialNumber.len == 0 ||
299 	    tbs_cert->subject.numberOfRDNs == 0 ||
300 	    tbs_cert->issuer.numberOfRDNs == 0) {
301 		return (KMF_ERR_INCOMPLETE_TBS_CERT);
302 	}
303 
304 	encodedCert->Length = 0;
305 	encodedCert->Data = NULL;
306 
307 	/* Pack the new certificate */
308 	ret = DerEncodeSignedCertificate(CertData, encodedCert);
309 
310 	return (ret);
311 }
312 
313 /*
314  * This function is used to setup the attribute list before calling
315  * kmf_find_prikey_by_cert().  This function is used by
316  *	kmf_decrypt_with_cert
317  *	kmf_sign_cert
318  *	kmf_sign_data
319  *
320  * The attribute list in these callers contain all the attributes
321  * needed by kmf_find_prikey_by_cert(), except the
322  * KMF_KEY_HANDLE attribute and the KMF_CERT_DATA_ATTR attribute.
323  * These 2 attributes need to be added or reset.
324  *
325  * The caller should free the new_attrlist after use it.
326  */
327 static KMF_RETURN
328 setup_findprikey_attrlist(KMF_ATTRIBUTE *src_attrlist, int src_num,
329     KMF_ATTRIBUTE **new_attrlist, int *new_num, KMF_KEY_HANDLE *key,
330     KMF_DATA *cert)
331 {
332 	KMF_ATTRIBUTE *attrlist = NULL;
333 	int cur_num = src_num;
334 	int index;
335 	int i;
336 
337 	if (src_attrlist == NULL || new_num == NULL || key == NULL ||
338 	    cert == NULL)
339 		return (KMF_ERR_BAD_PARAMETER);
340 
341 	/* Create a new attribute list with 2 more elements */
342 	attrlist = (KMF_ATTRIBUTE *) malloc(
343 	    (src_num + 2) * sizeof (KMF_ATTRIBUTE));
344 	if (attrlist == NULL)
345 		return (KMF_ERR_MEMORY);
346 
347 	/* Copy the src_attrlist to the new list */
348 	for (i = 0; i < src_num; i++) {
349 		attrlist[i].type = src_attrlist[i].type;
350 		attrlist[i].pValue = src_attrlist[i].pValue;
351 		attrlist[i].valueLen = src_attrlist[i].valueLen;
352 	}
353 
354 	/* Add or reset the key handle attribute */
355 	index = kmf_find_attr(KMF_KEY_HANDLE_ATTR, attrlist, cur_num);
356 	if (index == -1) {
357 		/* not found; add it */
358 		kmf_set_attr_at_index(attrlist, cur_num,
359 		    KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
360 		cur_num++;
361 	} else {
362 		/* found; just reset it */
363 		kmf_set_attr_at_index(attrlist, index,
364 		    KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
365 	}
366 
367 	/* add or reset the cert data attribute */
368 	index = kmf_find_attr(KMF_CERT_DATA_ATTR, attrlist, cur_num);
369 	if (index == -1) {
370 		/* not found; add it */
371 		kmf_set_attr_at_index(attrlist, cur_num,
372 		    KMF_CERT_DATA_ATTR, cert, sizeof (KMF_DATA));
373 		cur_num++;
374 	} else {
375 		/* found; just reset it */
376 		kmf_set_attr_at_index(attrlist, index,
377 		    KMF_CERT_DATA_ATTR, cert, sizeof (KMF_DATA));
378 	}
379 
380 	*new_attrlist = attrlist;
381 	*new_num = cur_num;
382 	return (KMF_OK);
383 }
384 
385 /*
386  * Determine a default signature type to use based on
387  * the key algorithm.
388  */
389 static KMF_OID *
390 get_default_signoid(KMF_KEY_HANDLE *key)
391 {
392 	KMF_OID *oid;
393 
394 	switch (key->keyalg) {
395 		case KMF_RSA:
396 			oid = (KMF_OID *)&KMFOID_SHA256WithRSA;
397 			break;
398 		case KMF_DSA:
399 			/* NSS doesnt support DSA-SHA2 hashes yet */
400 			if (key->kstype == KMF_KEYSTORE_NSS)
401 				oid = (KMF_OID *)&KMFOID_X9CM_DSAWithSHA1;
402 			else
403 				oid = (KMF_OID *)&KMFOID_SHA256WithDSA;
404 			break;
405 		case KMF_ECDSA:
406 			oid = (KMF_OID *)&KMFOID_SHA256WithECDSA;
407 			break;
408 		default:
409 			oid = NULL;
410 			break;
411 	}
412 	return (oid);
413 }
414 
415 /*
416  * This is to check to see if a certificate being signed has
417  * the keyCertSign KeyUsage bit set, and if so, make sure the
418  * "BasicConstraints" extension is also set accordingly.
419  */
420 static KMF_RETURN
421 check_for_basic_constraint(KMF_DATA *cert)
422 {
423 	KMF_RETURN rv = KMF_OK;
424 	KMF_X509EXT_KEY_USAGE  keyUsage;
425 	KMF_X509_CERTIFICATE *x509cert = NULL;
426 
427 	rv = kmf_get_cert_ku((const KMF_DATA *)cert, &keyUsage);
428 	if (rv == KMF_OK) {
429 		KMF_X509EXT_BASICCONSTRAINTS basicConstraint;
430 		KMF_BOOL critical;
431 		/* If keyCertSign is set, look for basicConstraints */
432 		if (keyUsage.KeyUsageBits & KMF_keyCertSign)
433 			rv = kmf_get_cert_basic_constraint(
434 			    (const KMF_DATA *)cert,
435 			    &critical, &basicConstraint);
436 
437 		/*
438 		 * If we got KMF_OK (or an error), then return
439 		 * because the extension is already present.  We
440 		 * only want to continue with this function if
441 		 * the extension is NOT found.
442 		 */
443 		if (rv != KMF_ERR_EXTENSION_NOT_FOUND)
444 			return (rv);
445 
446 		/*
447 		 * Don't limit the pathLen (for now).
448 		 * This should probably be a policy setting in the
449 		 * future.
450 		 */
451 		basicConstraint.cA = TRUE;
452 		basicConstraint.pathLenConstraintPresent = FALSE;
453 
454 		/*
455 		 * Decode the DER cert data into the internal
456 		 * X.509 structure we need to set extensions.
457 		 */
458 		rv = DerDecodeSignedCertificate(cert, &x509cert);
459 		if (rv != KMF_OK)
460 			return (rv);
461 		/*
462 		 * Add the missing basic constraint.
463 		 */
464 		rv = kmf_set_cert_basic_constraint(x509cert,
465 		    TRUE, &basicConstraint);
466 		if (rv != KMF_OK) {
467 			kmf_free_signed_cert(x509cert);
468 			free(x509cert);
469 			return (rv);
470 		}
471 		/* Free the old cert data record */
472 		kmf_free_data(cert);
473 
474 		/* Re-encode the cert with the extension */
475 		rv = kmf_encode_cert_record(x509cert, cert);
476 
477 		/* cleanup */
478 		kmf_free_signed_cert(x509cert);
479 		free(x509cert);
480 	}
481 	if (rv == KMF_ERR_EXTENSION_NOT_FOUND)
482 		rv = KMF_OK;
483 
484 	return (rv);
485 }
486 
487 /*
488  * Name: kmf_sign_cert
489  *
490  * Description:
491  *   This function signs a certificate using the signer cert and
492  *   returns a signed and DER-encoded certificate.
493  *
494  * The following types of certificate data can be submitted to be signed:
495  *	KMF_TBS_CERT_DATA_ATTR - a KMF_DATA ptr is provided in the attrlist
496  *		and is signed directly.
497  *	KMF_X509_CERTIFICATE_ATTR - a KMF_X509_CERTIFICATE record is provided
498  *		in the attribute list.  This is converted to raw KMF_DATA
499  *		prior to signing.
500  *
501  * The key for the signing operation can be provided as a KMF_KEY_HANDLE_ATTR
502  * or the caller may choose to provide a KMF_SIGNER_CERT_ATTR (KMF_DATA *).
503  * If the latter, this function will then attempt to find the private key
504  * associated with the certificate.  The private key must be stored in
505  * the same keystore as the signer certificate.
506  */
507 KMF_RETURN
508 kmf_sign_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
509 {
510 	KMF_RETURN ret;
511 	int new_numattr = numattr + 1;
512 	KMF_ATTRIBUTE *new_attrlist = NULL;
513 	KMF_DATA *signer_cert = NULL;
514 	KMF_DATA *tbs_cert = NULL;  /* to be signed cert */
515 	KMF_DATA *signed_cert = NULL;
516 	KMF_DATA unsignedCert = { 0, NULL };
517 	KMF_KEY_HANDLE sign_key, *sign_key_ptr;
518 	int freethekey = 0;
519 	KMF_POLICY_RECORD *policy;
520 	KMF_OID *oid = NULL;
521 	KMF_X509_CERTIFICATE *x509cert;
522 	KMF_X509_TBS_CERT *decodedTbsCert = NULL;
523 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
524 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
525 	    {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
526 	};
527 	int num_req_attrs = sizeof (required_attrs) /
528 	    sizeof (KMF_ATTRIBUTE_TESTER);
529 
530 	if (handle == NULL)
531 		return (KMF_ERR_BAD_PARAMETER);
532 
533 	CLEAR_ERROR(handle, ret);
534 
535 	ret = test_attributes(num_req_attrs, required_attrs,
536 	    0, NULL, numattr, attrlist);
537 	if (ret != KMF_OK)
538 		return (ret);
539 
540 	/* Get the signer cert and check its keyUsage */
541 	signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
542 	    numattr);
543 	sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist,
544 	    numattr);
545 	/*
546 	 * Only accept 1 or the other, not both.
547 	 */
548 	if (signer_cert == NULL && sign_key_ptr == NULL)
549 		return (KMF_ERR_BAD_PARAMETER);
550 	if (signer_cert != NULL && sign_key_ptr != NULL)
551 		return (KMF_ERR_BAD_PARAMETER);
552 
553 	oid = kmf_get_attr_ptr(KMF_OID_ATTR, attrlist, numattr);
554 	if (oid == NULL) {
555 		/*
556 		 * If the signature OID was not given, check
557 		 * for an algorithm index identifier instead.
558 		 */
559 		KMF_ALGORITHM_INDEX AlgId;
560 		ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, numattr,
561 		    &AlgId, NULL);
562 		if (ret == KMF_OK)
563 			oid = x509_algid_to_algoid(AlgId);
564 	}
565 
566 	if (signer_cert != NULL) {
567 		policy = handle->policy;
568 		ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_CERT);
569 		if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
570 			ret = KMF_OK;
571 		if (ret != KMF_OK)
572 			return (ret);
573 
574 		/*
575 		 * Find the private key from the signer certificate by calling
576 		 * kmf_find_prikey_by_cert().
577 		 */
578 		ret = setup_findprikey_attrlist(attrlist, numattr,
579 		    &new_attrlist, &new_numattr, &sign_key, signer_cert);
580 		if (ret != KMF_OK)
581 			goto out;
582 
583 		ret = kmf_find_prikey_by_cert(handle, new_numattr,
584 		    new_attrlist);
585 		if (ret != KMF_OK) {
586 			goto out;
587 		}
588 		sign_key_ptr = &sign_key;
589 		freethekey = 1;
590 	}
591 
592 	tbs_cert = kmf_get_attr_ptr(KMF_TBS_CERT_DATA_ATTR, attrlist,
593 	    numattr);
594 	if (tbs_cert == NULL) {
595 		x509cert = kmf_get_attr_ptr(KMF_X509_CERTIFICATE_ATTR, attrlist,
596 		    numattr);
597 		if (x509cert == NULL) {
598 			ret = KMF_ERR_BAD_PARAMETER;
599 			goto out;
600 		}
601 
602 		ret = kmf_encode_cert_record(x509cert, &unsignedCert);
603 		if (ret != KMF_OK)
604 			goto out;
605 
606 		tbs_cert = &unsignedCert;
607 	}
608 	/*
609 	 * Check for the keyCertSign bit in the KeyUsage extn.  If it is set,
610 	 * then the basicConstraints must also be present and be
611 	 * marked critical.
612 	 */
613 	ret = check_for_basic_constraint(tbs_cert);
614 	if (ret)
615 		goto out;
616 
617 	if (oid == NULL) {
618 		/*
619 		 * If OID is not known yet, use a default value
620 		 * based on the signers key type.
621 		 */
622 		oid = get_default_signoid(sign_key_ptr);
623 	}
624 
625 	signed_cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
626 	    numattr);
627 	if (signed_cert == NULL) {
628 		ret = KMF_ERR_BAD_PARAMETER;
629 		goto out;
630 	}
631 
632 	ret = sign_cert(handle, tbs_cert, sign_key_ptr, oid, signed_cert);
633 out:
634 	if (new_attrlist)
635 		(void) free(new_attrlist);
636 
637 	/* If we had to find the key, free it here. */
638 	if (freethekey)
639 		kmf_free_kmf_key(handle, &sign_key);
640 
641 	kmf_free_data(&unsignedCert);
642 	if (decodedTbsCert != NULL) {
643 		kmf_free_tbs_cert(decodedTbsCert);
644 		free(decodedTbsCert);
645 	}
646 	return (ret);
647 }
648 
649 /*
650  * Name: kmf_sign_data
651  *
652  * Description:
653  *   This function signs a block of data using the signer cert and
654  *   returns the the signature in output
655  */
656 KMF_RETURN
657 kmf_sign_data(KMF_HANDLE_T handle, int numattr,
658     KMF_ATTRIBUTE *attrlist)
659 {
660 	KMF_PLUGIN *plugin;
661 	KMF_RETURN ret = KMF_OK;
662 	KMF_ATTRIBUTE *new_attrlist = NULL;
663 	int new_numattr = numattr;
664 	KMF_DATA *signer_cert = NULL;
665 	KMF_DATA *tbs_data = NULL;  /* to be signed data */
666 	KMF_DATA *output = NULL;
667 	KMF_KEY_HANDLE sign_key, *sign_key_ptr;
668 	KMF_ALGORITHM_INDEX AlgId = KMF_ALGID_NONE;
669 	KMF_DATA	signature = { 0, NULL };
670 	KMF_OID *oid;
671 	KMF_POLICY_RECORD *policy;
672 
673 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
674 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
675 	    {KMF_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
676 	    {KMF_OUT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
677 	};
678 	int num_req_attrs = sizeof (required_attrs) /
679 	    sizeof (KMF_ATTRIBUTE_TESTER);
680 
681 	if (handle == NULL)
682 		return (KMF_ERR_BAD_PARAMETER);
683 
684 	CLEAR_ERROR(handle, ret);
685 
686 	ret = test_attributes(num_req_attrs, required_attrs,
687 	    0, NULL, numattr, attrlist);
688 	if (ret != KMF_OK)
689 		return (ret);
690 
691 	/* Get the signer cert and check its keyUsage. */
692 	signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
693 	    numattr);
694 	sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist,
695 	    numattr);
696 
697 	if (signer_cert == NULL && sign_key_ptr == NULL)
698 		return (KMF_ERR_BAD_PARAMETER);
699 
700 	/*
701 	 * If a signer cert was given, use it to find the private key
702 	 * to use for signing the data.
703 	 */
704 	if (signer_cert != NULL) {
705 		ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA);
706 
707 		/*
708 		 * Signing generic data does not require the
709 		 * KeyUsage extension.
710 		 */
711 		policy = handle->policy;
712 		if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
713 			ret = KMF_OK;
714 		if (ret != KMF_OK)
715 			return (ret);
716 
717 		/*
718 		 * Find the private key from the signer certificate.
719 		 */
720 		ret = setup_findprikey_attrlist(attrlist, numattr,
721 		    &new_attrlist, &new_numattr, &sign_key, signer_cert);
722 		if (ret != KMF_OK) {
723 			goto cleanup;
724 		}
725 
726 		ret = kmf_find_prikey_by_cert(handle, new_numattr,
727 		    new_attrlist);
728 		if (ret != KMF_OK) {
729 			goto cleanup;
730 		}
731 		sign_key_ptr = &sign_key;
732 	}
733 
734 	/* Get the tbs_data and signed_data attributes now */
735 	tbs_data = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, numattr);
736 	if (tbs_data == NULL) {
737 		ret = KMF_ERR_BAD_PARAMETER;
738 		goto cleanup;
739 	}
740 
741 	output = kmf_get_attr_ptr(KMF_OUT_DATA_ATTR, attrlist, numattr);
742 	if (output == NULL) {
743 		ret = KMF_ERR_BAD_PARAMETER;
744 		goto cleanup;
745 	}
746 
747 	/*
748 	 * Get the algorithm index attribute and its oid. If this attribute
749 	 * is not provided, then we use a default value.
750 	 */
751 	oid = kmf_get_attr_ptr(KMF_OID_ATTR, attrlist, numattr);
752 	if (oid == NULL) {
753 		ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist,
754 		    numattr, &AlgId, NULL);
755 		/* If there was no Algorithm ID, use default based on key */
756 		if (ret != KMF_OK)
757 			oid = get_default_signoid(sign_key_ptr);
758 		else
759 			oid = x509_algid_to_algoid(AlgId);
760 	}
761 	if (sign_key_ptr->keyp == NULL) {
762 		ret = KMF_ERR_BAD_PARAMETER;
763 		goto cleanup;
764 	}
765 
766 	/* Now call the plugin function to sign it */
767 	plugin = FindPlugin(handle, sign_key_ptr->kstype);
768 	if (plugin == NULL || plugin->funclist->SignData == NULL) {
769 		ret = KMF_ERR_PLUGIN_NOTFOUND;
770 		goto cleanup;
771 	}
772 
773 	ret = plugin->funclist->SignData(handle, sign_key_ptr, oid, tbs_data,
774 	    output);
775 	if (ret != KMF_OK)
776 		goto cleanup;
777 
778 	/*
779 	 * For DSA, NSS returns an encoded signature. Decode the
780 	 * signature and expect a 40-byte DSA signature.
781 	 */
782 	if (plugin->type == KMF_KEYSTORE_NSS &&
783 	    (IsEqualOid(oid, (KMF_OID *)&KMFOID_X9CM_DSAWithSHA1) ||
784 	    IsEqualOid(oid, (KMF_OID *)&KMFOID_SHA256WithDSA))) {
785 		ret = DerDecodeDSASignature(output, &signature);
786 		if (ret != KMF_OK)
787 			goto cleanup;
788 
789 		output->Length = signature.Length;
790 		(void) memcpy(output->Data, signature.Data, signature.Length);
791 	}
792 
793 cleanup:
794 	if (new_attrlist != NULL)
795 		free(new_attrlist);
796 
797 	if (signature.Data)
798 		free(signature.Data);
799 
800 	if (signer_cert != NULL && sign_key_ptr != NULL)
801 		kmf_free_kmf_key(handle, sign_key_ptr);
802 
803 	return (ret);
804 }
805 
806 /*
807  * kmf_verify_data
808  *
809  * This routine will try to verify a block of data using
810  * either a public key or a certificate as the source
811  * of the verification (the key).
812  *
813  * The caller may provider either a KMF_KEY_HANDLE_ATTR or
814  * a KMF_SIGNER_CERT_DATA_ATTR (with a KMF_DATA record) to
815  * use for the key to the verification step.  If a certificate
816  * is used and that certificate has the KeyUsage extension,
817  * the SIGN-DATA bit must be set.  Also, if a certificate
818  * is used, the verification will be done in a specific
819  * keystore mechanism.
820  *
821  * If a KMF_KEY_HANDLE is given in the attribute list, the
822  * verification will occur in the framework itself using
823  * PKCS#11 C_Verify functions.
824  */
825 KMF_RETURN
826 kmf_verify_data(KMF_HANDLE_T handle,
827 	int	num_args,
828 	KMF_ATTRIBUTE	*attrlist)
829 {
830 	KMF_RETURN ret = KMF_OK;
831 	KMF_PLUGIN *plugin;
832 	KMF_KEYSTORE_TYPE kstype;
833 	uint32_t len;
834 	KMF_DATA	derkey = { 0, NULL };
835 	KMF_KEY_HANDLE *KMFKey;
836 	KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_NONE;
837 	KMF_DATA *indata;
838 	KMF_DATA *insig;
839 	KMF_DATA *signer_cert;
840 	KMF_X509_SPKI spki;
841 	KMF_POLICY_RECORD *policy;
842 
843 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
844 		{KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
845 		{KMF_DATA_ATTR, FALSE, sizeof (KMF_DATA),
846 			sizeof (KMF_DATA)},
847 		{KMF_IN_SIGN_ATTR, FALSE, sizeof (KMF_DATA),
848 			sizeof (KMF_DATA)}
849 	};
850 
851 	int num_req_attrs = sizeof (required_attrs) /
852 	    sizeof (KMF_ATTRIBUTE_TESTER);
853 
854 	if (handle == NULL)
855 		return (KMF_ERR_BAD_PARAMETER);
856 
857 	CLEAR_ERROR(handle, ret);
858 
859 	ret = test_attributes(num_req_attrs, required_attrs,
860 	    0, NULL, num_args, attrlist);
861 
862 	if (ret != KMF_OK)
863 		return (ret);
864 
865 	len = sizeof (kstype);
866 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args,
867 	    &kstype, &len);
868 	if (ret != KMF_OK)
869 		return (ret);
870 
871 	KMFKey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, num_args);
872 	signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
873 	    num_args);
874 	if (KMFKey == NULL && signer_cert == NULL) {
875 		return (KMF_ERR_BAD_PARAMETER);
876 	}
877 
878 	len = sizeof (sigAlg);
879 	ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, num_args,
880 	    &sigAlg, &len);
881 
882 	/* We only need the algorithm index if we don't have a signer cert. */
883 	if (ret != KMF_OK && signer_cert == NULL)
884 		return (ret);
885 
886 	indata = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, num_args);
887 	if (indata == NULL)
888 		return (KMF_ERR_BAD_PARAMETER);
889 
890 	insig = kmf_get_attr_ptr(KMF_IN_SIGN_ATTR, attrlist, num_args);
891 	if (insig == NULL)
892 		return (KMF_ERR_BAD_PARAMETER);
893 
894 	/* If the caller passed a signer cert instead of a key use it. */
895 	if (signer_cert != NULL) {
896 		KMF_X509_CERTIFICATE *SignerCert = NULL;
897 
898 		policy = handle->policy;
899 		ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA);
900 		if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
901 			ret = KMF_OK;
902 		if (ret != KMF_OK)
903 			return (ret);
904 
905 		/* Decode the signer cert so we can get the SPKI data */
906 		ret = DerDecodeSignedCertificate(signer_cert, &SignerCert);
907 		if (ret != KMF_OK)
908 			return (ret);
909 
910 		/* If no algorithm specified, use the certs signature alg */
911 		if (sigAlg == KMF_ALGID_NONE)
912 			sigAlg = x509_algoid_to_algid(CERT_ALG_OID(SignerCert));
913 
914 		if (sigAlg == KMF_ALGID_NONE) {
915 			kmf_free_signed_cert(SignerCert);
916 			free(SignerCert);
917 			return (KMF_ERR_BAD_ALGORITHM);
918 		}
919 
920 		/*
921 		 * Verify the data locally (i.e. using PKCS#11).
922 		 * The verify operation uses a public key and does not
923 		 * require access to a specific keystore. Save time
924 		 * (and code) by just using the frameworks implementation
925 		 * of the verify operation using crypto framework
926 		 * APIs.
927 		 */
928 		ret = PKCS_VerifyData(handle, sigAlg,
929 		    &SignerCert->certificate.subjectPublicKeyInfo,
930 		    indata, insig);
931 
932 		kmf_free_signed_cert(SignerCert);
933 		free(SignerCert);
934 	} else {
935 		/* Retrieve public key data from keystore */
936 		plugin = FindPlugin(handle, kstype);
937 		if (plugin != NULL &&
938 		    plugin->funclist->EncodePubkeyData != NULL) {
939 			ret = plugin->funclist->EncodePubkeyData(handle,
940 			    KMFKey, &derkey);
941 		} else {
942 			return (KMF_ERR_PLUGIN_NOTFOUND);
943 		}
944 
945 		ret = DerDecodeSPKI(&derkey, &spki);
946 		if (ret == KMF_OK)
947 			ret = PKCS_VerifyData(handle, sigAlg, &spki,
948 			    indata, insig);
949 
950 		if (derkey.Data != NULL)
951 			free(derkey.Data);
952 
953 		kmf_free_algoid(&spki.algorithm);
954 		kmf_free_data(&spki.subjectPublicKey);
955 	}
956 
957 	return (ret);
958 }
959 /*
960  * Name: kmf_verify_cert
961  *
962  * Description:
963  *   This function verifies that the a certificate was signed
964  * using a specific private key and that the certificate has not
965  * been altered since it was signed using that private key
966  * The public key used for verification may be given in the
967  * attribute list as a KMF_KEY_HANDLE or the caller may give
968  * just the signing certificate (as KMF_SIGNER_CERT_DATA_ATTR)
969  * from which the public key needed for verification can be
970  * derived.
971  *
972  * Parameters:
973  *	handle(input) - opaque handle for KMF session
974  *	numattr  - number of attributes in the list
975  *	attrlist - KMF_ATTRIBUTES
976  *
977  * Returns:
978  *   A KMF_RETURN value indicating success or specifying a particular
979  * error condition.  The value KMF_OK indicates success. All other
980  * values represent an error condition.
981  */
982 KMF_RETURN
983 kmf_verify_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
984 {
985 	KMF_RETURN	ret;
986 	KMF_DATA	derkey = { 0, NULL };
987 	KMF_PLUGIN	*plugin;
988 	KMF_KEY_HANDLE *KMFKey;
989 	KMF_DATA *CertToBeVerified;
990 	KMF_DATA *SignerCert;
991 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
992 	    {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
993 	};
994 
995 	int num_req_attrs = sizeof (required_attrs) /
996 	    sizeof (KMF_ATTRIBUTE_TESTER);
997 
998 	CLEAR_ERROR(handle, ret);
999 	if (ret != KMF_OK)
1000 		return (ret);
1001 
1002 	ret = test_attributes(num_req_attrs, required_attrs,
1003 	    0, NULL, numattr, attrlist);
1004 	if (ret != KMF_OK)
1005 		return (ret);
1006 
1007 	KMFKey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1008 	SignerCert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
1009 	    numattr);
1010 
1011 	/*
1012 	 * Caller must provide at least a key handle or a cert to use
1013 	 * as the "key" for verification.
1014 	 */
1015 	if (KMFKey == NULL && SignerCert == NULL)
1016 		return (KMF_ERR_BAD_PARAMETER);
1017 
1018 	CertToBeVerified = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
1019 	    numattr);
1020 	if (CertToBeVerified == NULL)
1021 		return (KMF_ERR_BAD_PARAMETER);
1022 
1023 	if (SignerCert != NULL) {
1024 		ret = verify_cert_with_cert(handle, CertToBeVerified,
1025 		    SignerCert);
1026 	} else {
1027 		/*
1028 		 * The keystore must extract the pubkey data because
1029 		 * the framework doesn't have access to the raw key bytes
1030 		 * that are needed to construct the DER encoded public
1031 		 * key information needed for the verify operation.
1032 		 */
1033 		plugin = FindPlugin(handle, KMFKey->kstype);
1034 		if (plugin != NULL && plugin->funclist->EncodePubkeyData !=
1035 		    NULL) {
1036 			ret = plugin->funclist->EncodePubkeyData(handle,
1037 			    KMFKey, &derkey);
1038 		} else {
1039 			return (KMF_ERR_PLUGIN_NOTFOUND);
1040 		}
1041 
1042 		if (ret == KMF_OK && derkey.Length > 0) {
1043 			ret = verify_cert_with_key(handle, &derkey,
1044 			    CertToBeVerified);
1045 
1046 			if (derkey.Data != NULL)
1047 				free(derkey.Data);
1048 		}
1049 	}
1050 
1051 	return (ret);
1052 }
1053 
1054 /*
1055  * Name: kmf_encrypt
1056  *
1057  * Description:
1058  *   Uses the public key from the cert to encrypt the plaintext
1059  *   into the ciphertext.
1060  *
1061  * Parameters:
1062  *   handle(input) - opaque handle for KMF session
1063  *   cert(input) - pointer to a DER encoded certificate for encryption
1064  *		by using its public key
1065  *   plaintext(input) - pointer to the plaintext to be encrypted
1066  *   ciphertext(output) - pointer to the ciphertext contains
1067  *		encrypted data
1068  *
1069  * Returns:
1070  *   A KMF_RETURN value indicating success or specifying a particular
1071  * error condition.
1072  *   The value KMF_OK indicates success. All other values represent
1073  * an error condition.
1074  *
1075  */
1076 KMF_RETURN
1077 kmf_encrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1078 {
1079 	KMF_RETURN ret;
1080 	KMF_X509_CERTIFICATE *x509cert = NULL;
1081 	KMF_X509_SPKI *pubkey;
1082 	KMF_OID *alg;
1083 	KMF_ALGORITHM_INDEX algid;
1084 	KMF_DATA *cert;
1085 	KMF_DATA *plaintext;
1086 	KMF_DATA *ciphertext;
1087 	KMF_POLICY_RECORD *policy;
1088 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
1089 	    {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
1090 		sizeof (KMF_DATA)},
1091 	    {KMF_PLAINTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
1092 		sizeof (KMF_DATA)},
1093 	    {KMF_CIPHERTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
1094 		sizeof (KMF_DATA)}
1095 	};
1096 
1097 	int num_req_attrs = sizeof (required_attrs) /
1098 	    sizeof (KMF_ATTRIBUTE_TESTER);
1099 
1100 	CLEAR_ERROR(handle, ret);
1101 	if (ret != KMF_OK)
1102 		return (ret);
1103 
1104 	ret = test_attributes(num_req_attrs, required_attrs,
1105 	    0, NULL, numattr, attrlist);
1106 	if (ret != KMF_OK)
1107 		return (ret);
1108 
1109 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
1110 	    numattr);
1111 	plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist,
1112 	    numattr);
1113 	ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist,
1114 	    numattr);
1115 
1116 	if (cert == NULL || plaintext == NULL || ciphertext == NULL)
1117 		return (KMF_ERR_BAD_PARAMETER);
1118 
1119 	/* check the keyUsage of the certificate */
1120 	policy = handle->policy;
1121 	ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA);
1122 	if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
1123 		ret = KMF_OK;
1124 	if (ret != KMF_OK)
1125 		return (ret);
1126 
1127 	/* Decode the cert so we can get the SPKI data */
1128 	if ((ret = DerDecodeSignedCertificate(cert, &x509cert)) != KMF_OK)
1129 		return (ret);
1130 
1131 	/* Get the public key info from the certificate */
1132 	pubkey = &x509cert->certificate.subjectPublicKeyInfo;
1133 
1134 	/* Use the algorithm in SPKI to encrypt data */
1135 	alg = &pubkey->algorithm.algorithm;
1136 
1137 	algid = x509_algoid_to_algid(alg);
1138 
1139 	/* [EC]DSA does not support encrypt */
1140 	if (algid == KMF_ALGID_DSA ||
1141 	    algid == KMF_ALGID_SHA1WithDSA ||
1142 	    algid == KMF_ALGID_SHA256WithDSA ||
1143 	    algid == KMF_ALGID_SHA1WithECDSA ||
1144 	    algid == KMF_ALGID_SHA256WithECDSA ||
1145 	    algid == KMF_ALGID_SHA384WithECDSA ||
1146 	    algid == KMF_ALGID_SHA512WithECDSA ||
1147 	    algid == KMF_ALGID_NONE) {
1148 		kmf_free_signed_cert(x509cert);
1149 		free(x509cert);
1150 		return (KMF_ERR_BAD_ALGORITHM);
1151 	}
1152 
1153 	/*
1154 	 * Encrypt using the crypto framework (not the KMF plugin mechanism).
1155 	 */
1156 	ret = PKCS_EncryptData(handle, algid, pubkey, plaintext, ciphertext);
1157 
1158 	kmf_free_signed_cert(x509cert);
1159 	free(x509cert);
1160 
1161 	return (ret);
1162 }
1163 
1164 /*
1165  * Name: kmf_decrypt
1166  *
1167  * Description:
1168  *   Uses the private key associated with the cert to decrypt
1169  *   the ciphertext into the plaintext.
1170  */
1171 KMF_RETURN
1172 kmf_decrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1173 {
1174 	KMF_RETURN ret;
1175 	KMF_X509_CERTIFICATE *x509cert = NULL;
1176 	KMF_X509_SPKI *spki_ptr;
1177 	KMF_PLUGIN *plugin;
1178 	KMF_ALGORITHM_INDEX AlgorithmId;
1179 	KMF_ATTRIBUTE *new_attrlist = NULL;
1180 	int new_numattr;
1181 	KMF_DATA *cert = NULL;
1182 	KMF_DATA *ciphertext = NULL;
1183 	KMF_DATA *plaintext = NULL;
1184 	KMF_KEY_HANDLE prikey;
1185 	KMF_POLICY_RECORD *policy;
1186 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
1187 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
1188 	    {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
1189 	    {KMF_PLAINTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
1190 		sizeof (KMF_DATA)},
1191 	    {KMF_CIPHERTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
1192 		sizeof (KMF_DATA)},
1193 	};
1194 	int num_req_attrs = sizeof (required_attrs) /
1195 	    sizeof (KMF_ATTRIBUTE_TESTER);
1196 
1197 	if (handle == NULL)
1198 		return (KMF_ERR_BAD_PARAMETER);
1199 	CLEAR_ERROR(handle, ret);
1200 
1201 	ret = test_attributes(num_req_attrs, required_attrs,
1202 	    0, NULL, numattr, attrlist);
1203 	if (ret != KMF_OK)
1204 		return (ret);
1205 
1206 
1207 	/* Get the cert and check its keyUsage */
1208 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
1209 	    numattr);
1210 	if (cert == NULL)
1211 		return (KMF_ERR_BAD_PARAMETER);
1212 
1213 	/* check the keyUsage of the certificate */
1214 	policy = handle->policy;
1215 	ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA);
1216 	if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
1217 		ret = KMF_OK;
1218 	if (ret != KMF_OK)
1219 		return (ret);
1220 
1221 	/* Get the ciphertext and plaintext attributes */
1222 	ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist,
1223 	    numattr);
1224 	if (ciphertext == NULL)
1225 		return (KMF_ERR_BAD_PARAMETER);
1226 
1227 	plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist,
1228 	    numattr);
1229 	if (plaintext == NULL)
1230 		return (KMF_ERR_BAD_PARAMETER);
1231 
1232 	/*
1233 	 * Retrieve the private key from the keystore based on
1234 	 * the certificate.
1235 	 */
1236 	ret = setup_findprikey_attrlist(attrlist, numattr, &new_attrlist,
1237 	    &new_numattr, &prikey, cert);
1238 	if (ret != KMF_OK)
1239 		goto cleanup;
1240 
1241 	ret = kmf_find_prikey_by_cert(handle, new_numattr, new_attrlist);
1242 	if (ret != KMF_OK)
1243 		goto cleanup;
1244 
1245 	/* Decode the cert so we can get the alogorithm */
1246 	ret = DerDecodeSignedCertificate(cert, &x509cert);
1247 	if (ret != KMF_OK)
1248 		goto cleanup;
1249 
1250 	spki_ptr = &x509cert->certificate.subjectPublicKeyInfo;
1251 	AlgorithmId = x509_algoid_to_algid((KMF_OID *)
1252 	    &spki_ptr->algorithm.algorithm);
1253 
1254 	/* [EC]DSA does not support decrypt */
1255 	if (AlgorithmId == KMF_ALGID_DSA ||
1256 	    AlgorithmId == KMF_ALGID_ECDSA) {
1257 		ret = KMF_ERR_BAD_ALGORITHM;
1258 		goto cleanup;
1259 	}
1260 
1261 	plugin = FindPlugin(handle, prikey.kstype);
1262 
1263 	if (plugin != NULL && plugin->funclist->DecryptData != NULL) {
1264 		ret = plugin->funclist->DecryptData(handle,
1265 		    &prikey, &spki_ptr->algorithm.algorithm,
1266 		    ciphertext, plaintext);
1267 	} else {
1268 		ret = KMF_ERR_PLUGIN_NOTFOUND;
1269 	}
1270 
1271 cleanup:
1272 	if (new_attrlist != NULL)
1273 		free(new_attrlist);
1274 
1275 	kmf_free_kmf_key(handle, &prikey);
1276 	kmf_free_signed_cert(x509cert);
1277 	free(x509cert);
1278 
1279 	return (ret);
1280 }
1281 
1282 KMF_RETURN
1283 kmf_store_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1284 {
1285 	KMF_PLUGIN *plugin;
1286 	KMF_RETURN ret = KMF_OK;
1287 	KMF_KEYSTORE_TYPE kstype;
1288 
1289 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
1290 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
1291 	    {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
1292 	};
1293 
1294 	int num_req_attrs = sizeof (required_attrs) /
1295 	    sizeof (KMF_ATTRIBUTE_TESTER);
1296 
1297 	if (handle == NULL)
1298 		return (KMF_ERR_BAD_PARAMETER);
1299 
1300 	CLEAR_ERROR(handle, ret);
1301 
1302 	ret = test_attributes(num_req_attrs, required_attrs,
1303 	    0, NULL, numattr, attrlist);
1304 	if (ret != KMF_OK)
1305 		return (ret);
1306 
1307 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
1308 	    &kstype, NULL);
1309 	if (ret != KMF_OK)
1310 		return (ret);
1311 
1312 	plugin = FindPlugin(handle, kstype);
1313 	if (plugin == NULL || plugin->funclist->StoreCert == NULL)
1314 		return (KMF_ERR_PLUGIN_NOTFOUND);
1315 
1316 	return (plugin->funclist->StoreCert(handle, numattr, attrlist));
1317 }
1318 
1319 KMF_RETURN
1320 kmf_import_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1321 {
1322 	KMF_PLUGIN *plugin;
1323 	KMF_RETURN ret = KMF_OK;
1324 	KMF_KEYSTORE_TYPE kstype;
1325 
1326 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
1327 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
1328 	    {KMF_CERT_FILENAME_ATTR, TRUE, 1, 0},
1329 	};
1330 
1331 	int num_req_attrs = sizeof (required_attrs) /
1332 	    sizeof (KMF_ATTRIBUTE_TESTER);
1333 
1334 	if (handle == NULL)
1335 		return (KMF_ERR_BAD_PARAMETER);
1336 
1337 	CLEAR_ERROR(handle, ret);
1338 
1339 	ret = test_attributes(num_req_attrs, required_attrs, 0, NULL,
1340 	    numattr, attrlist);
1341 	if (ret != KMF_OK)
1342 		return (ret);
1343 
1344 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
1345 	    &kstype, NULL);
1346 	if (ret != KMF_OK)
1347 		return (ret);
1348 
1349 	plugin = FindPlugin(handle, kstype);
1350 	if (plugin == NULL || plugin->funclist->ImportCert == NULL)
1351 		return (KMF_ERR_PLUGIN_NOTFOUND);
1352 
1353 	return (plugin->funclist->ImportCert(handle, numattr, attrlist));
1354 }
1355 
1356 KMF_RETURN
1357 kmf_delete_cert_from_keystore(KMF_HANDLE_T handle, int numattr,
1358     KMF_ATTRIBUTE *attrlist)
1359 {
1360 	KMF_PLUGIN *plugin;
1361 	KMF_RETURN ret = KMF_OK;
1362 	KMF_KEYSTORE_TYPE kstype;
1363 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
1364 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}
1365 	};
1366 	int num_req_attrs = sizeof (required_attrs) /
1367 	    sizeof (KMF_ATTRIBUTE_TESTER);
1368 
1369 	if (handle == NULL)
1370 		return (KMF_ERR_BAD_PARAMETER);
1371 
1372 	CLEAR_ERROR(handle, ret);
1373 
1374 	ret = test_attributes(num_req_attrs, required_attrs,
1375 	    0, NULL, numattr, attrlist);
1376 	if (ret != KMF_OK)
1377 		return (ret);
1378 
1379 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
1380 	    &kstype, NULL);
1381 	if (ret != KMF_OK)
1382 		return (ret);
1383 
1384 	plugin = FindPlugin(handle, kstype);
1385 	if (plugin == NULL || plugin->funclist->DeleteCert == NULL)
1386 		return (KMF_ERR_PLUGIN_NOTFOUND);
1387 
1388 	return (plugin->funclist->DeleteCert(handle, numattr, attrlist));
1389 }
1390 
1391 
1392 /*
1393  * This function gets the CRL URI entries from the certificate's Distribution
1394  * points extension, and downloads the CRL file.  The function also returns
1395  * the URI string and the format of the CRL file.   The caller should free
1396  * the space allocated for the returned URI string.
1397  */
1398 static KMF_RETURN
1399 cert_get_crl(KMF_HANDLE_T handle, const KMF_DATA *cert, char *proxy,
1400     char *filename, char **retn_uri, KMF_ENCODE_FORMAT *format)
1401 {
1402 	KMF_RETURN ret = KMF_OK;
1403 	KMF_X509EXT_CRLDISTPOINTS crl_dps;
1404 	boolean_t done = B_FALSE;
1405 	char uri[1024];
1406 	char *proxyname = NULL;
1407 	char *proxy_port_s = NULL;
1408 	int proxy_port = 0;
1409 	int i, j;
1410 	char *path = NULL;
1411 
1412 	if (handle == NULL || cert == NULL || filename == NULL ||
1413 	    retn_uri == NULL || format == NULL)
1414 		return (KMF_ERR_BAD_PARAMETER);
1415 
1416 	/* Get the proxy info */
1417 	if (proxy != NULL) {
1418 		proxyname = strtok(proxy, ":");
1419 		proxy_port_s = strtok(NULL, "\0");
1420 		if (proxy_port_s != NULL) {
1421 			proxy_port = strtol(proxy_port_s, NULL, 0);
1422 		} else {
1423 			proxy_port = 8080; /* default */
1424 		}
1425 	}
1426 
1427 	/*
1428 	 * Get the CRL URI from the certificate's CRL Distribution
1429 	 * Points extension and download the CRL file.  There maybe more than
1430 	 * one CRL URI entries in the DP extension, so we will continue
1431 	 * the process until a CRL file is sucessfully downloaded or we
1432 	 * are running out the CRL URI's.
1433 	 */
1434 	ret = kmf_get_cert_crl_dist_pts((const KMF_DATA *)cert,
1435 	    &crl_dps);
1436 	if (ret != KMF_OK)
1437 		goto out;
1438 
1439 	for (i = 0; i < crl_dps.number; i++) {
1440 		KMF_CRL_DIST_POINT *dp = &(crl_dps.dplist[i]);
1441 		KMF_GENERALNAMES *fullname = &(dp->name.full_name);
1442 		KMF_DATA *data;
1443 
1444 		if (done)
1445 			break;
1446 		for (j = 0; j < fullname->number; j++) {
1447 			data = &(fullname->namelist[j].name);
1448 			(void) memcpy(uri, data->Data, data->Length);
1449 			uri[data->Length] = '\0';
1450 			ret = kmf_download_crl(handle, uri, proxyname,
1451 			    proxy_port, 30, filename, format);
1452 			if (ret == KMF_OK) {
1453 				done = B_TRUE;
1454 				path = malloc(data->Length + 1);
1455 				if (path == NULL) {
1456 					ret = KMF_ERR_MEMORY;
1457 					goto out;
1458 				}
1459 				(void) strncpy(path, uri, data->Length);
1460 				*retn_uri = path;
1461 				break;
1462 			}
1463 		}
1464 	}
1465 
1466 out:
1467 	kmf_free_crl_dist_pts(&crl_dps);
1468 	return (ret);
1469 }
1470 
1471 static KMF_RETURN
1472 check_crl_validity(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype,
1473 	char *crlfilename, KMF_DATA *issuer_cert)
1474 {
1475 	KMF_RETURN ret = KMF_OK;
1476 	KMF_POLICY_RECORD *policy;
1477 
1478 	if (handle == NULL)
1479 		return (KMF_ERR_BAD_PARAMETER);
1480 
1481 	policy = handle->policy;
1482 
1483 	/*
1484 	 * NSS CRL is not file based, and its signature
1485 	 * has been verified during CRL import.
1486 	 * We only check CRL validity for file-based CRLs,
1487 	 * NSS handles these checks internally.
1488 	 */
1489 	if (kstype == KMF_KEYSTORE_NSS)
1490 		return (KMF_OK);
1491 
1492 	/*
1493 	 * Check the CRL signature if needed.
1494 	 */
1495 	if (!policy->validation_info.crl_info.ignore_crl_sign) {
1496 		ret = kmf_verify_crl_file(handle, crlfilename,
1497 		    issuer_cert);
1498 		if (ret != KMF_OK)
1499 			return (ret);
1500 	}
1501 	/*
1502 	 * Check the CRL validity if needed.
1503 	 */
1504 	if (!policy->validation_info.crl_info.ignore_crl_date) {
1505 		ret = kmf_check_crl_date(handle, crlfilename);
1506 		if (ret != KMF_OK)
1507 			return (ret);
1508 	}
1509 
1510 	return (ret);
1511 }
1512 
1513 static KMF_RETURN
1514 cert_crl_check(KMF_HANDLE_T handle,  KMF_KEYSTORE_TYPE *kstype,
1515 	KMF_DATA *user_cert, KMF_DATA *issuer_cert)
1516 {
1517 	KMF_POLICY_RECORD *policy;
1518 	KMF_RETURN ret = KMF_OK;
1519 	KMF_ATTRIBUTE attrlist[16];
1520 	int numattr = 0;
1521 	int fd;
1522 	boolean_t crlchk;
1523 	char user_certfile[MAXPATHLEN];
1524 	char crlfile_tmp[MAXPATHLEN];
1525 	char *basefilename = NULL;
1526 	char *dir = NULL;
1527 	char *crlfilename = NULL;
1528 	char *proxy = NULL;
1529 	char *uri = NULL;
1530 	KMF_ENCODE_FORMAT format;
1531 
1532 	if (handle == NULL || kstype == NULL || user_cert == NULL ||
1533 	    issuer_cert == NULL)
1534 		return (KMF_ERR_BAD_PARAMETER);
1535 
1536 	if (!is_valid_keystore_type(*kstype))
1537 		return (KMF_ERR_BAD_PARAMETER);
1538 
1539 	policy = handle->policy;
1540 
1541 	/*
1542 	 * If the get-crl-uri policy is TRUE, then download the CRL
1543 	 * file first.   The newly downloaded file will be stored in the
1544 	 * NSS internal database for NSS keystore, and stored in a file for
1545 	 * the File-based CRL plugins (OpenSSL and PKCS11).
1546 	 *
1547 	 * For file-based plugins, if the get-crl-uri policy is FALSE,
1548 	 * then the caller should provide a CRL file in the policy.
1549 	 * Also, after this step is done, the "crlfilename" variable should
1550 	 * contain the proper CRL file to be used for the rest of CRL
1551 	 * validation process.
1552 	 */
1553 	basefilename = policy->validation_info.crl_info.basefilename;
1554 	dir = policy->validation_info.crl_info.directory;
1555 	if (policy->validation_info.crl_info.get_crl_uri) {
1556 		/*
1557 		 * Check to see if we already have this CRL.
1558 		 */
1559 		if (basefilename == NULL)
1560 			basefilename = basename(uri);
1561 
1562 		crlfilename = get_fullpath(dir == NULL ? "./" : dir,
1563 		    basefilename);
1564 		if (crlfilename == NULL) {
1565 			ret = KMF_ERR_BAD_CRLFILE;
1566 			goto cleanup;
1567 		}
1568 
1569 		/*
1570 		 * If this file already exists and is valid, we don't need to
1571 		 * download a new one.
1572 		 */
1573 		if ((fd = open(crlfilename, O_RDONLY)) != -1) {
1574 			(void) close(fd);
1575 			if ((ret = check_crl_validity(handle, *kstype,
1576 			    crlfilename, issuer_cert)) == KMF_OK) {
1577 				goto checkcrl;
1578 			}
1579 		}
1580 
1581 		/*
1582 		 * Create a temporary file to hold the new CRL file initially.
1583 		 */
1584 		(void) strlcpy(crlfile_tmp, CRLFILE_TEMPNAME,
1585 		    sizeof (crlfile_tmp));
1586 		if (mkstemp(crlfile_tmp) == -1) {
1587 			ret = KMF_ERR_INTERNAL;
1588 			goto cleanup;
1589 		}
1590 
1591 		/*
1592 		 * Get the URI entry from the certificate's CRL distribution
1593 		 * points extension and download the CRL file.
1594 		 */
1595 		proxy = policy->validation_info.crl_info.proxy;
1596 		ret = cert_get_crl(handle, user_cert, proxy, crlfile_tmp,
1597 		    &uri, &format);
1598 		if (ret != KMF_OK) {
1599 			(void) unlink(crlfile_tmp);
1600 			goto cleanup;
1601 		}
1602 		/*
1603 		 * If we just downloaded one, make sure it is OK.
1604 		 */
1605 		if ((ret = check_crl_validity(handle, *kstype, crlfile_tmp,
1606 		    issuer_cert)) != KMF_OK)
1607 			return (ret);
1608 
1609 		/* Cache the CRL file. */
1610 		if (*kstype == KMF_KEYSTORE_NSS) {
1611 			/*
1612 			 * For NSS keystore, import this CRL file into th
1613 			 * internal database.
1614 			 */
1615 			numattr = 0;
1616 			kmf_set_attr_at_index(attrlist, numattr,
1617 			    KMF_KEYSTORE_TYPE_ATTR, kstype, sizeof (kstype));
1618 			numattr++;
1619 
1620 			kmf_set_attr_at_index(attrlist, numattr,
1621 			    KMF_CRL_FILENAME_ATTR, crlfile_tmp,
1622 			    strlen(crlfile_tmp));
1623 			numattr++;
1624 
1625 			crlchk = B_FALSE;
1626 			kmf_set_attr_at_index(attrlist, numattr,
1627 			    KMF_CRL_CHECK_ATTR,	&crlchk, sizeof (boolean_t));
1628 			numattr++;
1629 
1630 			ret = kmf_import_crl(handle, numattr, attrlist);
1631 			(void) unlink(crlfile_tmp);
1632 			if (ret != KMF_OK)
1633 				goto cleanup;
1634 		} else {
1635 			if (rename(crlfile_tmp, crlfilename) == -1) {
1636 				(void) unlink(crlfile_tmp);
1637 				ret = KMF_ERR_WRITE_FILE;
1638 				goto cleanup;
1639 			}
1640 		}
1641 	} else {
1642 		/*
1643 		 * If the get_crl_uri policy is FALSE, for File-based CRL
1644 		 * plugins, get the input CRL file from the policy.
1645 		 */
1646 		if (*kstype != KMF_KEYSTORE_NSS) {
1647 			if (basefilename == NULL) {
1648 				ret = KMF_ERR_BAD_PARAMETER;
1649 				goto cleanup;
1650 			}
1651 
1652 			crlfilename = get_fullpath(dir == NULL ? "./" : dir,
1653 			    basefilename);
1654 			if (crlfilename == NULL) {
1655 				ret = KMF_ERR_BAD_CRLFILE;
1656 				goto cleanup;
1657 			}
1658 			/*
1659 			 * Make sure this CRL is still valid.
1660 			 */
1661 			if ((ret = check_crl_validity(handle, *kstype,
1662 			    crlfilename, issuer_cert)) != KMF_OK)
1663 				return (ret);
1664 			}
1665 	}
1666 
1667 checkcrl:
1668 	/*
1669 	 * Check the CRL revocation for the certificate.
1670 	 */
1671 	numattr = 0;
1672 
1673 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
1674 	    kstype, sizeof (kstype));
1675 	numattr++;
1676 
1677 	switch (*kstype) {
1678 	case KMF_KEYSTORE_NSS:
1679 		kmf_set_attr_at_index(attrlist, numattr,
1680 		    KMF_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA));
1681 		numattr++;
1682 		break;
1683 	case KMF_KEYSTORE_PK11TOKEN:
1684 	case KMF_KEYSTORE_OPENSSL:
1685 		/*
1686 		 * Create temporary file to hold the user certificate.
1687 		 */
1688 		(void) strlcpy(user_certfile, CERTFILE_TEMPNAME,
1689 		    sizeof (user_certfile));
1690 		if (mkstemp(user_certfile) == -1) {
1691 			ret = KMF_ERR_INTERNAL;
1692 			goto cleanup;
1693 		}
1694 
1695 		ret = kmf_create_cert_file(user_cert, KMF_FORMAT_ASN1,
1696 		    user_certfile);
1697 		if (ret != KMF_OK)  {
1698 			goto cleanup;
1699 		}
1700 
1701 		kmf_set_attr_at_index(attrlist,  numattr,
1702 		    KMF_CERT_FILENAME_ATTR,
1703 		    user_certfile, strlen(user_certfile));
1704 		numattr++;
1705 
1706 		kmf_set_attr_at_index(attrlist,  numattr,
1707 		    KMF_CRL_FILENAME_ATTR,
1708 		    crlfilename, strlen(crlfilename));
1709 		numattr++;
1710 		break;
1711 	default:
1712 		ret = KMF_ERR_PLUGIN_NOTFOUND;
1713 		goto cleanup;
1714 	}
1715 
1716 	ret = kmf_find_cert_in_crl(handle, numattr, attrlist);
1717 	if (ret == KMF_ERR_NOT_REVOKED)  {
1718 		ret = KMF_OK;
1719 	}
1720 
1721 cleanup:
1722 	(void) unlink(user_certfile);
1723 
1724 	if (crlfilename != NULL)
1725 		free(crlfilename);
1726 
1727 	if (uri != NULL)
1728 		free(uri);
1729 
1730 	return (ret);
1731 }
1732 
1733 static KMF_RETURN
1734 cert_ocsp_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
1735 	KMF_DATA *user_cert, KMF_DATA *issuer_cert, KMF_DATA *response,
1736 	char *slotlabel, char *dirpath)
1737 {
1738 	KMF_RETURN ret = KMF_OK;
1739 	KMF_POLICY_RECORD *policy;
1740 	KMF_DATA *new_response = NULL;
1741 	boolean_t ignore_response_sign = B_FALSE;
1742 	uint32_t ltime = 0;
1743 	KMF_DATA *signer_cert = NULL;
1744 	KMF_BIGINT sernum = { NULL, 0 };
1745 	int response_status;
1746 	int reason;
1747 	int cert_status;
1748 	KMF_ATTRIBUTE attrlist[32];
1749 	int numattr;
1750 
1751 	if (handle == NULL || kstype == NULL || user_cert == NULL ||
1752 	    issuer_cert == NULL)
1753 		return (KMF_ERR_BAD_PARAMETER);
1754 
1755 	policy = handle->policy;
1756 
1757 	/*
1758 	 * Get the response lifetime from policy.
1759 	 */
1760 	if (policy->VAL_OCSP_BASIC.response_lifetime != NULL &&
1761 	    (str2lifetime(policy->VAL_OCSP_BASIC.response_lifetime, &ltime)
1762 	    < 0))
1763 		return (KMF_ERR_OCSP_RESPONSE_LIFETIME);
1764 
1765 	/*
1766 	 * Get the ignore_response_sign policy.
1767 	 *
1768 	 * If ignore_response_sign is FALSE, we need to verify the response.
1769 	 * Find the OCSP Responder certificate if it is specified in the OCSP
1770 	 * policy.
1771 	 */
1772 	ignore_response_sign = policy->VAL_OCSP_BASIC.ignore_response_sign;
1773 
1774 	if (ignore_response_sign == B_FALSE &&
1775 	    policy->VAL_OCSP.has_resp_cert == B_TRUE) {
1776 		char *signer_name;
1777 		KMF_X509_DER_CERT signer_retrcert;
1778 		uchar_t *bytes = NULL;
1779 		size_t bytelen;
1780 		uint32_t num = 0;
1781 		KMF_ATTRIBUTE fc_attrlist[16];
1782 		int fc_numattr = 0;
1783 		char *dir = "./";
1784 
1785 		if (policy->VAL_OCSP_RESP_CERT.name == NULL ||
1786 		    policy->VAL_OCSP_RESP_CERT.serial == NULL)
1787 			return (KMF_ERR_POLICY_NOT_FOUND);
1788 
1789 		signer_cert = malloc(sizeof (KMF_DATA));
1790 		if (signer_cert == NULL) {
1791 			ret = KMF_ERR_MEMORY;
1792 			goto out;
1793 		}
1794 		(void) memset(signer_cert, 0, sizeof (KMF_DATA));
1795 
1796 		signer_name = policy->VAL_OCSP_RESP_CERT.name;
1797 		ret = kmf_hexstr_to_bytes(
1798 		    (uchar_t *)policy->VAL_OCSP_RESP_CERT.serial,
1799 		    &bytes, &bytelen);
1800 		if (ret != KMF_OK || bytes == NULL) {
1801 			ret = KMF_ERR_OCSP_POLICY;
1802 			goto out;
1803 		}
1804 		sernum.val = bytes;
1805 		sernum.len = bytelen;
1806 
1807 		kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1808 		    KMF_KEYSTORE_TYPE_ATTR, kstype,
1809 		    sizeof (KMF_KEYSTORE_TYPE));
1810 		fc_numattr++;
1811 
1812 		kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1813 		    KMF_SUBJECT_NAME_ATTR, signer_name, strlen(signer_name));
1814 		fc_numattr++;
1815 
1816 		kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR,
1817 		    &sernum, sizeof (KMF_BIGINT));
1818 		fc_numattr++;
1819 
1820 		if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
1821 			kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1822 			    KMF_TOKEN_LABEL_ATTR, slotlabel,
1823 			    strlen(slotlabel));
1824 			fc_numattr++;
1825 		}
1826 
1827 		if (*kstype == KMF_KEYSTORE_OPENSSL) {
1828 			if (dirpath == NULL) {
1829 				kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1830 				    KMF_DIRPATH_ATTR, dir, strlen(dir));
1831 				fc_numattr++;
1832 			} else {
1833 				kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1834 				    KMF_DIRPATH_ATTR, dirpath,
1835 				    strlen(dirpath));
1836 				fc_numattr++;
1837 			}
1838 		}
1839 
1840 		num = 0;
1841 		kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1842 		    KMF_COUNT_ATTR, &num, sizeof (uint32_t));
1843 		fc_numattr++;
1844 
1845 		ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
1846 		if (ret != KMF_OK || num != 1) {
1847 			if (num == 0)
1848 				ret = KMF_ERR_CERT_NOT_FOUND;
1849 			if (num > 0)
1850 				ret = KMF_ERR_CERT_MULTIPLE_FOUND;
1851 			goto out;
1852 		}
1853 
1854 		(void) memset(&signer_retrcert, 0, sizeof (KMF_X509_DER_CERT));
1855 		kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1856 		    KMF_X509_DER_CERT_ATTR, &signer_retrcert,
1857 		    sizeof (KMF_X509_DER_CERT));
1858 		fc_numattr++;
1859 
1860 		ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
1861 		if (ret == KMF_OK) {
1862 			signer_cert->Length =
1863 			    signer_retrcert.certificate.Length;
1864 			signer_cert->Data = signer_retrcert.certificate.Data;
1865 		} else {
1866 			goto out;
1867 		}
1868 	}
1869 
1870 	/*
1871 	 * If the caller provides an OCSP response, we will use it directly.
1872 	 * Otherwise, we will try to fetch an OCSP response for the given
1873 	 * certificate now.
1874 	 */
1875 	if (response == NULL) {
1876 		new_response = (KMF_DATA *) malloc(sizeof (KMF_DATA));
1877 		if (new_response == NULL) {
1878 			ret = KMF_ERR_MEMORY;
1879 			goto out;
1880 		}
1881 		new_response->Data = NULL;
1882 		new_response->Length = 0;
1883 
1884 		ret = kmf_get_ocsp_for_cert(handle, user_cert, issuer_cert,
1885 		    new_response);
1886 		if (ret != KMF_OK)
1887 			goto out;
1888 	}
1889 
1890 	/*
1891 	 * Process the OCSP response and retrieve the certificate status.
1892 	 */
1893 	numattr = 0;
1894 	kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_CERT_DATA_ATTR,
1895 	    issuer_cert, sizeof (KMF_DATA));
1896 	numattr++;
1897 
1898 	kmf_set_attr_at_index(attrlist, numattr, KMF_USER_CERT_DATA_ATTR,
1899 	    user_cert, sizeof (KMF_DATA));
1900 	numattr++;
1901 
1902 	if (signer_cert != NULL) {
1903 		kmf_set_attr_at_index(attrlist, numattr,
1904 		    KMF_SIGNER_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA));
1905 		numattr++;
1906 	}
1907 
1908 	kmf_set_attr_at_index(attrlist, numattr, KMF_OCSP_RESPONSE_DATA_ATTR,
1909 	    response == NULL ? new_response : response, sizeof (KMF_DATA));
1910 	numattr++;
1911 
1912 	kmf_set_attr_at_index(attrlist, numattr, KMF_RESPONSE_LIFETIME_ATTR,
1913 	    &ltime, sizeof (uint32_t));
1914 	numattr++;
1915 
1916 	kmf_set_attr_at_index(attrlist, numattr,
1917 	    KMF_IGNORE_RESPONSE_SIGN_ATTR, &ignore_response_sign,
1918 	    sizeof (boolean_t));
1919 	numattr++;
1920 
1921 	kmf_set_attr_at_index(attrlist, numattr,
1922 	    KMF_OCSP_RESPONSE_STATUS_ATTR, &response_status, sizeof (int));
1923 	numattr++;
1924 
1925 	kmf_set_attr_at_index(attrlist, numattr,
1926 	    KMF_OCSP_RESPONSE_REASON_ATTR, &reason, sizeof (int));
1927 	numattr++;
1928 
1929 	kmf_set_attr_at_index(attrlist, numattr,
1930 	    KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, &cert_status, sizeof (int));
1931 	numattr++;
1932 
1933 	ret = kmf_get_ocsp_status_for_cert(handle, numattr, attrlist);
1934 	if (ret == KMF_OK) {
1935 		switch (cert_status) {
1936 		case OCSP_GOOD:
1937 			break;
1938 		case OCSP_UNKNOWN:
1939 			ret = KMF_ERR_OCSP_UNKNOWN_CERT;
1940 			break;
1941 		case OCSP_REVOKED:
1942 			ret = KMF_ERR_OCSP_REVOKED;
1943 			break;
1944 		}
1945 	}
1946 
1947 out:
1948 	if (new_response) {
1949 		kmf_free_data(new_response);
1950 		free(new_response);
1951 	}
1952 
1953 	if (signer_cert) {
1954 		kmf_free_data(signer_cert);
1955 		free(signer_cert);
1956 	}
1957 
1958 	if (sernum.val != NULL)
1959 		free(sernum.val);
1960 
1961 	return (ret);
1962 }
1963 
1964 static KMF_RETURN
1965 cert_ku_check(KMF_HANDLE_T handle, KMF_DATA *cert)
1966 {
1967 	KMF_POLICY_RECORD *policy;
1968 	KMF_X509EXT_KEY_USAGE keyusage;
1969 	KMF_RETURN ret = KMF_OK;
1970 	KMF_X509EXT_BASICCONSTRAINTS constraint;
1971 	KMF_BOOL	critical = B_FALSE;
1972 
1973 	if (handle == NULL || cert == NULL)
1974 		return (KMF_ERR_BAD_PARAMETER);
1975 
1976 	policy = handle->policy;
1977 	(void) memset(&keyusage, 0, sizeof (keyusage));
1978 	ret = kmf_get_cert_ku(cert, &keyusage);
1979 
1980 	if (ret == KMF_ERR_EXTENSION_NOT_FOUND) {
1981 		if (policy->ku_bits) {
1982 			/* keyusage is not set in cert but is set in policy */
1983 			return (KMF_ERR_KEYUSAGE);
1984 		} else {
1985 			/* no keyusage set in both cert and policy */
1986 			return (KMF_OK);
1987 		}
1988 	}
1989 
1990 	if (ret != KMF_OK) {
1991 		/* real error */
1992 		return (ret);
1993 	}
1994 
1995 	/*
1996 	 * If KeyCertSign is set, then constraints.cA must be TRUE and
1997 	 * marked critical.
1998 	 */
1999 	if ((keyusage.KeyUsageBits & KMF_keyCertSign)) {
2000 		(void) memset(&constraint, 0, sizeof (constraint));
2001 		ret = kmf_get_cert_basic_constraint(cert,
2002 		    &critical, &constraint);
2003 
2004 		if (ret != KMF_OK) {
2005 			/* real error */
2006 			return (ret);
2007 		}
2008 		if (!constraint.cA || !critical)
2009 			return (KMF_ERR_KEYUSAGE);
2010 	}
2011 
2012 	/*
2013 	 * Rule: if the KU bit is set in policy, the corresponding KU bit
2014 	 * must be set in the certificate (but not vice versa).
2015 	 */
2016 	if ((policy->ku_bits & keyusage.KeyUsageBits) == policy->ku_bits) {
2017 		return (KMF_OK);
2018 	} else {
2019 		return (KMF_ERR_KEYUSAGE);
2020 	}
2021 
2022 }
2023 
2024 static KMF_RETURN
2025 cert_eku_check(KMF_HANDLE_T handle, KMF_DATA *cert)
2026 {
2027 	KMF_POLICY_RECORD *policy;
2028 	KMF_RETURN ret = KMF_OK;
2029 	KMF_X509EXT_EKU eku;
2030 	uint16_t cert_eku = 0, policy_eku = 0;
2031 	int i;
2032 
2033 	if (handle == NULL || cert == NULL)
2034 		return (KMF_ERR_BAD_PARAMETER);
2035 	policy = handle->policy;
2036 
2037 	/*
2038 	 * If the policy does not have any EKU, then there is
2039 	 * nothing further to check.
2040 	 */
2041 	if (policy->eku_set.eku_count == 0)
2042 		return (KMF_OK);
2043 
2044 	ret = kmf_get_cert_eku(cert, &eku);
2045 	if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) {
2046 		/* real error */
2047 		return (ret);
2048 	}
2049 
2050 	if (ret == KMF_ERR_EXTENSION_NOT_FOUND) {
2051 		cert_eku = 0;
2052 	} else {
2053 		/*
2054 		 * Build the EKU bitmap based on the certificate
2055 		 */
2056 		for (i = 0; i < eku.nEKUs; i++) {
2057 			if (IsEqualOid(&eku.keyPurposeIdList[i],
2058 			    (KMF_OID *)&KMFOID_PKIX_KP_ServerAuth)) {
2059 				cert_eku |= KMF_EKU_SERVERAUTH;
2060 			} else if (IsEqualOid(&eku.keyPurposeIdList[i],
2061 			    (KMF_OID *)&KMFOID_PKIX_KP_ClientAuth)) {
2062 				cert_eku |= KMF_EKU_CLIENTAUTH;
2063 			} else if (IsEqualOid(&eku.keyPurposeIdList[i],
2064 			    (KMF_OID *)&KMFOID_PKIX_KP_CodeSigning)) {
2065 				cert_eku |= KMF_EKU_CODESIGNING;
2066 			} else if (IsEqualOid(&eku.keyPurposeIdList[i],
2067 			    (KMF_OID *)&KMFOID_PKIX_KP_EmailProtection)) {
2068 				cert_eku |= KMF_EKU_EMAIL;
2069 			} else if (IsEqualOid(&eku.keyPurposeIdList[i],
2070 			    (KMF_OID *)&KMFOID_PKIX_KP_TimeStamping)) {
2071 				cert_eku |= KMF_EKU_TIMESTAMP;
2072 			} else if (IsEqualOid(&eku.keyPurposeIdList[i],
2073 			    (KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning)) {
2074 				cert_eku |= KMF_EKU_OCSPSIGNING;
2075 			} else if (!policy->ignore_unknown_ekus) {
2076 				return (KMF_ERR_KEYUSAGE);
2077 			}
2078 		} /* for */
2079 	}
2080 
2081 
2082 	/*
2083 	 * Build the EKU bitmap based on the policy
2084 	 */
2085 	for (i = 0; i < policy->eku_set.eku_count; i++) {
2086 		if (IsEqualOid(&policy->eku_set.ekulist[i],
2087 		    (KMF_OID *)&KMFOID_PKIX_KP_ServerAuth)) {
2088 			policy_eku |= KMF_EKU_SERVERAUTH;
2089 		} else if (IsEqualOid(&policy->eku_set.ekulist[i],
2090 		    (KMF_OID *)&KMFOID_PKIX_KP_ClientAuth)) {
2091 			policy_eku |= KMF_EKU_CLIENTAUTH;
2092 		} else if (IsEqualOid(&policy->eku_set.ekulist[i],
2093 		    (KMF_OID *)&KMFOID_PKIX_KP_CodeSigning)) {
2094 			policy_eku |= KMF_EKU_CODESIGNING;
2095 		} else if (IsEqualOid(&policy->eku_set.ekulist[i],
2096 		    (KMF_OID *)&KMFOID_PKIX_KP_EmailProtection)) {
2097 			policy_eku |= KMF_EKU_EMAIL;
2098 		} else if (IsEqualOid(&policy->eku_set.ekulist[i],
2099 		    (KMF_OID *)&KMFOID_PKIX_KP_TimeStamping)) {
2100 			policy_eku |= KMF_EKU_TIMESTAMP;
2101 		} else if (IsEqualOid(&policy->eku_set.ekulist[i],
2102 		    (KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning)) {
2103 			policy_eku |= KMF_EKU_OCSPSIGNING;
2104 		} else if (!policy->ignore_unknown_ekus) {
2105 			return (KMF_ERR_KEYUSAGE);
2106 		}
2107 	} /* for */
2108 
2109 	/*
2110 	 * Rule: if the EKU OID is set in policy, the corresponding EKU OID
2111 	 * must be set in the certificate (but not vice versa).
2112 	 */
2113 	if ((policy_eku & cert_eku) == policy_eku) {
2114 		return (KMF_OK);
2115 	} else {
2116 		return (KMF_ERR_KEYUSAGE);
2117 	}
2118 }
2119 
2120 static KMF_RETURN
2121 find_issuer_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
2122     char *user_issuer, KMF_DATA *issuer_cert,
2123     char *slotlabel, char *dirpath)
2124 {
2125 	KMF_RETURN ret = KMF_OK;
2126 	KMF_X509_DER_CERT *certlist = NULL;
2127 	uint32_t i, num = 0;
2128 	time_t t_notbefore;
2129 	time_t t_notafter;
2130 	time_t latest;
2131 	KMF_DATA tmp_cert = { 0, NULL };
2132 	KMF_ATTRIBUTE fc_attrlist[16];
2133 	int fc_numattr = 0;
2134 	char *dir = "./";
2135 
2136 	if (handle == NULL || kstype == NULL || user_issuer == NULL ||
2137 	    issuer_cert == NULL)
2138 		return (KMF_ERR_BAD_PARAMETER);
2139 
2140 	if (!is_valid_keystore_type(*kstype))
2141 		return (KMF_ERR_BAD_PARAMETER);
2142 
2143 	kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR,
2144 	    kstype, sizeof (KMF_KEYSTORE_TYPE));
2145 	fc_numattr++;
2146 
2147 	kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR,
2148 	    user_issuer, strlen(user_issuer));
2149 	fc_numattr++;
2150 
2151 	if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
2152 		kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2153 		    KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel));
2154 		fc_numattr++;
2155 	}
2156 
2157 	if (*kstype == KMF_KEYSTORE_OPENSSL) {
2158 		if (dirpath == NULL) {
2159 			kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2160 			    KMF_DIRPATH_ATTR, dir, strlen(dir));
2161 			fc_numattr++;
2162 		} else {
2163 			kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2164 			    KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2165 			fc_numattr++;
2166 		}
2167 	}
2168 
2169 	num = 0;
2170 	kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2171 	    KMF_COUNT_ATTR, &num, sizeof (uint32_t));
2172 	fc_numattr++;
2173 
2174 	ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
2175 
2176 	if (ret == KMF_OK && num > 0) {
2177 		certlist = (KMF_X509_DER_CERT *)malloc(num *
2178 		    sizeof (KMF_X509_DER_CERT));
2179 
2180 		if (certlist == NULL) {
2181 			ret = KMF_ERR_MEMORY;
2182 			goto out;
2183 		}
2184 
2185 		kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2186 		    KMF_X509_DER_CERT_ATTR, certlist,
2187 		    sizeof (KMF_X509_DER_CERT));
2188 		fc_numattr++;
2189 
2190 		ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
2191 		if (ret != KMF_OK) {
2192 			free(certlist);
2193 			certlist = NULL;
2194 			goto out;
2195 		}
2196 	} else {
2197 		goto out;
2198 	}
2199 
2200 	if (num == 1) {
2201 		/* only one issuer cert is found */
2202 		tmp_cert.Length = certlist[0].certificate.Length;
2203 		tmp_cert.Data = certlist[0].certificate.Data;
2204 	} else {
2205 		/*
2206 		 * More than one issuer certs are found. We will
2207 		 * pick the latest one.
2208 		 */
2209 		latest = 0;
2210 		for (i = 0; i < num; i++) {
2211 			ret = kmf_get_cert_validity(&certlist[i].certificate,
2212 			    &t_notbefore, &t_notafter);
2213 			if (ret != KMF_OK) {
2214 				ret = KMF_ERR_VALIDITY_PERIOD;
2215 				goto out;
2216 			}
2217 
2218 			if (t_notbefore > latest) {
2219 				tmp_cert.Length =
2220 				    certlist[i].certificate.Length;
2221 				tmp_cert.Data =
2222 				    certlist[i].certificate.Data;
2223 				latest = t_notbefore;
2224 			}
2225 
2226 		}
2227 	}
2228 
2229 	issuer_cert->Length = tmp_cert.Length;
2230 	issuer_cert->Data = malloc(tmp_cert.Length);
2231 	if (issuer_cert->Data == NULL) {
2232 		ret = KMF_ERR_MEMORY;
2233 		goto out;
2234 	}
2235 	(void) memcpy(issuer_cert->Data, tmp_cert.Data,
2236 	    tmp_cert.Length);
2237 
2238 out:
2239 	if (certlist != NULL) {
2240 		for (i = 0; i < num; i++)
2241 			kmf_free_kmf_cert(handle, &certlist[i]);
2242 		free(certlist);
2243 	}
2244 
2245 	return (ret);
2246 
2247 }
2248 
2249 static KMF_RETURN
2250 find_ta_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
2251 	KMF_DATA *ta_cert, KMF_X509_NAME *user_issuerDN,
2252 	char *slotlabel, char *dirpath)
2253 {
2254 	KMF_POLICY_RECORD *policy;
2255 	KMF_RETURN ret = KMF_OK;
2256 	uint32_t num = 0;
2257 	char *ta_name;
2258 	KMF_BIGINT serial = { NULL, 0 };
2259 	uchar_t *bytes = NULL;
2260 	size_t bytelen;
2261 	KMF_X509_DER_CERT ta_retrCert;
2262 	char *ta_subject = NULL;
2263 	KMF_X509_NAME ta_subjectDN;
2264 	KMF_ATTRIBUTE fc_attrlist[16];
2265 	int fc_numattr = 0;
2266 	char *dir = "./";
2267 
2268 	if (handle == NULL || kstype == NULL || ta_cert == NULL ||
2269 	    user_issuerDN == NULL)
2270 		return (KMF_ERR_BAD_PARAMETER);
2271 
2272 	if (!is_valid_keystore_type(*kstype))
2273 		return (KMF_ERR_BAD_PARAMETER);
2274 
2275 	/* Get the TA name and serial number from the policy */
2276 	policy = handle->policy;
2277 	ta_name = policy->ta_name;
2278 
2279 	/*
2280 	 * Use name and serial from policy.
2281 	 */
2282 	ret = kmf_hexstr_to_bytes((uchar_t *)policy->ta_serial,
2283 	    &bytes, &bytelen);
2284 	if (ret != KMF_OK || bytes == NULL) {
2285 		ret = KMF_ERR_TA_POLICY;
2286 		goto out;
2287 	}
2288 	serial.val = bytes;
2289 	serial.len = bytelen;
2290 
2291 	/* set up fc_attrlist for kmf_find_cert */
2292 	kmf_set_attr_at_index(fc_attrlist,
2293 	    fc_numattr++, KMF_BIGINT_ATTR,
2294 	    &serial, sizeof (KMF_BIGINT));
2295 
2296 	kmf_set_attr_at_index(fc_attrlist,
2297 	    fc_numattr++, KMF_SUBJECT_NAME_ATTR,
2298 	    ta_name, strlen(ta_name));
2299 
2300 	kmf_set_attr_at_index(fc_attrlist, fc_numattr++, KMF_KEYSTORE_TYPE_ATTR,
2301 	    kstype, sizeof (KMF_KEYSTORE_TYPE));
2302 
2303 	if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
2304 		kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
2305 		    KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel));
2306 	}
2307 
2308 	if (*kstype == KMF_KEYSTORE_OPENSSL) {
2309 		if (dirpath == NULL) {
2310 			kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
2311 			    KMF_DIRPATH_ATTR, dir, strlen(dir));
2312 		} else {
2313 			kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
2314 			    KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2315 		}
2316 	}
2317 
2318 	num = 0;
2319 	kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
2320 	    KMF_COUNT_ATTR, &num, sizeof (uint32_t));
2321 
2322 	ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
2323 	if (ret != KMF_OK || num != 1)  {
2324 		if (num == 0)
2325 			ret = KMF_ERR_CERT_NOT_FOUND;
2326 		if (num > 1)
2327 			ret = KMF_ERR_CERT_MULTIPLE_FOUND;
2328 		goto out;
2329 	}
2330 
2331 	kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2332 	    KMF_X509_DER_CERT_ATTR, &ta_retrCert, sizeof (KMF_X509_DER_CERT));
2333 	fc_numattr++;
2334 
2335 	ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
2336 	if (ret == KMF_OK)  {
2337 		ta_cert->Length = ta_retrCert.certificate.Length;
2338 		ta_cert->Data = malloc(ta_retrCert.certificate.Length);
2339 		if (ta_cert->Data == NULL) {
2340 			ret = KMF_ERR_MEMORY;
2341 			goto out;
2342 		}
2343 		(void) memcpy(ta_cert->Data, ta_retrCert.certificate.Data,
2344 		    ta_retrCert.certificate.Length);
2345 	} else {
2346 		goto out;
2347 	}
2348 
2349 	/*
2350 	 * The found TA's name must be matching with issuer name in
2351 	 * subscriber's certificate.
2352 	 */
2353 	(void) memset(&ta_subjectDN, 0, sizeof (ta_subjectDN));
2354 
2355 	ret = kmf_get_cert_subject_str(handle, ta_cert, &ta_subject);
2356 	if (ret != KMF_OK)
2357 		goto out;
2358 
2359 	ret = kmf_dn_parser(ta_subject,  &ta_subjectDN);
2360 	if (ret != KMF_OK)
2361 		goto out;
2362 
2363 	if (kmf_compare_rdns(user_issuerDN, &ta_subjectDN) != 0)
2364 		ret = KMF_ERR_CERT_NOT_FOUND;
2365 
2366 	kmf_free_dn(&ta_subjectDN);
2367 
2368 	/* Make sure the TA cert has the correct extensions */
2369 	if (ret == KMF_OK) {
2370 		ret = check_key_usage(handle, ta_cert, KMF_KU_SIGN_CERT);
2371 		if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
2372 			ret = KMF_OK;
2373 	}
2374 out:
2375 	if (ta_retrCert.certificate.Data)
2376 		kmf_free_kmf_cert(handle, &ta_retrCert);
2377 
2378 	if ((ret != KMF_OK))
2379 		kmf_free_data(ta_cert);
2380 
2381 	if (ta_subject != NULL)
2382 		free(ta_subject);
2383 
2384 	if (serial.val != NULL)
2385 		free(serial.val);
2386 
2387 	return (ret);
2388 }
2389 
2390 KMF_RETURN
2391 kmf_validate_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
2392 {
2393 	KMF_RETURN ret = KMF_OK;
2394 	KMF_KEYSTORE_TYPE *kstype = NULL;
2395 	KMF_DATA *pcert = NULL;
2396 	int *result = NULL;
2397 	char *slotlabel = NULL;
2398 	char *dirpath = NULL;
2399 	KMF_DATA *ocsp_response = NULL;
2400 	KMF_DATA ta_cert = { 0, NULL };
2401 	KMF_DATA issuer_cert = { 0, NULL };
2402 	char *user_issuer = NULL, *user_subject = NULL;
2403 	KMF_X509_NAME user_issuerDN, user_subjectDN;
2404 	boolean_t	self_signed = B_FALSE;
2405 	KMF_POLICY_RECORD *policy;
2406 
2407 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
2408 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
2409 	    {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
2410 	    {KMF_VALIDATE_RESULT_ATTR, FALSE, 1, sizeof (int)}
2411 	};
2412 	int num_req_attrs = sizeof (required_attrs) /
2413 	    sizeof (KMF_ATTRIBUTE_TESTER);
2414 
2415 	if (handle == NULL)
2416 		return (KMF_ERR_BAD_PARAMETER);
2417 
2418 	CLEAR_ERROR(handle, ret);
2419 
2420 	ret = test_attributes(num_req_attrs, required_attrs,
2421 	    0, NULL, numattr, attrlist);
2422 	if (ret != KMF_OK)
2423 		return (ret);
2424 
2425 	policy = handle->policy;
2426 
2427 	/* Get the attribute values */
2428 	kstype = kmf_get_attr_ptr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr);
2429 	pcert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
2430 	result = kmf_get_attr_ptr(KMF_VALIDATE_RESULT_ATTR, attrlist, numattr);
2431 	if (kstype == NULL || pcert == NULL || result == NULL)
2432 		return (KMF_ERR_BAD_PARAMETER);
2433 
2434 	slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
2435 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2436 	ocsp_response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, attrlist,
2437 	    numattr);
2438 
2439 	/* Initialize the returned result */
2440 	*result = KMF_CERT_VALIDATE_OK;
2441 
2442 	/*
2443 	 * Get the issuer information from the input certficate first.
2444 	 */
2445 	if ((ret = kmf_get_cert_issuer_str(handle, pcert,
2446 	    &user_issuer)) != KMF_OK) {
2447 		*result |= KMF_CERT_VALIDATE_ERR_USER;
2448 	} else if ((ret = kmf_dn_parser(user_issuer,  &user_issuerDN)) !=
2449 	    KMF_OK) {
2450 		*result |= KMF_CERT_VALIDATE_ERR_USER;
2451 	}
2452 
2453 	/*
2454 	 * Check if the certificate is a self-signed cert.
2455 	 */
2456 	if ((ret = kmf_get_cert_subject_str(handle, pcert,
2457 	    &user_subject)) != KMF_OK) {
2458 		*result |= KMF_CERT_VALIDATE_ERR_USER;
2459 	} else if ((ret = kmf_dn_parser(user_subject,  &user_subjectDN)) !=
2460 	    KMF_OK) {
2461 		*result |= KMF_CERT_VALIDATE_ERR_USER;
2462 	}
2463 
2464 	if ((*result & KMF_CERT_VALIDATE_ERR_USER) == 0 &&
2465 	    (kmf_compare_rdns(&user_issuerDN, &user_subjectDN)) == 0) {
2466 		/*
2467 		 * this is a self-signed cert
2468 		 */
2469 		self_signed = B_TRUE;
2470 	}
2471 
2472 	kmf_free_dn(&user_subjectDN);
2473 
2474 	/*
2475 	 * Check KeyUsage extension of the subscriber's certificate
2476 	 */
2477 	ret = cert_ku_check(handle, pcert);
2478 	if (ret != KMF_OK)  {
2479 		*result |= KMF_CERT_VALIDATE_ERR_KEYUSAGE;
2480 	}
2481 
2482 	/*
2483 	 * Validate Extended KeyUsage extension
2484 	 */
2485 	ret = cert_eku_check(handle, pcert);
2486 	if (ret != KMF_OK)  {
2487 		*result |= KMF_CERT_VALIDATE_ERR_EXT_KEYUSAGE;
2488 	}
2489 
2490 	/*
2491 	 * Check the certificate's validity period
2492 	 *
2493 	 * This step is needed when "ignore_date" in policy is set
2494 	 * to false.
2495 	 */
2496 	if (!policy->ignore_date) {
2497 		/*
2498 		 * Validate expiration date
2499 		 */
2500 		ret = kmf_check_cert_date(handle, pcert);
2501 		if (ret != KMF_OK)
2502 			*result |= KMF_CERT_VALIDATE_ERR_TIME;
2503 	}
2504 
2505 	/*
2506 	 * When "ignore_trust_anchor" in policy is set to FALSE,
2507 	 * we will try to find the TA cert based on the TA policy
2508 	 * attributes.
2509 	 *
2510 	 * TA's subject name (ta_name) and serial number (ta_serial)
2511 	 * are defined as optional attributes in policy dtd, but they
2512 	 * should exist in policy when "ignore_trust_anchor" is set
2513 	 * to FALSE. The policy verification code has enforced that.
2514 	 *
2515 	 * The serial number may be NULL if the ta_name == "search"
2516 	 * which indicates that KMF should try to locate the issuer
2517 	 * of the subject cert instead of using a specific TA name.
2518 	 */
2519 	if (policy->ignore_trust_anchor) {
2520 		goto check_revocation;
2521 	}
2522 
2523 	/*
2524 	 * Verify the signature of subscriber's certificate using
2525 	 * TA certificate.
2526 	 */
2527 	if (self_signed) {
2528 		ret = verify_cert_with_cert(handle, pcert, pcert);
2529 		if (ret != KMF_OK)
2530 			*result |= KMF_CERT_VALIDATE_ERR_SIGNATURE;
2531 	} else if (user_issuer != NULL) {
2532 		if (policy->ta_name != NULL &&
2533 		    strcasecmp(policy->ta_name, "search") == 0) {
2534 			ret = find_issuer_cert(handle, kstype, user_issuer,
2535 			    &issuer_cert, slotlabel, dirpath);
2536 			if (ret != KMF_OK)  {
2537 				*result |= KMF_CERT_VALIDATE_ERR_TA;
2538 			} else {
2539 				ta_cert = issuer_cert; /* used later */
2540 			}
2541 		} else {
2542 			/*
2543 			 * If we didnt find the user_issuer string, we
2544 			 * won't have a "user_issuerDN" either.
2545 			 */
2546 			ret = find_ta_cert(handle, kstype, &ta_cert,
2547 			    &user_issuerDN, slotlabel, dirpath);
2548 		}
2549 		if (ret != KMF_OK)  {
2550 			*result |= KMF_CERT_VALIDATE_ERR_TA;
2551 		}
2552 
2553 		/* Only verify if we got the TA without an error. */
2554 		if ((*result & KMF_CERT_VALIDATE_ERR_TA) == 0) {
2555 			ret = verify_cert_with_cert(handle, pcert,
2556 			    &ta_cert);
2557 			if (ret != KMF_OK)
2558 				*result |= KMF_CERT_VALIDATE_ERR_SIGNATURE;
2559 		}
2560 	} else {
2561 		/* No issuer was found, so we cannot find a trust anchor */
2562 		*result |= KMF_CERT_VALIDATE_ERR_TA;
2563 	}
2564 
2565 check_revocation:
2566 	/*
2567 	 * Check certificate revocation
2568 	 */
2569 	if (self_signed) {
2570 		/* skip revocation checking */
2571 		goto out;
2572 	}
2573 
2574 	/*
2575 	 * When CRL or OCSP revocation method is set in the policy,
2576 	 * we will try to find the issuer of the subscriber certificate
2577 	 * using the issuer name of the subscriber certificate. The
2578 	 * issuer certificate will be used to do the CRL checking
2579 	 * and OCSP checking.
2580 	 */
2581 	if (!(policy->revocation & KMF_REVOCATION_METHOD_CRL) &&
2582 	    !(policy->revocation & KMF_REVOCATION_METHOD_OCSP)) {
2583 		goto out;
2584 	}
2585 
2586 	/*
2587 	 * If we did not find the issuer cert earlier
2588 	 * (when policy->ta_name == "search"), get it here.
2589 	 * We need the issuer cert if the revocation method is
2590 	 * CRL or OCSP.
2591 	 */
2592 	if (issuer_cert.Length == 0 &&
2593 	    policy->revocation & KMF_REVOCATION_METHOD_CRL ||
2594 	    policy->revocation & KMF_REVOCATION_METHOD_OCSP) {
2595 		ret = find_issuer_cert(handle, kstype, user_issuer,
2596 		    &issuer_cert, slotlabel, dirpath);
2597 		if (ret != KMF_OK)  {
2598 			*result |= KMF_CERT_VALIDATE_ERR_ISSUER;
2599 		}
2600 	}
2601 
2602 	if (policy->revocation & KMF_REVOCATION_METHOD_CRL &&
2603 	    (*result & KMF_CERT_VALIDATE_ERR_ISSUER) == 0) {
2604 		ret = cert_crl_check(handle, kstype, pcert, &issuer_cert);
2605 		if (ret != KMF_OK)  {
2606 			*result |= KMF_CERT_VALIDATE_ERR_CRL;
2607 		}
2608 	}
2609 
2610 	if (policy->revocation & KMF_REVOCATION_METHOD_OCSP &&
2611 	    (*result & KMF_CERT_VALIDATE_ERR_ISSUER) == 0) {
2612 		ret = cert_ocsp_check(handle, kstype, pcert, &issuer_cert,
2613 		    ocsp_response, slotlabel, dirpath);
2614 		if (ret != KMF_OK)  {
2615 			*result |= KMF_CERT_VALIDATE_ERR_OCSP;
2616 		}
2617 	}
2618 out:
2619 	if (user_issuer) {
2620 		kmf_free_dn(&user_issuerDN);
2621 		free(user_issuer);
2622 	}
2623 
2624 	if (user_subject)
2625 		free(user_subject);
2626 
2627 	/*
2628 	 * If we did not copy ta_cert to issuer_cert, free it.
2629 	 */
2630 	if (issuer_cert.Data &&
2631 	    issuer_cert.Data != ta_cert.Data)
2632 		kmf_free_data(&issuer_cert);
2633 
2634 	kmf_free_data(&ta_cert);
2635 
2636 	/*
2637 	 * If we got an error flag from any of the checks,
2638 	 * remap the return code to a generic "CERT_VALIDATION"
2639 	 * error so the caller knows to check the individual flags.
2640 	 */
2641 	if (*result != 0)
2642 		ret = KMF_ERR_CERT_VALIDATION;
2643 
2644 	return (ret);
2645 }
2646 
2647 KMF_RETURN
2648 kmf_create_cert_file(const KMF_DATA *certdata, KMF_ENCODE_FORMAT format,
2649 	char *certfile)
2650 {
2651 	KMF_RETURN rv = KMF_OK;
2652 	int fd = -1;
2653 	KMF_DATA pemdata = { 0, NULL };
2654 
2655 	if (certdata == NULL || certfile == NULL)
2656 		return (KMF_ERR_BAD_PARAMETER);
2657 
2658 	if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1)
2659 		return (KMF_ERR_BAD_PARAMETER);
2660 
2661 	if (format == KMF_FORMAT_PEM) {
2662 		int len;
2663 		rv = kmf_der_to_pem(KMF_CERT,
2664 		    certdata->Data, certdata->Length,
2665 		    &pemdata.Data, &len);
2666 		if (rv != KMF_OK)
2667 			goto cleanup;
2668 		pemdata.Length = (size_t)len;
2669 	}
2670 
2671 	if ((fd = open(certfile, O_CREAT | O_RDWR | O_TRUNC, 0644)) == -1) {
2672 		rv = KMF_ERR_OPEN_FILE;
2673 		goto cleanup;
2674 	}
2675 
2676 	if (format == KMF_FORMAT_PEM) {
2677 		if (write(fd, pemdata.Data, pemdata.Length) !=
2678 		    pemdata.Length) {
2679 			rv = KMF_ERR_WRITE_FILE;
2680 		}
2681 	} else {
2682 		if (write(fd, certdata->Data, certdata->Length) !=
2683 		    certdata->Length) {
2684 			rv = KMF_ERR_WRITE_FILE;
2685 		}
2686 	}
2687 
2688 cleanup:
2689 	if (fd != -1)
2690 		(void) close(fd);
2691 
2692 	kmf_free_data(&pemdata);
2693 
2694 	return (rv);
2695 }
2696 
2697 /*
2698  * kmf_is_cert_data
2699  *
2700  * Determine if a KMF_DATA buffer contains an encoded X.509 certificate.
2701  *
2702  * Return:
2703  *   KMF_OK if it is a certificate
2704  *   KMF_ERR_ENCODING (or other error) if not.
2705  */
2706 KMF_RETURN
2707 kmf_is_cert_data(KMF_DATA *data, KMF_ENCODE_FORMAT *fmt)
2708 {
2709 	KMF_RETURN rv = KMF_OK;
2710 	KMF_X509_CERTIFICATE *x509 = NULL;
2711 	KMF_DATA oldpem = { 0, NULL };
2712 	uchar_t *d = NULL;
2713 	int len = 0;
2714 
2715 	if (data == NULL || fmt == NULL)
2716 		return (KMF_ERR_BAD_PARAMETER);
2717 
2718 	rv = kmf_get_data_format(data, fmt);
2719 	if (rv != KMF_OK)
2720 		return (rv);
2721 	switch (*fmt) {
2722 		case KMF_FORMAT_ASN1:
2723 			rv = DerDecodeSignedCertificate(data, &x509);
2724 			break;
2725 		case KMF_FORMAT_PEM:
2726 			/* Convert to ASN.1 DER first */
2727 			rv = kmf_pem_to_der(data->Data, data->Length,
2728 			    &d, &len);
2729 			if (rv != KMF_OK)
2730 				return (rv);
2731 			oldpem.Data = d;
2732 			oldpem.Length = len;
2733 			rv = DerDecodeSignedCertificate(&oldpem, &x509);
2734 			kmf_free_data(&oldpem);
2735 			break;
2736 		case KMF_FORMAT_PKCS12:
2737 		case KMF_FORMAT_UNDEF:
2738 		default:
2739 			return (KMF_ERR_ENCODING);
2740 	}
2741 
2742 	if (x509 != NULL) {
2743 		kmf_free_signed_cert(x509);
2744 		free(x509);
2745 	}
2746 	return (rv);
2747 }
2748 
2749 KMF_RETURN
2750 kmf_is_cert_file(KMF_HANDLE_T handle, char *filename,
2751 	KMF_ENCODE_FORMAT *pformat)
2752 {
2753 	KMF_RETURN ret;
2754 	KMF_DATA filedata;
2755 
2756 	CLEAR_ERROR(handle, ret);
2757 	if (ret != KMF_OK)
2758 		return (ret);
2759 
2760 	if (filename  == NULL || pformat == NULL)
2761 		return (KMF_ERR_BAD_PARAMETER);
2762 
2763 	ret = kmf_read_input_file(handle, filename, &filedata);
2764 	if (ret != KMF_OK)
2765 		return (ret);
2766 
2767 	ret = kmf_is_cert_data(&filedata, pformat);
2768 	if (ret == KMF_ERR_BAD_CERT_FORMAT)
2769 		ret = KMF_ERR_BAD_CERTFILE;
2770 
2771 	kmf_free_data(&filedata);
2772 	return (ret);
2773 }
2774 
2775 /*
2776  * This function checks the validity period of a der-encoded certificate.
2777  */
2778 KMF_RETURN
2779 kmf_check_cert_date(KMF_HANDLE_T handle, const KMF_DATA *cert)
2780 {
2781 	KMF_RETURN rv;
2782 	struct tm *gmt;
2783 	time_t t_now;
2784 	time_t t_notbefore;
2785 	time_t t_notafter;
2786 	KMF_POLICY_RECORD *policy;
2787 	uint32_t adj;
2788 
2789 	CLEAR_ERROR(handle, rv);
2790 	if (rv != KMF_OK)
2791 		return (rv);
2792 
2793 	if (cert == NULL || cert->Data == NULL || cert->Length == 0)
2794 		return (KMF_ERR_BAD_PARAMETER);
2795 
2796 	policy = handle->policy;
2797 	rv = kmf_get_cert_validity(cert, &t_notbefore, &t_notafter);
2798 	if (rv != KMF_OK)
2799 		return (rv);
2800 
2801 	/*
2802 	 * Get the current time. The time returned from time() is local which
2803 	 * cannot be used directly. It must be converted to UTC/GMT first.
2804 	 */
2805 	t_now = time(NULL);
2806 	gmt = gmtime(&t_now);
2807 	t_now = mktime(gmt);
2808 
2809 	/*
2810 	 * Adjust the validity time
2811 	 */
2812 	if (policy->validity_adjusttime != NULL) {
2813 		if (str2lifetime(policy->validity_adjusttime, &adj) < 0)
2814 			return (KMF_ERR_VALIDITY_PERIOD);
2815 	} else {
2816 		adj = 0;
2817 	}
2818 
2819 	t_notafter += adj;
2820 	t_notbefore -= adj;
2821 
2822 	if (t_now <= t_notafter && t_now >= t_notbefore) {
2823 		rv = KMF_OK;
2824 	} else {
2825 		rv = KMF_ERR_VALIDITY_PERIOD;
2826 	}
2827 
2828 	return (rv);
2829 }
2830 
2831 KMF_RETURN
2832 kmf_export_pk12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
2833 {
2834 	KMF_PLUGIN *plugin;
2835 	KMF_RETURN ret = KMF_OK;
2836 	KMF_KEYSTORE_TYPE kstype;
2837 
2838 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
2839 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
2840 	    {KMF_OUTPUT_FILENAME_ATTR, TRUE, 1, 0},
2841 	};
2842 
2843 	int num_req_attrs = sizeof (required_attrs) /
2844 	    sizeof (KMF_ATTRIBUTE_TESTER);
2845 
2846 	if (handle == NULL)
2847 		return (KMF_ERR_BAD_PARAMETER);
2848 
2849 	CLEAR_ERROR(handle, ret);
2850 
2851 	ret = test_attributes(num_req_attrs, required_attrs, 0, NULL,
2852 	    numattr, attrlist);
2853 	if (ret != KMF_OK)
2854 		return (ret);
2855 
2856 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
2857 	    &kstype, NULL);
2858 	if (ret != KMF_OK)
2859 		return (ret);
2860 
2861 	plugin = FindPlugin(handle, kstype);
2862 	if (plugin == NULL || plugin->funclist->ExportPK12 == NULL)
2863 		return (KMF_ERR_PLUGIN_NOTFOUND);
2864 
2865 	return (plugin->funclist->ExportPK12(handle, numattr, attrlist));
2866 }
2867 
2868 
2869 KMF_RETURN
2870 kmf_build_pk12(KMF_HANDLE_T handle, int numcerts,
2871     KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
2872     KMF_CREDENTIAL *p12cred, char *filename)
2873 {
2874 	KMF_RETURN rv;
2875 	KMF_PLUGIN *plugin;
2876 	KMF_RETURN (*buildpk12)(KMF_HANDLE *, int, KMF_X509_DER_CERT *,
2877 	    int, KMF_KEY_HANDLE *, KMF_CREDENTIAL *, char *);
2878 
2879 	CLEAR_ERROR(handle, rv);
2880 	if (rv != KMF_OK)
2881 		return (rv);
2882 
2883 	if (filename == NULL ||	p12cred == NULL ||
2884 	    (certlist == NULL && keylist == NULL))
2885 		return (KMF_ERR_BAD_PARAMETER);
2886 
2887 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
2888 	if (plugin == NULL || plugin->dldesc == NULL) {
2889 		return (KMF_ERR_PLUGIN_NOTFOUND);
2890 	}
2891 
2892 	buildpk12 = (KMF_RETURN(*)())dlsym(plugin->dldesc,
2893 	    "openssl_build_pk12");
2894 	if (buildpk12 == NULL) {
2895 		return (KMF_ERR_FUNCTION_NOT_FOUND);
2896 	}
2897 
2898 	rv = buildpk12(handle, numcerts, certlist, numkeys, keylist, p12cred,
2899 	    filename);
2900 
2901 	return (rv);
2902 }
2903 
2904 
2905 KMF_RETURN
2906 kmf_import_objects(KMF_HANDLE_T handle, char *filename,
2907 	KMF_CREDENTIAL *cred,
2908 	KMF_X509_DER_CERT **certs, int *ncerts,
2909 	KMF_RAW_KEY_DATA **rawkeys, int *nkeys)
2910 {
2911 	KMF_RETURN rv;
2912 	KMF_PLUGIN *plugin;
2913 	KMF_RETURN (*import_objects)(KMF_HANDLE *, char *, KMF_CREDENTIAL *,
2914 	    KMF_X509_DER_CERT **, int *, KMF_RAW_KEY_DATA **, int *);
2915 
2916 	CLEAR_ERROR(handle, rv);
2917 	if (rv != KMF_OK)
2918 		return (rv);
2919 
2920 	if (filename == NULL ||	cred == NULL ||	certs == NULL ||
2921 	    ncerts == NULL ||rawkeys == NULL || nkeys == NULL)
2922 		return (KMF_ERR_BAD_PARAMETER);
2923 
2924 	/*
2925 	 * Use the Keypair reader from the OpenSSL plugin.
2926 	 */
2927 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
2928 	if (plugin == NULL || plugin->dldesc == NULL) {
2929 		return (KMF_ERR_PLUGIN_NOTFOUND);
2930 	}
2931 
2932 	import_objects = (KMF_RETURN(*)())dlsym(plugin->dldesc,
2933 	    "openssl_import_objects");
2934 	if (import_objects == NULL) {
2935 		return (KMF_ERR_FUNCTION_NOT_FOUND);
2936 	}
2937 
2938 	/* Use OpenSSL interfaces to get raw key and cert data */
2939 	rv = import_objects(handle, filename, cred, certs, ncerts,
2940 	    rawkeys, nkeys);
2941 
2942 	return (rv);
2943 }
2944 
2945 KMF_BOOL
2946 IsEqualOid(KMF_OID *Oid1, KMF_OID *Oid2)
2947 {
2948 	return ((Oid1->Length == Oid2->Length) &&
2949 	    !memcmp(Oid1->Data, Oid2->Data, Oid1->Length));
2950 }
2951 
2952 static KMF_RETURN
2953 set_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid,
2954 	KMF_OID *newoid)
2955 {
2956 	if (destid == NULL || newoid == NULL)
2957 		return (KMF_ERR_BAD_PARAMETER);
2958 
2959 	destid->algorithm.Length = newoid->Length;
2960 	destid->algorithm.Data = malloc(destid->algorithm.Length);
2961 	if (destid->algorithm.Data == NULL)
2962 		return (KMF_ERR_MEMORY);
2963 
2964 	(void) memcpy(destid->algorithm.Data, newoid->Data,
2965 	    destid->algorithm.Length);
2966 
2967 	return (KMF_OK);
2968 }
2969 
2970 KMF_RETURN
2971 copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid,
2972 	KMF_X509_ALGORITHM_IDENTIFIER *srcid)
2973 {
2974 	KMF_RETURN ret = KMF_OK;
2975 	if (!destid || !srcid)
2976 		return (KMF_ERR_BAD_PARAMETER);
2977 
2978 	destid->algorithm.Length = srcid->algorithm.Length;
2979 	destid->algorithm.Data = malloc(destid->algorithm.Length);
2980 	if (destid->algorithm.Data == NULL)
2981 		return (KMF_ERR_MEMORY);
2982 
2983 	(void) memcpy(destid->algorithm.Data, srcid->algorithm.Data,
2984 	    destid->algorithm.Length);
2985 
2986 	destid->parameters.Length = srcid->parameters.Length;
2987 	if (destid->parameters.Length > 0) {
2988 		destid->parameters.Data = malloc(destid->parameters.Length);
2989 		if (destid->parameters.Data == NULL)
2990 			return (KMF_ERR_MEMORY);
2991 
2992 		(void) memcpy(destid->parameters.Data, srcid->parameters.Data,
2993 		    destid->parameters.Length);
2994 	} else {
2995 		destid->parameters.Data = NULL;
2996 	}
2997 	return (ret);
2998 }
2999 
3000 static KMF_RETURN
3001 sign_cert(KMF_HANDLE_T handle,
3002 	const KMF_DATA *SubjectCert,
3003 	KMF_KEY_HANDLE	*Signkey,
3004 	KMF_OID		*signature_oid,
3005 	KMF_DATA	*SignedCert)
3006 {
3007 	KMF_X509_CERTIFICATE	*subj_cert = NULL;
3008 	KMF_DATA		data_to_sign = { 0, NULL };
3009 	KMF_DATA		signed_data = { 0, NULL };
3010 	KMF_RETURN		ret = KMF_OK;
3011 	KMF_ALGORITHM_INDEX	algid;
3012 	int i = 0;
3013 	KMF_ATTRIBUTE attrlist[8];
3014 
3015 	if (!SignedCert)
3016 		return (KMF_ERR_BAD_PARAMETER);
3017 
3018 	SignedCert->Length = 0;
3019 	SignedCert->Data = NULL;
3020 
3021 	if (!SubjectCert)
3022 		return (KMF_ERR_BAD_PARAMETER);
3023 
3024 	if (!SubjectCert->Data || !SubjectCert->Length)
3025 		return (KMF_ERR_BAD_PARAMETER);
3026 
3027 	/*
3028 	 * Shortcut - just extract the already encoded TBS cert data from
3029 	 * the original data buffer.  Since we haven't changed anything,
3030 	 * there is no need to re-encode it.
3031 	 */
3032 	ret = ExtractX509CertParts((KMF_DATA *)SubjectCert,
3033 	    &data_to_sign, NULL);
3034 	if (ret != KMF_OK) {
3035 		goto cleanup;
3036 	}
3037 
3038 	/* Estimate the signed data length generously */
3039 	signed_data.Length = data_to_sign.Length*2;
3040 	signed_data.Data = calloc(1, signed_data.Length);
3041 	if (!signed_data.Data) {
3042 		ret = KMF_ERR_MEMORY;
3043 		goto cleanup;
3044 	}
3045 
3046 	/*
3047 	 * If we got here OK, decode into a structure and then re-encode
3048 	 * the complete certificate.
3049 	 */
3050 	ret = DerDecodeSignedCertificate(SubjectCert, &subj_cert);
3051 	if (ret != KMF_OK) {
3052 		goto cleanup;
3053 	}
3054 
3055 	/* We are re-signing this cert, so clear out old signature data */
3056 	if (!IsEqualOid(&subj_cert->signature.algorithmIdentifier.algorithm,
3057 	    signature_oid)) {
3058 		kmf_free_algoid(&subj_cert->signature.algorithmIdentifier);
3059 		ret = set_algoid(&subj_cert->signature.algorithmIdentifier,
3060 		    signature_oid);
3061 		if (ret != KMF_OK)
3062 			goto cleanup;
3063 		ret = set_algoid(&subj_cert->certificate.signature,
3064 		    signature_oid);
3065 		if (ret)
3066 			goto cleanup;
3067 
3068 		/* Free the previous "data to be signed" block */
3069 		kmf_free_data(&data_to_sign);
3070 
3071 		/*
3072 		 * We changed the cert (updated the signature OID), so we
3073 		 * need to re-encode it so the correct data gets signed.
3074 		 */
3075 		ret = DerEncodeTbsCertificate(&subj_cert->certificate,
3076 		    &data_to_sign);
3077 		if (ret != KMF_OK)
3078 			goto cleanup;
3079 	}
3080 	kmf_set_attr_at_index(attrlist, i, KMF_KEYSTORE_TYPE_ATTR,
3081 	    &Signkey->kstype, sizeof (KMF_KEYSTORE_TYPE));
3082 	i++;
3083 	kmf_set_attr_at_index(attrlist, i, KMF_KEY_HANDLE_ATTR,
3084 	    Signkey, sizeof (KMF_KEY_HANDLE));
3085 	i++;
3086 	kmf_set_attr_at_index(attrlist, i, KMF_DATA_ATTR,
3087 	    &data_to_sign, sizeof (KMF_DATA));
3088 	i++;
3089 	kmf_set_attr_at_index(attrlist, i, KMF_OUT_DATA_ATTR,
3090 	    &signed_data, sizeof (KMF_DATA));
3091 	i++;
3092 	kmf_set_attr_at_index(attrlist, i, KMF_OID_ATTR,
3093 	    signature_oid, sizeof (KMF_OID));
3094 	i++;
3095 
3096 	/* Sign the data */
3097 	ret = kmf_sign_data(handle, i, attrlist);
3098 
3099 	if (ret != KMF_OK)
3100 		goto cleanup;
3101 
3102 	algid = x509_algoid_to_algid(signature_oid);
3103 
3104 	if (algid == KMF_ALGID_SHA1WithECDSA ||
3105 	    algid == KMF_ALGID_SHA256WithECDSA ||
3106 	    algid == KMF_ALGID_SHA384WithECDSA ||
3107 	    algid == KMF_ALGID_SHA512WithECDSA) {
3108 		/* ASN.1 encode ECDSA signature */
3109 		KMF_DATA signature;
3110 
3111 		ret = DerEncodeECDSASignature(&signed_data, &signature);
3112 		kmf_free_data(&signed_data);
3113 
3114 		if (ret != KMF_OK)
3115 			goto cleanup;
3116 
3117 		subj_cert->signature.encrypted = signature;
3118 	} else if (algid == KMF_ALGID_SHA1WithDSA ||
3119 	    algid == KMF_ALGID_SHA256WithDSA) {
3120 		/*
3121 		 * For DSA, kmf_sign_data() returns a 40-byte
3122 		 * signature. We must encode the signature correctly.
3123 		 */
3124 		KMF_DATA signature;
3125 
3126 		ret = DerEncodeDSASignature(&signed_data, &signature);
3127 		kmf_free_data(&signed_data);
3128 
3129 		if (ret != KMF_OK)
3130 			goto cleanup;
3131 
3132 		subj_cert->signature.encrypted = signature;
3133 	} else {
3134 		ret = copy_data(&subj_cert->signature.encrypted, &signed_data);
3135 		kmf_free_data(&signed_data);
3136 
3137 		if (ret != KMF_OK)
3138 			goto cleanup;
3139 	}
3140 
3141 	/* Now, re-encode the cert with the new signature */
3142 	ret = DerEncodeSignedCertificate(subj_cert, SignedCert);
3143 
3144 cleanup:
3145 	/* Cleanup & return */
3146 	if (ret != KMF_OK)
3147 		kmf_free_data(SignedCert);
3148 
3149 	kmf_free_data(&data_to_sign);
3150 
3151 	if (subj_cert != NULL) {
3152 		kmf_free_signed_cert(subj_cert);
3153 		free(subj_cert);
3154 	}
3155 
3156 	return (ret);
3157 }
3158 
3159 static KMF_RETURN
3160 verify_cert_with_key(KMF_HANDLE_T handle,
3161 	KMF_DATA *derkey,
3162 	const KMF_DATA *CertToBeVerified)
3163 {
3164 	KMF_RETURN ret = KMF_OK;
3165 	KMF_X509_CERTIFICATE *signed_cert = NULL;
3166 	KMF_X509_SPKI	spki;
3167 	KMF_DATA	data_to_verify = { 0, NULL };
3168 	KMF_DATA	signed_data = { 0, NULL };
3169 	KMF_DATA	signature = { 0, NULL };
3170 	KMF_ALGORITHM_INDEX	algid;
3171 
3172 	/* check the caller and do other setup for this SPI call */
3173 	if (handle == NULL || CertToBeVerified == NULL ||
3174 	    derkey == NULL || derkey->Data == NULL)
3175 		return (KMF_ERR_BAD_PARAMETER);
3176 
3177 	(void) memset(&spki, 0, sizeof (KMF_X509_SPKI));
3178 
3179 	ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerified,
3180 	    &data_to_verify, &signed_data);
3181 
3182 	if (ret != KMF_OK)
3183 		goto cleanup;
3184 
3185 	ret = DerDecodeSPKI(derkey, &spki);
3186 	if (ret != KMF_OK)
3187 		goto cleanup;
3188 
3189 	/* Decode the signer cert so we can get the Algorithm data */
3190 	ret = DerDecodeSignedCertificate(CertToBeVerified, &signed_cert);
3191 	if (ret != KMF_OK)
3192 		return (ret);
3193 
3194 	algid = x509_algoid_to_algid(CERT_SIG_OID(signed_cert));
3195 
3196 	if (algid == KMF_ALGID_NONE)
3197 		return (KMF_ERR_BAD_ALGORITHM);
3198 
3199 	if (algid == KMF_ALGID_SHA1WithDSA ||
3200 	    algid == KMF_ALGID_SHA256WithDSA) {
3201 		ret = DerDecodeDSASignature(&signed_data, &signature);
3202 		if (ret != KMF_OK)
3203 			goto cleanup;
3204 	} else if (algid == KMF_ALGID_SHA1WithECDSA ||
3205 	    algid == KMF_ALGID_SHA256WithECDSA ||
3206 	    algid == KMF_ALGID_SHA384WithECDSA ||
3207 	    algid == KMF_ALGID_SHA512WithECDSA) {
3208 		ret = DerDecodeECDSASignature(&signed_data, &signature);
3209 		if (ret != KMF_OK)
3210 			goto cleanup;
3211 	} else {
3212 		signature.Data = signed_data.Data;
3213 		signature.Length = signed_data.Length;
3214 	}
3215 
3216 	ret = PKCS_VerifyData(handle, algid, &spki,
3217 	    &data_to_verify, &signature);
3218 
3219 cleanup:
3220 	if (data_to_verify.Data != NULL)
3221 		free(data_to_verify.Data);
3222 
3223 	if (signed_data.Data != NULL)
3224 		free(signed_data.Data);
3225 
3226 	if (signed_cert) {
3227 		kmf_free_signed_cert(signed_cert);
3228 		free(signed_cert);
3229 	}
3230 	if (algid == KMF_ALGID_SHA1WithDSA ||
3231 	    algid == KMF_ALGID_SHA256WithDSA ||
3232 	    algid == KMF_ALGID_SHA1WithECDSA ||
3233 	    algid == KMF_ALGID_SHA256WithECDSA ||
3234 	    algid == KMF_ALGID_SHA384WithECDSA ||
3235 	    algid == KMF_ALGID_SHA512WithECDSA) {
3236 		free(signature.Data);
3237 	}
3238 
3239 	kmf_free_algoid(&spki.algorithm);
3240 	kmf_free_data(&spki.subjectPublicKey);
3241 
3242 	return (ret);
3243 }
3244 
3245 /*
3246  * Use a signer cert to verify another certificate's signature.
3247  * This code forces the use of the PKCS11 mechanism for the verify
3248  * operation for the Cryptographic Framework's FIPS-140 boundary.
3249  */
3250 static KMF_RETURN
3251 verify_cert_with_cert(KMF_HANDLE_T handle,
3252 	const KMF_DATA *CertToBeVerifiedData,
3253 	const KMF_DATA *SignerCertData)
3254 {
3255 	KMF_RETURN ret = KMF_OK;
3256 	KMF_X509_CERTIFICATE *SignerCert = NULL;
3257 	KMF_X509_CERTIFICATE *ToBeVerifiedCert = NULL;
3258 	KMF_DATA	data_to_verify = { 0, NULL };
3259 	KMF_DATA	signed_data = { 0, NULL };
3260 	KMF_DATA	signature;
3261 	KMF_ALGORITHM_INDEX	algid;
3262 	KMF_POLICY_RECORD	*policy;
3263 
3264 	if (handle == NULL ||
3265 	    !CertToBeVerifiedData ||
3266 	    !CertToBeVerifiedData->Data ||
3267 	    !CertToBeVerifiedData->Length)
3268 		return (KMF_ERR_BAD_PARAMETER);
3269 
3270 	if (!SignerCertData ||
3271 	    !SignerCertData->Data ||
3272 	    !SignerCertData->Length)
3273 		return (KMF_ERR_BAD_PARAMETER);
3274 
3275 	policy = handle->policy;
3276 
3277 	/* Make sure the signer has proper key usage bits */
3278 	ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_CERT);
3279 	if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
3280 		ret = KMF_OK;
3281 	if (ret != KMF_OK)
3282 		return (ret);
3283 
3284 	/* Decode the cert into parts for verification */
3285 	ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerifiedData,
3286 	    &data_to_verify, &signed_data);
3287 	if (ret != KMF_OK)
3288 		goto cleanup;
3289 
3290 	/* Decode the to-be-verified cert so we know what algorithm to use */
3291 	ret = DerDecodeSignedCertificate(CertToBeVerifiedData,
3292 	    &ToBeVerifiedCert);
3293 	if (ret != KMF_OK)
3294 		goto cleanup;
3295 
3296 	algid = x509_algoid_to_algid(CERT_SIG_OID(ToBeVerifiedCert));
3297 
3298 	if (algid == KMF_ALGID_SHA1WithDSA ||
3299 	    algid == KMF_ALGID_SHA256WithDSA) {
3300 		ret = DerDecodeDSASignature(&signed_data, &signature);
3301 		if (ret != KMF_OK)
3302 			goto cleanup;
3303 	} else if (algid == KMF_ALGID_SHA1WithECDSA ||
3304 	    algid == KMF_ALGID_SHA256WithECDSA ||
3305 	    algid == KMF_ALGID_SHA384WithECDSA ||
3306 	    algid == KMF_ALGID_SHA512WithECDSA) {
3307 		ret = DerDecodeECDSASignature(&signed_data, &signature);
3308 		if (ret != KMF_OK)
3309 			goto cleanup;
3310 	} else {
3311 		signature.Data = signed_data.Data;
3312 		signature.Length = signed_data.Length;
3313 	}
3314 
3315 	ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert);
3316 	if (ret != KMF_OK)
3317 		goto cleanup;
3318 
3319 	/*
3320 	 * Force use of PKCS11 API for kcfd/libelfsign.  This is
3321 	 * required for the Cryptographic Framework's FIPS-140 boundary.
3322 	 */
3323 	ret = PKCS_VerifyData(handle, algid,
3324 	    &SignerCert->certificate.subjectPublicKeyInfo,
3325 	    &data_to_verify, &signature);
3326 
3327 cleanup:
3328 	kmf_free_data(&data_to_verify);
3329 	kmf_free_data(&signed_data);
3330 
3331 	if (SignerCert) {
3332 		kmf_free_signed_cert(SignerCert);
3333 		free(SignerCert);
3334 	}
3335 
3336 	if (ToBeVerifiedCert) {
3337 		kmf_free_signed_cert(ToBeVerifiedCert);
3338 		free(ToBeVerifiedCert);
3339 	}
3340 
3341 	if (algid == KMF_ALGID_SHA1WithDSA ||
3342 	    algid == KMF_ALGID_SHA256WithDSA ||
3343 	    algid == KMF_ALGID_SHA1WithECDSA ||
3344 	    algid == KMF_ALGID_SHA256WithECDSA ||
3345 	    algid == KMF_ALGID_SHA384WithECDSA ||
3346 	    algid == KMF_ALGID_SHA512WithECDSA) {
3347 		free(signature.Data);
3348 	}
3349 
3350 	return (ret);
3351 }
3352