xref: /illumos-gate/usr/src/lib/libkmf/libkmf/common/csrcrlop.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 2008 Sun Microsystems, Inc.  All rights reserved.
22  * Use is subject to license terms.
23  */
24 
25 #pragma ident	"%Z%%M%	%I%	%E% SMI"
26 
27 #include <stdio.h>
28 #include <link.h>
29 #include <fcntl.h>
30 #include <ctype.h>
31 #include <sys/param.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/socket.h>
35 
36 #include <ber_der.h>
37 #include <kmfapiP.h>
38 
39 #include <pem_encode.h>
40 #include <libgen.h>
41 #include <cryptoutil.h>
42 
43 static KMF_RETURN
44 setup_crl_call(KMF_HANDLE_T, int, KMF_ATTRIBUTE *, KMF_PLUGIN **);
45 
46 /*
47  *
48  * Name: kmf_set_csr_pubkey
49  *
50  * Description:
51  *   This function converts the specified plugin public key to SPKI form,
52  *   and save it in the KMF_CSR_DATA internal structure
53  *
54  * Parameters:
55  *   KMFkey(input) - pointer to the KMF_KEY_HANDLE structure containing the
56  *		public key generated by the plug-in CreateKeypair
57  *   Csr(input/output) - pointer to a KMF_CSR_DATA structure containing
58  *		SPKI
59  *
60  * Returns:
61  *   A KMF_RETURN value indicating success or specifying a particular
62  *   error condition.
63  *   The value KMF_OK indicates success. All other values represent
64  *   an error condition.
65  *
66  */
67 KMF_RETURN
68 kmf_set_csr_pubkey(KMF_HANDLE_T handle,
69 	KMF_KEY_HANDLE *KMFKey,
70 	KMF_CSR_DATA *Csr)
71 {
72 	KMF_RETURN ret;
73 	KMF_X509_SPKI *spki_ptr;
74 	KMF_PLUGIN *plugin;
75 	KMF_DATA KeyData = {NULL, 0};
76 
77 	CLEAR_ERROR(handle, ret);
78 	if (ret != KMF_OK)
79 		return (ret);
80 
81 	if (KMFKey == NULL || Csr == NULL) {
82 		return (KMF_ERR_BAD_PARAMETER);
83 	}
84 
85 	/* The keystore must extract the pubkey data */
86 	plugin = FindPlugin(handle, KMFKey->kstype);
87 	if (plugin != NULL && plugin->funclist->EncodePubkeyData != NULL) {
88 		ret = plugin->funclist->EncodePubkeyData(handle,
89 		    KMFKey, &KeyData);
90 	} else {
91 		return (KMF_ERR_PLUGIN_NOTFOUND);
92 	}
93 
94 	spki_ptr = &Csr->csr.subjectPublicKeyInfo;
95 
96 	ret = DerDecodeSPKI(&KeyData, spki_ptr);
97 
98 	kmf_free_data(&KeyData);
99 
100 	return (ret);
101 }
102 
103 KMF_RETURN
104 kmf_set_csr_version(KMF_CSR_DATA *CsrData, uint32_t version)
105 {
106 	if (CsrData == NULL)
107 		return (KMF_ERR_BAD_PARAMETER);
108 
109 	/*
110 	 * From RFC 3280:
111 	 * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
112 	 */
113 	if (version != 0 && version != 1 && version != 2)
114 		return (KMF_ERR_BAD_PARAMETER);
115 	return (set_integer(&CsrData->csr.version, (void *)&version,
116 	    sizeof (uint32_t)));
117 }
118 
119 KMF_RETURN
120 kmf_set_csr_subject(KMF_CSR_DATA *CsrData,
121 	KMF_X509_NAME *subject_name_ptr)
122 {
123 	KMF_RETURN rv = KMF_OK;
124 	KMF_X509_NAME *temp_name_ptr = NULL;
125 
126 	if (CsrData != NULL && subject_name_ptr != NULL) {
127 		rv = CopyRDN(subject_name_ptr, &temp_name_ptr);
128 		if (rv == KMF_OK) {
129 			CsrData->csr.subject = *temp_name_ptr;
130 		}
131 	} else {
132 		return (KMF_ERR_BAD_PARAMETER);
133 	}
134 	return (rv);
135 }
136 KMF_RETURN
137 kmf_create_csr_file(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format,
138 	char *csrfile)
139 {
140 	KMF_RETURN rv = KMF_OK;
141 	int fd = -1;
142 	KMF_DATA pemdata = {NULL, 0};
143 
144 	if (csrdata == NULL || csrfile == NULL)
145 		return (KMF_ERR_BAD_PARAMETER);
146 
147 	if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1)
148 		return (KMF_ERR_BAD_PARAMETER);
149 
150 	if (format == KMF_FORMAT_PEM) {
151 		int len;
152 		rv = kmf_der_to_pem(KMF_CSR,
153 		    csrdata->Data, csrdata->Length,
154 		    &pemdata.Data, &len);
155 		if (rv != KMF_OK)
156 			goto cleanup;
157 		pemdata.Length = (size_t)len;
158 	}
159 
160 	if ((fd = open(csrfile, O_CREAT |O_RDWR, 0644)) == -1) {
161 		rv = KMF_ERR_OPEN_FILE;
162 		goto cleanup;
163 	}
164 
165 	if (format == KMF_FORMAT_PEM) {
166 		if (write(fd, pemdata.Data, pemdata.Length) !=
167 		    pemdata.Length) {
168 			rv = KMF_ERR_WRITE_FILE;
169 		}
170 	} else {
171 		if (write(fd, csrdata->Data, csrdata->Length) !=
172 		    csrdata->Length) {
173 			rv = KMF_ERR_WRITE_FILE;
174 		}
175 	}
176 
177 cleanup:
178 	if (fd != -1)
179 		(void) close(fd);
180 
181 	kmf_free_data(&pemdata);
182 
183 	return (rv);
184 }
185 
186 KMF_RETURN
187 kmf_set_csr_extn(KMF_CSR_DATA *Csr, KMF_X509_EXTENSION *extn)
188 {
189 	KMF_RETURN ret = KMF_OK;
190 	KMF_X509_EXTENSIONS *exts;
191 
192 	if (Csr == NULL || extn == NULL)
193 		return (KMF_ERR_BAD_PARAMETER);
194 
195 	exts = &Csr->csr.extensions;
196 
197 	ret = add_an_extension(exts, extn);
198 
199 	return (ret);
200 }
201 
202 KMF_RETURN
203 kmf_set_csr_sig_alg(KMF_CSR_DATA *CsrData,
204 	KMF_ALGORITHM_INDEX sigAlg)
205 {
206 	KMF_OID	*alg;
207 
208 	if (CsrData == NULL)
209 		return (KMF_ERR_BAD_PARAMETER);
210 
211 	alg = x509_algid_to_algoid(sigAlg);
212 
213 	if (alg != NULL) {
214 		(void) copy_data((KMF_DATA *)
215 		    &CsrData->signature.algorithmIdentifier.algorithm,
216 		    (KMF_DATA *)alg);
217 		(void) copy_data(
218 		    &CsrData->signature.algorithmIdentifier.parameters,
219 		    &CsrData->csr.subjectPublicKeyInfo.algorithm.parameters);
220 	} else {
221 		return (KMF_ERR_BAD_PARAMETER);
222 	}
223 	return (KMF_OK);
224 }
225 
226 KMF_RETURN
227 kmf_set_csr_subject_altname(KMF_CSR_DATA *Csr,
228 	char *altname, int critical,
229 	KMF_GENERALNAMECHOICES alttype)
230 {
231 	KMF_RETURN ret = KMF_OK;
232 
233 	if (Csr == NULL || altname == NULL)
234 		return (KMF_ERR_BAD_PARAMETER);
235 
236 	ret = kmf_set_altname(&Csr->csr.extensions,
237 	    (KMF_OID *)&KMFOID_SubjectAltName, critical, alttype,
238 	    altname);
239 
240 	return (ret);
241 }
242 
243 KMF_RETURN
244 kmf_set_csr_ku(KMF_CSR_DATA *CSRData,
245 	int critical, uint16_t kubits)
246 {
247 	KMF_RETURN ret = KMF_OK;
248 
249 	if (CSRData == NULL)
250 		return (KMF_ERR_BAD_PARAMETER);
251 
252 	ret = set_key_usage_extension(
253 	    &CSRData->csr.extensions, critical, kubits);
254 
255 	return (ret);
256 }
257 
258 KMF_RETURN
259 kmf_add_csr_eku(KMF_CSR_DATA *CSRData, KMF_OID *ekuOID,
260 	int critical)
261 {
262 	KMF_RETURN ret = KMF_OK;
263 	KMF_X509_EXTENSION *foundextn;
264 	KMF_X509_EXTENSION newextn;
265 	BerElement *asn1 = NULL;
266 	BerValue *extdata = NULL;
267 	char *olddata = NULL;
268 	size_t oldsize = 0;
269 	KMF_X509EXT_EKU ekudata;
270 
271 	if (CSRData == NULL || ekuOID == NULL)
272 		return (KMF_ERR_BAD_PARAMETER);
273 
274 	(void) memset(&ekudata, 0, sizeof (KMF_X509EXT_EKU));
275 	(void) memset(&newextn, 0, sizeof (newextn));
276 
277 	foundextn = FindExtn(&CSRData->csr.extensions,
278 	    (KMF_OID *)&KMFOID_ExtendedKeyUsage);
279 	if (foundextn != NULL) {
280 		ret = GetSequenceContents((char *)foundextn->BERvalue.Data,
281 		    foundextn->BERvalue.Length, &olddata, &oldsize);
282 		if (ret != KMF_OK)
283 			goto out;
284 
285 		/*
286 		 * If the EKU is already in the cert, then just return OK.
287 		 */
288 		ret = parse_eku_data(&foundextn->BERvalue, &ekudata);
289 		if (ret == KMF_OK) {
290 			if (is_eku_present(&ekudata, ekuOID)) {
291 				goto out;
292 			}
293 		}
294 	}
295 	if ((asn1 = kmfder_alloc()) == NULL)
296 		return (KMF_ERR_MEMORY);
297 
298 	if (kmfber_printf(asn1, "{") == -1) {
299 		ret = KMF_ERR_ENCODING;
300 		goto out;
301 	}
302 
303 	/* Write the old extension data first */
304 	if (olddata != NULL && oldsize > 0) {
305 		if (kmfber_write(asn1, olddata, oldsize, 0) == -1) {
306 			ret = KMF_ERR_ENCODING;
307 			goto out;
308 		}
309 	}
310 
311 	/* Append this EKU OID and close the sequence */
312 	if (kmfber_printf(asn1, "D}", ekuOID) == -1) {
313 		ret = KMF_ERR_ENCODING;
314 		goto out;
315 	}
316 
317 	if (kmfber_flatten(asn1, &extdata) == -1) {
318 		ret = KMF_ERR_ENCODING;
319 		goto out;
320 	}
321 
322 	/*
323 	 * If we are just adding to an existing list of EKU OIDs,
324 	 * just replace the BER data associated with the found extension.
325 	 */
326 	if (foundextn != NULL) {
327 		free(foundextn->BERvalue.Data);
328 		foundextn->critical = critical;
329 		foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val;
330 		foundextn->BERvalue.Length = extdata->bv_len;
331 	} else {
332 		ret = copy_data(&newextn.extnId,
333 		    (KMF_DATA *)&KMFOID_ExtendedKeyUsage);
334 		if (ret != KMF_OK)
335 			goto out;
336 		newextn.critical = critical;
337 		newextn.format = KMF_X509_DATAFORMAT_ENCODED;
338 		newextn.BERvalue.Data = (uchar_t *)extdata->bv_val;
339 		newextn.BERvalue.Length = extdata->bv_len;
340 		ret = kmf_set_csr_extn(CSRData, &newextn);
341 		if (ret != KMF_OK)
342 			free(newextn.BERvalue.Data);
343 	}
344 
345 out:
346 	kmf_free_eku(&ekudata);
347 	if (extdata != NULL)
348 		free(extdata);
349 
350 	if (olddata != NULL)
351 		free(olddata);
352 
353 	if (asn1 != NULL)
354 		kmfber_free(asn1, 1);
355 
356 	if (ret != KMF_OK)
357 		kmf_free_data(&newextn.extnId);
358 
359 	return (ret);
360 }
361 
362 static KMF_RETURN
363 sign_csr(KMF_HANDLE_T handle,
364 	const KMF_DATA *SubjectCsr,
365 	KMF_KEY_HANDLE	*Signkey,
366 	KMF_X509_ALGORITHM_IDENTIFIER *algo,
367 	KMF_DATA	*SignedCsr)
368 {
369 
370 	KMF_CSR_DATA	subj_csr;
371 	KMF_TBS_CSR	*tbs_csr = NULL;
372 	KMF_DATA	signed_data = {0, NULL};
373 	KMF_RETURN	ret = KMF_OK;
374 
375 	if (!SignedCsr)
376 		return (KMF_ERR_BAD_PARAMETER);
377 
378 	SignedCsr->Length = 0;
379 	SignedCsr->Data = NULL;
380 
381 	if (!SubjectCsr)
382 		return (KMF_ERR_BAD_PARAMETER);
383 
384 	if (!SubjectCsr->Data || !SubjectCsr->Length)
385 		return (KMF_ERR_BAD_PARAMETER);
386 
387 	(void) memset(&subj_csr, 0, sizeof (subj_csr));
388 	/* Estimate the signed data length generously */
389 	signed_data.Length = SubjectCsr->Length*2;
390 	signed_data.Data = calloc(1, signed_data.Length);
391 	if (!signed_data.Data) {
392 		ret = KMF_ERR_MEMORY;
393 		goto cleanup;
394 	}
395 
396 	/* Sign the data */
397 	ret = KMF_SignDataWithKey(handle, Signkey, &algo->algorithm,
398 	    (KMF_DATA *)SubjectCsr, &signed_data);
399 
400 	if (KMF_OK != ret)
401 		goto cleanup;
402 
403 	/*
404 	 * If we got here OK, decode into a structure and then re-encode
405 	 * the complete CSR.
406 	 */
407 	ret = DerDecodeTbsCsr(SubjectCsr, &tbs_csr);
408 	if (ret)
409 		goto cleanup;
410 
411 	(void) memcpy(&subj_csr.csr, tbs_csr, sizeof (KMF_TBS_CSR));
412 
413 	ret = copy_algoid(&subj_csr.signature.algorithmIdentifier, algo);
414 	if (ret)
415 		goto cleanup;
416 
417 	subj_csr.signature.encrypted = signed_data;
418 
419 	/* Now, re-encode the CSR with the new signature */
420 	ret = DerEncodeSignedCsr(&subj_csr, SignedCsr);
421 	if (ret != KMF_OK) {
422 		kmf_free_data(SignedCsr);
423 		goto cleanup;
424 	}
425 
426 	/* Cleanup & return */
427 cleanup:
428 	free(tbs_csr);
429 
430 	kmf_free_tbs_csr(&subj_csr.csr);
431 
432 	kmf_free_algoid(&subj_csr.signature.algorithmIdentifier);
433 	kmf_free_data(&signed_data);
434 
435 	return (ret);
436 }
437 
438 /*
439  *
440  * Name: kmf_sign_csr
441  *
442  * Description:
443  *   This function signs a CSR and returns the result as a
444  *   signed, encoded CSR in SignedCsr
445  *
446  * Parameters:
447  *   tbsCsr(input) - pointer to a KMF_DATA structure containing a
448  *		DER encoded TBS CSR data
449  *   Signkey(input) - pointer to the KMF_KEY_HANDLE structure containing
450  *		the private key generated by the plug-in CreateKeypair
451  *   algo(input) - contains algorithm info needed for signing
452  *   SignedCsr(output) - pointer to the KMF_DATA structure containing
453  *		the signed CSR
454  *
455  * Returns:
456  *   A KMF_RETURN value indicating success or specifying a particular
457  *   error condition.
458  *   The value KMF_OK indicates success. All other values represent
459  *   an error condition.
460  *
461  */
462 KMF_RETURN
463 kmf_sign_csr(KMF_HANDLE_T handle,
464 	const KMF_CSR_DATA *tbsCsr,
465 	KMF_KEY_HANDLE	*Signkey,
466 	KMF_DATA	*SignedCsr)
467 {
468 	KMF_RETURN err;
469 	KMF_DATA csrdata = { NULL, 0 };
470 
471 	CLEAR_ERROR(handle, err);
472 	if (err != KMF_OK)
473 		return (err);
474 
475 	if (tbsCsr == NULL || Signkey == NULL || SignedCsr == NULL)
476 		return (KMF_ERR_BAD_PARAMETER);
477 
478 	SignedCsr->Data = NULL;
479 	SignedCsr->Length = 0;
480 
481 	err = DerEncodeTbsCsr((KMF_TBS_CSR *)&tbsCsr->csr, &csrdata);
482 	if (err == KMF_OK) {
483 		err = sign_csr(handle, &csrdata, Signkey,
484 		    (KMF_X509_ALGORITHM_IDENTIFIER *)
485 		    &tbsCsr->signature.algorithmIdentifier,
486 		    SignedCsr);
487 	}
488 
489 	if (err != KMF_OK) {
490 		kmf_free_data(SignedCsr);
491 	}
492 	kmf_free_data(&csrdata);
493 	return (err);
494 }
495 
496 /*
497  * kmf_decode_csr
498  *
499  * Description:
500  *   This function decodes raw CSR data and fills in the KMF_CSR_DATA
501  *   record.
502  *
503  * Inputs:
504  *	KMF_HANDLE_T handle
505  *	KMF_DATA *rawcsr
506  *	KMF_CSR_DATA *csrdata;
507  */
508 KMF_RETURN
509 kmf_decode_csr(KMF_HANDLE_T handle, KMF_DATA *rawcsr, KMF_CSR_DATA *csrdata)
510 {
511 	KMF_RETURN rv;
512 	KMF_CSR_DATA *cdata = NULL;
513 
514 	if (handle == NULL || rawcsr == NULL || csrdata == NULL)
515 		return (KMF_ERR_BAD_PARAMETER);
516 
517 	rv = DerDecodeSignedCsr(rawcsr, &cdata);
518 	if (rv != KMF_OK)
519 		return (rv);
520 
521 	(void) memcpy(csrdata, cdata, sizeof (KMF_CSR_DATA));
522 
523 	free(cdata);
524 	return (rv);
525 }
526 
527 KMF_RETURN
528 kmf_verify_csr(KMF_HANDLE_T handle, int numattr,
529 	KMF_ATTRIBUTE *attrlist)
530 {
531 	KMF_RETURN rv = KMF_OK;
532 	KMF_CSR_DATA *csrdata = NULL;
533 	KMF_ALGORITHM_INDEX algid;
534 	KMF_X509_ALGORITHM_IDENTIFIER *x509alg;
535 	KMF_DATA rawcsr;
536 
537 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
538 	    {KMF_CSR_DATA_ATTR, FALSE, sizeof (KMF_CSR_DATA),
539 	    sizeof (KMF_CSR_DATA)},
540 	};
541 
542 	int num_req_attrs = sizeof (required_attrs) /
543 	    sizeof (KMF_ATTRIBUTE_TESTER);
544 
545 	if (handle == NULL)
546 		return (KMF_ERR_BAD_PARAMETER);
547 
548 	CLEAR_ERROR(handle, rv);
549 
550 	rv = test_attributes(num_req_attrs, required_attrs,
551 	    0, NULL, numattr, attrlist);
552 	if (rv != KMF_OK)
553 		return (rv);
554 
555 	csrdata = kmf_get_attr_ptr(KMF_CSR_DATA_ATTR, attrlist, numattr);
556 	if (csrdata == NULL)
557 		return (KMF_ERR_BAD_PARAMETER);
558 
559 	rv = DerEncodeTbsCsr(&csrdata->csr, &rawcsr);
560 	if (rv != KMF_OK)
561 		return (rv);
562 
563 	x509alg = &csrdata->signature.algorithmIdentifier;
564 	algid = x509_algoid_to_algid(&x509alg->algorithm);
565 
566 	rv = PKCS_VerifyData(handle, algid,
567 	    &csrdata->csr.subjectPublicKeyInfo,
568 	    &rawcsr,
569 	    &csrdata->signature.encrypted);
570 
571 	kmf_free_data(&rawcsr);
572 	return (rv);
573 }
574 
575 static KMF_RETURN
576 setup_crl_call(KMF_HANDLE_T handle, int numattr,
577 	KMF_ATTRIBUTE *attrlist, KMF_PLUGIN **plugin)
578 {
579 	KMF_RETURN ret;
580 	KMF_KEYSTORE_TYPE kstype;
581 	uint32_t len = sizeof (kstype);
582 
583 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
584 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}
585 	};
586 
587 	int num_req_attrs = sizeof (required_attrs) /
588 	    sizeof (KMF_ATTRIBUTE_TESTER);
589 
590 	if (handle == NULL || plugin == NULL)
591 		return (KMF_ERR_BAD_PARAMETER);
592 
593 	CLEAR_ERROR(handle, ret);
594 
595 	ret = test_attributes(num_req_attrs, required_attrs,
596 	    0, NULL, numattr, attrlist);
597 	if (ret != KMF_OK)
598 		return (ret);
599 
600 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
601 	    &kstype, &len);
602 	if (ret != KMF_OK)
603 		return (ret);
604 
605 	switch (kstype) {
606 	case KMF_KEYSTORE_NSS:
607 		*plugin = FindPlugin(handle, kstype);
608 		break;
609 
610 	case KMF_KEYSTORE_OPENSSL:
611 	case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
612 		*plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
613 		break;
614 	default:
615 		return (KMF_ERR_PLUGIN_NOTFOUND);
616 	}
617 	return (KMF_OK);
618 }
619 
620 KMF_RETURN
621 kmf_import_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
622 {
623 	KMF_RETURN ret;
624 	KMF_PLUGIN *plugin;
625 
626 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
627 	if (ret != KMF_OK)
628 		return (ret);
629 
630 	if (plugin == NULL)
631 		return (KMF_ERR_PLUGIN_NOTFOUND);
632 	else if (plugin->funclist->ImportCRL != NULL)
633 		return (plugin->funclist->ImportCRL(handle, numattr, attrlist));
634 
635 	return (KMF_ERR_FUNCTION_NOT_FOUND);
636 }
637 
638 KMF_RETURN
639 kmf_delete_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
640 {
641 	KMF_RETURN ret;
642 	KMF_PLUGIN *plugin;
643 
644 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
645 	if (ret != KMF_OK)
646 		return (ret);
647 
648 	if (plugin == NULL)
649 		return (KMF_ERR_PLUGIN_NOTFOUND);
650 	else if (plugin->funclist->DeleteCRL != NULL)
651 		return (plugin->funclist->DeleteCRL(handle, numattr, attrlist));
652 
653 	return (KMF_ERR_FUNCTION_NOT_FOUND);
654 }
655 
656 KMF_RETURN
657 kmf_list_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
658 {
659 	KMF_PLUGIN *plugin;
660 	KMF_RETURN ret;
661 
662 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
663 	if (ret != KMF_OK)
664 		return (ret);
665 
666 	if (plugin == NULL)
667 		return (KMF_ERR_PLUGIN_NOTFOUND);
668 	else if (plugin->funclist->ListCRL != NULL)
669 		return (plugin->funclist->ListCRL(handle, numattr, attrlist));
670 	return (KMF_ERR_FUNCTION_NOT_FOUND);
671 }
672 
673 KMF_RETURN
674 kmf_find_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
675 {
676 	KMF_PLUGIN *plugin;
677 	KMF_RETURN ret;
678 	KMF_KEYSTORE_TYPE kstype;
679 	uint32_t len = sizeof (kstype);
680 
681 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
682 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1,
683 	    sizeof (KMF_KEYSTORE_TYPE)},
684 	    {KMF_CRL_COUNT_ATTR, FALSE,
685 	    sizeof (char *), sizeof (char *)}
686 	};
687 
688 	int num_req_attrs = sizeof (required_attrs) /
689 	    sizeof (KMF_ATTRIBUTE_TESTER);
690 	if (handle == NULL)
691 		return (KMF_ERR_BAD_PARAMETER);
692 
693 	CLEAR_ERROR(handle, ret);
694 
695 	ret = test_attributes(num_req_attrs, required_attrs,
696 	    0, NULL, numattr, attrlist);
697 	if (ret != KMF_OK)
698 		return (ret);
699 
700 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
701 	    &kstype, &len);
702 	if (ret != KMF_OK)
703 		return (ret);
704 
705 	switch (kstype) {
706 	case KMF_KEYSTORE_NSS:
707 		plugin = FindPlugin(handle, kstype);
708 		break;
709 	case KMF_KEYSTORE_OPENSSL:
710 	case KMF_KEYSTORE_PK11TOKEN:
711 		return (KMF_ERR_FUNCTION_NOT_FOUND);
712 	default:
713 		/*
714 		 * FindCRL is only implemented for NSS. PKCS#11
715 		 * and file-based keystores just store in a file
716 		 * and don't need a "Find" function.
717 		 */
718 		return (KMF_ERR_PLUGIN_NOTFOUND);
719 	}
720 
721 	if (plugin == NULL)
722 		return (KMF_ERR_PLUGIN_NOTFOUND);
723 	else if (plugin->funclist->FindCRL != NULL) {
724 		return (plugin->funclist->FindCRL(handle, numattr,
725 		    attrlist));
726 	}
727 	return (KMF_ERR_FUNCTION_NOT_FOUND);
728 }
729 
730 KMF_RETURN
731 kmf_find_cert_in_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
732 {
733 	KMF_RETURN ret;
734 	KMF_PLUGIN *plugin;
735 
736 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
737 	if (ret != KMF_OK)
738 		return (ret);
739 
740 	if (plugin == NULL)
741 		return (KMF_ERR_PLUGIN_NOTFOUND);
742 	else if (plugin->funclist->FindCertInCRL != NULL)
743 		return (plugin->funclist->FindCertInCRL(handle, numattr,
744 		    attrlist));
745 
746 	return (KMF_ERR_FUNCTION_NOT_FOUND);
747 }
748 
749 KMF_RETURN
750 kmf_verify_crl_file(KMF_HANDLE_T handle, char *crlfile, KMF_DATA *tacert)
751 {
752 	KMF_PLUGIN *plugin;
753 	KMF_RETURN (*verifyCRLFile)(KMF_HANDLE_T, char *, KMF_DATA *);
754 
755 	if (handle == NULL)
756 		return (KMF_ERR_BAD_PARAMETER);
757 
758 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
759 	if (plugin == NULL || plugin->dldesc == NULL) {
760 		return (KMF_ERR_PLUGIN_NOTFOUND);
761 	}
762 
763 	verifyCRLFile = (KMF_RETURN(*)())dlsym(plugin->dldesc,
764 	    "OpenSSL_VerifyCRLFile");
765 
766 	if (verifyCRLFile == NULL) {
767 		return (KMF_ERR_FUNCTION_NOT_FOUND);
768 	}
769 
770 	return (verifyCRLFile(handle, crlfile, tacert));
771 }
772 
773 KMF_RETURN
774 kmf_check_crl_date(KMF_HANDLE_T handle, char *crlname)
775 {
776 	KMF_PLUGIN *plugin;
777 	KMF_RETURN (*checkCRLDate)(void *, char *);
778 	KMF_RETURN ret = KMF_OK;
779 
780 	if (handle == NULL)
781 		return (KMF_ERR_BAD_PARAMETER);
782 
783 	CLEAR_ERROR(handle, ret);
784 	if (ret != KMF_OK)
785 		return (ret);
786 
787 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
788 	if (plugin == NULL || plugin->dldesc == NULL) {
789 		return (KMF_ERR_PLUGIN_NOTFOUND);
790 	}
791 
792 	checkCRLDate = (KMF_RETURN(*)())dlsym(plugin->dldesc,
793 	    "OpenSSL_CheckCRLDate");
794 
795 	if (checkCRLDate == NULL) {
796 		return (KMF_ERR_FUNCTION_NOT_FOUND);
797 	}
798 
799 	return (checkCRLDate(handle, crlname));
800 }
801 
802 KMF_RETURN
803 kmf_is_crl_file(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat)
804 {
805 	KMF_PLUGIN *plugin;
806 	KMF_RETURN (*IsCRLFileFn)(void *, char *, KMF_ENCODE_FORMAT *);
807 	KMF_RETURN ret = KMF_OK;
808 
809 	CLEAR_ERROR(handle, ret);
810 	if (ret != KMF_OK)
811 		return (ret);
812 
813 	if (filename  == NULL || pformat == NULL) {
814 		return (KMF_ERR_BAD_PARAMETER);
815 	}
816 
817 	/*
818 	 * This framework function is actually implemented in the openssl
819 	 * plugin library, so we find the function address and call it.
820 	 */
821 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
822 	if (plugin == NULL || plugin->dldesc == NULL) {
823 		return (KMF_ERR_PLUGIN_NOTFOUND);
824 	}
825 
826 	IsCRLFileFn = (KMF_RETURN(*)())dlsym(plugin->dldesc,
827 	    "OpenSSL_IsCRLFile");
828 	if (IsCRLFileFn == NULL) {
829 		return (KMF_ERR_FUNCTION_NOT_FOUND);
830 	}
831 
832 	return (IsCRLFileFn(handle, filename, pformat));
833 }
834 
835 /*
836  * Phase 1 APIs still needed to maintain compat with elfsign.
837  */
838 KMF_RETURN
839 KMF_CreateCSRFile(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format,
840 	char *csrfile)
841 {
842 	return (kmf_create_csr_file(csrdata, format, csrfile));
843 }
844 
845 KMF_RETURN
846 KMF_SetCSRPubKey(KMF_HANDLE_T handle,
847 	KMF_KEY_HANDLE *KMFKey,
848 	KMF_CSR_DATA *Csr)
849 {
850 	return (kmf_set_csr_pubkey(handle, KMFKey, Csr));
851 }
852 
853 KMF_RETURN
854 KMF_SetCSRVersion(KMF_CSR_DATA *CsrData, uint32_t version)
855 {
856 	return (kmf_set_csr_version(CsrData, version));
857 }
858 
859 KMF_RETURN
860 KMF_SetCSRSignatureAlgorithm(KMF_CSR_DATA *CsrData,
861 	KMF_ALGORITHM_INDEX sigAlg)
862 {
863 	return (kmf_set_csr_sig_alg(CsrData, sigAlg));
864 }
865 
866 KMF_RETURN
867 KMF_SignCSR(KMF_HANDLE_T handle,
868 	const KMF_CSR_DATA *tbsCsr,
869 	KMF_KEY_HANDLE	*Signkey,
870 	KMF_DATA	*SignedCsr)
871 {
872 	return (kmf_sign_csr(handle, tbsCsr, Signkey, SignedCsr));
873 }
874 
875 KMF_RETURN
876 KMF_SetCSRSubjectName(KMF_CSR_DATA *CsrData,
877 	KMF_X509_NAME *subject_name_ptr)
878 {
879 	return (kmf_set_csr_subject(CsrData, subject_name_ptr));
880 }
881