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