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