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