xref: /illumos-gate/usr/src/lib/libkmf/libkmf/common/csrcrlop.c (revision 6b35cb3cf158584a9408d44b9b6796564e8e1882)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  *
21  * Copyright 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
kmf_set_csr_pubkey(KMF_HANDLE_T handle,KMF_KEY_HANDLE * KMFKey,KMF_CSR_DATA * Csr)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 = { 0, NULL };
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
kmf_set_csr_version(KMF_CSR_DATA * CsrData,uint32_t version)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
kmf_set_csr_subject(KMF_CSR_DATA * CsrData,KMF_X509_NAME * subject_name_ptr)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
kmf_create_csr_file(KMF_DATA * csrdata,KMF_ENCODE_FORMAT format,char * csrfile)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 = { 0, NULL };
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
kmf_set_csr_extn(KMF_CSR_DATA * Csr,KMF_X509_EXTENSION * extn)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
kmf_set_csr_sig_alg(KMF_CSR_DATA * CsrData,KMF_ALGORITHM_INDEX sigAlg)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
kmf_set_csr_subject_altname(KMF_CSR_DATA * Csr,char * altname,int critical,KMF_GENERALNAMECHOICES alttype)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
kmf_set_csr_ku(KMF_CSR_DATA * CSRData,int critical,uint16_t kubits)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
kmf_add_csr_eku(KMF_CSR_DATA * CSRData,KMF_OID * ekuOID,int critical)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
sign_csr(KMF_HANDLE_T handle,const KMF_DATA * SubjectCsr,KMF_KEY_HANDLE * Signkey,KMF_X509_ALGORITHM_IDENTIFIER * algo,KMF_DATA * SignedCsr)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 	KMF_ALGORITHM_INDEX algid;
373 	int i = 0;
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 	kmf_set_attr_at_index(attlist, i++,
397 	    KMF_KEYSTORE_TYPE_ATTR, &Signkey->kstype,
398 	    sizeof (Signkey->kstype));
399 
400 	kmf_set_attr_at_index(attlist, i++,
401 	    KMF_KEY_HANDLE_ATTR, Signkey, sizeof (KMF_KEY_HANDLE));
402 
403 	kmf_set_attr_at_index(attlist, i++, KMF_OID_ATTR, &algo->algorithm,
404 	    sizeof (KMF_OID));
405 
406 	kmf_set_attr_at_index(attlist, i++, KMF_DATA_ATTR,
407 	    (KMF_DATA *)SubjectCsr, sizeof (KMF_DATA));
408 
409 	kmf_set_attr_at_index(attlist, i++, KMF_OUT_DATA_ATTR,
410 	    &signed_data, sizeof (KMF_DATA));
411 
412 	ret = kmf_sign_data(handle, i, attlist);
413 	if (KMF_OK != ret)
414 		goto cleanup;
415 	/*
416 	 * If we got here OK, decode into a structure and then re-encode
417 	 * the complete CSR.
418 	 */
419 	ret = DerDecodeTbsCsr(SubjectCsr, &tbs_csr);
420 	if (ret)
421 		goto cleanup;
422 
423 	(void) memcpy(&subj_csr.csr, tbs_csr, sizeof (KMF_TBS_CSR));
424 
425 	ret = copy_algoid(&subj_csr.signature.algorithmIdentifier, algo);
426 	if (ret)
427 		goto cleanup;
428 
429 	algid = x509_algoid_to_algid(&algo->algorithm);
430 	if (algid == KMF_ALGID_SHA1WithDSA ||
431 	    algid == KMF_ALGID_SHA256WithDSA ||
432 	    algid == KMF_ALGID_SHA1WithECDSA ||
433 	    algid == KMF_ALGID_SHA256WithECDSA ||
434 	    algid == KMF_ALGID_SHA384WithECDSA ||
435 	    algid == KMF_ALGID_SHA512WithECDSA) {
436 		/*
437 		 * For DSA and ECDSA, we must encode the
438 		 * signature correctly.
439 		 */
440 		KMF_DATA signature;
441 
442 		ret = DerEncodeDSASignature(&signed_data, &signature);
443 		kmf_free_data(&signed_data);
444 
445 		if (ret != KMF_OK)
446 			goto cleanup;
447 
448 		subj_csr.signature.encrypted = signature;
449 	} else {
450 		subj_csr.signature.encrypted = signed_data;
451 	}
452 
453 	/* Now, re-encode the CSR with the new signature */
454 	ret = DerEncodeSignedCsr(&subj_csr, SignedCsr);
455 	if (ret != KMF_OK) {
456 		kmf_free_data(SignedCsr);
457 		goto cleanup;
458 	}
459 
460 	/* Cleanup & return */
461 cleanup:
462 	free(tbs_csr);
463 
464 	kmf_free_tbs_csr(&subj_csr.csr);
465 
466 	kmf_free_algoid(&subj_csr.signature.algorithmIdentifier);
467 	kmf_free_data(&signed_data);
468 
469 	return (ret);
470 }
471 
472 /*
473  *
474  * Name: kmf_sign_csr
475  *
476  * Description:
477  *   This function signs a CSR and returns the result as a
478  *   signed, encoded CSR in SignedCsr
479  *
480  * Parameters:
481  *   tbsCsr(input) - pointer to a KMF_DATA structure containing a
482  *		DER encoded TBS CSR data
483  *   Signkey(input) - pointer to the KMF_KEY_HANDLE structure containing
484  *		the private key generated by the plug-in CreateKeypair
485  *   algo(input) - contains algorithm info needed for signing
486  *   SignedCsr(output) - pointer to the KMF_DATA structure containing
487  *		the signed CSR
488  *
489  * Returns:
490  *   A KMF_RETURN value indicating success or specifying a particular
491  *   error condition.
492  *   The value KMF_OK indicates success. All other values represent
493  *   an error condition.
494  *
495  */
496 KMF_RETURN
kmf_sign_csr(KMF_HANDLE_T handle,const KMF_CSR_DATA * tbsCsr,KMF_KEY_HANDLE * Signkey,KMF_DATA * SignedCsr)497 kmf_sign_csr(KMF_HANDLE_T handle,
498 	const KMF_CSR_DATA *tbsCsr,
499 	KMF_KEY_HANDLE	*Signkey,
500 	KMF_DATA	*SignedCsr)
501 {
502 	KMF_RETURN err;
503 	KMF_DATA csrdata = { 0, NULL };
504 
505 	CLEAR_ERROR(handle, err);
506 	if (err != KMF_OK)
507 		return (err);
508 
509 	if (tbsCsr == NULL || Signkey == NULL || SignedCsr == NULL)
510 		return (KMF_ERR_BAD_PARAMETER);
511 
512 	SignedCsr->Data = NULL;
513 	SignedCsr->Length = 0;
514 
515 	err = DerEncodeTbsCsr((KMF_TBS_CSR *)&tbsCsr->csr, &csrdata);
516 	if (err == KMF_OK) {
517 		err = sign_csr(handle, &csrdata, Signkey,
518 		    (KMF_X509_ALGORITHM_IDENTIFIER *)
519 		    &tbsCsr->signature.algorithmIdentifier,
520 		    SignedCsr);
521 	}
522 
523 	if (err != KMF_OK) {
524 		kmf_free_data(SignedCsr);
525 	}
526 	kmf_free_data(&csrdata);
527 	return (err);
528 }
529 
530 /*
531  * kmf_decode_csr
532  *
533  * Description:
534  *   This function decodes raw CSR data and fills in the KMF_CSR_DATA
535  *   record.
536  *
537  * Inputs:
538  *	KMF_HANDLE_T handle
539  *	KMF_DATA *rawcsr
540  *	KMF_CSR_DATA *csrdata;
541  */
542 KMF_RETURN
kmf_decode_csr(KMF_HANDLE_T handle,KMF_DATA * rawcsr,KMF_CSR_DATA * csrdata)543 kmf_decode_csr(KMF_HANDLE_T handle, KMF_DATA *rawcsr, KMF_CSR_DATA *csrdata)
544 {
545 	KMF_RETURN rv;
546 	KMF_CSR_DATA *cdata = NULL;
547 
548 	if (handle == NULL || rawcsr == NULL || csrdata == NULL)
549 		return (KMF_ERR_BAD_PARAMETER);
550 
551 	rv = DerDecodeSignedCsr(rawcsr, &cdata);
552 	if (rv != KMF_OK)
553 		return (rv);
554 
555 	(void) memcpy(csrdata, cdata, sizeof (KMF_CSR_DATA));
556 
557 	free(cdata);
558 	return (rv);
559 }
560 
561 KMF_RETURN
kmf_verify_csr(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)562 kmf_verify_csr(KMF_HANDLE_T handle, int numattr,
563 	KMF_ATTRIBUTE *attrlist)
564 {
565 	KMF_RETURN rv = KMF_OK;
566 	KMF_CSR_DATA *csrdata = NULL;
567 	KMF_ALGORITHM_INDEX algid;
568 	KMF_X509_ALGORITHM_IDENTIFIER *x509alg;
569 	KMF_DATA rawcsr;
570 
571 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
572 	    {KMF_CSR_DATA_ATTR, FALSE, sizeof (KMF_CSR_DATA),
573 	    sizeof (KMF_CSR_DATA)},
574 	};
575 
576 	int num_req_attrs = sizeof (required_attrs) /
577 	    sizeof (KMF_ATTRIBUTE_TESTER);
578 
579 	if (handle == NULL)
580 		return (KMF_ERR_BAD_PARAMETER);
581 
582 	CLEAR_ERROR(handle, rv);
583 
584 	rv = test_attributes(num_req_attrs, required_attrs,
585 	    0, NULL, numattr, attrlist);
586 	if (rv != KMF_OK)
587 		return (rv);
588 
589 	csrdata = kmf_get_attr_ptr(KMF_CSR_DATA_ATTR, attrlist, numattr);
590 	if (csrdata == NULL)
591 		return (KMF_ERR_BAD_PARAMETER);
592 
593 	rv = DerEncodeTbsCsr(&csrdata->csr, &rawcsr);
594 	if (rv != KMF_OK)
595 		return (rv);
596 
597 	x509alg = &csrdata->signature.algorithmIdentifier;
598 	algid = x509_algoid_to_algid(&x509alg->algorithm);
599 	if (algid == KMF_ALGID_SHA1WithDSA ||
600 	    algid == KMF_ALGID_SHA256WithDSA) {
601 		/* Decode the DSA signature before verifying it */
602 		KMF_DATA signature;
603 		rv = DerDecodeDSASignature(&csrdata->signature.encrypted,
604 		    &signature);
605 		if (rv != KMF_OK)
606 			goto end;
607 
608 		rv = PKCS_VerifyData(handle, algid,
609 		    &csrdata->csr.subjectPublicKeyInfo,
610 		    &rawcsr, &signature);
611 
612 		kmf_free_data(&signature);
613 	} else if (algid == KMF_ALGID_SHA1WithECDSA ||
614 	    algid == KMF_ALGID_SHA256WithECDSA ||
615 	    algid == KMF_ALGID_SHA384WithECDSA ||
616 	    algid == KMF_ALGID_SHA512WithECDSA) {
617 		KMF_DATA signature;
618 		rv = DerDecodeECDSASignature(&csrdata->signature.encrypted,
619 		    &signature);
620 		if (rv != KMF_OK)
621 			goto end;
622 
623 		rv = PKCS_VerifyData(handle, algid,
624 		    &csrdata->csr.subjectPublicKeyInfo,
625 		    &rawcsr, &signature);
626 
627 		kmf_free_data(&signature);
628 	} else {
629 		rv = PKCS_VerifyData(handle, algid,
630 		    &csrdata->csr.subjectPublicKeyInfo,
631 		    &rawcsr,
632 		    &csrdata->signature.encrypted);
633 	}
634 
635 end:
636 	kmf_free_data(&rawcsr);
637 	return (rv);
638 }
639 
640 static KMF_RETURN
setup_crl_call(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist,KMF_PLUGIN ** plugin)641 setup_crl_call(KMF_HANDLE_T handle, int numattr,
642 	KMF_ATTRIBUTE *attrlist, KMF_PLUGIN **plugin)
643 {
644 	KMF_RETURN ret;
645 	KMF_KEYSTORE_TYPE kstype;
646 	uint32_t len = sizeof (kstype);
647 
648 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
649 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}
650 	};
651 
652 	int num_req_attrs = sizeof (required_attrs) /
653 	    sizeof (KMF_ATTRIBUTE_TESTER);
654 
655 	if (handle == NULL || plugin == NULL)
656 		return (KMF_ERR_BAD_PARAMETER);
657 
658 	CLEAR_ERROR(handle, ret);
659 
660 	ret = test_attributes(num_req_attrs, required_attrs,
661 	    0, NULL, numattr, attrlist);
662 	if (ret != KMF_OK)
663 		return (ret);
664 
665 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
666 	    &kstype, &len);
667 	if (ret != KMF_OK)
668 		return (ret);
669 
670 	switch (kstype) {
671 	case KMF_KEYSTORE_NSS:
672 		*plugin = FindPlugin(handle, kstype);
673 		break;
674 
675 	case KMF_KEYSTORE_OPENSSL:
676 	case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
677 		*plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
678 		break;
679 	default:
680 		return (KMF_ERR_PLUGIN_NOTFOUND);
681 	}
682 	return (KMF_OK);
683 }
684 
685 KMF_RETURN
kmf_import_crl(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)686 kmf_import_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
687 {
688 	KMF_RETURN ret;
689 	KMF_PLUGIN *plugin;
690 
691 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
692 	if (ret != KMF_OK)
693 		return (ret);
694 
695 	if (plugin == NULL)
696 		return (KMF_ERR_PLUGIN_NOTFOUND);
697 	else if (plugin->funclist->ImportCRL != NULL)
698 		return (plugin->funclist->ImportCRL(handle, numattr, attrlist));
699 
700 	return (KMF_ERR_FUNCTION_NOT_FOUND);
701 }
702 
703 KMF_RETURN
kmf_delete_crl(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)704 kmf_delete_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
705 {
706 	KMF_RETURN ret;
707 	KMF_PLUGIN *plugin;
708 
709 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
710 	if (ret != KMF_OK)
711 		return (ret);
712 
713 	if (plugin == NULL)
714 		return (KMF_ERR_PLUGIN_NOTFOUND);
715 	else if (plugin->funclist->DeleteCRL != NULL)
716 		return (plugin->funclist->DeleteCRL(handle, numattr, attrlist));
717 
718 	return (KMF_ERR_FUNCTION_NOT_FOUND);
719 }
720 
721 KMF_RETURN
kmf_list_crl(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)722 kmf_list_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
723 {
724 	KMF_PLUGIN *plugin;
725 	KMF_RETURN ret;
726 
727 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
728 	if (ret != KMF_OK)
729 		return (ret);
730 
731 	if (plugin == NULL)
732 		return (KMF_ERR_PLUGIN_NOTFOUND);
733 	else if (plugin->funclist->ListCRL != NULL)
734 		return (plugin->funclist->ListCRL(handle, numattr, attrlist));
735 	return (KMF_ERR_FUNCTION_NOT_FOUND);
736 }
737 
738 KMF_RETURN
kmf_find_crl(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)739 kmf_find_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
740 {
741 	KMF_PLUGIN *plugin;
742 	KMF_RETURN ret;
743 	KMF_KEYSTORE_TYPE kstype;
744 	uint32_t len = sizeof (kstype);
745 
746 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
747 	    {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1,
748 	    sizeof (KMF_KEYSTORE_TYPE)},
749 	    {KMF_CRL_COUNT_ATTR, FALSE,
750 	    sizeof (char *), sizeof (char *)}
751 	};
752 
753 	int num_req_attrs = sizeof (required_attrs) /
754 	    sizeof (KMF_ATTRIBUTE_TESTER);
755 	if (handle == NULL)
756 		return (KMF_ERR_BAD_PARAMETER);
757 
758 	CLEAR_ERROR(handle, ret);
759 
760 	ret = test_attributes(num_req_attrs, required_attrs,
761 	    0, NULL, numattr, attrlist);
762 	if (ret != KMF_OK)
763 		return (ret);
764 
765 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
766 	    &kstype, &len);
767 	if (ret != KMF_OK)
768 		return (ret);
769 
770 	switch (kstype) {
771 	case KMF_KEYSTORE_NSS:
772 		plugin = FindPlugin(handle, kstype);
773 		break;
774 	case KMF_KEYSTORE_OPENSSL:
775 	case KMF_KEYSTORE_PK11TOKEN:
776 		return (KMF_ERR_FUNCTION_NOT_FOUND);
777 	default:
778 		/*
779 		 * FindCRL is only implemented for NSS. PKCS#11
780 		 * and file-based keystores just store in a file
781 		 * and don't need a "Find" function.
782 		 */
783 		return (KMF_ERR_PLUGIN_NOTFOUND);
784 	}
785 
786 	if (plugin == NULL)
787 		return (KMF_ERR_PLUGIN_NOTFOUND);
788 	else if (plugin->funclist->FindCRL != NULL) {
789 		return (plugin->funclist->FindCRL(handle, numattr,
790 		    attrlist));
791 	}
792 	return (KMF_ERR_FUNCTION_NOT_FOUND);
793 }
794 
795 KMF_RETURN
kmf_find_cert_in_crl(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)796 kmf_find_cert_in_crl(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
797 {
798 	KMF_RETURN ret;
799 	KMF_PLUGIN *plugin;
800 
801 	ret = setup_crl_call(handle, numattr, attrlist, &plugin);
802 	if (ret != KMF_OK)
803 		return (ret);
804 
805 	if (plugin == NULL)
806 		return (KMF_ERR_PLUGIN_NOTFOUND);
807 	else if (plugin->funclist->FindCertInCRL != NULL)
808 		return (plugin->funclist->FindCertInCRL(handle, numattr,
809 		    attrlist));
810 
811 	return (KMF_ERR_FUNCTION_NOT_FOUND);
812 }
813 
814 KMF_RETURN
kmf_verify_crl_file(KMF_HANDLE_T handle,char * crlfile,KMF_DATA * tacert)815 kmf_verify_crl_file(KMF_HANDLE_T handle, char *crlfile, KMF_DATA *tacert)
816 {
817 	KMF_PLUGIN *plugin;
818 	KMF_RETURN (*verifyCRLFile)(KMF_HANDLE_T, char *, KMF_DATA *);
819 
820 	if (handle == NULL)
821 		return (KMF_ERR_BAD_PARAMETER);
822 
823 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
824 	if (plugin == NULL || plugin->dldesc == NULL) {
825 		return (KMF_ERR_PLUGIN_NOTFOUND);
826 	}
827 
828 	verifyCRLFile = (KMF_RETURN(*)())dlsym(plugin->dldesc,
829 	    "OpenSSL_VerifyCRLFile");
830 
831 	if (verifyCRLFile == NULL) {
832 		return (KMF_ERR_FUNCTION_NOT_FOUND);
833 	}
834 
835 	return (verifyCRLFile(handle, crlfile, tacert));
836 }
837 
838 KMF_RETURN
kmf_check_crl_date(KMF_HANDLE_T handle,char * crlname)839 kmf_check_crl_date(KMF_HANDLE_T handle, char *crlname)
840 {
841 	KMF_PLUGIN *plugin;
842 	KMF_RETURN (*checkCRLDate)(void *, char *);
843 	KMF_RETURN ret = KMF_OK;
844 
845 	if (handle == NULL)
846 		return (KMF_ERR_BAD_PARAMETER);
847 
848 	CLEAR_ERROR(handle, ret);
849 	if (ret != KMF_OK)
850 		return (ret);
851 
852 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
853 	if (plugin == NULL || plugin->dldesc == NULL) {
854 		return (KMF_ERR_PLUGIN_NOTFOUND);
855 	}
856 
857 	checkCRLDate = (KMF_RETURN(*)())dlsym(plugin->dldesc,
858 	    "OpenSSL_CheckCRLDate");
859 
860 	if (checkCRLDate == NULL) {
861 		return (KMF_ERR_FUNCTION_NOT_FOUND);
862 	}
863 
864 	return (checkCRLDate(handle, crlname));
865 }
866 
867 KMF_RETURN
kmf_is_crl_file(KMF_HANDLE_T handle,char * filename,KMF_ENCODE_FORMAT * pformat)868 kmf_is_crl_file(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat)
869 {
870 	KMF_PLUGIN *plugin;
871 	KMF_RETURN (*IsCRLFileFn)(void *, char *, KMF_ENCODE_FORMAT *);
872 	KMF_RETURN ret = KMF_OK;
873 
874 	CLEAR_ERROR(handle, ret);
875 	if (ret != KMF_OK)
876 		return (ret);
877 
878 	if (filename  == NULL || pformat == NULL) {
879 		return (KMF_ERR_BAD_PARAMETER);
880 	}
881 
882 	/*
883 	 * This framework function is actually implemented in the openssl
884 	 * plugin library, so we find the function address and call it.
885 	 */
886 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
887 	if (plugin == NULL || plugin->dldesc == NULL) {
888 		return (KMF_ERR_PLUGIN_NOTFOUND);
889 	}
890 
891 	IsCRLFileFn = (KMF_RETURN(*)())dlsym(plugin->dldesc,
892 	    "OpenSSL_IsCRLFile");
893 	if (IsCRLFileFn == NULL) {
894 		return (KMF_ERR_FUNCTION_NOT_FOUND);
895 	}
896 
897 	return (IsCRLFileFn(handle, filename, pformat));
898 }
899