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 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