199ebb4caSwyllys /*
299ebb4caSwyllys  * CDDL HEADER START
399ebb4caSwyllys  *
499ebb4caSwyllys  * The contents of this file are subject to the terms of the
599ebb4caSwyllys  * Common Development and Distribution License (the "License").
699ebb4caSwyllys  * You may not use this file except in compliance with the License.
799ebb4caSwyllys  *
899ebb4caSwyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
999ebb4caSwyllys  * or http://www.opensolaris.org/os/licensing.
1099ebb4caSwyllys  * See the License for the specific language governing permissions
1199ebb4caSwyllys  * and limitations under the License.
1299ebb4caSwyllys  *
1399ebb4caSwyllys  * When distributing Covered Code, include this CDDL HEADER in each
1499ebb4caSwyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1599ebb4caSwyllys  * If applicable, add the following below this CDDL HEADER, with the
1699ebb4caSwyllys  * fields enclosed by brackets "[]" replaced with your own identifying
1799ebb4caSwyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
1899ebb4caSwyllys  *
1999ebb4caSwyllys  * CDDL HEADER END
2030a5e8faSwyllys  *
219f0bc604SWyllys Ingersoll  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
2299ebb4caSwyllys  * Use is subject to license terms.
2399ebb4caSwyllys  */
2499ebb4caSwyllys 
2599ebb4caSwyllys #include <stdio.h>
2699ebb4caSwyllys #include <link.h>
2799ebb4caSwyllys #include <fcntl.h>
2899ebb4caSwyllys #include <ctype.h>
2999ebb4caSwyllys #include <sys/param.h>
3099ebb4caSwyllys #include <sys/types.h>
3199ebb4caSwyllys #include <sys/stat.h>
3299ebb4caSwyllys #include <sys/socket.h>
3399ebb4caSwyllys 
3499ebb4caSwyllys #include <ber_der.h>
3599ebb4caSwyllys #include <kmfapiP.h>
3699ebb4caSwyllys 
3799ebb4caSwyllys #include <pem_encode.h>
3899ebb4caSwyllys #include <libgen.h>
3999ebb4caSwyllys #include <cryptoutil.h>
4099ebb4caSwyllys 
4130a5e8faSwyllys static KMF_RETURN
4230a5e8faSwyllys setup_crl_call(KMF_HANDLE_T, int, KMF_ATTRIBUTE *, KMF_PLUGIN **);
4399ebb4caSwyllys 
4499ebb4caSwyllys /*
4599ebb4caSwyllys  *
4630a5e8faSwyllys  * Name: kmf_set_csr_pubkey
4799ebb4caSwyllys  *
4899ebb4caSwyllys  * Description:
4999ebb4caSwyllys  *   This function converts the specified plugin public key to SPKI form,
5099ebb4caSwyllys  *   and save it in the KMF_CSR_DATA internal structure
5199ebb4caSwyllys  *
5299ebb4caSwyllys  * Parameters:
5399ebb4caSwyllys  *   KMFkey(input) - pointer to the KMF_KEY_HANDLE structure containing the
5499ebb4caSwyllys  *		public key generated by the plug-in CreateKeypair
5599ebb4caSwyllys  *   Csr(input/output) - pointer to a KMF_CSR_DATA structure containing
5699ebb4caSwyllys  *		SPKI
5799ebb4caSwyllys  *
5899ebb4caSwyllys  * Returns:
5999ebb4caSwyllys  *   A KMF_RETURN value indicating success or specifying a particular
6099ebb4caSwyllys  *   error condition.
6199ebb4caSwyllys  *   The value KMF_OK indicates success. All other values represent
6299ebb4caSwyllys  *   an error condition.
6399ebb4caSwyllys  *
6499ebb4caSwyllys  */
6599ebb4caSwyllys KMF_RETURN
kmf_set_csr_pubkey(KMF_HANDLE_T handle,KMF_KEY_HANDLE * KMFKey,KMF_CSR_DATA * Csr)6630a5e8faSwyllys kmf_set_csr_pubkey(KMF_HANDLE_T handle,
6799ebb4caSwyllys 	KMF_KEY_HANDLE *KMFKey,
6899ebb4caSwyllys 	KMF_CSR_DATA *Csr)
6999ebb4caSwyllys {
7030a5e8faSwyllys 	KMF_RETURN ret;
7199ebb4caSwyllys 	KMF_X509_SPKI *spki_ptr;
7299ebb4caSwyllys 	KMF_PLUGIN *plugin;
73*6b35cb3cSRichard PALO 	KMF_DATA KeyData = { 0, NULL };
7499ebb4caSwyllys 
7599ebb4caSwyllys 	CLEAR_ERROR(handle, ret);
7699ebb4caSwyllys 	if (ret != KMF_OK)
7799ebb4caSwyllys 		return (ret);
7899ebb4caSwyllys 
7999ebb4caSwyllys 	if (KMFKey == NULL || Csr == NULL) {
8099ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
8199ebb4caSwyllys 	}
8299ebb4caSwyllys 
8399ebb4caSwyllys 	/* The keystore must extract the pubkey data */
8499ebb4caSwyllys 	plugin = FindPlugin(handle, KMFKey->kstype);
8599ebb4caSwyllys 	if (plugin != NULL && plugin->funclist->EncodePubkeyData != NULL) {
8699ebb4caSwyllys 		ret = plugin->funclist->EncodePubkeyData(handle,
8799ebb4caSwyllys 		    KMFKey, &KeyData);
8899ebb4caSwyllys 	} else {
8999ebb4caSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
9099ebb4caSwyllys 	}
9199ebb4caSwyllys 
9299ebb4caSwyllys 	spki_ptr = &Csr->csr.subjectPublicKeyInfo;
9399ebb4caSwyllys 
9499ebb4caSwyllys 	ret = DerDecodeSPKI(&KeyData, spki_ptr);
9599ebb4caSwyllys 
9630a5e8faSwyllys 	kmf_free_data(&KeyData);
9799ebb4caSwyllys 
9899ebb4caSwyllys 	return (ret);
9999ebb4caSwyllys }
10099ebb4caSwyllys 
10199ebb4caSwyllys KMF_RETURN
kmf_set_csr_version(KMF_CSR_DATA * CsrData,uint32_t version)10230a5e8faSwyllys kmf_set_csr_version(KMF_CSR_DATA *CsrData, uint32_t version)
10399ebb4caSwyllys {
10499ebb4caSwyllys 	if (CsrData == NULL)
10599ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
10699ebb4caSwyllys 
10799ebb4caSwyllys 	/*
10899ebb4caSwyllys 	 * From RFC 3280:
10999ebb4caSwyllys 	 * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
11099ebb4caSwyllys 	 */
11199ebb4caSwyllys 	if (version != 0 && version != 1 && version != 2)
11299ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
11399ebb4caSwyllys 	return (set_integer(&CsrData->csr.version, (void *)&version,
11430a5e8faSwyllys 	    sizeof (uint32_t)));
11599ebb4caSwyllys }
11699ebb4caSwyllys 
11799ebb4caSwyllys KMF_RETURN
kmf_set_csr_subject(KMF_CSR_DATA * CsrData,KMF_X509_NAME * subject_name_ptr)11830a5e8faSwyllys kmf_set_csr_subject(KMF_CSR_DATA *CsrData,
11999ebb4caSwyllys 	KMF_X509_NAME *subject_name_ptr)
12099ebb4caSwyllys {
12197732469Shaimay 	KMF_RETURN rv = KMF_OK;
12297732469Shaimay 	KMF_X509_NAME *temp_name_ptr = NULL;
12399ebb4caSwyllys 
12497732469Shaimay 	if (CsrData != NULL && subject_name_ptr != NULL) {
12597732469Shaimay 		rv = CopyRDN(subject_name_ptr, &temp_name_ptr);
12697732469Shaimay 		if (rv == KMF_OK) {
12797732469Shaimay 			CsrData->csr.subject = *temp_name_ptr;
12897732469Shaimay 		}
12997732469Shaimay 	} else {
13097732469Shaimay 		return (KMF_ERR_BAD_PARAMETER);
13197732469Shaimay 	}
13297732469Shaimay 	return (rv);
13399ebb4caSwyllys }
13499ebb4caSwyllys KMF_RETURN
kmf_create_csr_file(KMF_DATA * csrdata,KMF_ENCODE_FORMAT format,char * csrfile)13530a5e8faSwyllys kmf_create_csr_file(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format,
13699ebb4caSwyllys 	char *csrfile)
13799ebb4caSwyllys {
13899ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
13999ebb4caSwyllys 	int fd = -1;
140*6b35cb3cSRichard PALO 	KMF_DATA pemdata = { 0, NULL };
14199ebb4caSwyllys 
14299ebb4caSwyllys 	if (csrdata == NULL || csrfile == NULL)
14399ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
14499ebb4caSwyllys 
14599ebb4caSwyllys 	if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1)
14699ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
14799ebb4caSwyllys 
14899ebb4caSwyllys 	if (format == KMF_FORMAT_PEM) {
14999ebb4caSwyllys 		int len;
15030a5e8faSwyllys 		rv = kmf_der_to_pem(KMF_CSR,
15130a5e8faSwyllys 		    csrdata->Data, csrdata->Length,
15230a5e8faSwyllys 		    &pemdata.Data, &len);
15399ebb4caSwyllys 		if (rv != KMF_OK)
15499ebb4caSwyllys 			goto cleanup;
15599ebb4caSwyllys 		pemdata.Length = (size_t)len;
15699ebb4caSwyllys 	}
15799ebb4caSwyllys 
15899ebb4caSwyllys 	if ((fd = open(csrfile, O_CREAT |O_RDWR, 0644)) == -1) {
15999ebb4caSwyllys 		rv = KMF_ERR_OPEN_FILE;
16099ebb4caSwyllys 		goto cleanup;
16199ebb4caSwyllys 	}
16299ebb4caSwyllys 
16399ebb4caSwyllys 	if (format == KMF_FORMAT_PEM) {
16499ebb4caSwyllys 		if (write(fd, pemdata.Data, pemdata.Length) !=
16530a5e8faSwyllys 		    pemdata.Length) {
16699ebb4caSwyllys 			rv = KMF_ERR_WRITE_FILE;
16799ebb4caSwyllys 		}
16899ebb4caSwyllys 	} else {
16999ebb4caSwyllys 		if (write(fd, csrdata->Data, csrdata->Length) !=
17030a5e8faSwyllys 		    csrdata->Length) {
17199ebb4caSwyllys 			rv = KMF_ERR_WRITE_FILE;
17299ebb4caSwyllys 		}
17399ebb4caSwyllys 	}
17499ebb4caSwyllys 
17599ebb4caSwyllys cleanup:
17699ebb4caSwyllys 	if (fd != -1)
17799ebb4caSwyllys 		(void) close(fd);
17899ebb4caSwyllys 
17930a5e8faSwyllys 	kmf_free_data(&pemdata);
18099ebb4caSwyllys 
18199ebb4caSwyllys 	return (rv);
18299ebb4caSwyllys }
18399ebb4caSwyllys 
18499ebb4caSwyllys KMF_RETURN
kmf_set_csr_extn(KMF_CSR_DATA * Csr,KMF_X509_EXTENSION * extn)18530a5e8faSwyllys kmf_set_csr_extn(KMF_CSR_DATA *Csr, KMF_X509_EXTENSION *extn)
18699ebb4caSwyllys {
18799ebb4caSwyllys 	KMF_RETURN ret = KMF_OK;
18899ebb4caSwyllys 	KMF_X509_EXTENSIONS *exts;
18999ebb4caSwyllys 
19099ebb4caSwyllys 	if (Csr == NULL || extn == NULL)
19199ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
19299ebb4caSwyllys 
19399ebb4caSwyllys 	exts = &Csr->csr.extensions;
19499ebb4caSwyllys 
19599ebb4caSwyllys 	ret = add_an_extension(exts, extn);
19699ebb4caSwyllys 
19799ebb4caSwyllys 	return (ret);
19899ebb4caSwyllys }
19999ebb4caSwyllys 
20099ebb4caSwyllys KMF_RETURN
kmf_set_csr_sig_alg(KMF_CSR_DATA * CsrData,KMF_ALGORITHM_INDEX sigAlg)20130a5e8faSwyllys kmf_set_csr_sig_alg(KMF_CSR_DATA *CsrData,
20299ebb4caSwyllys 	KMF_ALGORITHM_INDEX sigAlg)
20399ebb4caSwyllys {
20499ebb4caSwyllys 	KMF_OID	*alg;
20599ebb4caSwyllys 
20699ebb4caSwyllys 	if (CsrData == NULL)
20799ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
20899ebb4caSwyllys 
20930a5e8faSwyllys 	alg = x509_algid_to_algoid(sigAlg);
21099ebb4caSwyllys 
21199ebb4caSwyllys 	if (alg != NULL) {
21299ebb4caSwyllys 		(void) copy_data((KMF_DATA *)
21330a5e8faSwyllys 		    &CsrData->signature.algorithmIdentifier.algorithm,
21430a5e8faSwyllys 		    (KMF_DATA *)alg);
21599ebb4caSwyllys 		(void) copy_data(
21699ebb4caSwyllys 		    &CsrData->signature.algorithmIdentifier.parameters,
21799ebb4caSwyllys 		    &CsrData->csr.subjectPublicKeyInfo.algorithm.parameters);
21899ebb4caSwyllys 	} else {
21999ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
22099ebb4caSwyllys 	}
22199ebb4caSwyllys 	return (KMF_OK);
22299ebb4caSwyllys }
22399ebb4caSwyllys 
22499ebb4caSwyllys KMF_RETURN
kmf_set_csr_subject_altname(KMF_CSR_DATA * Csr,char * altname,int critical,KMF_GENERALNAMECHOICES alttype)22530a5e8faSwyllys kmf_set_csr_subject_altname(KMF_CSR_DATA *Csr,
22699ebb4caSwyllys 	char *altname, int critical,
22799ebb4caSwyllys 	KMF_GENERALNAMECHOICES alttype)
22899ebb4caSwyllys {
22999ebb4caSwyllys 	KMF_RETURN ret = KMF_OK;
23099ebb4caSwyllys 
23199ebb4caSwyllys 	if (Csr == NULL || altname == NULL)
23299ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
23399ebb4caSwyllys 
23430a5e8faSwyllys 	ret = kmf_set_altname(&Csr->csr.extensions,
23530a5e8faSwyllys 	    (KMF_OID *)&KMFOID_SubjectAltName, critical, alttype,
23630a5e8faSwyllys 	    altname);
23799ebb4caSwyllys 
23899ebb4caSwyllys 	return (ret);
23999ebb4caSwyllys }
24099ebb4caSwyllys 
24199ebb4caSwyllys KMF_RETURN
kmf_set_csr_ku(KMF_CSR_DATA * CSRData,int critical,uint16_t kubits)24230a5e8faSwyllys kmf_set_csr_ku(KMF_CSR_DATA *CSRData,
24399ebb4caSwyllys 	int critical, uint16_t kubits)
24499ebb4caSwyllys {
24599ebb4caSwyllys 	KMF_RETURN ret = KMF_OK;
24699ebb4caSwyllys 
24799ebb4caSwyllys 	if (CSRData == NULL)
24899ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
24999ebb4caSwyllys 
25099ebb4caSwyllys 	ret = set_key_usage_extension(
25130a5e8faSwyllys 	    &CSRData->csr.extensions, critical, kubits);
25230a5e8faSwyllys 
25330a5e8faSwyllys 	return (ret);
25430a5e8faSwyllys }
25530a5e8faSwyllys 
256d00756ccSwyllys KMF_RETURN
kmf_add_csr_eku(KMF_CSR_DATA * CSRData,KMF_OID * ekuOID,int critical)257d00756ccSwyllys kmf_add_csr_eku(KMF_CSR_DATA *CSRData, KMF_OID *ekuOID,
258d00756ccSwyllys 	int critical)
259d00756ccSwyllys {
260d00756ccSwyllys 	KMF_RETURN ret = KMF_OK;
261d00756ccSwyllys 	KMF_X509_EXTENSION *foundextn;
262d00756ccSwyllys 	KMF_X509_EXTENSION newextn;
263d00756ccSwyllys 	BerElement *asn1 = NULL;
264d00756ccSwyllys 	BerValue *extdata = NULL;
265d00756ccSwyllys 	char *olddata = NULL;
266d00756ccSwyllys 	size_t oldsize = 0;
267d00756ccSwyllys 	KMF_X509EXT_EKU ekudata;
268d00756ccSwyllys 
269d00756ccSwyllys 	if (CSRData == NULL || ekuOID == NULL)
270d00756ccSwyllys 		return (KMF_ERR_BAD_PARAMETER);
271d00756ccSwyllys 
272d00756ccSwyllys 	(void) memset(&ekudata, 0, sizeof (KMF_X509EXT_EKU));
273d00756ccSwyllys 	(void) memset(&newextn, 0, sizeof (newextn));
274d00756ccSwyllys 
275d00756ccSwyllys 	foundextn = FindExtn(&CSRData->csr.extensions,
276d00756ccSwyllys 	    (KMF_OID *)&KMFOID_ExtendedKeyUsage);
277d00756ccSwyllys 	if (foundextn != NULL) {
278d00756ccSwyllys 		ret = GetSequenceContents((char *)foundextn->BERvalue.Data,
279d00756ccSwyllys 		    foundextn->BERvalue.Length, &olddata, &oldsize);
280d00756ccSwyllys 		if (ret != KMF_OK)
281d00756ccSwyllys 			goto out;
282d00756ccSwyllys 
283d00756ccSwyllys 		/*
284d00756ccSwyllys 		 * If the EKU is already in the cert, then just return OK.
285d00756ccSwyllys 		 */
286d00756ccSwyllys 		ret = parse_eku_data(&foundextn->BERvalue, &ekudata);
287d00756ccSwyllys 		if (ret == KMF_OK) {
288d00756ccSwyllys 			if (is_eku_present(&ekudata, ekuOID)) {
289d00756ccSwyllys 				goto out;
290d00756ccSwyllys 			}
291d00756ccSwyllys 		}
292d00756ccSwyllys 	}
293d00756ccSwyllys 	if ((asn1 = kmfder_alloc()) == NULL)
294d00756ccSwyllys 		return (KMF_ERR_MEMORY);
295d00756ccSwyllys 
296d00756ccSwyllys 	if (kmfber_printf(asn1, "{") == -1) {
297d00756ccSwyllys 		ret = KMF_ERR_ENCODING;
298d00756ccSwyllys 		goto out;
299d00756ccSwyllys 	}
300d00756ccSwyllys 
301d00756ccSwyllys 	/* Write the old extension data first */
302d00756ccSwyllys 	if (olddata != NULL && oldsize > 0) {
303d00756ccSwyllys 		if (kmfber_write(asn1, olddata, oldsize, 0) == -1) {
304d00756ccSwyllys 			ret = KMF_ERR_ENCODING;
305d00756ccSwyllys 			goto out;
306d00756ccSwyllys 		}
307d00756ccSwyllys 	}
308d00756ccSwyllys 
309d00756ccSwyllys 	/* Append this EKU OID and close the sequence */
310d00756ccSwyllys 	if (kmfber_printf(asn1, "D}", ekuOID) == -1) {
311d00756ccSwyllys 		ret = KMF_ERR_ENCODING;
312d00756ccSwyllys 		goto out;
313d00756ccSwyllys 	}
314d00756ccSwyllys 
315d00756ccSwyllys 	if (kmfber_flatten(asn1, &extdata) == -1) {
316d00756ccSwyllys 		ret = KMF_ERR_ENCODING;
317d00756ccSwyllys 		goto out;
318d00756ccSwyllys 	}
319d00756ccSwyllys 
320d00756ccSwyllys 	/*
321d00756ccSwyllys 	 * If we are just adding to an existing list of EKU OIDs,
322d00756ccSwyllys 	 * just replace the BER data associated with the found extension.
323d00756ccSwyllys 	 */
324d00756ccSwyllys 	if (foundextn != NULL) {
325d00756ccSwyllys 		free(foundextn->BERvalue.Data);
326d00756ccSwyllys 		foundextn->critical = critical;
327d00756ccSwyllys 		foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val;
328d00756ccSwyllys 		foundextn->BERvalue.Length = extdata->bv_len;
329d00756ccSwyllys 	} else {
330d00756ccSwyllys 		ret = copy_data(&newextn.extnId,
331d00756ccSwyllys 		    (KMF_DATA *)&KMFOID_ExtendedKeyUsage);
332d00756ccSwyllys 		if (ret != KMF_OK)
333d00756ccSwyllys 			goto out;
334d00756ccSwyllys 		newextn.critical = critical;
335d00756ccSwyllys 		newextn.format = KMF_X509_DATAFORMAT_ENCODED;
336d00756ccSwyllys 		newextn.BERvalue.Data = (uchar_t *)extdata->bv_val;
337d00756ccSwyllys 		newextn.BERvalue.Length = extdata->bv_len;
338d00756ccSwyllys 		ret = kmf_set_csr_extn(CSRData, &newextn);
339d00756ccSwyllys 		if (ret != KMF_OK)
340d00756ccSwyllys 			free(newextn.BERvalue.Data);
341d00756ccSwyllys 	}
342d00756ccSwyllys 
343d00756ccSwyllys out:
344d00756ccSwyllys 	kmf_free_eku(&ekudata);
345d00756ccSwyllys 	if (extdata != NULL)
346d00756ccSwyllys 		free(extdata);
347d00756ccSwyllys 
348d00756ccSwyllys 	if (olddata != NULL)
349d00756ccSwyllys 		free(olddata);
350d00756ccSwyllys 
351d00756ccSwyllys 	if (asn1 != NULL)
352d00756ccSwyllys 		kmfber_free(asn1, 1);
353d00756ccSwyllys 
354d00756ccSwyllys 	if (ret != KMF_OK)
355d00756ccSwyllys 		kmf_free_data(&newextn.extnId);
356d00756ccSwyllys 
357d00756ccSwyllys 	return (ret);
358d00756ccSwyllys }
359d00756ccSwyllys 
36030a5e8faSwyllys static KMF_RETURN
sign_csr(KMF_HANDLE_T handle,const KMF_DATA * SubjectCsr,KMF_KEY_HANDLE * Signkey,KMF_X509_ALGORITHM_IDENTIFIER * algo,KMF_DATA * SignedCsr)361d00756ccSwyllys sign_csr(KMF_HANDLE_T handle,
36230a5e8faSwyllys 	const KMF_DATA *SubjectCsr,
36330a5e8faSwyllys 	KMF_KEY_HANDLE	*Signkey,
36430a5e8faSwyllys 	KMF_X509_ALGORITHM_IDENTIFIER *algo,
36530a5e8faSwyllys 	KMF_DATA	*SignedCsr)
36630a5e8faSwyllys {
36730a5e8faSwyllys 	KMF_CSR_DATA	subj_csr;
36830a5e8faSwyllys 	KMF_TBS_CSR	*tbs_csr = NULL;
369*6b35cb3cSRichard PALO 	KMF_DATA	signed_data = { 0, NULL };
37030a5e8faSwyllys 	KMF_RETURN	ret = KMF_OK;
3719f0bc604SWyllys Ingersoll 	KMF_ATTRIBUTE	attlist[5];
372e65e5c2dSWyllys Ingersoll 	KMF_ALGORITHM_INDEX algid;
3739f0bc604SWyllys Ingersoll 	int i = 0;
37430a5e8faSwyllys 
37530a5e8faSwyllys 	if (!SignedCsr)
37630a5e8faSwyllys 		return (KMF_ERR_BAD_PARAMETER);
37730a5e8faSwyllys 
37830a5e8faSwyllys 	SignedCsr->Length = 0;
37930a5e8faSwyllys 	SignedCsr->Data = NULL;
38030a5e8faSwyllys 
38130a5e8faSwyllys 	if (!SubjectCsr)
38230a5e8faSwyllys 		return (KMF_ERR_BAD_PARAMETER);
38330a5e8faSwyllys 
38430a5e8faSwyllys 	if (!SubjectCsr->Data || !SubjectCsr->Length)
38530a5e8faSwyllys 		return (KMF_ERR_BAD_PARAMETER);
38630a5e8faSwyllys 
38730a5e8faSwyllys 	(void) memset(&subj_csr, 0, sizeof (subj_csr));
38830a5e8faSwyllys 	/* Estimate the signed data length generously */
38930a5e8faSwyllys 	signed_data.Length = SubjectCsr->Length*2;
39030a5e8faSwyllys 	signed_data.Data = calloc(1, signed_data.Length);
39130a5e8faSwyllys 	if (!signed_data.Data) {
39230a5e8faSwyllys 		ret = KMF_ERR_MEMORY;
39330a5e8faSwyllys 		goto cleanup;
39430a5e8faSwyllys 	}
39530a5e8faSwyllys 
3969f0bc604SWyllys Ingersoll 	kmf_set_attr_at_index(attlist, i++,
3979f0bc604SWyllys Ingersoll 	    KMF_KEYSTORE_TYPE_ATTR, &Signkey->kstype,
3989f0bc604SWyllys Ingersoll 	    sizeof (Signkey->kstype));
3999f0bc604SWyllys Ingersoll 
4009f0bc604SWyllys Ingersoll 	kmf_set_attr_at_index(attlist, i++,
4019f0bc604SWyllys Ingersoll 	    KMF_KEY_HANDLE_ATTR, Signkey, sizeof (KMF_KEY_HANDLE));
4029f0bc604SWyllys Ingersoll 
4039f0bc604SWyllys Ingersoll 	kmf_set_attr_at_index(attlist, i++, KMF_OID_ATTR, &algo->algorithm,
4049f0bc604SWyllys Ingersoll 	    sizeof (KMF_OID));
40530a5e8faSwyllys 
4069f0bc604SWyllys Ingersoll 	kmf_set_attr_at_index(attlist, i++, KMF_DATA_ATTR,
4079f0bc604SWyllys Ingersoll 	    (KMF_DATA *)SubjectCsr, sizeof (KMF_DATA));
4089f0bc604SWyllys Ingersoll 
4099f0bc604SWyllys Ingersoll 	kmf_set_attr_at_index(attlist, i++, KMF_OUT_DATA_ATTR,
4109f0bc604SWyllys Ingersoll 	    &signed_data, sizeof (KMF_DATA));
4119f0bc604SWyllys Ingersoll 
4129f0bc604SWyllys Ingersoll 	ret = kmf_sign_data(handle, i, attlist);
41330a5e8faSwyllys 	if (KMF_OK != ret)
41430a5e8faSwyllys 		goto cleanup;
41530a5e8faSwyllys 	/*
41630a5e8faSwyllys 	 * If we got here OK, decode into a structure and then re-encode
41730a5e8faSwyllys 	 * the complete CSR.
41830a5e8faSwyllys 	 */
41930a5e8faSwyllys 	ret = DerDecodeTbsCsr(SubjectCsr, &tbs_csr);
42030a5e8faSwyllys 	if (ret)
42130a5e8faSwyllys 		goto cleanup;
42230a5e8faSwyllys 
42330a5e8faSwyllys 	(void) memcpy(&subj_csr.csr, tbs_csr, sizeof (KMF_TBS_CSR));
42430a5e8faSwyllys 
42530a5e8faSwyllys 	ret = copy_algoid(&subj_csr.signature.algorithmIdentifier, algo);
42630a5e8faSwyllys 	if (ret)
42730a5e8faSwyllys 		goto cleanup;
42830a5e8faSwyllys 
429e65e5c2dSWyllys Ingersoll 	algid = x509_algoid_to_algid(&algo->algorithm);
430e65e5c2dSWyllys Ingersoll 	if (algid == KMF_ALGID_SHA1WithDSA ||
431e65e5c2dSWyllys Ingersoll 	    algid == KMF_ALGID_SHA256WithDSA ||
432e65e5c2dSWyllys Ingersoll 	    algid == KMF_ALGID_SHA1WithECDSA ||
433e65e5c2dSWyllys Ingersoll 	    algid == KMF_ALGID_SHA256WithECDSA ||
434e65e5c2dSWyllys Ingersoll 	    algid == KMF_ALGID_SHA384WithECDSA ||
435e65e5c2dSWyllys Ingersoll 	    algid == KMF_ALGID_SHA512WithECDSA) {
436e65e5c2dSWyllys Ingersoll 		/*
437e65e5c2dSWyllys Ingersoll 		 * For DSA and ECDSA, we must encode the
438e65e5c2dSWyllys Ingersoll 		 * signature correctly.
439e65e5c2dSWyllys Ingersoll 		 */
440e65e5c2dSWyllys Ingersoll 		KMF_DATA signature;
441e65e5c2dSWyllys Ingersoll 
442e65e5c2dSWyllys Ingersoll 		ret = DerEncodeDSASignature(&signed_data, &signature);
443e65e5c2dSWyllys Ingersoll 		kmf_free_data(&signed_data);
444e65e5c2dSWyllys Ingersoll 
445e65e5c2dSWyllys Ingersoll 		if (ret != KMF_OK)
446e65e5c2dSWyllys Ingersoll 			goto cleanup;
447e65e5c2dSWyllys Ingersoll 
448e65e5c2dSWyllys Ingersoll 		subj_csr.signature.encrypted = signature;
449e65e5c2dSWyllys Ingersoll 	} else {
450e65e5c2dSWyllys Ingersoll 		subj_csr.signature.encrypted = signed_data;
451e65e5c2dSWyllys Ingersoll 	}
45230a5e8faSwyllys 
45330a5e8faSwyllys 	/* Now, re-encode the CSR with the new signature */
45430a5e8faSwyllys 	ret = DerEncodeSignedCsr(&subj_csr, SignedCsr);
45530a5e8faSwyllys 	if (ret != KMF_OK) {
45630a5e8faSwyllys 		kmf_free_data(SignedCsr);
45730a5e8faSwyllys 		goto cleanup;
45830a5e8faSwyllys 	}
45930a5e8faSwyllys 
46030a5e8faSwyllys 	/* Cleanup & return */
46130a5e8faSwyllys cleanup:
46230a5e8faSwyllys 	free(tbs_csr);
46330a5e8faSwyllys 
46430a5e8faSwyllys 	kmf_free_tbs_csr(&subj_csr.csr);
46530a5e8faSwyllys 
46630a5e8faSwyllys 	kmf_free_algoid(&subj_csr.signature.algorithmIdentifier);
46730a5e8faSwyllys 	kmf_free_data(&signed_data);
46899ebb4caSwyllys 
46999ebb4caSwyllys 	return (ret);
47099ebb4caSwyllys }
47199ebb4caSwyllys 
47299ebb4caSwyllys /*
47399ebb4caSwyllys  *
47430a5e8faSwyllys  * Name: kmf_sign_csr
47599ebb4caSwyllys  *
47699ebb4caSwyllys  * Description:
47799ebb4caSwyllys  *   This function signs a CSR and returns the result as a
47899ebb4caSwyllys  *   signed, encoded CSR in SignedCsr
47999ebb4caSwyllys  *
48099ebb4caSwyllys  * Parameters:
48199ebb4caSwyllys  *   tbsCsr(input) - pointer to a KMF_DATA structure containing a
48299ebb4caSwyllys  *		DER encoded TBS CSR data
48399ebb4caSwyllys  *   Signkey(input) - pointer to the KMF_KEY_HANDLE structure containing
48499ebb4caSwyllys  *		the private key generated by the plug-in CreateKeypair
48599ebb4caSwyllys  *   algo(input) - contains algorithm info needed for signing
48699ebb4caSwyllys  *   SignedCsr(output) - pointer to the KMF_DATA structure containing
48799ebb4caSwyllys  *		the signed CSR
48899ebb4caSwyllys  *
48999ebb4caSwyllys  * Returns:
49099ebb4caSwyllys  *   A KMF_RETURN value indicating success or specifying a particular
49199ebb4caSwyllys  *   error condition.
49299ebb4caSwyllys  *   The value KMF_OK indicates success. All other values represent
49399ebb4caSwyllys  *   an error condition.
49499ebb4caSwyllys  *
49599ebb4caSwyllys  */
49699ebb4caSwyllys KMF_RETURN
kmf_sign_csr(KMF_HANDLE_T handle,const KMF_CSR_DATA * tbsCsr,KMF_KEY_HANDLE * Signkey,KMF_DATA * SignedCsr)49730a5e8faSwyllys kmf_sign_csr(KMF_HANDLE_T handle,
49899ebb4caSwyllys 	const KMF_CSR_DATA *tbsCsr,
49999ebb4caSwyllys 	KMF_KEY_HANDLE	*Signkey,
50099ebb4caSwyllys 	KMF_DATA	*SignedCsr)
50199ebb4caSwyllys {
50299ebb4caSwyllys 	KMF_RETURN err;
503*6b35cb3cSRichard PALO 	KMF_DATA csrdata = { 0, NULL };
50499ebb4caSwyllys 
50599ebb4caSwyllys 	CLEAR_ERROR(handle, err);
50699ebb4caSwyllys 	if (err != KMF_OK)
50799ebb4caSwyllys 		return (err);
50899ebb4caSwyllys 
50930a5e8faSwyllys 	if (tbsCsr == NULL || Signkey == NULL || SignedCsr == NULL)
51099ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
51199ebb4caSwyllys 
51299ebb4caSwyllys 	SignedCsr->Data = NULL;
51399ebb4caSwyllys 	SignedCsr->Length = 0;
51499ebb4caSwyllys 
51599ebb4caSwyllys 	err = DerEncodeTbsCsr((KMF_TBS_CSR *)&tbsCsr->csr, &csrdata);
51699ebb4caSwyllys 	if (err == KMF_OK) {
517d00756ccSwyllys 		err = sign_csr(handle, &csrdata, Signkey,
51830a5e8faSwyllys 		    (KMF_X509_ALGORITHM_IDENTIFIER *)
51930a5e8faSwyllys 		    &tbsCsr->signature.algorithmIdentifier,
52030a5e8faSwyllys 		    SignedCsr);
52199ebb4caSwyllys 	}
52299ebb4caSwyllys 
52399ebb4caSwyllys 	if (err != KMF_OK) {
52430a5e8faSwyllys 		kmf_free_data(SignedCsr);
52599ebb4caSwyllys 	}
52630a5e8faSwyllys 	kmf_free_data(&csrdata);
52799ebb4caSwyllys 	return (err);
52899ebb4caSwyllys }
52999ebb4caSwyllys 
530d00756ccSwyllys /*
531d00756ccSwyllys  * kmf_decode_csr
532d00756ccSwyllys  *
533d00756ccSwyllys  * Description:
534d00756ccSwyllys  *   This function decodes raw CSR data and fills in the KMF_CSR_DATA
535d00756ccSwyllys  *   record.
536d00756ccSwyllys  *
537d00756ccSwyllys  * Inputs:
538d00756ccSwyllys  *	KMF_HANDLE_T handle
539d00756ccSwyllys  *	KMF_DATA *rawcsr
540d00756ccSwyllys  *	KMF_CSR_DATA *csrdata;
541d00756ccSwyllys  */
542d00756ccSwyllys KMF_RETURN
kmf_decode_csr(KMF_HANDLE_T handle,KMF_DATA * rawcsr,KMF_CSR_DATA * csrdata)543d00756ccSwyllys kmf_decode_csr(KMF_HANDLE_T handle, KMF_DATA *rawcsr, KMF_CSR_DATA *csrdata)
544d00756ccSwyllys {
545d00756ccSwyllys 	KMF_RETURN rv;
546d00756ccSwyllys 	KMF_CSR_DATA *cdata = NULL;
547d00756ccSwyllys 
548d00756ccSwyllys 	if (handle == NULL || rawcsr == NULL || csrdata == NULL)
549d00756ccSwyllys 		return (KMF_ERR_BAD_PARAMETER);
550d00756ccSwyllys 
551d00756ccSwyllys 	rv = DerDecodeSignedCsr(rawcsr, &cdata);
552d00756ccSwyllys 	if (rv != KMF_OK)
553d00756ccSwyllys 		return (rv);
554d00756ccSwyllys 
555d00756ccSwyllys 	(void) memcpy(csrdata, cdata, sizeof (KMF_CSR_DATA));
556d00756ccSwyllys 
557d00756ccSwyllys 	free(cdata);
558d00756ccSwyllys 	return (rv);
559d00756ccSwyllys }
560d00756ccSwyllys 
561d00756ccSwyllys KMF_RETURN
kmf_verify_csr(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)562d00756ccSwyllys kmf_verify_csr(KMF_HANDLE_T handle, int numattr,
563d00756ccSwyllys 	KMF_ATTRIBUTE *attrlist)
564d00756ccSwyllys {
565d00756ccSwyllys 	KMF_RETURN rv = KMF_OK;
566d00756ccSwyllys 	KMF_CSR_DATA *csrdata = NULL;
567d00756ccSwyllys 	KMF_ALGORITHM_INDEX algid;
568d00756ccSwyllys 	KMF_X509_ALGORITHM_IDENTIFIER *x509alg;
569d00756ccSwyllys 	KMF_DATA rawcsr;
570d00756ccSwyllys 
571d00756ccSwyllys 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
572d00756ccSwyllys 	    {KMF_CSR_DATA_ATTR, FALSE, sizeof (KMF_CSR_DATA),
573d00756ccSwyllys 	    sizeof (KMF_CSR_DATA)},
574d00756ccSwyllys 	};
575d00756ccSwyllys 
576d00756ccSwyllys 	int num_req_attrs = sizeof (required_attrs) /
577d00756ccSwyllys 	    sizeof (KMF_ATTRIBUTE_TESTER);
578d00756ccSwyllys 
579d00756ccSwyllys 	if (handle == NULL)
580d00756ccSwyllys 		return (KMF_ERR_BAD_PARAMETER);
581d00756ccSwyllys 
582d00756ccSwyllys 	CLEAR_ERROR(handle, rv);
583d00756ccSwyllys 
584d00756ccSwyllys 	rv = test_attributes(num_req_attrs, required_attrs,
585d00756ccSwyllys 	    0, NULL, numattr, attrlist);
586d00756ccSwyllys 	if (rv != KMF_OK)
587d00756ccSwyllys 		return (rv);
588d00756ccSwyllys 
589d00756ccSwyllys 	csrdata = kmf_get_attr_ptr(KMF_CSR_DATA_ATTR, attrlist, numattr);
590d00756ccSwyllys 	if (csrdata == NULL)
591d00756ccSwyllys 		return (KMF_ERR_BAD_PARAMETER);
592d00756ccSwyllys 
593d00756ccSwyllys 	rv = DerEncodeTbsCsr(&csrdata->csr, &rawcsr);
594d00756ccSwyllys 	if (rv != KMF_OK)
595d00756ccSwyllys 		return (rv);
596d00756ccSwyllys 
597d00756ccSwyllys 	x509alg = &csrdata->signature.algorithmIdentifier;
598d00756ccSwyllys 	algid = x509_algoid_to_algid(&x509alg->algorithm);
599e65e5c2dSWyllys Ingersoll 	if (algid == KMF_ALGID_SHA1WithDSA ||
600e65e5c2dSWyllys Ingersoll 	    algid == KMF_ALGID_SHA256WithDSA) {
601e65e5c2dSWyllys Ingersoll 		/* Decode the DSA signature before verifying it */
602e65e5c2dSWyllys Ingersoll 		KMF_DATA signature;
603e65e5c2dSWyllys Ingersoll 		rv = DerDecodeDSASignature(&csrdata->signature.encrypted,
604e65e5c2dSWyllys Ingersoll 		    &signature);
605e65e5c2dSWyllys Ingersoll 		if (rv != KMF_OK)
606e65e5c2dSWyllys Ingersoll 			goto end;
607e65e5c2dSWyllys Ingersoll 
608e65e5c2dSWyllys Ingersoll 		rv = PKCS_VerifyData(handle, algid,
609e65e5c2dSWyllys Ingersoll 		    &csrdata->csr.subjectPublicKeyInfo,
610e65e5c2dSWyllys Ingersoll 		    &rawcsr, &signature);
611e65e5c2dSWyllys Ingersoll 
612e65e5c2dSWyllys Ingersoll 		kmf_free_data(&signature);
613e65e5c2dSWyllys Ingersoll 	} else if (algid == KMF_ALGID_SHA1WithECDSA ||
614e65e5c2dSWyllys Ingersoll 	    algid == KMF_ALGID_SHA256WithECDSA ||
615e65e5c2dSWyllys Ingersoll 	    algid == KMF_ALGID_SHA384WithECDSA ||
616e65e5c2dSWyllys Ingersoll 	    algid == KMF_ALGID_SHA512WithECDSA) {
617e65e5c2dSWyllys Ingersoll 		KMF_DATA signature;
618e65e5c2dSWyllys Ingersoll 		rv = DerDecodeECDSASignature(&csrdata->signature.encrypted,
619e65e5c2dSWyllys Ingersoll 		    &signature);
620e65e5c2dSWyllys Ingersoll 		if (rv != KMF_OK)
621e65e5c2dSWyllys Ingersoll 			goto end;
622d00756ccSwyllys 
623e65e5c2dSWyllys Ingersoll 		rv = PKCS_VerifyData(handle, algid,
624e65e5c2dSWyllys Ingersoll 		    &csrdata->csr.subjectPublicKeyInfo,
625e65e5c2dSWyllys Ingersoll 		    &rawcsr, &signature);
626d00756ccSwyllys 
627e65e5c2dSWyllys Ingersoll 		kmf_free_data(&signature);
628e65e5c2dSWyllys Ingersoll 	} else {
629e65e5c2dSWyllys Ingersoll 		rv = PKCS_VerifyData(handle, algid,
630e65e5c2dSWyllys Ingersoll 		    &csrdata->csr.subjectPublicKeyInfo,
631e65e5c2dSWyllys Ingersoll 		    &rawcsr,
632e65e5c2dSWyllys Ingersoll 		    &csrdata->signature.encrypted);
633e65e5c2dSWyllys Ingersoll 	}
634e65e5c2dSWyllys Ingersoll 
635e65e5c2dSWyllys Ingersoll end:
636d00756ccSwyllys 	kmf_free_data(&rawcsr);
637d00756ccSwyllys 	return (rv);
638d00756ccSwyllys }
639d00756ccSwyllys 
64030a5e8faSwyllys static KMF_RETURN
setup_crl_call(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist,KMF_PLUGIN ** plugin)64130a5e8faSwyllys setup_crl_call(KMF_HANDLE_T handle, int numattr,
64230a5e8faSwyllys 	KMF_ATTRIBUTE *attrlist, KMF_PLUGIN **plugin)
64399ebb4caSwyllys {
64499ebb4caSwyllys 	KMF_RETURN ret;
64530a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype;
64630a5e8faSwyllys 	uint32_t len = sizeof (kstype);
64730a5e8faSwyllys 
64830a5e8faSwyllys 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
64930a5e8faSwyllys 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}
65030a5e8faSwyllys 	};
65130a5e8faSwyllys 
65230a5e8faSwyllys 	int num_req_attrs = sizeof (required_attrs) /
65330a5e8faSwyllys 	    sizeof (KMF_ATTRIBUTE_TESTER);
65430a5e8faSwyllys 
65530a5e8faSwyllys 	if (handle == NULL || plugin == NULL)
65630a5e8faSwyllys 		return (KMF_ERR_BAD_PARAMETER);
65799ebb4caSwyllys 
65899ebb4caSwyllys 	CLEAR_ERROR(handle, ret);
65930a5e8faSwyllys 
66030a5e8faSwyllys 	ret = test_attributes(num_req_attrs, required_attrs,
66130a5e8faSwyllys 	    0, NULL, numattr, attrlist);
66299ebb4caSwyllys 	if (ret != KMF_OK)
66399ebb4caSwyllys 		return (ret);
66499ebb4caSwyllys 
66530a5e8faSwyllys 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
66630a5e8faSwyllys 	    &kstype, &len);
66730a5e8faSwyllys 	if (ret != KMF_OK)
66830a5e8faSwyllys 		return (ret);
66999ebb4caSwyllys 
67030a5e8faSwyllys 	switch (kstype) {
67199ebb4caSwyllys 	case KMF_KEYSTORE_NSS:
67230a5e8faSwyllys 		*plugin = FindPlugin(handle, kstype);
67399ebb4caSwyllys 		break;
67499ebb4caSwyllys 
67599ebb4caSwyllys 	case KMF_KEYSTORE_OPENSSL:
67699ebb4caSwyllys 	case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
67730a5e8faSwyllys 		*plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
67899ebb4caSwyllys 		break;
67999ebb4caSwyllys 	default:
68099ebb4caSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
68199ebb4caSwyllys 	}
68230a5e8faSwyllys 	return (KMF_OK);
68399ebb4caSwyllys }
68499ebb4caSwyllys 
68599ebb4caSwyllys KMF_RETURN
kmf_import_crl(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)68630a5e8faSwyllys kmf_import_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
68799ebb4caSwyllys {
68899ebb4caSwyllys 	KMF_RETURN ret;
68930a5e8faSwyllys 	KMF_PLUGIN *plugin;
69099ebb4caSwyllys 
69130a5e8faSwyllys 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
69299ebb4caSwyllys 	if (ret != KMF_OK)
69399ebb4caSwyllys 		return (ret);
69499ebb4caSwyllys 
69530a5e8faSwyllys 	if (plugin == NULL)
69699ebb4caSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
69730a5e8faSwyllys 	else if (plugin->funclist->ImportCRL != NULL)
69830a5e8faSwyllys 		return (plugin->funclist->ImportCRL(handle, numattr, attrlist));
69999ebb4caSwyllys 
70030a5e8faSwyllys 	return (KMF_ERR_FUNCTION_NOT_FOUND);
70199ebb4caSwyllys }
70299ebb4caSwyllys 
70399ebb4caSwyllys KMF_RETURN
kmf_delete_crl(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)70430a5e8faSwyllys kmf_delete_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
70599ebb4caSwyllys {
70699ebb4caSwyllys 	KMF_RETURN ret;
70730a5e8faSwyllys 	KMF_PLUGIN *plugin;
70899ebb4caSwyllys 
70930a5e8faSwyllys 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
71099ebb4caSwyllys 	if (ret != KMF_OK)
71199ebb4caSwyllys 		return (ret);
71299ebb4caSwyllys 
71330a5e8faSwyllys 	if (plugin == NULL)
71499ebb4caSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
71530a5e8faSwyllys 	else if (plugin->funclist->DeleteCRL != NULL)
71630a5e8faSwyllys 		return (plugin->funclist->DeleteCRL(handle, numattr, attrlist));
71799ebb4caSwyllys 
71830a5e8faSwyllys 	return (KMF_ERR_FUNCTION_NOT_FOUND);
71999ebb4caSwyllys }
72099ebb4caSwyllys 
72199ebb4caSwyllys KMF_RETURN
kmf_list_crl(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)72230a5e8faSwyllys kmf_list_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
72399ebb4caSwyllys {
72499ebb4caSwyllys 	KMF_PLUGIN *plugin;
72599ebb4caSwyllys 	KMF_RETURN ret;
72699ebb4caSwyllys 
72730a5e8faSwyllys 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
72899ebb4caSwyllys 	if (ret != KMF_OK)
72999ebb4caSwyllys 		return (ret);
73099ebb4caSwyllys 
73130a5e8faSwyllys 	if (plugin == NULL)
73299ebb4caSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
73330a5e8faSwyllys 	else if (plugin->funclist->ListCRL != NULL)
73430a5e8faSwyllys 		return (plugin->funclist->ListCRL(handle, numattr, attrlist));
73530a5e8faSwyllys 	return (KMF_ERR_FUNCTION_NOT_FOUND);
73699ebb4caSwyllys }
73799ebb4caSwyllys 
73899ebb4caSwyllys KMF_RETURN
kmf_find_crl(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)73930a5e8faSwyllys kmf_find_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
74099ebb4caSwyllys {
74199ebb4caSwyllys 	KMF_PLUGIN *plugin;
74299ebb4caSwyllys 	KMF_RETURN ret;
74330a5e8faSwyllys 	KMF_KEYSTORE_TYPE kstype;
74430a5e8faSwyllys 	uint32_t len = sizeof (kstype);
74530a5e8faSwyllys 
74630a5e8faSwyllys 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
74730a5e8faSwyllys 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1,
74830a5e8faSwyllys 	    sizeof (KMF_KEYSTORE_TYPE)},
74930a5e8faSwyllys 	    {KMF_CRL_COUNT_ATTR, FALSE,
75030a5e8faSwyllys 	    sizeof (char *), sizeof (char *)}
75130a5e8faSwyllys 	};
75230a5e8faSwyllys 
75330a5e8faSwyllys 	int num_req_attrs = sizeof (required_attrs) /
75430a5e8faSwyllys 	    sizeof (KMF_ATTRIBUTE_TESTER);
75530a5e8faSwyllys 	if (handle == NULL)
75630a5e8faSwyllys 		return (KMF_ERR_BAD_PARAMETER);
75799ebb4caSwyllys 
75899ebb4caSwyllys 	CLEAR_ERROR(handle, ret);
75930a5e8faSwyllys 
76030a5e8faSwyllys 	ret = test_attributes(num_req_attrs, required_attrs,
76130a5e8faSwyllys 	    0, NULL, numattr, attrlist);
76299ebb4caSwyllys 	if (ret != KMF_OK)
76399ebb4caSwyllys 		return (ret);
76499ebb4caSwyllys 
76530a5e8faSwyllys 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
76630a5e8faSwyllys 	    &kstype, &len);
76730a5e8faSwyllys 	if (ret != KMF_OK)
76830a5e8faSwyllys 		return (ret);
76999ebb4caSwyllys 
77030a5e8faSwyllys 	switch (kstype) {
77199ebb4caSwyllys 	case KMF_KEYSTORE_NSS:
77230a5e8faSwyllys 		plugin = FindPlugin(handle, kstype);
77399ebb4caSwyllys 		break;
77499ebb4caSwyllys 	case KMF_KEYSTORE_OPENSSL:
77530a5e8faSwyllys 	case KMF_KEYSTORE_PK11TOKEN:
77630a5e8faSwyllys 		return (KMF_ERR_FUNCTION_NOT_FOUND);
77799ebb4caSwyllys 	default:
77830a5e8faSwyllys 		/*
77930a5e8faSwyllys 		 * FindCRL is only implemented for NSS. PKCS#11
78030a5e8faSwyllys 		 * and file-based keystores just store in a file
78130a5e8faSwyllys 		 * and don't need a "Find" function.
78230a5e8faSwyllys 		 */
78399ebb4caSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
78499ebb4caSwyllys 	}
78599ebb4caSwyllys 
78630a5e8faSwyllys 	if (plugin == NULL)
78799ebb4caSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
78830a5e8faSwyllys 	else if (plugin->funclist->FindCRL != NULL) {
78930a5e8faSwyllys 		return (plugin->funclist->FindCRL(handle, numattr,
79030a5e8faSwyllys 		    attrlist));
79199ebb4caSwyllys 	}
79230a5e8faSwyllys 	return (KMF_ERR_FUNCTION_NOT_FOUND);
79399ebb4caSwyllys }
79499ebb4caSwyllys 
79599ebb4caSwyllys KMF_RETURN
kmf_find_cert_in_crl(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)79630a5e8faSwyllys kmf_find_cert_in_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
79799ebb4caSwyllys {
79899ebb4caSwyllys 	KMF_RETURN ret;
79930a5e8faSwyllys 	KMF_PLUGIN *plugin;
80099ebb4caSwyllys 
80130a5e8faSwyllys 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
80299ebb4caSwyllys 	if (ret != KMF_OK)
80399ebb4caSwyllys 		return (ret);
80499ebb4caSwyllys 
80530a5e8faSwyllys 	if (plugin == NULL)
80630a5e8faSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
80730a5e8faSwyllys 	else if (plugin->funclist->FindCertInCRL != NULL)
80830a5e8faSwyllys 		return (plugin->funclist->FindCertInCRL(handle, numattr,
80930a5e8faSwyllys 		    attrlist));
81030a5e8faSwyllys 
81130a5e8faSwyllys 	return (KMF_ERR_FUNCTION_NOT_FOUND);
81230a5e8faSwyllys }
81330a5e8faSwyllys 
81430a5e8faSwyllys KMF_RETURN
kmf_verify_crl_file(KMF_HANDLE_T handle,char * crlfile,KMF_DATA * tacert)81530a5e8faSwyllys kmf_verify_crl_file(KMF_HANDLE_T handle, char *crlfile, KMF_DATA *tacert)
81630a5e8faSwyllys {
81730a5e8faSwyllys 	KMF_PLUGIN *plugin;
81830a5e8faSwyllys 	KMF_RETURN (*verifyCRLFile)(KMF_HANDLE_T, char *, KMF_DATA *);
81930a5e8faSwyllys 
82030a5e8faSwyllys 	if (handle == NULL)
82199ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
82299ebb4caSwyllys 
82399ebb4caSwyllys 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
82499ebb4caSwyllys 	if (plugin == NULL || plugin->dldesc == NULL) {
82599ebb4caSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
82699ebb4caSwyllys 	}
82799ebb4caSwyllys 
82899ebb4caSwyllys 	verifyCRLFile = (KMF_RETURN(*)())dlsym(plugin->dldesc,
82999ebb4caSwyllys 	    "OpenSSL_VerifyCRLFile");
83099ebb4caSwyllys 
83199ebb4caSwyllys 	if (verifyCRLFile == NULL) {
83299ebb4caSwyllys 		return (KMF_ERR_FUNCTION_NOT_FOUND);
83399ebb4caSwyllys 	}
83499ebb4caSwyllys 
83530a5e8faSwyllys 	return (verifyCRLFile(handle, crlfile, tacert));
83699ebb4caSwyllys }
83799ebb4caSwyllys 
83899ebb4caSwyllys KMF_RETURN
kmf_check_crl_date(KMF_HANDLE_T handle,char * crlname)83930a5e8faSwyllys kmf_check_crl_date(KMF_HANDLE_T handle, char *crlname)
84099ebb4caSwyllys {
84199ebb4caSwyllys 	KMF_PLUGIN *plugin;
84230a5e8faSwyllys 	KMF_RETURN (*checkCRLDate)(void *, char *);
84330a5e8faSwyllys 	KMF_RETURN ret = KMF_OK;
84430a5e8faSwyllys 
84530a5e8faSwyllys 	if (handle == NULL)
84630a5e8faSwyllys 		return (KMF_ERR_BAD_PARAMETER);
84799ebb4caSwyllys 
84899ebb4caSwyllys 	CLEAR_ERROR(handle, ret);
84999ebb4caSwyllys 	if (ret != KMF_OK)
85099ebb4caSwyllys 		return (ret);
85199ebb4caSwyllys 
85299ebb4caSwyllys 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
85399ebb4caSwyllys 	if (plugin == NULL || plugin->dldesc == NULL) {
85499ebb4caSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
85599ebb4caSwyllys 	}
85699ebb4caSwyllys 
85799ebb4caSwyllys 	checkCRLDate = (KMF_RETURN(*)())dlsym(plugin->dldesc,
85899ebb4caSwyllys 	    "OpenSSL_CheckCRLDate");
85999ebb4caSwyllys 
86099ebb4caSwyllys 	if (checkCRLDate == NULL) {
86199ebb4caSwyllys 		return (KMF_ERR_FUNCTION_NOT_FOUND);
86299ebb4caSwyllys 	}
86399ebb4caSwyllys 
86430a5e8faSwyllys 	return (checkCRLDate(handle, crlname));
86599ebb4caSwyllys }
86699ebb4caSwyllys 
86799ebb4caSwyllys KMF_RETURN
kmf_is_crl_file(KMF_HANDLE_T handle,char * filename,KMF_ENCODE_FORMAT * pformat)86830a5e8faSwyllys kmf_is_crl_file(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat)
86999ebb4caSwyllys {
87099ebb4caSwyllys 	KMF_PLUGIN *plugin;
87199ebb4caSwyllys 	KMF_RETURN (*IsCRLFileFn)(void *, char *, KMF_ENCODE_FORMAT *);
87230a5e8faSwyllys 	KMF_RETURN ret = KMF_OK;
87399ebb4caSwyllys 
87499ebb4caSwyllys 	CLEAR_ERROR(handle, ret);
87599ebb4caSwyllys 	if (ret != KMF_OK)
87699ebb4caSwyllys 		return (ret);
87799ebb4caSwyllys 
87899ebb4caSwyllys 	if (filename  == NULL || pformat == NULL) {
87999ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
88099ebb4caSwyllys 	}
88199ebb4caSwyllys 
88299ebb4caSwyllys 	/*
88399ebb4caSwyllys 	 * This framework function is actually implemented in the openssl
88499ebb4caSwyllys 	 * plugin library, so we find the function address and call it.
88599ebb4caSwyllys 	 */
88699ebb4caSwyllys 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
88799ebb4caSwyllys 	if (plugin == NULL || plugin->dldesc == NULL) {
88899ebb4caSwyllys 		return (KMF_ERR_PLUGIN_NOTFOUND);
88999ebb4caSwyllys 	}
89099ebb4caSwyllys 
89199ebb4caSwyllys 	IsCRLFileFn = (KMF_RETURN(*)())dlsym(plugin->dldesc,
89299ebb4caSwyllys 	    "OpenSSL_IsCRLFile");
89399ebb4caSwyllys 	if (IsCRLFileFn == NULL) {
89499ebb4caSwyllys 		return (KMF_ERR_FUNCTION_NOT_FOUND);
89599ebb4caSwyllys 	}
89699ebb4caSwyllys 
89799ebb4caSwyllys 	return (IsCRLFileFn(handle, filename, pformat));
89899ebb4caSwyllys }
899