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