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 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <link.h> 30 #include <fcntl.h> 31 #include <ctype.h> 32 #include <sys/param.h> 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <sys/socket.h> 36 #include <ber_der.h> 37 #include <kmfapiP.h> 38 #include <pem_encode.h> 39 #include <libgen.h> 40 #include <cryptoutil.h> 41 42 #define CERTFILE_TEMPNAME "/tmp/user.certXXXXXX" 43 #define CRLFILE_TEMPNAME "/tmp/crlXXXXXX" 44 #define X509_FORMAT_VERSION 2 45 46 static KMF_RETURN 47 sign_cert(KMF_HANDLE_T, const KMF_DATA *, KMF_KEY_HANDLE *, KMF_DATA *); 48 49 static KMF_RETURN 50 verify_cert_with_key(KMF_HANDLE_T, KMF_DATA *, const KMF_DATA *); 51 52 static KMF_RETURN 53 verify_cert_with_cert(KMF_HANDLE_T, const KMF_DATA *, const KMF_DATA *); 54 55 56 static KMF_RETURN 57 get_keyalg_from_cert(KMF_DATA *cert, KMF_KEY_ALG *keyalg) 58 { 59 KMF_RETURN rv; 60 KMF_X509_CERTIFICATE *SignerCert = NULL; 61 KMF_ALGORITHM_INDEX AlgorithmId; 62 63 rv = DerDecodeSignedCertificate(cert, &SignerCert); 64 65 if (rv != KMF_OK) 66 return (rv); 67 68 /* Get the algorithm info from the signer certificate */ 69 AlgorithmId = x509_algoid_to_algid( 70 &SignerCert->signature.algorithmIdentifier.algorithm); 71 72 switch (AlgorithmId) { 73 case KMF_ALGID_MD5WithRSA: 74 case KMF_ALGID_MD2WithRSA: 75 case KMF_ALGID_SHA1WithRSA: 76 *keyalg = KMF_RSA; 77 break; 78 case KMF_ALGID_SHA1WithDSA: 79 *keyalg = KMF_DSA; 80 break; 81 default: 82 rv = KMF_ERR_BAD_ALGORITHM; 83 } 84 85 kmf_free_signed_cert(SignerCert); 86 free(SignerCert); 87 return (rv); 88 } 89 90 /* 91 * Name: kmf_find_prikey_by_cert 92 * 93 * Description: 94 * This function finds the corresponding private key in keystore 95 * for a certificate 96 */ 97 KMF_RETURN 98 kmf_find_prikey_by_cert(KMF_HANDLE_T handle, int numattr, 99 KMF_ATTRIBUTE *attrlist) 100 { 101 KMF_PLUGIN *plugin; 102 KMF_RETURN ret = KMF_OK; 103 KMF_KEYSTORE_TYPE kstype; 104 KMF_KEY_ALG keyalg; 105 KMF_KEY_HANDLE *key = NULL; 106 KMF_DATA *cert = NULL; 107 108 KMF_ATTRIBUTE_TESTER required_attrs[] = { 109 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 110 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, 111 {KMF_KEY_HANDLE_ATTR, TRUE, sizeof (KMF_KEY_HANDLE), 112 sizeof (KMF_KEY_HANDLE)} 113 }; 114 115 int num_req_attrs = sizeof (required_attrs) / 116 sizeof (KMF_ATTRIBUTE_TESTER); 117 118 if (handle == NULL) 119 return (KMF_ERR_BAD_PARAMETER); 120 121 CLEAR_ERROR(handle, ret); 122 123 ret = test_attributes(num_req_attrs, required_attrs, 124 0, NULL, numattr, attrlist); 125 if (ret != KMF_OK) 126 return (ret); 127 128 /* 129 * First, get the key algorithm info from the certificate and saves it 130 * in the returned key handle. 131 */ 132 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 133 if (cert == NULL) 134 return (KMF_ERR_BAD_PARAMETER); 135 136 ret = get_keyalg_from_cert(cert, &keyalg); 137 if (ret != KMF_OK) 138 return (ret); 139 140 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 141 if (key == NULL) 142 return (KMF_ERR_BAD_PARAMETER); 143 key->keyalg = keyalg; 144 145 /* Call the plugin to do the work. */ 146 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, 147 &kstype, NULL); 148 if (ret != KMF_OK) 149 return (ret); 150 151 plugin = FindPlugin(handle, kstype); 152 if (plugin == NULL || plugin->funclist->FindPrikeyByCert == NULL) 153 return (KMF_ERR_PLUGIN_NOTFOUND); 154 155 return (plugin->funclist->FindPrikeyByCert(handle, numattr, attrlist)); 156 } 157 158 159 KMF_RETURN 160 check_key_usage(void *handle, 161 const KMF_DATA *cert, 162 const KMF_KU_PURPOSE purpose) 163 { 164 KMF_X509EXT_BASICCONSTRAINTS constraint; 165 KMF_BOOL critical = B_FALSE; 166 KMF_X509EXT_KEY_USAGE keyusage; 167 KMF_RETURN ret = KMF_OK; 168 169 if (handle == NULL || cert == NULL) 170 return (KMF_ERR_BAD_PARAMETER); 171 172 (void) memset(&constraint, 0, sizeof (KMF_X509EXT_BASICCONSTRAINTS)); 173 (void) memset(&keyusage, 0, sizeof (KMF_X509EXT_KEY_USAGE)); 174 175 ret = kmf_get_cert_ku(cert, &keyusage); 176 if (ret != KMF_OK) 177 /* 178 * If absent or error, the cert is assumed to be invalid 179 * for all key usage checking. 180 */ 181 return (ret); 182 183 184 switch (purpose) { 185 case KMF_KU_SIGN_CERT: 186 /* 187 * RFC 3280: 188 * The keyCertSign bit is asserted when the subject 189 * public key is used for verifying a signature on 190 * public key certificates. If the keyCertSign bit 191 * is asserted, then the cA bit in the basic constraints 192 * extension (section 4.2.1.10) MUST also be asserted. 193 * The basic constraints extension MUST appear as a 194 * critical extension in all CA certificates that 195 * contain public keys used to validate digital 196 * signatures on certificates. 197 */ 198 ret = kmf_get_cert_basic_constraint(cert, &critical, 199 &constraint); 200 201 if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) { 202 /* real error */ 203 return (ret); 204 } 205 206 if ((!critical) || (!constraint.cA) || 207 (!(keyusage.KeyUsageBits & KMF_keyCertSign))) 208 return (KMF_ERR_KEYUSAGE); 209 break; 210 case KMF_KU_SIGN_DATA: 211 /* 212 * RFC 3280: 213 * The digitalSignature bit is asserted when the subject 214 * public key is used with a digital signature mechanism 215 * to support security services other than certificate 216 * signing(bit 5), or CRL signing(bit 6). 217 */ 218 if (!(keyusage.KeyUsageBits & KMF_digitalSignature)) 219 return (KMF_ERR_KEYUSAGE); 220 break; 221 case KMF_KU_ENCRYPT_DATA: 222 /* 223 * RFC 3280: 224 * The dataEncipherment bit is asserted when the subject 225 * public key is used for enciphering user data, other than 226 * cryptographic keys. 227 */ 228 if (!(keyusage.KeyUsageBits & KMF_dataEncipherment)) 229 return (KMF_ERR_KEYUSAGE); 230 break; 231 default: 232 return (KMF_ERR_BAD_PARAMETER); 233 } 234 235 return (KMF_OK); 236 } 237 238 KMF_RETURN 239 kmf_find_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 240 { 241 KMF_PLUGIN *plugin; 242 KMF_RETURN ret = KMF_OK; 243 KMF_KEYSTORE_TYPE kstype; 244 KMF_ATTRIBUTE_TESTER required_attrs[] = { 245 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 246 {KMF_COUNT_ATTR, FALSE, sizeof (uint32_t), sizeof (uint32_t)} 247 }; 248 int num_req_attrs = sizeof (required_attrs) / 249 sizeof (KMF_ATTRIBUTE_TESTER); 250 251 if (handle == NULL) 252 return (KMF_ERR_BAD_PARAMETER); 253 254 CLEAR_ERROR(handle, ret); 255 256 ret = test_attributes(num_req_attrs, required_attrs, 257 0, NULL, numattr, attrlist); 258 if (ret != KMF_OK) 259 return (ret); 260 261 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, 262 &kstype, NULL); 263 if (ret != KMF_OK) 264 return (ret); 265 266 plugin = FindPlugin(handle, kstype); 267 if (plugin == NULL || plugin->funclist->FindCert == NULL) 268 return (KMF_ERR_PLUGIN_NOTFOUND); 269 270 return (plugin->funclist->FindCert(handle, numattr, attrlist)); 271 } 272 273 #define NODATA(d) (d.Data == NULL || d.Length == NULL) 274 275 KMF_RETURN 276 kmf_encode_cert_record(KMF_X509_CERTIFICATE *CertData, KMF_DATA *encodedCert) 277 { 278 KMF_RETURN ret; 279 KMF_X509_TBS_CERT *tbs_cert; 280 281 if (CertData == NULL || encodedCert == NULL) 282 return (KMF_ERR_BAD_PARAMETER); 283 284 /* 285 * Validate that all required fields are present. 286 */ 287 tbs_cert = &(CertData->certificate); 288 if (NODATA(tbs_cert->version) || 289 NODATA(tbs_cert->signature.algorithm) || 290 NODATA(tbs_cert->subjectPublicKeyInfo.subjectPublicKey) || 291 tbs_cert->serialNumber.val == NULL || 292 tbs_cert->serialNumber.len == 0 || 293 tbs_cert->subject.numberOfRDNs == 0 || 294 tbs_cert->issuer.numberOfRDNs == 0) { 295 return (KMF_ERR_INCOMPLETE_TBS_CERT); 296 } 297 298 encodedCert->Length = 0; 299 encodedCert->Data = NULL; 300 301 /* Pack the new certificate */ 302 ret = DerEncodeSignedCertificate(CertData, encodedCert); 303 304 return (ret); 305 } 306 307 /* 308 * This function is used to setup the attribute list before calling 309 * kmf_find_prikey_by_cert(). This function is used by 310 * kmf_decrypt_with_cert 311 * kmf_sign_cert 312 * kmf_sign_data 313 * 314 * The attribute list in these callers contain all the attributes 315 * needed by kmf_find_prikey_by_cert(), except the 316 * KMF_KEY_HANDLE attribute and the KMF_CERT_DATA_ATTR attribute. 317 * These 2 attributes need to be added or reset. 318 * 319 * The caller should free the new_attrlist after use it. 320 */ 321 static KMF_RETURN 322 setup_findprikey_attrlist(KMF_ATTRIBUTE *src_attrlist, int src_num, 323 KMF_ATTRIBUTE **new_attrlist, int *new_num, KMF_KEY_HANDLE *key, 324 KMF_DATA *cert) 325 { 326 KMF_ATTRIBUTE *attrlist = NULL; 327 int cur_num = src_num; 328 int index; 329 int i; 330 331 if (src_attrlist == NULL || new_num == NULL || key == NULL || 332 cert == NULL) 333 return (KMF_ERR_BAD_PARAMETER); 334 335 /* Create a new attribute list with 2 more elements */ 336 attrlist = (KMF_ATTRIBUTE *) malloc( 337 (src_num + 2) * sizeof (KMF_ATTRIBUTE)); 338 if (attrlist == NULL) 339 return (KMF_ERR_MEMORY); 340 341 /* Copy the src_attrlist to the new list */ 342 for (i = 0; i < src_num; i++) { 343 attrlist[i].type = src_attrlist[i].type; 344 attrlist[i].pValue = src_attrlist[i].pValue; 345 attrlist[i].valueLen = src_attrlist[i].valueLen; 346 } 347 348 /* Add or reset the key handle attribute */ 349 index = kmf_find_attr(KMF_KEY_HANDLE_ATTR, attrlist, cur_num); 350 if (index == -1) { 351 /* not found; add it */ 352 kmf_set_attr_at_index(attrlist, cur_num, 353 KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); 354 cur_num++; 355 } else { 356 /* found; just reset it */ 357 kmf_set_attr_at_index(attrlist, index, 358 KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); 359 } 360 361 /* add or reset the cert data attribute */ 362 index = kmf_find_attr(KMF_CERT_DATA_ATTR, attrlist, cur_num); 363 if (index == -1) { 364 /* not found; add it */ 365 kmf_set_attr_at_index(attrlist, cur_num, 366 KMF_CERT_DATA_ATTR, cert, sizeof (KMF_DATA)); 367 cur_num++; 368 } else { 369 /* found; just reset it */ 370 kmf_set_attr_at_index(attrlist, index, 371 KMF_CERT_DATA_ATTR, cert, sizeof (KMF_DATA)); 372 } 373 374 *new_attrlist = attrlist; 375 *new_num = cur_num; 376 return (KMF_OK); 377 } 378 379 380 /* 381 * Name: kmf_sign_cert 382 * 383 * Description: 384 * This function signs a certificate using the signer cert and 385 * returns a signed and DER-encoded certificate. 386 * 387 * The following types of certificate data can be submitted to be signed: 388 * KMF_TBS_CERT_DATA_ATTR - a KMF_DATA ptr is provided in the attrlist 389 * and is signed directly. 390 * KMF_X509_CERTIFICATE_ATTR - a KMF_X509_CERTIFICATE record is provided 391 * in the attribute list. This is converted to raw KMF_DATA 392 * prior to signing. 393 * 394 * The key for the signing operation can be provided as a KMF_KEY_HANDLE_ATTR 395 * or the caller may choose to provide a KMF_SIGNER_CERT_ATTR (KMF_DATA *). 396 * If the latter, this function will then attempt to find the private key 397 * associated with the certificate. The private key must be stored in 398 * the same keystore as the signer certificate. 399 */ 400 KMF_RETURN 401 kmf_sign_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 402 { 403 KMF_RETURN ret; 404 int new_numattr = numattr + 1; 405 KMF_ATTRIBUTE *new_attrlist = NULL; 406 KMF_DATA *signer_cert = NULL; 407 KMF_DATA *tbs_cert = NULL; /* to be signed cert */ 408 KMF_DATA *signed_cert = NULL; 409 KMF_DATA unsignedCert = {NULL, 0}; 410 KMF_KEY_HANDLE sign_key, *sign_key_ptr; 411 int freethekey = 0; 412 KMF_X509_CERTIFICATE *x509cert; 413 KMF_ATTRIBUTE_TESTER required_attrs[] = { 414 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 415 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)} 416 }; 417 int num_req_attrs = sizeof (required_attrs) / 418 sizeof (KMF_ATTRIBUTE_TESTER); 419 420 if (handle == NULL) 421 return (KMF_ERR_BAD_PARAMETER); 422 423 CLEAR_ERROR(handle, ret); 424 425 ret = test_attributes(num_req_attrs, required_attrs, 426 0, NULL, numattr, attrlist); 427 if (ret != KMF_OK) 428 return (ret); 429 430 /* Get the signer cert and check its keyUsage */ 431 signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist, 432 numattr); 433 sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, 434 numattr); 435 if (signer_cert == NULL && sign_key_ptr == NULL) 436 return (KMF_ERR_BAD_PARAMETER); 437 438 if (signer_cert != NULL) { 439 ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_CERT); 440 if (ret != KMF_OK) 441 return (ret); 442 443 /* 444 * Find the private key from the signer certificate by calling 445 * kmf_find_prikey_by_cert(). 446 */ 447 ret = setup_findprikey_attrlist(attrlist, numattr, 448 &new_attrlist, &new_numattr, &sign_key, signer_cert); 449 if (ret != KMF_OK) 450 goto out; 451 452 ret = kmf_find_prikey_by_cert(handle, new_numattr, 453 new_attrlist); 454 if (ret != KMF_OK) { 455 goto out; 456 } 457 sign_key_ptr = &sign_key; 458 freethekey = 1; 459 } 460 461 /* Now we are ready to sign */ 462 tbs_cert = kmf_get_attr_ptr(KMF_TBS_CERT_DATA_ATTR, attrlist, 463 numattr); 464 if (tbs_cert == NULL) { 465 x509cert = kmf_get_attr_ptr(KMF_X509_CERTIFICATE_ATTR, attrlist, 466 numattr); 467 if (x509cert == NULL) { 468 ret = KMF_ERR_BAD_PARAMETER; 469 goto out; 470 } 471 ret = kmf_encode_cert_record(x509cert, &unsignedCert); 472 if (ret == KMF_OK) 473 tbs_cert = &unsignedCert; 474 else 475 goto out; 476 } 477 478 signed_cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, 479 numattr); 480 if (signed_cert == NULL) { 481 ret = KMF_ERR_BAD_PARAMETER; 482 goto out; 483 } 484 485 ret = sign_cert(handle, tbs_cert, sign_key_ptr, signed_cert); 486 487 out: 488 if (new_attrlist) 489 (void) free(new_attrlist); 490 491 /* If we had to find the key, free it here. */ 492 if (freethekey) 493 kmf_free_kmf_key(handle, &sign_key); 494 495 kmf_free_data(&unsignedCert); 496 return (ret); 497 } 498 499 /* 500 * Name: kmf_sign_data 501 * 502 * Description: 503 * This function signs a block of data using the signer cert and 504 * returns the the signature in output 505 */ 506 KMF_RETURN 507 kmf_sign_data(KMF_HANDLE_T handle, int numattr, 508 KMF_ATTRIBUTE *attrlist) 509 { 510 KMF_PLUGIN *plugin; 511 KMF_RETURN ret = KMF_OK; 512 KMF_ATTRIBUTE *new_attrlist = NULL; 513 int new_numattr = numattr; 514 KMF_DATA *signer_cert = NULL; 515 KMF_DATA *tbs_data = NULL; /* to be signed data */ 516 KMF_DATA *output = NULL; 517 KMF_KEY_HANDLE sign_key, *sign_key_ptr; 518 KMF_X509_CERTIFICATE *x509_cert = NULL; 519 KMF_ALGORITHM_INDEX AlgId; 520 KMF_DATA signature = {0, NULL}; 521 KMF_OID *oid; 522 523 KMF_ATTRIBUTE_TESTER required_attrs[] = { 524 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 525 {KMF_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, 526 {KMF_OUT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)} 527 }; 528 int num_req_attrs = sizeof (required_attrs) / 529 sizeof (KMF_ATTRIBUTE_TESTER); 530 531 if (handle == NULL) 532 return (KMF_ERR_BAD_PARAMETER); 533 534 CLEAR_ERROR(handle, ret); 535 536 ret = test_attributes(num_req_attrs, required_attrs, 537 0, NULL, numattr, attrlist); 538 if (ret != KMF_OK) 539 return (ret); 540 541 /* Get the signer cert and check its keyUsage. */ 542 signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist, 543 numattr); 544 sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, 545 numattr); 546 547 if (signer_cert == NULL && sign_key_ptr == NULL) 548 return (KMF_ERR_BAD_PARAMETER); 549 550 /* 551 * If a signer cert was given, use it to find the private key 552 * to use for signing the data. 553 */ 554 if (signer_cert != NULL) { 555 ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA); 556 557 /* 558 * Signing generic data does not require the 559 * KeyUsage extension. 560 */ 561 if (ret == KMF_ERR_EXTENSION_NOT_FOUND) 562 ret = KMF_OK; 563 if (ret != KMF_OK) 564 return (ret); 565 566 /* 567 * Find the private key from the signer certificate. 568 */ 569 ret = setup_findprikey_attrlist(attrlist, numattr, 570 &new_attrlist, &new_numattr, &sign_key, signer_cert); 571 if (ret != KMF_OK) { 572 goto cleanup; 573 } 574 575 ret = kmf_find_prikey_by_cert(handle, new_numattr, 576 new_attrlist); 577 if (ret != KMF_OK) { 578 goto cleanup; 579 } 580 sign_key_ptr = &sign_key; 581 } 582 583 /* Get the tbs_data and signed_data attributes now */ 584 tbs_data = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, numattr); 585 if (tbs_data == NULL) { 586 ret = KMF_ERR_BAD_PARAMETER; 587 goto cleanup; 588 } 589 590 output = kmf_get_attr_ptr(KMF_OUT_DATA_ATTR, attrlist, numattr); 591 if (output == NULL) { 592 ret = KMF_ERR_BAD_PARAMETER; 593 goto cleanup; 594 } 595 596 /* 597 * Get the algorithm index attribute and its oid. If this attribute 598 * is not provided, then we use the algorithm in the signer cert. 599 */ 600 oid = kmf_get_attr_ptr(KMF_OID_ATTR, attrlist, numattr); 601 ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, numattr, 602 &AlgId, NULL); 603 /* 604 * We need to know the Algorithm ID, it can be found 3 ways: 605 * 1. caller supplied OID in the attribute list. 606 * 2. caller supplied Algorithm Index in the attribute list. 607 * 3. caller supplied neither, but did supply a certificate, find 608 * the ALG OID from the certificate. 609 */ 610 /* If none of the above, return error. */ 611 if (oid == NULL && ret != KMF_OK && signer_cert == NULL) { 612 ret = KMF_ERR_BAD_PARAMETER; 613 goto cleanup; 614 } else if (oid == NULL && ret != KMF_OK) { 615 /* if no OID and No AlgID, use the signer cert */ 616 ret = DerDecodeSignedCertificate(signer_cert, &x509_cert); 617 if (ret != KMF_OK) 618 goto cleanup; 619 620 oid = CERT_ALG_OID(x509_cert); 621 AlgId = x509_algoid_to_algid(oid); 622 if (AlgId == KMF_ALGID_NONE) { 623 ret = KMF_ERR_BAD_PARAMETER; 624 goto cleanup; 625 } 626 } else if (oid == NULL && ret == KMF_OK) { 627 /* AlgID was given by caller, convert it to OID */ 628 oid = x509_algid_to_algoid(AlgId); 629 } else { /* Else, the OID must have been given */ 630 ret = KMF_OK; 631 } 632 633 /* Now call the plugin function to sign it */ 634 plugin = FindPlugin(handle, sign_key_ptr->kstype); 635 if (plugin == NULL || plugin->funclist->SignData == NULL) { 636 ret = KMF_ERR_PLUGIN_NOTFOUND; 637 goto cleanup; 638 } 639 640 ret = plugin->funclist->SignData(handle, sign_key_ptr, oid, tbs_data, 641 output); 642 if (ret != KMF_OK) 643 goto cleanup; 644 645 /* 646 * For DSA, NSS returns an encoded signature. Decode the 647 * signature as DSA signature should be 40-byte long. 648 */ 649 if (plugin->type == KMF_KEYSTORE_NSS && 650 AlgId == KMF_ALGID_SHA1WithDSA) { 651 ret = DerDecodeDSASignature(output, &signature); 652 if (ret != KMF_OK) 653 goto cleanup; 654 output->Length = signature.Length; 655 (void) memcpy(output->Data, signature.Data, signature.Length); 656 } 657 658 cleanup: 659 if (new_attrlist != NULL) 660 free(new_attrlist); 661 662 if (signature.Data) 663 free(signature.Data); 664 665 if (signer_cert != NULL && sign_key_ptr != NULL) 666 kmf_free_kmf_key(handle, sign_key_ptr); 667 668 if (x509_cert != NULL) { 669 kmf_free_signed_cert(x509_cert); 670 free(x509_cert); 671 } 672 673 return (ret); 674 } 675 676 /* 677 * kmf_verify_data 678 * 679 * This routine will try to verify a block of data using 680 * either a public key or a certificate as the source 681 * of the verification (the key). 682 * 683 * The caller may provider either a KMF_KEY_HANDLE_ATTR or 684 * a KMF_SIGNER_CERT_DATA_ATTR (with a KMF_DATA record) to 685 * use for the key to the verification step. If a certificate 686 * is used and that certificate has the KeyUsage extension, 687 * the SIGN-DATA bit must be set. Also, if a certificate 688 * is used, the verification will be done in a specific 689 * keystore mechanism. 690 * 691 * If a KMF_KEY_HANDLE is given in the attribute list, the 692 * verification will occur in the framework itself using 693 * PKCS#11 C_Verify functions. 694 */ 695 KMF_RETURN 696 kmf_verify_data(KMF_HANDLE_T handle, 697 int num_args, 698 KMF_ATTRIBUTE *attrlist) 699 { 700 KMF_RETURN ret = KMF_OK; 701 KMF_PLUGIN *plugin; 702 KMF_KEYSTORE_TYPE kstype; 703 uint32_t len; 704 KMF_DATA derkey = {0, NULL}; 705 KMF_KEY_HANDLE *KMFKey; 706 KMF_ALGORITHM_INDEX sigAlg; 707 KMF_DATA *indata; 708 KMF_DATA *insig; 709 KMF_DATA *signer_cert; 710 KMF_X509_SPKI spki; 711 712 KMF_ATTRIBUTE_TESTER required_attrs[] = { 713 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 714 {KMF_DATA_ATTR, FALSE, sizeof (KMF_DATA), 715 sizeof (KMF_DATA)}, 716 {KMF_IN_SIGN_ATTR, FALSE, sizeof (KMF_DATA), 717 sizeof (KMF_DATA)} 718 }; 719 720 int num_req_attrs = sizeof (required_attrs) / 721 sizeof (KMF_ATTRIBUTE_TESTER); 722 723 if (handle == NULL) 724 return (KMF_ERR_BAD_PARAMETER); 725 726 CLEAR_ERROR(handle, ret); 727 728 ret = test_attributes(num_req_attrs, required_attrs, 729 0, NULL, num_args, attrlist); 730 731 if (ret != KMF_OK) 732 return (ret); 733 734 len = sizeof (kstype); 735 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, 736 &kstype, &len); 737 if (ret != KMF_OK) 738 return (ret); 739 740 KMFKey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, num_args); 741 signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist, 742 num_args); 743 if (KMFKey == NULL && signer_cert == NULL) { 744 return (KMF_ERR_BAD_PARAMETER); 745 } 746 747 len = sizeof (sigAlg); 748 ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, num_args, 749 &sigAlg, &len); 750 if (ret != KMF_OK) 751 return (ret); 752 753 indata = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, num_args); 754 if (indata == NULL) 755 return (KMF_ERR_BAD_PARAMETER); 756 757 insig = kmf_get_attr_ptr(KMF_IN_SIGN_ATTR, attrlist, num_args); 758 if (insig == NULL) 759 return (KMF_ERR_BAD_PARAMETER); 760 761 /* If the caller passed a signer cert instead of a key use it. */ 762 if (signer_cert != NULL) { 763 ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA); 764 if (ret != KMF_OK) 765 return (ret); 766 767 if (kstype == KMF_KEYSTORE_NSS) 768 kstype = KMF_KEYSTORE_PK11TOKEN; 769 plugin = FindPlugin(handle, kstype); 770 if (plugin == NULL) 771 return (KMF_ERR_PLUGIN_NOTFOUND); 772 if (plugin->funclist->VerifyDataWithCert == NULL) 773 return (KMF_ERR_FUNCTION_NOT_FOUND); 774 775 CLEAR_ERROR(handle, ret); 776 ret = plugin->funclist->VerifyDataWithCert(handle, 777 sigAlg, indata, insig, signer_cert); 778 } else { 779 /* Retrieve public key data from keystore */ 780 plugin = FindPlugin(handle, kstype); 781 if (plugin != NULL && 782 plugin->funclist->EncodePubkeyData != NULL) { 783 ret = plugin->funclist->EncodePubkeyData(handle, 784 KMFKey, &derkey); 785 } else { 786 return (KMF_ERR_PLUGIN_NOTFOUND); 787 } 788 789 ret = DerDecodeSPKI(&derkey, &spki); 790 if (ret == KMF_OK) { 791 ret = PKCS_VerifyData(handle, sigAlg, &spki, 792 indata, insig); 793 } 794 795 if (derkey.Data != NULL) 796 free(derkey.Data); 797 798 kmf_free_algoid(&spki.algorithm); 799 kmf_free_data(&spki.subjectPublicKey); 800 } 801 802 return (ret); 803 } 804 /* 805 * Name: kmf_verify_cert 806 * 807 * Description: 808 * This function verifies that the a certificate was signed 809 * using a specific private key and that the certificate has not 810 * been altered since it was signed using that private key 811 * The public key used for verification may be given in the 812 * attribute list as a KMF_KEY_HANDLE or the caller may give 813 * just the signing certificate (as KMF_SIGNER_CERT_DATA_ATTR) 814 * from which the public key needed for verification can be 815 * derived. 816 * 817 * Parameters: 818 * handle(input) - opaque handle for KMF session 819 * numattr - number of attributes in the list 820 * attrlist - KMF_ATTRIBUTES 821 * 822 * Returns: 823 * A KMF_RETURN value indicating success or specifying a particular 824 * error condition. The value KMF_OK indicates success. All other 825 * values represent an error condition. 826 */ 827 KMF_RETURN 828 kmf_verify_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 829 { 830 KMF_RETURN ret; 831 KMF_DATA derkey = {0, NULL}; 832 KMF_PLUGIN *plugin; 833 KMF_KEY_HANDLE *KMFKey; 834 KMF_DATA *CertToBeVerified; 835 KMF_DATA *SignerCert; 836 KMF_ATTRIBUTE_TESTER required_attrs[] = { 837 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)} 838 }; 839 840 int num_req_attrs = sizeof (required_attrs) / 841 sizeof (KMF_ATTRIBUTE_TESTER); 842 843 CLEAR_ERROR(handle, ret); 844 if (ret != KMF_OK) 845 return (ret); 846 847 ret = test_attributes(num_req_attrs, required_attrs, 848 0, NULL, numattr, attrlist); 849 if (ret != KMF_OK) 850 return (ret); 851 852 KMFKey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 853 SignerCert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist, 854 numattr); 855 856 /* 857 * Caller must provide at least a key handle or a cert to use 858 * as the "key" for verification. 859 */ 860 if (KMFKey == NULL && SignerCert == NULL) 861 return (KMF_ERR_BAD_PARAMETER); 862 863 CertToBeVerified = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, 864 numattr); 865 if (CertToBeVerified == NULL) 866 return (KMF_ERR_BAD_PARAMETER); 867 868 if (SignerCert != NULL) { 869 ret = verify_cert_with_cert(handle, CertToBeVerified, 870 SignerCert); 871 } else { 872 /* 873 * The keystore must extract the pubkey data because 874 * the framework doesn't have access to the raw key bytes 875 * that are needed to construct the DER encoded public 876 * key information needed for the verify operation. 877 */ 878 plugin = FindPlugin(handle, KMFKey->kstype); 879 if (plugin != NULL && plugin->funclist->EncodePubkeyData != 880 NULL) { 881 ret = plugin->funclist->EncodePubkeyData(handle, 882 KMFKey, &derkey); 883 } else { 884 return (KMF_ERR_PLUGIN_NOTFOUND); 885 } 886 887 if (ret == KMF_OK && derkey.Length > 0) { 888 ret = verify_cert_with_key(handle, &derkey, 889 CertToBeVerified); 890 891 if (derkey.Data != NULL) 892 free(derkey.Data); 893 } 894 } 895 896 return (ret); 897 } 898 899 /* 900 * Utility routine for verifying generic data using a 901 * certificate to derive the public key. This is 902 * done in a specific plugin because there are situations 903 * where we want to force this operation to happen in 904 * a specific keystore. 905 * For example: 906 * libelfsign verifies signatures on crypto libraries. 907 * We cannot use libpkcs11 functions to verify the pkcs11 908 * libraries because it results in a circular dependency. 909 * So, when libelfsign is verifying library sigs, it 910 * always forces the operation to happen in OpenSSL 911 * to avoid the circular dependency. 912 */ 913 static KMF_RETURN 914 plugin_verify_data_with_cert(KMF_HANDLE_T handle, 915 KMF_KEYSTORE_TYPE kstype, 916 KMF_ALGORITHM_INDEX algid, 917 KMF_DATA *indata, 918 KMF_DATA *insig, 919 const KMF_DATA *SignerCert) 920 { 921 KMF_PLUGIN *plugin; 922 KMF_RETURN ret = KMF_OK; 923 924 /* 925 * If NSS, use PKCS#11, we are not accessing the database(s), 926 * we just prefer the "verify" operation from the crypto framework. 927 * The OpenSSL version is unique in order to avoid a dependency loop 928 * with the kcfd(1M) process. 929 */ 930 if (kstype == KMF_KEYSTORE_NSS) 931 kstype = KMF_KEYSTORE_PK11TOKEN; 932 933 plugin = FindPlugin(handle, kstype); 934 if (plugin == NULL) 935 return (KMF_ERR_PLUGIN_NOTFOUND); 936 937 if (plugin->funclist->VerifyDataWithCert == NULL) 938 return (KMF_ERR_FUNCTION_NOT_FOUND); 939 940 CLEAR_ERROR(handle, ret); 941 ret = (plugin->funclist->VerifyDataWithCert(handle, 942 algid, indata, insig, (KMF_DATA *)SignerCert)); 943 944 return (ret); 945 } 946 947 /* 948 * Name: kmf_encrypt 949 * 950 * Description: 951 * Uses the public key from the cert to encrypt the plaintext 952 * into the ciphertext. 953 * 954 * Parameters: 955 * handle(input) - opaque handle for KMF session 956 * cert(input) - pointer to a DER encoded certificate for encryption 957 * by using its public key 958 * plaintext(input) - pointer to the plaintext to be encrypted 959 * ciphertext(output) - pointer to the ciphertext contains 960 * encrypted data 961 * 962 * Returns: 963 * A KMF_RETURN value indicating success or specifying a particular 964 * error condition. 965 * The value KMF_OK indicates success. All other values represent 966 * an error condition. 967 * 968 */ 969 KMF_RETURN 970 kmf_encrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 971 { 972 KMF_RETURN ret; 973 KMF_X509_CERTIFICATE *x509cert = NULL; 974 KMF_X509_SPKI *pubkey; 975 KMF_OID *alg; 976 KMF_ALGORITHM_INDEX algid; 977 KMF_DATA *cert; 978 KMF_DATA *plaintext; 979 KMF_DATA *ciphertext; 980 KMF_ATTRIBUTE_TESTER required_attrs[] = { 981 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 982 sizeof (KMF_DATA)}, 983 {KMF_PLAINTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 984 sizeof (KMF_DATA)}, 985 {KMF_CIPHERTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 986 sizeof (KMF_DATA)} 987 }; 988 989 int num_req_attrs = sizeof (required_attrs) / 990 sizeof (KMF_ATTRIBUTE_TESTER); 991 992 CLEAR_ERROR(handle, ret); 993 if (ret != KMF_OK) 994 return (ret); 995 996 ret = test_attributes(num_req_attrs, required_attrs, 997 0, NULL, numattr, attrlist); 998 if (ret != KMF_OK) 999 return (ret); 1000 1001 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, 1002 numattr); 1003 plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist, 1004 numattr); 1005 ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist, 1006 numattr); 1007 1008 if (cert == NULL || plaintext == NULL || ciphertext == NULL) 1009 return (KMF_ERR_BAD_PARAMETER); 1010 1011 /* check the keyUsage of the certificate */ 1012 ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA); 1013 if (ret == KMF_ERR_EXTENSION_NOT_FOUND) 1014 ret = KMF_OK; 1015 if (ret != KMF_OK) 1016 return (ret); 1017 1018 /* Decode the cert so we can get the SPKI data */ 1019 if ((ret = DerDecodeSignedCertificate(cert, &x509cert)) != KMF_OK) 1020 return (ret); 1021 1022 /* Get the public key info from the certificate */ 1023 pubkey = &x509cert->certificate.subjectPublicKeyInfo; 1024 1025 /* Use the algorithm in SPKI to encrypt data */ 1026 alg = &pubkey->algorithm.algorithm; 1027 1028 algid = x509_algoid_to_algid(alg); 1029 1030 /* DSA does not support encrypt */ 1031 if (algid == KMF_ALGID_DSA || algid == KMF_ALGID_NONE) { 1032 kmf_free_signed_cert(x509cert); 1033 free(x509cert); 1034 return (KMF_ERR_BAD_ALGORITHM); 1035 } 1036 1037 /* 1038 * Encrypt using the crypto framework (not the KMF plugin mechanism). 1039 */ 1040 ret = PKCS_EncryptData(handle, algid, pubkey, plaintext, ciphertext); 1041 1042 kmf_free_signed_cert(x509cert); 1043 free(x509cert); 1044 1045 return (ret); 1046 } 1047 1048 /* 1049 * Name: kmf_decrypt 1050 * 1051 * Description: 1052 * Uses the private key associated with the cert to decrypt 1053 * the ciphertext into the plaintext. 1054 */ 1055 KMF_RETURN 1056 kmf_decrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 1057 { 1058 KMF_RETURN ret; 1059 KMF_X509_CERTIFICATE *x509cert = NULL; 1060 KMF_X509_SPKI *spki_ptr; 1061 KMF_PLUGIN *plugin; 1062 KMF_ALGORITHM_INDEX AlgorithmId; 1063 KMF_ATTRIBUTE *new_attrlist = NULL; 1064 int new_numattr; 1065 KMF_DATA *cert = NULL; 1066 KMF_DATA *ciphertext = NULL; 1067 KMF_DATA *plaintext = NULL; 1068 KMF_KEY_HANDLE prikey; 1069 KMF_ATTRIBUTE_TESTER required_attrs[] = { 1070 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 1071 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, 1072 {KMF_PLAINTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1073 sizeof (KMF_DATA)}, 1074 {KMF_CIPHERTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1075 sizeof (KMF_DATA)}, 1076 }; 1077 int num_req_attrs = sizeof (required_attrs) / 1078 sizeof (KMF_ATTRIBUTE_TESTER); 1079 1080 if (handle == NULL) 1081 return (KMF_ERR_BAD_PARAMETER); 1082 CLEAR_ERROR(handle, ret); 1083 1084 ret = test_attributes(num_req_attrs, required_attrs, 1085 0, NULL, numattr, attrlist); 1086 if (ret != KMF_OK) 1087 return (ret); 1088 1089 1090 /* Get the cert and check its keyUsage */ 1091 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, 1092 numattr); 1093 if (cert == NULL) 1094 return (KMF_ERR_BAD_PARAMETER); 1095 1096 /* check the keyUsage of the certificate */ 1097 ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA); 1098 if (ret == KMF_ERR_EXTENSION_NOT_FOUND) 1099 ret = KMF_OK; 1100 if (ret != KMF_OK) 1101 return (ret); 1102 1103 /* Get the ciphertext and plaintext attributes */ 1104 ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist, 1105 numattr); 1106 if (ciphertext == NULL) 1107 return (KMF_ERR_BAD_PARAMETER); 1108 1109 plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist, 1110 numattr); 1111 if (plaintext == NULL) 1112 return (KMF_ERR_BAD_PARAMETER); 1113 1114 /* 1115 * Retrieve the private key from the keystore based on 1116 * the certificate. 1117 */ 1118 ret = setup_findprikey_attrlist(attrlist, numattr, &new_attrlist, 1119 &new_numattr, &prikey, cert); 1120 if (ret != KMF_OK) 1121 goto cleanup; 1122 1123 ret = kmf_find_prikey_by_cert(handle, new_numattr, new_attrlist); 1124 if (ret != KMF_OK) 1125 goto cleanup; 1126 1127 /* Decode the cert so we can get the alogorithm */ 1128 ret = DerDecodeSignedCertificate(cert, &x509cert); 1129 if (ret != KMF_OK) 1130 goto cleanup; 1131 1132 spki_ptr = &x509cert->certificate.subjectPublicKeyInfo; 1133 AlgorithmId = x509_algoid_to_algid((KMF_OID *) 1134 &spki_ptr->algorithm.algorithm); 1135 1136 /* DSA does not support decrypt */ 1137 if (AlgorithmId == KMF_ALGID_DSA) { 1138 ret = KMF_ERR_BAD_ALGORITHM; 1139 goto cleanup; 1140 } 1141 1142 plugin = FindPlugin(handle, prikey.kstype); 1143 1144 if (plugin != NULL && plugin->funclist->DecryptData != NULL) { 1145 ret = plugin->funclist->DecryptData(handle, 1146 &prikey, &spki_ptr->algorithm.algorithm, 1147 ciphertext, plaintext); 1148 } else { 1149 ret = KMF_ERR_PLUGIN_NOTFOUND; 1150 } 1151 1152 cleanup: 1153 if (new_attrlist != NULL) 1154 free(new_attrlist); 1155 1156 kmf_free_kmf_key(handle, &prikey); 1157 kmf_free_signed_cert(x509cert); 1158 free(x509cert); 1159 1160 return (ret); 1161 } 1162 1163 KMF_RETURN 1164 kmf_store_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 1165 { 1166 KMF_PLUGIN *plugin; 1167 KMF_RETURN ret = KMF_OK; 1168 KMF_KEYSTORE_TYPE kstype; 1169 1170 KMF_ATTRIBUTE_TESTER required_attrs[] = { 1171 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 1172 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, 1173 }; 1174 1175 int num_req_attrs = sizeof (required_attrs) / 1176 sizeof (KMF_ATTRIBUTE_TESTER); 1177 1178 if (handle == NULL) 1179 return (KMF_ERR_BAD_PARAMETER); 1180 1181 CLEAR_ERROR(handle, ret); 1182 1183 ret = test_attributes(num_req_attrs, required_attrs, 1184 0, NULL, numattr, attrlist); 1185 if (ret != KMF_OK) 1186 return (ret); 1187 1188 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, 1189 &kstype, NULL); 1190 if (ret != KMF_OK) 1191 return (ret); 1192 1193 plugin = FindPlugin(handle, kstype); 1194 if (plugin == NULL || plugin->funclist->StoreCert == NULL) 1195 return (KMF_ERR_PLUGIN_NOTFOUND); 1196 1197 return (plugin->funclist->StoreCert(handle, numattr, attrlist)); 1198 } 1199 1200 KMF_RETURN 1201 kmf_import_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 1202 { 1203 KMF_PLUGIN *plugin; 1204 KMF_RETURN ret = KMF_OK; 1205 KMF_KEYSTORE_TYPE kstype; 1206 1207 KMF_ATTRIBUTE_TESTER required_attrs[] = { 1208 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 1209 {KMF_CERT_FILENAME_ATTR, TRUE, 1, 0}, 1210 }; 1211 1212 int num_req_attrs = sizeof (required_attrs) / 1213 sizeof (KMF_ATTRIBUTE_TESTER); 1214 1215 if (handle == NULL) 1216 return (KMF_ERR_BAD_PARAMETER); 1217 1218 CLEAR_ERROR(handle, ret); 1219 1220 ret = test_attributes(num_req_attrs, required_attrs, 0, NULL, 1221 numattr, attrlist); 1222 if (ret != KMF_OK) 1223 return (ret); 1224 1225 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, 1226 &kstype, NULL); 1227 if (ret != KMF_OK) 1228 return (ret); 1229 1230 plugin = FindPlugin(handle, kstype); 1231 if (plugin == NULL || plugin->funclist->ImportCert == NULL) 1232 return (KMF_ERR_PLUGIN_NOTFOUND); 1233 1234 return (plugin->funclist->ImportCert(handle, numattr, attrlist)); 1235 } 1236 1237 KMF_RETURN 1238 kmf_delete_cert_from_keystore(KMF_HANDLE_T handle, int numattr, 1239 KMF_ATTRIBUTE *attrlist) 1240 { 1241 KMF_PLUGIN *plugin; 1242 KMF_RETURN ret = KMF_OK; 1243 KMF_KEYSTORE_TYPE kstype; 1244 KMF_ATTRIBUTE_TESTER required_attrs[] = { 1245 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)} 1246 }; 1247 int num_req_attrs = sizeof (required_attrs) / 1248 sizeof (KMF_ATTRIBUTE_TESTER); 1249 1250 if (handle == NULL) 1251 return (KMF_ERR_BAD_PARAMETER); 1252 1253 CLEAR_ERROR(handle, ret); 1254 1255 ret = test_attributes(num_req_attrs, required_attrs, 1256 0, NULL, numattr, attrlist); 1257 if (ret != KMF_OK) 1258 return (ret); 1259 1260 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, 1261 &kstype, NULL); 1262 if (ret != KMF_OK) 1263 return (ret); 1264 1265 plugin = FindPlugin(handle, kstype); 1266 if (plugin == NULL || plugin->funclist->DeleteCert == NULL) 1267 return (KMF_ERR_PLUGIN_NOTFOUND); 1268 1269 return (plugin->funclist->DeleteCert(handle, numattr, attrlist)); 1270 } 1271 1272 1273 /* 1274 * This function gets the CRL URI entries from the certificate's Distribution 1275 * points extension, and downloads the CRL file. The function also returns 1276 * the URI string and the format of the CRL file. The caller should free 1277 * the space allocated for the returned URI string. 1278 */ 1279 static KMF_RETURN 1280 cert_get_crl(KMF_HANDLE_T handle, const KMF_DATA *cert, char *proxy, 1281 char *filename, char **retn_uri, KMF_ENCODE_FORMAT *format) 1282 { 1283 KMF_RETURN ret = KMF_OK; 1284 KMF_X509EXT_CRLDISTPOINTS crl_dps; 1285 boolean_t done = B_FALSE; 1286 char uri[1024]; 1287 char *proxyname = NULL; 1288 char *proxy_port_s = NULL; 1289 int proxy_port = 0; 1290 int i, j; 1291 char *path = NULL; 1292 1293 if (handle == NULL || cert == NULL || filename == NULL || 1294 retn_uri == NULL || format == NULL) 1295 return (KMF_ERR_BAD_PARAMETER); 1296 1297 /* Get the proxy info */ 1298 if (proxy != NULL) { 1299 proxyname = strtok(proxy, ":"); 1300 proxy_port_s = strtok(NULL, "\0"); 1301 if (proxy_port_s != NULL) { 1302 proxy_port = strtol(proxy_port_s, NULL, 0); 1303 } else { 1304 proxy_port = 8080; /* default */ 1305 } 1306 } 1307 1308 /* 1309 * Get the CRL URI from the certificate's CRL Distribution 1310 * Points extension and download the CRL file. There maybe more than 1311 * one CRL URI entries in the DP extension, so we will continue 1312 * the process until a CRL file is sucessfully downloaded or we 1313 * are running out the CRL URI's. 1314 */ 1315 ret = kmf_get_cert_crl_dist_pts((const KMF_DATA *)cert, 1316 &crl_dps); 1317 if (ret != KMF_OK) 1318 goto out; 1319 1320 for (i = 0; i < crl_dps.number; i++) { 1321 KMF_CRL_DIST_POINT *dp = &(crl_dps.dplist[i]); 1322 KMF_GENERALNAMES *fullname = &(dp->name.full_name); 1323 KMF_DATA *data; 1324 1325 if (done) 1326 break; 1327 for (j = 0; j < fullname->number; j++) { 1328 data = &(fullname->namelist[j].name); 1329 (void) memcpy(uri, data->Data, data->Length); 1330 uri[data->Length] = '\0'; 1331 ret = kmf_download_crl(handle, uri, proxyname, 1332 proxy_port, 30, filename, format); 1333 if (ret == KMF_OK) { 1334 done = B_TRUE; 1335 path = malloc(data->Length + 1); 1336 if (path == NULL) { 1337 ret = KMF_ERR_MEMORY; 1338 goto out; 1339 } 1340 (void) strncpy(path, uri, data->Length); 1341 *retn_uri = path; 1342 break; 1343 } 1344 } 1345 } 1346 1347 out: 1348 kmf_free_crl_dist_pts(&crl_dps); 1349 return (ret); 1350 } 1351 1352 static KMF_RETURN 1353 check_crl_validity(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype, 1354 char *crlfilename, KMF_DATA *issuer_cert) 1355 { 1356 KMF_RETURN ret = KMF_OK; 1357 KMF_POLICY_RECORD *policy; 1358 1359 if (handle == NULL) 1360 return (KMF_ERR_BAD_PARAMETER); 1361 1362 policy = handle->policy; 1363 1364 /* 1365 * NSS CRL is not file based, and its signature 1366 * has been verified during CRL import. 1367 * We only check CRL validity for file-based CRLs, 1368 * NSS handles these checks internally. 1369 */ 1370 if (kstype == KMF_KEYSTORE_NSS) 1371 return (KMF_OK); 1372 1373 /* 1374 * Check the CRL signature if needed. 1375 */ 1376 if (!policy->validation_info.crl_info.ignore_crl_sign) { 1377 ret = kmf_verify_crl_file(handle, crlfilename, 1378 issuer_cert); 1379 if (ret != KMF_OK) 1380 return (ret); 1381 } 1382 /* 1383 * Check the CRL validity if needed. 1384 */ 1385 if (!policy->validation_info.crl_info.ignore_crl_date) { 1386 ret = kmf_check_crl_date(handle, crlfilename); 1387 if (ret != KMF_OK) 1388 return (ret); 1389 } 1390 1391 return (ret); 1392 } 1393 1394 static KMF_RETURN 1395 cert_crl_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, 1396 KMF_DATA *user_cert, KMF_DATA *issuer_cert) 1397 { 1398 KMF_POLICY_RECORD *policy; 1399 KMF_RETURN ret = KMF_OK; 1400 KMF_ATTRIBUTE attrlist[16]; 1401 int numattr = 0; 1402 int fd; 1403 boolean_t crlchk; 1404 char user_certfile[MAXPATHLEN]; 1405 char crlfile_tmp[MAXPATHLEN]; 1406 char *basefilename = NULL; 1407 char *dir = NULL; 1408 char *crlfilename = NULL; 1409 char *proxy = NULL; 1410 char *uri = NULL; 1411 KMF_ENCODE_FORMAT format; 1412 1413 if (handle == NULL || kstype == NULL || user_cert == NULL || 1414 issuer_cert == NULL) 1415 return (KMF_ERR_BAD_PARAMETER); 1416 1417 if (!is_valid_keystore_type(*kstype)) 1418 return (KMF_ERR_BAD_PARAMETER); 1419 1420 policy = handle->policy; 1421 1422 /* 1423 * If the get-crl-uri policy is TRUE, then download the CRL 1424 * file first. The newly downloaded file will be stored in the 1425 * NSS internal database for NSS keystore, and stored in a file for 1426 * the File-based CRL plugins (OpenSSL and PKCS11). 1427 * 1428 * For file-based plugins, if the get-crl-uri policy is FALSE, 1429 * then the caller should provide a CRL file in the policy. 1430 * Also, after this step is done, the "crlfilename" variable should 1431 * contain the proper CRL file to be used for the rest of CRL 1432 * validation process. 1433 */ 1434 basefilename = policy->validation_info.crl_info.basefilename; 1435 dir = policy->validation_info.crl_info.directory; 1436 if (policy->validation_info.crl_info.get_crl_uri) { 1437 /* 1438 * Check to see if we already have this CRL. 1439 */ 1440 if (basefilename == NULL) 1441 basefilename = basename(uri); 1442 1443 crlfilename = get_fullpath(dir == NULL ? "./" : dir, 1444 basefilename); 1445 if (crlfilename == NULL) { 1446 ret = KMF_ERR_BAD_CRLFILE; 1447 goto cleanup; 1448 } 1449 1450 /* 1451 * If this file already exists and is valid, we don't need to 1452 * download a new one. 1453 */ 1454 if ((fd = open(crlfilename, O_RDONLY)) != -1) { 1455 (void) close(fd); 1456 if ((ret = check_crl_validity(handle, *kstype, 1457 crlfilename, issuer_cert)) == KMF_OK) { 1458 goto checkcrl; 1459 } 1460 } 1461 1462 /* 1463 * Create a temporary file to hold the new CRL file initially. 1464 */ 1465 (void) strlcpy(crlfile_tmp, CRLFILE_TEMPNAME, 1466 sizeof (crlfile_tmp)); 1467 if (mkstemp(crlfile_tmp) == -1) { 1468 ret = KMF_ERR_INTERNAL; 1469 goto cleanup; 1470 } 1471 1472 /* 1473 * Get the URI entry from the certificate's CRL distribution 1474 * points extension and download the CRL file. 1475 */ 1476 proxy = policy->validation_info.crl_info.proxy; 1477 ret = cert_get_crl(handle, user_cert, proxy, crlfile_tmp, 1478 &uri, &format); 1479 if (ret != KMF_OK) { 1480 (void) unlink(crlfile_tmp); 1481 goto cleanup; 1482 } 1483 /* 1484 * If we just downloaded one, make sure it is OK. 1485 */ 1486 if ((ret = check_crl_validity(handle, *kstype, crlfile_tmp, 1487 issuer_cert)) != KMF_OK) 1488 return (ret); 1489 1490 /* Cache the CRL file. */ 1491 if (*kstype == KMF_KEYSTORE_NSS) { 1492 /* 1493 * For NSS keystore, import this CRL file into th 1494 * internal database. 1495 */ 1496 numattr = 0; 1497 kmf_set_attr_at_index(attrlist, numattr, 1498 KMF_KEYSTORE_TYPE_ATTR, kstype, sizeof (kstype)); 1499 numattr++; 1500 1501 kmf_set_attr_at_index(attrlist, numattr, 1502 KMF_CRL_FILENAME_ATTR, crlfile_tmp, 1503 strlen(crlfile_tmp)); 1504 numattr++; 1505 1506 crlchk = B_FALSE; 1507 kmf_set_attr_at_index(attrlist, numattr, 1508 KMF_CRL_CHECK_ATTR, &crlchk, sizeof (boolean_t)); 1509 numattr++; 1510 1511 ret = kmf_import_crl(handle, numattr, attrlist); 1512 (void) unlink(crlfile_tmp); 1513 if (ret != KMF_OK) 1514 goto cleanup; 1515 } else { 1516 if (rename(crlfile_tmp, crlfilename) == -1) { 1517 (void) unlink(crlfile_tmp); 1518 ret = KMF_ERR_WRITE_FILE; 1519 goto cleanup; 1520 } 1521 } 1522 } else { 1523 /* 1524 * If the get_crl_uri policy is FALSE, for File-based CRL 1525 * plugins, get the input CRL file from the policy. 1526 */ 1527 if (*kstype != KMF_KEYSTORE_NSS) { 1528 if (basefilename == NULL) { 1529 ret = KMF_ERR_BAD_PARAMETER; 1530 goto cleanup; 1531 } 1532 1533 crlfilename = get_fullpath(dir == NULL ? "./" : dir, 1534 basefilename); 1535 if (crlfilename == NULL) { 1536 ret = KMF_ERR_BAD_CRLFILE; 1537 goto cleanup; 1538 } 1539 /* 1540 * Make sure this CRL is still valid. 1541 */ 1542 if ((ret = check_crl_validity(handle, *kstype, 1543 crlfilename, issuer_cert)) != KMF_OK) 1544 return (ret); 1545 } 1546 } 1547 1548 checkcrl: 1549 /* 1550 * Check the CRL revocation for the certificate. 1551 */ 1552 numattr = 0; 1553 1554 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 1555 kstype, sizeof (kstype)); 1556 numattr++; 1557 1558 switch (*kstype) { 1559 case KMF_KEYSTORE_NSS: 1560 kmf_set_attr_at_index(attrlist, numattr, 1561 KMF_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA)); 1562 numattr++; 1563 break; 1564 case KMF_KEYSTORE_PK11TOKEN: 1565 case KMF_KEYSTORE_OPENSSL: 1566 /* 1567 * Create temporary file to hold the user certificate. 1568 */ 1569 (void) strlcpy(user_certfile, CERTFILE_TEMPNAME, 1570 sizeof (user_certfile)); 1571 if (mkstemp(user_certfile) == -1) { 1572 ret = KMF_ERR_INTERNAL; 1573 goto cleanup; 1574 } 1575 1576 ret = kmf_create_cert_file(user_cert, KMF_FORMAT_ASN1, 1577 user_certfile); 1578 if (ret != KMF_OK) { 1579 goto cleanup; 1580 } 1581 1582 kmf_set_attr_at_index(attrlist, numattr, 1583 KMF_CERT_FILENAME_ATTR, 1584 user_certfile, strlen(user_certfile)); 1585 numattr++; 1586 1587 kmf_set_attr_at_index(attrlist, numattr, 1588 KMF_CRL_FILENAME_ATTR, 1589 crlfilename, strlen(crlfilename)); 1590 numattr++; 1591 break; 1592 default: 1593 ret = KMF_ERR_PLUGIN_NOTFOUND; 1594 goto cleanup; 1595 } 1596 1597 ret = kmf_find_cert_in_crl(handle, numattr, attrlist); 1598 if (ret == KMF_ERR_NOT_REVOKED) { 1599 ret = KMF_OK; 1600 } 1601 1602 cleanup: 1603 (void) unlink(user_certfile); 1604 1605 if (crlfilename != NULL) 1606 free(crlfilename); 1607 1608 if (uri != NULL) 1609 free(uri); 1610 1611 return (ret); 1612 } 1613 1614 static KMF_RETURN 1615 cert_ocsp_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, 1616 KMF_DATA *user_cert, KMF_DATA *issuer_cert, KMF_DATA *response, 1617 char *slotlabel, char *dirpath) 1618 { 1619 KMF_RETURN ret = KMF_OK; 1620 KMF_POLICY_RECORD *policy; 1621 KMF_DATA *new_response = NULL; 1622 boolean_t ignore_response_sign = B_FALSE; 1623 uint32_t ltime = 0; 1624 KMF_DATA *signer_cert = NULL; 1625 KMF_BIGINT sernum = { NULL, 0 }; 1626 int response_status; 1627 int reason; 1628 int cert_status; 1629 KMF_ATTRIBUTE attrlist[32]; 1630 int numattr; 1631 1632 if (handle == NULL || kstype == NULL || user_cert == NULL || 1633 issuer_cert == NULL) 1634 return (KMF_ERR_BAD_PARAMETER); 1635 1636 policy = handle->policy; 1637 1638 /* 1639 * Get the response lifetime from policy. 1640 */ 1641 if (policy->VAL_OCSP_BASIC.response_lifetime != NULL && 1642 (str2lifetime(policy->VAL_OCSP_BASIC.response_lifetime, <ime) 1643 < 0)) 1644 return (KMF_ERR_OCSP_RESPONSE_LIFETIME); 1645 1646 /* 1647 * Get the ignore_response_sign policy. 1648 * 1649 * If ignore_response_sign is FALSE, we need to verify the response. 1650 * Find the OCSP Responder certificate if it is specified in the OCSP 1651 * policy. 1652 */ 1653 ignore_response_sign = policy->VAL_OCSP_BASIC.ignore_response_sign; 1654 1655 if (ignore_response_sign == B_FALSE && 1656 policy->VAL_OCSP.has_resp_cert == B_TRUE) { 1657 char *signer_name; 1658 KMF_X509_DER_CERT signer_retrcert; 1659 uchar_t *bytes = NULL; 1660 size_t bytelen; 1661 uint32_t num = 0; 1662 KMF_ATTRIBUTE fc_attrlist[16]; 1663 int fc_numattr = 0; 1664 char *dir = "./"; 1665 1666 if (policy->VAL_OCSP_RESP_CERT.name == NULL || 1667 policy->VAL_OCSP_RESP_CERT.serial == NULL) 1668 return (KMF_ERR_POLICY_NOT_FOUND); 1669 1670 signer_cert = malloc(sizeof (KMF_DATA)); 1671 if (signer_cert == NULL) { 1672 ret = KMF_ERR_MEMORY; 1673 goto out; 1674 } 1675 (void) memset(signer_cert, 0, sizeof (KMF_DATA)); 1676 1677 signer_name = policy->VAL_OCSP_RESP_CERT.name; 1678 ret = kmf_hexstr_to_bytes( 1679 (uchar_t *)policy->VAL_OCSP_RESP_CERT.serial, 1680 &bytes, &bytelen); 1681 if (ret != KMF_OK || bytes == NULL) { 1682 ret = KMF_ERR_OCSP_POLICY; 1683 goto out; 1684 } 1685 sernum.val = bytes; 1686 sernum.len = bytelen; 1687 1688 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1689 KMF_KEYSTORE_TYPE_ATTR, kstype, 1690 sizeof (KMF_KEYSTORE_TYPE)); 1691 fc_numattr++; 1692 1693 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1694 KMF_SUBJECT_NAME_ATTR, signer_name, strlen(signer_name)); 1695 fc_numattr++; 1696 1697 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR, 1698 &sernum, sizeof (KMF_BIGINT)); 1699 fc_numattr++; 1700 1701 if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) { 1702 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1703 KMF_TOKEN_LABEL_ATTR, slotlabel, 1704 strlen(slotlabel)); 1705 fc_numattr++; 1706 } 1707 1708 if (*kstype == KMF_KEYSTORE_OPENSSL) { 1709 if (dirpath == NULL) { 1710 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1711 KMF_DIRPATH_ATTR, dir, strlen(dir)); 1712 fc_numattr++; 1713 } else { 1714 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1715 KMF_DIRPATH_ATTR, dirpath, 1716 strlen(dirpath)); 1717 fc_numattr++; 1718 } 1719 } 1720 1721 num = 0; 1722 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1723 KMF_COUNT_ATTR, &num, sizeof (uint32_t)); 1724 fc_numattr++; 1725 1726 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 1727 if (ret != KMF_OK || num != 1) { 1728 if (num == 0) 1729 ret = KMF_ERR_CERT_NOT_FOUND; 1730 if (num > 0) 1731 ret = KMF_ERR_CERT_MULTIPLE_FOUND; 1732 goto out; 1733 } 1734 1735 (void) memset(&signer_retrcert, 0, sizeof (KMF_X509_DER_CERT)); 1736 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1737 KMF_X509_DER_CERT_ATTR, &signer_retrcert, 1738 sizeof (KMF_X509_DER_CERT)); 1739 fc_numattr++; 1740 1741 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 1742 if (ret == KMF_OK) { 1743 signer_cert->Length = 1744 signer_retrcert.certificate.Length; 1745 signer_cert->Data = signer_retrcert.certificate.Data; 1746 } else { 1747 goto out; 1748 } 1749 } 1750 1751 /* 1752 * If the caller provides an OCSP response, we will use it directly. 1753 * Otherwise, we will try to fetch an OCSP response for the given 1754 * certificate now. 1755 */ 1756 if (response == NULL) { 1757 new_response = (KMF_DATA *) malloc(sizeof (KMF_DATA)); 1758 if (new_response == NULL) { 1759 ret = KMF_ERR_MEMORY; 1760 goto out; 1761 } 1762 new_response->Data = NULL; 1763 new_response->Length = 0; 1764 1765 ret = kmf_get_ocsp_for_cert(handle, user_cert, issuer_cert, 1766 new_response); 1767 if (ret != KMF_OK) 1768 goto out; 1769 } 1770 1771 /* 1772 * Process the OCSP response and retrieve the certificate status. 1773 */ 1774 numattr = 0; 1775 kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_CERT_DATA_ATTR, 1776 issuer_cert, sizeof (KMF_DATA)); 1777 numattr++; 1778 1779 kmf_set_attr_at_index(attrlist, numattr, KMF_USER_CERT_DATA_ATTR, 1780 user_cert, sizeof (KMF_DATA)); 1781 numattr++; 1782 1783 if (signer_cert != NULL) { 1784 kmf_set_attr_at_index(attrlist, numattr, 1785 KMF_SIGNER_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA)); 1786 numattr++; 1787 } 1788 1789 kmf_set_attr_at_index(attrlist, numattr, KMF_OCSP_RESPONSE_DATA_ATTR, 1790 response == NULL ? new_response : response, sizeof (KMF_DATA)); 1791 numattr++; 1792 1793 kmf_set_attr_at_index(attrlist, numattr, KMF_RESPONSE_LIFETIME_ATTR, 1794 <ime, sizeof (uint32_t)); 1795 numattr++; 1796 1797 kmf_set_attr_at_index(attrlist, numattr, 1798 KMF_IGNORE_RESPONSE_SIGN_ATTR, &ignore_response_sign, 1799 sizeof (boolean_t)); 1800 numattr++; 1801 1802 kmf_set_attr_at_index(attrlist, numattr, 1803 KMF_OCSP_RESPONSE_STATUS_ATTR, &response_status, sizeof (int)); 1804 numattr++; 1805 1806 kmf_set_attr_at_index(attrlist, numattr, 1807 KMF_OCSP_RESPONSE_REASON_ATTR, &reason, sizeof (int)); 1808 numattr++; 1809 1810 kmf_set_attr_at_index(attrlist, numattr, 1811 KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, &cert_status, sizeof (int)); 1812 numattr++; 1813 1814 ret = kmf_get_ocsp_status_for_cert(handle, numattr, attrlist); 1815 if (ret == KMF_OK) { 1816 switch (cert_status) { 1817 case OCSP_GOOD: 1818 break; 1819 case OCSP_UNKNOWN: 1820 ret = KMF_ERR_OCSP_UNKNOWN_CERT; 1821 break; 1822 case OCSP_REVOKED: 1823 ret = KMF_ERR_OCSP_REVOKED; 1824 break; 1825 } 1826 } 1827 1828 out: 1829 if (new_response) { 1830 kmf_free_data(new_response); 1831 free(new_response); 1832 } 1833 1834 if (signer_cert) { 1835 kmf_free_data(signer_cert); 1836 free(signer_cert); 1837 } 1838 1839 if (sernum.val != NULL) 1840 free(sernum.val); 1841 1842 return (ret); 1843 } 1844 1845 static KMF_RETURN 1846 cert_ku_check(KMF_HANDLE_T handle, KMF_DATA *cert) 1847 { 1848 KMF_POLICY_RECORD *policy; 1849 KMF_X509EXT_KEY_USAGE keyusage; 1850 KMF_RETURN ret = KMF_OK; 1851 KMF_X509EXT_BASICCONSTRAINTS constraint; 1852 KMF_BOOL critical = B_FALSE; 1853 1854 if (handle == NULL || cert == NULL) 1855 return (KMF_ERR_BAD_PARAMETER); 1856 1857 policy = handle->policy; 1858 (void) memset(&keyusage, 0, sizeof (keyusage)); 1859 ret = kmf_get_cert_ku(cert, &keyusage); 1860 1861 if (ret == KMF_ERR_EXTENSION_NOT_FOUND) { 1862 if (policy->ku_bits) { 1863 /* keyusage is not set in cert but is set in policy */ 1864 return (KMF_ERR_KEYUSAGE); 1865 } else { 1866 /* no keyusage set in both cert and policy */ 1867 return (KMF_OK); 1868 } 1869 } 1870 1871 if (ret != KMF_OK) { 1872 /* real error */ 1873 return (ret); 1874 } 1875 1876 /* 1877 * If KeyCertSign is set, then constraints.cA must be TRUE and 1878 * marked critical. 1879 */ 1880 if ((keyusage.KeyUsageBits & KMF_keyCertSign)) { 1881 (void) memset(&constraint, 0, sizeof (constraint)); 1882 ret = kmf_get_cert_basic_constraint(cert, 1883 &critical, &constraint); 1884 1885 if (ret != KMF_OK) { 1886 /* real error */ 1887 return (ret); 1888 } 1889 if (!constraint.cA || !critical) 1890 return (KMF_ERR_KEYUSAGE); 1891 } 1892 1893 /* 1894 * Rule: if the KU bit is set in policy, the corresponding KU bit 1895 * must be set in the certificate (but not vice versa). 1896 */ 1897 if ((policy->ku_bits & keyusage.KeyUsageBits) == policy->ku_bits) { 1898 return (KMF_OK); 1899 } else { 1900 return (KMF_ERR_KEYUSAGE); 1901 } 1902 1903 } 1904 1905 static KMF_RETURN 1906 cert_eku_check(KMF_HANDLE_T handle, KMF_DATA *cert) 1907 { 1908 KMF_POLICY_RECORD *policy; 1909 KMF_RETURN ret = KMF_OK; 1910 KMF_X509EXT_EKU eku; 1911 uint16_t cert_eku = 0, policy_eku = 0; 1912 int i; 1913 1914 if (handle == NULL || cert == NULL) 1915 return (KMF_ERR_BAD_PARAMETER); 1916 policy = handle->policy; 1917 1918 /* 1919 * If the policy does not have any EKU, then there is 1920 * nothing further to check. 1921 */ 1922 if (policy->eku_set.eku_count == 0) 1923 return (KMF_OK); 1924 1925 ret = kmf_get_cert_eku(cert, &eku); 1926 if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) { 1927 /* real error */ 1928 return (ret); 1929 } 1930 1931 if (ret == KMF_ERR_EXTENSION_NOT_FOUND) { 1932 cert_eku = 0; 1933 } else { 1934 /* 1935 * Build the EKU bitmap based on the certificate 1936 */ 1937 for (i = 0; i < eku.nEKUs; i++) { 1938 if (IsEqualOid(&eku.keyPurposeIdList[i], 1939 (KMF_OID *)&KMFOID_PKIX_KP_ServerAuth)) { 1940 cert_eku |= KMF_EKU_SERVERAUTH; 1941 } else if (IsEqualOid(&eku.keyPurposeIdList[i], 1942 (KMF_OID *)&KMFOID_PKIX_KP_ClientAuth)) { 1943 cert_eku |= KMF_EKU_CLIENTAUTH; 1944 } else if (IsEqualOid(&eku.keyPurposeIdList[i], 1945 (KMF_OID *)&KMFOID_PKIX_KP_CodeSigning)) { 1946 cert_eku |= KMF_EKU_CODESIGNING; 1947 } else if (IsEqualOid(&eku.keyPurposeIdList[i], 1948 (KMF_OID *)&KMFOID_PKIX_KP_EmailProtection)) { 1949 cert_eku |= KMF_EKU_EMAIL; 1950 } else if (IsEqualOid(&eku.keyPurposeIdList[i], 1951 (KMF_OID *)&KMFOID_PKIX_KP_TimeStamping)) { 1952 cert_eku |= KMF_EKU_TIMESTAMP; 1953 } else if (IsEqualOid(&eku.keyPurposeIdList[i], 1954 (KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning)) { 1955 cert_eku |= KMF_EKU_OCSPSIGNING; 1956 } else if (!policy->ignore_unknown_ekus) { 1957 return (KMF_ERR_KEYUSAGE); 1958 } 1959 } /* for */ 1960 } 1961 1962 1963 /* 1964 * Build the EKU bitmap based on the policy 1965 */ 1966 for (i = 0; i < policy->eku_set.eku_count; i++) { 1967 if (IsEqualOid(&policy->eku_set.ekulist[i], 1968 (KMF_OID *)&KMFOID_PKIX_KP_ServerAuth)) { 1969 policy_eku |= KMF_EKU_SERVERAUTH; 1970 } else if (IsEqualOid(&policy->eku_set.ekulist[i], 1971 (KMF_OID *)&KMFOID_PKIX_KP_ClientAuth)) { 1972 policy_eku |= KMF_EKU_CLIENTAUTH; 1973 } else if (IsEqualOid(&policy->eku_set.ekulist[i], 1974 (KMF_OID *)&KMFOID_PKIX_KP_CodeSigning)) { 1975 policy_eku |= KMF_EKU_CODESIGNING; 1976 } else if (IsEqualOid(&policy->eku_set.ekulist[i], 1977 (KMF_OID *)&KMFOID_PKIX_KP_EmailProtection)) { 1978 policy_eku |= KMF_EKU_EMAIL; 1979 } else if (IsEqualOid(&policy->eku_set.ekulist[i], 1980 (KMF_OID *)&KMFOID_PKIX_KP_TimeStamping)) { 1981 policy_eku |= KMF_EKU_TIMESTAMP; 1982 } else if (IsEqualOid(&policy->eku_set.ekulist[i], 1983 (KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning)) { 1984 policy_eku |= KMF_EKU_OCSPSIGNING; 1985 } else if (!policy->ignore_unknown_ekus) { 1986 return (KMF_ERR_KEYUSAGE); 1987 } 1988 } /* for */ 1989 1990 /* 1991 * Rule: if the EKU OID is set in policy, the corresponding EKU OID 1992 * must be set in the certificate (but not vice versa). 1993 */ 1994 if ((policy_eku & cert_eku) == policy_eku) { 1995 return (KMF_OK); 1996 } else { 1997 return (KMF_ERR_KEYUSAGE); 1998 } 1999 } 2000 2001 static KMF_RETURN 2002 find_issuer_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, 2003 char *user_issuer, KMF_DATA *issuer_cert, 2004 char *slotlabel, char *dirpath) 2005 { 2006 KMF_RETURN ret = KMF_OK; 2007 KMF_X509_DER_CERT *certlist = NULL; 2008 uint32_t i, num = 0; 2009 time_t t_notbefore; 2010 time_t t_notafter; 2011 time_t latest; 2012 KMF_DATA tmp_cert = {0, NULL}; 2013 KMF_ATTRIBUTE fc_attrlist[16]; 2014 int fc_numattr = 0; 2015 char *dir = "./"; 2016 2017 if (handle == NULL || kstype == NULL || user_issuer == NULL || 2018 issuer_cert == NULL) 2019 return (KMF_ERR_BAD_PARAMETER); 2020 2021 if (!is_valid_keystore_type(*kstype)) 2022 return (KMF_ERR_BAD_PARAMETER); 2023 2024 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR, 2025 kstype, sizeof (KMF_KEYSTORE_TYPE)); 2026 fc_numattr++; 2027 2028 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR, 2029 user_issuer, strlen(user_issuer)); 2030 fc_numattr++; 2031 2032 if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) { 2033 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2034 KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel)); 2035 fc_numattr++; 2036 } 2037 2038 if (*kstype == KMF_KEYSTORE_OPENSSL) { 2039 if (dirpath == NULL) { 2040 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2041 KMF_DIRPATH_ATTR, dir, strlen(dir)); 2042 fc_numattr++; 2043 } else { 2044 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2045 KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); 2046 fc_numattr++; 2047 } 2048 } 2049 2050 num = 0; 2051 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2052 KMF_COUNT_ATTR, &num, sizeof (uint32_t)); 2053 fc_numattr++; 2054 2055 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 2056 2057 if (ret == KMF_OK && num > 0) { 2058 certlist = (KMF_X509_DER_CERT *)malloc(num * 2059 sizeof (KMF_X509_DER_CERT)); 2060 2061 if (certlist == NULL) { 2062 ret = KMF_ERR_MEMORY; 2063 goto out; 2064 } 2065 2066 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2067 KMF_X509_DER_CERT_ATTR, certlist, 2068 sizeof (KMF_X509_DER_CERT)); 2069 fc_numattr++; 2070 2071 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 2072 if (ret != KMF_OK) { 2073 free(certlist); 2074 certlist = NULL; 2075 goto out; 2076 } 2077 } else { 2078 goto out; 2079 } 2080 2081 if (num == 1) { 2082 /* only one issuer cert is found */ 2083 tmp_cert.Length = certlist[0].certificate.Length; 2084 tmp_cert.Data = certlist[0].certificate.Data; 2085 } else { 2086 /* 2087 * More than one issuer certs are found. We will 2088 * pick the latest one. 2089 */ 2090 latest = 0; 2091 for (i = 0; i < num; i++) { 2092 ret = kmf_get_cert_validity(&certlist[i].certificate, 2093 &t_notbefore, &t_notafter); 2094 if (ret != KMF_OK) { 2095 ret = KMF_ERR_VALIDITY_PERIOD; 2096 goto out; 2097 } 2098 2099 if (t_notbefore > latest) { 2100 tmp_cert.Length = 2101 certlist[i].certificate.Length; 2102 tmp_cert.Data = 2103 certlist[i].certificate.Data; 2104 latest = t_notbefore; 2105 } 2106 2107 } 2108 } 2109 2110 issuer_cert->Length = tmp_cert.Length; 2111 issuer_cert->Data = malloc(tmp_cert.Length); 2112 if (issuer_cert->Data == NULL) { 2113 ret = KMF_ERR_MEMORY; 2114 goto out; 2115 } 2116 (void) memcpy(issuer_cert->Data, tmp_cert.Data, 2117 tmp_cert.Length); 2118 2119 out: 2120 if (certlist != NULL) { 2121 for (i = 0; i < num; i++) 2122 kmf_free_kmf_cert(handle, &certlist[i]); 2123 free(certlist); 2124 } 2125 2126 return (ret); 2127 2128 } 2129 2130 static KMF_RETURN 2131 find_ta_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, 2132 KMF_DATA *ta_cert, KMF_X509_NAME *user_issuerDN, 2133 char *slotlabel, char *dirpath) 2134 { 2135 KMF_POLICY_RECORD *policy; 2136 KMF_RETURN ret = KMF_OK; 2137 uint32_t num = 0; 2138 char *ta_name; 2139 KMF_BIGINT serial = { NULL, 0 }; 2140 uchar_t *bytes = NULL; 2141 size_t bytelen; 2142 KMF_X509_DER_CERT ta_retrCert; 2143 char *ta_subject = NULL; 2144 KMF_X509_NAME ta_subjectDN; 2145 KMF_ATTRIBUTE fc_attrlist[16]; 2146 int fc_numattr = 0; 2147 char *dir = "./"; 2148 2149 if (handle == NULL || kstype == NULL || ta_cert == NULL || 2150 user_issuerDN == NULL) 2151 return (KMF_ERR_BAD_PARAMETER); 2152 2153 if (!is_valid_keystore_type(*kstype)) 2154 return (KMF_ERR_BAD_PARAMETER); 2155 2156 /* Get the TA name and serial number from the policy */ 2157 policy = handle->policy; 2158 ta_name = policy->ta_name; 2159 ret = kmf_hexstr_to_bytes((uchar_t *)policy->ta_serial, 2160 &bytes, &bytelen); 2161 if (ret != KMF_OK || bytes == NULL) { 2162 ret = KMF_ERR_TA_POLICY; 2163 goto out; 2164 } 2165 serial.val = bytes; 2166 serial.len = bytelen; 2167 2168 /* set up fc_attrlist for kmf_find_cert */ 2169 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR, 2170 kstype, sizeof (KMF_KEYSTORE_TYPE)); 2171 fc_numattr++; 2172 2173 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR, 2174 ta_name, strlen(ta_name)); 2175 fc_numattr++; 2176 2177 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR, 2178 &serial, sizeof (KMF_BIGINT)); 2179 fc_numattr++; 2180 2181 if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) { 2182 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2183 KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel)); 2184 fc_numattr++; 2185 } 2186 2187 if (*kstype == KMF_KEYSTORE_OPENSSL) { 2188 if (dirpath == NULL) { 2189 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2190 KMF_DIRPATH_ATTR, dir, strlen(dir)); 2191 fc_numattr++; 2192 } else { 2193 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2194 KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); 2195 fc_numattr++; 2196 } 2197 } 2198 2199 num = 0; 2200 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2201 KMF_COUNT_ATTR, &num, sizeof (uint32_t)); 2202 fc_numattr++; 2203 2204 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 2205 if (ret != KMF_OK || num != 1) { 2206 if (num == 0) 2207 ret = KMF_ERR_CERT_NOT_FOUND; 2208 if (num > 1) 2209 ret = KMF_ERR_CERT_MULTIPLE_FOUND; 2210 goto out; 2211 } 2212 2213 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2214 KMF_X509_DER_CERT_ATTR, &ta_retrCert, sizeof (KMF_X509_DER_CERT)); 2215 fc_numattr++; 2216 2217 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 2218 if (ret == KMF_OK) { 2219 ta_cert->Length = ta_retrCert.certificate.Length; 2220 ta_cert->Data = malloc(ta_retrCert.certificate.Length); 2221 if (ta_cert->Data == NULL) { 2222 ret = KMF_ERR_MEMORY; 2223 goto out; 2224 } 2225 (void) memcpy(ta_cert->Data, ta_retrCert.certificate.Data, 2226 ta_retrCert.certificate.Length); 2227 } else { 2228 goto out; 2229 } 2230 2231 /* 2232 * The found TA's name must be matching with issuer name in 2233 * subscriber's certificate. 2234 */ 2235 (void) memset(&ta_subjectDN, 0, sizeof (ta_subjectDN)); 2236 2237 ret = kmf_get_cert_subject_str(handle, ta_cert, &ta_subject); 2238 if (ret != KMF_OK) 2239 goto out; 2240 2241 ret = kmf_dn_parser(ta_subject, &ta_subjectDN); 2242 if (ret != KMF_OK) 2243 goto out; 2244 2245 if (kmf_compare_rdns(user_issuerDN, &ta_subjectDN) != 0) 2246 ret = KMF_ERR_CERT_NOT_FOUND; 2247 2248 kmf_free_dn(&ta_subjectDN); 2249 2250 /* Make sure the TA cert has the correct extensions */ 2251 if (ret == KMF_OK) 2252 ret = check_key_usage(handle, ta_cert, KMF_KU_SIGN_CERT); 2253 out: 2254 if (ta_retrCert.certificate.Data) 2255 kmf_free_kmf_cert(handle, &ta_retrCert); 2256 2257 if ((ret != KMF_OK) && (ta_cert->Data != NULL)) 2258 free(ta_cert->Data); 2259 2260 if (serial.val != NULL) 2261 free(serial.val); 2262 2263 if (ta_subject) 2264 free(ta_subject); 2265 2266 return (ret); 2267 } 2268 2269 KMF_RETURN 2270 kmf_validate_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 2271 { 2272 KMF_RETURN ret = KMF_OK; 2273 KMF_KEYSTORE_TYPE *kstype = NULL; 2274 KMF_DATA *pcert = NULL; 2275 int *result = NULL; 2276 char *slotlabel = NULL; 2277 char *dirpath = NULL; 2278 KMF_DATA *ocsp_response = NULL; 2279 KMF_DATA ta_cert = {0, NULL}; 2280 KMF_DATA issuer_cert = {0, NULL}; 2281 char *user_issuer = NULL, *user_subject = NULL; 2282 KMF_X509_NAME user_issuerDN, user_subjectDN; 2283 boolean_t self_signed = B_FALSE; 2284 KMF_POLICY_RECORD *policy; 2285 2286 KMF_ATTRIBUTE_TESTER required_attrs[] = { 2287 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 2288 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, 2289 {KMF_VALIDATE_RESULT_ATTR, FALSE, 1, sizeof (int)} 2290 }; 2291 int num_req_attrs = sizeof (required_attrs) / 2292 sizeof (KMF_ATTRIBUTE_TESTER); 2293 2294 if (handle == NULL) 2295 return (KMF_ERR_BAD_PARAMETER); 2296 2297 CLEAR_ERROR(handle, ret); 2298 2299 ret = test_attributes(num_req_attrs, required_attrs, 2300 0, NULL, numattr, attrlist); 2301 if (ret != KMF_OK) 2302 return (ret); 2303 2304 policy = handle->policy; 2305 2306 /* Get the attribute values */ 2307 kstype = kmf_get_attr_ptr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr); 2308 pcert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 2309 result = kmf_get_attr_ptr(KMF_VALIDATE_RESULT_ATTR, attrlist, numattr); 2310 if (kstype == NULL || pcert == NULL || result == NULL) 2311 return (KMF_ERR_BAD_PARAMETER); 2312 2313 slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr); 2314 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 2315 ocsp_response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, attrlist, 2316 numattr); 2317 2318 /* Initialize the returned result */ 2319 *result = KMF_CERT_VALIDATE_OK; 2320 2321 /* 2322 * Get the issuer information from the input certficate first. 2323 */ 2324 if ((ret = kmf_get_cert_issuer_str(handle, pcert, 2325 &user_issuer)) != KMF_OK) { 2326 *result |= KMF_CERT_VALIDATE_ERR_USER; 2327 goto out; 2328 } 2329 2330 if ((ret = kmf_dn_parser(user_issuer, &user_issuerDN)) != KMF_OK) { 2331 *result |= KMF_CERT_VALIDATE_ERR_USER; 2332 goto out; 2333 } 2334 2335 /* 2336 * Check if the certificate is a self-signed cert. 2337 */ 2338 if ((ret = kmf_get_cert_subject_str(handle, pcert, 2339 &user_subject)) != KMF_OK) { 2340 *result |= KMF_CERT_VALIDATE_ERR_USER; 2341 kmf_free_dn(&user_issuerDN); 2342 goto out; 2343 } 2344 2345 if ((ret = kmf_dn_parser(user_subject, &user_subjectDN)) != KMF_OK) { 2346 *result |= KMF_CERT_VALIDATE_ERR_USER; 2347 kmf_free_dn(&user_issuerDN); 2348 goto out; 2349 } 2350 2351 if ((kmf_compare_rdns(&user_issuerDN, &user_subjectDN)) == 0) { 2352 /* 2353 * this is a self-signed cert 2354 */ 2355 self_signed = B_TRUE; 2356 } 2357 2358 kmf_free_dn(&user_subjectDN); 2359 2360 /* 2361 * Check KeyUsage extension of the subscriber's certificate 2362 */ 2363 ret = cert_ku_check(handle, pcert); 2364 if (ret != KMF_OK) { 2365 *result |= KMF_CERT_VALIDATE_ERR_KEYUSAGE; 2366 goto out; 2367 } 2368 2369 /* 2370 * Validate Extended KeyUsage extension 2371 */ 2372 ret = cert_eku_check(handle, pcert); 2373 if (ret != KMF_OK) { 2374 *result |= KMF_CERT_VALIDATE_ERR_EXT_KEYUSAGE; 2375 goto out; 2376 } 2377 2378 /* 2379 * Check the certificate's validity period 2380 * 2381 * This step is needed when "ignore_date" in policy is set 2382 * to false. 2383 */ 2384 if (!policy->ignore_date) { 2385 /* 2386 * Validate expiration date 2387 */ 2388 ret = kmf_check_cert_date(handle, pcert); 2389 if (ret != KMF_OK) { 2390 *result |= KMF_CERT_VALIDATE_ERR_TIME; 2391 goto out; 2392 } 2393 } 2394 2395 /* 2396 * When "ignore_trust_anchor" in policy is set to FALSE, 2397 * we will try to find the TA cert based on the TA policy 2398 * attributes. 2399 * 2400 * TA's subject name (ta_name) and serial number (ta_serial) 2401 * are defined as optional attributes in policy dtd, but they 2402 * should exist in policy when "ignore_trust_anchor" is set 2403 * to FALSE. The policy verification code has enforced that. 2404 */ 2405 if (policy->ignore_trust_anchor) { 2406 goto check_revocation; 2407 } 2408 2409 /* 2410 * Verify the signature of subscriber's certificate using 2411 * TA certificate. 2412 */ 2413 if (self_signed) { 2414 ret = verify_cert_with_cert(handle, pcert, pcert); 2415 } else { 2416 ret = find_ta_cert(handle, kstype, &ta_cert, 2417 &user_issuerDN, slotlabel, dirpath); 2418 if (ret != KMF_OK) { 2419 *result |= KMF_CERT_VALIDATE_ERR_TA; 2420 goto out; 2421 } 2422 2423 ret = check_key_usage(handle, &ta_cert, KMF_KU_SIGN_CERT); 2424 if (ret != KMF_OK) 2425 goto out; 2426 2427 ret = verify_cert_with_cert(handle, pcert, &ta_cert); 2428 } 2429 if (ret != KMF_OK) { 2430 *result |= KMF_CERT_VALIDATE_ERR_SIGNATURE; 2431 goto out; 2432 } 2433 2434 check_revocation: 2435 /* 2436 * Check certificate revocation 2437 */ 2438 if (self_signed) { 2439 /* skip revocation checking */ 2440 goto out; 2441 } 2442 2443 /* 2444 * When CRL or OCSP revocation method is set in the policy, 2445 * we will try to find the issuer of the subscriber certificate 2446 * using the issuer name of the subscriber certificate. The 2447 * issuer certificate will be used to do the CRL checking 2448 * and OCSP checking. 2449 */ 2450 if (!(policy->revocation & KMF_REVOCATION_METHOD_CRL) && 2451 !(policy->revocation & KMF_REVOCATION_METHOD_OCSP)) { 2452 goto out; 2453 } 2454 2455 ret = find_issuer_cert(handle, kstype, user_issuer, &issuer_cert, 2456 slotlabel, dirpath); 2457 if (ret != KMF_OK) { 2458 *result |= KMF_CERT_VALIDATE_ERR_ISSUER; 2459 goto out; 2460 } 2461 2462 if (policy->revocation & KMF_REVOCATION_METHOD_CRL) { 2463 ret = cert_crl_check(handle, kstype, pcert, &issuer_cert); 2464 if (ret != KMF_OK) { 2465 *result |= KMF_CERT_VALIDATE_ERR_CRL; 2466 goto out; 2467 } 2468 } 2469 2470 if (policy->revocation & KMF_REVOCATION_METHOD_OCSP) { 2471 ret = cert_ocsp_check(handle, kstype, pcert, &issuer_cert, 2472 ocsp_response, slotlabel, dirpath); 2473 if (ret != KMF_OK) { 2474 *result |= KMF_CERT_VALIDATE_ERR_OCSP; 2475 goto out; 2476 } 2477 } 2478 2479 out: 2480 if (user_issuer) { 2481 kmf_free_dn(&user_issuerDN); 2482 free(user_issuer); 2483 } 2484 2485 if (user_subject) 2486 free(user_subject); 2487 2488 if (ta_cert.Data) 2489 free(ta_cert.Data); 2490 2491 if (issuer_cert.Data) 2492 free(issuer_cert.Data); 2493 2494 return (ret); 2495 2496 } 2497 2498 KMF_RETURN 2499 kmf_create_cert_file(const KMF_DATA *certdata, KMF_ENCODE_FORMAT format, 2500 char *certfile) 2501 { 2502 KMF_RETURN rv = KMF_OK; 2503 int fd = -1; 2504 KMF_DATA pemdata = {NULL, 0}; 2505 2506 if (certdata == NULL || certfile == NULL) 2507 return (KMF_ERR_BAD_PARAMETER); 2508 2509 if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1) 2510 return (KMF_ERR_BAD_PARAMETER); 2511 2512 if (format == KMF_FORMAT_PEM) { 2513 int len; 2514 rv = kmf_der_to_pem(KMF_CERT, 2515 certdata->Data, certdata->Length, 2516 &pemdata.Data, &len); 2517 if (rv != KMF_OK) 2518 goto cleanup; 2519 pemdata.Length = (size_t)len; 2520 } 2521 2522 if ((fd = open(certfile, O_CREAT | O_RDWR | O_TRUNC, 0644)) == -1) { 2523 rv = KMF_ERR_OPEN_FILE; 2524 goto cleanup; 2525 } 2526 2527 if (format == KMF_FORMAT_PEM) { 2528 if (write(fd, pemdata.Data, pemdata.Length) != 2529 pemdata.Length) { 2530 rv = KMF_ERR_WRITE_FILE; 2531 } 2532 } else { 2533 if (write(fd, certdata->Data, certdata->Length) != 2534 certdata->Length) { 2535 rv = KMF_ERR_WRITE_FILE; 2536 } 2537 } 2538 2539 cleanup: 2540 if (fd != -1) 2541 (void) close(fd); 2542 2543 kmf_free_data(&pemdata); 2544 2545 return (rv); 2546 } 2547 2548 KMF_RETURN 2549 kmf_is_cert_file(KMF_HANDLE_T handle, char *filename, 2550 KMF_ENCODE_FORMAT *pformat) 2551 { 2552 KMF_PLUGIN *plugin; 2553 KMF_RETURN (*IsCertFileFn)(void *, char *, KMF_ENCODE_FORMAT *); 2554 2555 KMF_RETURN ret; 2556 2557 CLEAR_ERROR(handle, ret); 2558 if (ret != KMF_OK) 2559 return (ret); 2560 2561 if (filename == NULL || pformat == NULL) { 2562 return (KMF_ERR_BAD_PARAMETER); 2563 } 2564 2565 /* 2566 * This framework function is actually implemented in the openssl 2567 * plugin library, so we find the function address and call it. 2568 */ 2569 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 2570 if (plugin == NULL || plugin->dldesc == NULL) { 2571 return (KMF_ERR_PLUGIN_NOTFOUND); 2572 } 2573 2574 IsCertFileFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 2575 "OpenSSL_IsCertFile"); 2576 if (IsCertFileFn == NULL) { 2577 return (KMF_ERR_FUNCTION_NOT_FOUND); 2578 } 2579 2580 return (IsCertFileFn(handle, filename, pformat)); 2581 } 2582 2583 /* 2584 * This function checks the validity period of a der-encoded certificate. 2585 */ 2586 KMF_RETURN 2587 kmf_check_cert_date(KMF_HANDLE_T handle, const KMF_DATA *cert) 2588 { 2589 KMF_RETURN rv; 2590 struct tm *gmt; 2591 time_t t_now; 2592 time_t t_notbefore; 2593 time_t t_notafter; 2594 KMF_POLICY_RECORD *policy; 2595 uint32_t adj; 2596 2597 CLEAR_ERROR(handle, rv); 2598 if (rv != KMF_OK) 2599 return (rv); 2600 2601 if (cert == NULL || cert->Data == NULL || cert->Length == 0) 2602 return (KMF_ERR_BAD_PARAMETER); 2603 2604 policy = handle->policy; 2605 rv = kmf_get_cert_validity(cert, &t_notbefore, &t_notafter); 2606 if (rv != KMF_OK) 2607 return (rv); 2608 2609 /* 2610 * Get the current time. The time returned from time() is local which 2611 * cannot be used directly. It must be converted to UTC/GMT first. 2612 */ 2613 t_now = time(NULL); 2614 gmt = gmtime(&t_now); 2615 t_now = mktime(gmt); 2616 2617 /* 2618 * Adjust the validity time 2619 */ 2620 if (policy->validity_adjusttime != NULL) { 2621 if (str2lifetime(policy->validity_adjusttime, &adj) < 0) 2622 return (KMF_ERR_VALIDITY_PERIOD); 2623 } else { 2624 adj = 0; 2625 } 2626 2627 t_notafter += adj; 2628 t_notbefore -= adj; 2629 2630 if (t_now <= t_notafter && t_now >= t_notbefore) { 2631 rv = KMF_OK; 2632 } else { 2633 rv = KMF_ERR_VALIDITY_PERIOD; 2634 } 2635 2636 return (rv); 2637 } 2638 2639 KMF_RETURN 2640 kmf_export_pk12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 2641 { 2642 KMF_PLUGIN *plugin; 2643 KMF_RETURN ret = KMF_OK; 2644 KMF_KEYSTORE_TYPE kstype; 2645 2646 KMF_ATTRIBUTE_TESTER required_attrs[] = { 2647 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 2648 {KMF_OUTPUT_FILENAME_ATTR, TRUE, 1, 0}, 2649 }; 2650 2651 int num_req_attrs = sizeof (required_attrs) / 2652 sizeof (KMF_ATTRIBUTE_TESTER); 2653 2654 if (handle == NULL) 2655 return (KMF_ERR_BAD_PARAMETER); 2656 2657 CLEAR_ERROR(handle, ret); 2658 2659 ret = test_attributes(num_req_attrs, required_attrs, 0, NULL, 2660 numattr, attrlist); 2661 if (ret != KMF_OK) 2662 return (ret); 2663 2664 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, 2665 &kstype, NULL); 2666 if (ret != KMF_OK) 2667 return (ret); 2668 2669 plugin = FindPlugin(handle, kstype); 2670 if (plugin == NULL || plugin->funclist->ExportPK12 == NULL) 2671 return (KMF_ERR_PLUGIN_NOTFOUND); 2672 2673 return (plugin->funclist->ExportPK12(handle, numattr, attrlist)); 2674 } 2675 2676 2677 KMF_RETURN 2678 kmf_build_pk12(KMF_HANDLE_T handle, int numcerts, 2679 KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist, 2680 KMF_CREDENTIAL *p12cred, char *filename) 2681 { 2682 KMF_RETURN rv; 2683 KMF_PLUGIN *plugin; 2684 KMF_RETURN (*buildpk12)(KMF_HANDLE *, int, KMF_X509_DER_CERT *, 2685 int, KMF_KEY_HANDLE *, KMF_CREDENTIAL *, char *); 2686 2687 CLEAR_ERROR(handle, rv); 2688 if (rv != KMF_OK) 2689 return (rv); 2690 2691 if (filename == NULL || p12cred == NULL || 2692 (certlist == NULL && keylist == NULL)) 2693 return (KMF_ERR_BAD_PARAMETER); 2694 2695 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 2696 if (plugin == NULL || plugin->dldesc == NULL) { 2697 return (KMF_ERR_PLUGIN_NOTFOUND); 2698 } 2699 2700 buildpk12 = (KMF_RETURN(*)())dlsym(plugin->dldesc, 2701 "openssl_build_pk12"); 2702 if (buildpk12 == NULL) { 2703 return (KMF_ERR_FUNCTION_NOT_FOUND); 2704 } 2705 2706 rv = buildpk12(handle, numcerts, certlist, numkeys, keylist, p12cred, 2707 filename); 2708 2709 return (rv); 2710 } 2711 2712 2713 KMF_RETURN 2714 kmf_import_objects(KMF_HANDLE_T handle, char *filename, 2715 KMF_CREDENTIAL *cred, 2716 KMF_X509_DER_CERT **certs, int *ncerts, 2717 KMF_RAW_KEY_DATA **rawkeys, int *nkeys) 2718 { 2719 KMF_RETURN rv; 2720 KMF_PLUGIN *plugin; 2721 KMF_RETURN (*import_objects)(KMF_HANDLE *, char *, KMF_CREDENTIAL *, 2722 KMF_X509_DER_CERT **, int *, KMF_RAW_KEY_DATA **, int *); 2723 2724 CLEAR_ERROR(handle, rv); 2725 if (rv != KMF_OK) 2726 return (rv); 2727 2728 if (filename == NULL || cred == NULL || certs == NULL || 2729 ncerts == NULL ||rawkeys == NULL || nkeys == NULL) 2730 return (KMF_ERR_BAD_PARAMETER); 2731 2732 /* 2733 * Use the Keypair reader from the OpenSSL plugin. 2734 */ 2735 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 2736 if (plugin == NULL || plugin->dldesc == NULL) { 2737 return (KMF_ERR_PLUGIN_NOTFOUND); 2738 } 2739 2740 import_objects = (KMF_RETURN(*)())dlsym(plugin->dldesc, 2741 "openssl_import_objects"); 2742 if (import_objects == NULL) { 2743 return (KMF_ERR_FUNCTION_NOT_FOUND); 2744 } 2745 2746 /* Use OpenSSL interfaces to get raw key and cert data */ 2747 rv = import_objects(handle, filename, cred, certs, ncerts, 2748 rawkeys, nkeys); 2749 2750 return (rv); 2751 } 2752 2753 KMF_BOOL 2754 IsEqualOid(KMF_OID *Oid1, KMF_OID *Oid2) 2755 { 2756 return ((Oid1->Length == Oid2->Length) && 2757 !memcmp(Oid1->Data, Oid2->Data, Oid1->Length)); 2758 } 2759 2760 KMF_RETURN 2761 copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, 2762 KMF_X509_ALGORITHM_IDENTIFIER *srcid) 2763 { 2764 KMF_RETURN ret = KMF_OK; 2765 if (!destid || !srcid) 2766 return (KMF_ERR_BAD_PARAMETER); 2767 2768 destid->algorithm.Length = srcid->algorithm.Length; 2769 destid->algorithm.Data = malloc(destid->algorithm.Length); 2770 if (destid->algorithm.Data == NULL) 2771 return (KMF_ERR_MEMORY); 2772 2773 (void) memcpy(destid->algorithm.Data, srcid->algorithm.Data, 2774 destid->algorithm.Length); 2775 2776 destid->parameters.Length = srcid->parameters.Length; 2777 if (destid->parameters.Length > 0) { 2778 destid->parameters.Data = malloc(destid->parameters.Length); 2779 if (destid->parameters.Data == NULL) 2780 return (KMF_ERR_MEMORY); 2781 2782 (void) memcpy(destid->parameters.Data, srcid->parameters.Data, 2783 destid->parameters.Length); 2784 } else { 2785 destid->parameters.Data = NULL; 2786 } 2787 return (ret); 2788 } 2789 2790 static KMF_RETURN 2791 sign_cert(KMF_HANDLE_T handle, 2792 const KMF_DATA *SubjectCert, 2793 KMF_KEY_HANDLE *Signkey, 2794 KMF_DATA *SignedCert) 2795 { 2796 KMF_X509_CERTIFICATE *subj_cert = NULL; 2797 KMF_DATA data_to_sign = {0, NULL}; 2798 KMF_DATA signed_data = {0, NULL}; 2799 KMF_RETURN ret = KMF_OK; 2800 KMF_ALGORITHM_INDEX algid; 2801 int i = 0; 2802 KMF_ATTRIBUTE attrlist[8]; 2803 KMF_OID *oid; 2804 2805 if (!SignedCert) 2806 return (KMF_ERR_BAD_PARAMETER); 2807 2808 SignedCert->Length = 0; 2809 SignedCert->Data = NULL; 2810 2811 if (!SubjectCert) 2812 return (KMF_ERR_BAD_PARAMETER); 2813 2814 if (!SubjectCert->Data || !SubjectCert->Length) 2815 return (KMF_ERR_BAD_PARAMETER); 2816 2817 /* 2818 * Shortcut - just extract the already encoded TBS cert data from 2819 * the original data buffer. Since we haven't changed anything, 2820 * there is no need to re-encode it. 2821 */ 2822 ret = ExtractX509CertParts((KMF_DATA *)SubjectCert, 2823 &data_to_sign, NULL); 2824 if (ret != KMF_OK) { 2825 goto cleanup; 2826 } 2827 2828 /* Estimate the signed data length generously */ 2829 signed_data.Length = data_to_sign.Length*2; 2830 signed_data.Data = calloc(1, signed_data.Length); 2831 if (!signed_data.Data) { 2832 ret = KMF_ERR_MEMORY; 2833 goto cleanup; 2834 } 2835 2836 /* 2837 * If we got here OK, decode into a structure and then re-encode 2838 * the complete certificate. 2839 */ 2840 ret = DerDecodeSignedCertificate(SubjectCert, &subj_cert); 2841 if (ret != KMF_OK) { 2842 goto cleanup; 2843 } 2844 2845 /* We are re-signing this cert, so clear out old signature data */ 2846 if (subj_cert->signature.algorithmIdentifier.algorithm.Length == 0) { 2847 kmf_free_algoid(&subj_cert->signature.algorithmIdentifier); 2848 ret = copy_algoid(&subj_cert->signature.algorithmIdentifier, 2849 &subj_cert->certificate.signature); 2850 } 2851 2852 if (ret) 2853 goto cleanup; 2854 2855 kmf_set_attr_at_index(attrlist, i, KMF_KEYSTORE_TYPE_ATTR, 2856 &Signkey->kstype, sizeof (KMF_KEYSTORE_TYPE)); 2857 i++; 2858 kmf_set_attr_at_index(attrlist, i, KMF_KEY_HANDLE_ATTR, 2859 Signkey, sizeof (KMF_KEY_HANDLE)); 2860 i++; 2861 kmf_set_attr_at_index(attrlist, i, KMF_DATA_ATTR, 2862 &data_to_sign, sizeof (KMF_DATA)); 2863 i++; 2864 kmf_set_attr_at_index(attrlist, i, KMF_OUT_DATA_ATTR, 2865 &signed_data, sizeof (KMF_DATA)); 2866 i++; 2867 oid = CERT_ALG_OID(subj_cert); 2868 kmf_set_attr_at_index(attrlist, i, KMF_OID_ATTR, 2869 oid, sizeof (KMF_OID)); 2870 i++; 2871 2872 /* Sign the data */ 2873 ret = kmf_sign_data(handle, i, attrlist); 2874 2875 if (ret != KMF_OK) 2876 goto cleanup; 2877 2878 algid = x509_algoid_to_algid(CERT_SIG_OID(subj_cert)); 2879 2880 /* 2881 * For DSA, KMF_SignDataWithKey() returns a 40-bytes decoded 2882 * signature. So we must encode the signature correctly. 2883 */ 2884 if (algid == KMF_ALGID_SHA1WithDSA) { 2885 2886 KMF_DATA signature; 2887 2888 ret = DerEncodeDSASignature(&signed_data, &signature); 2889 kmf_free_data(&signed_data); 2890 2891 if (ret != KMF_OK) 2892 goto cleanup; 2893 2894 subj_cert->signature.encrypted = signature; 2895 } else { 2896 subj_cert->signature.encrypted = signed_data; 2897 } 2898 2899 /* Now, re-encode the cert with the new signature */ 2900 ret = DerEncodeSignedCertificate(subj_cert, SignedCert); 2901 2902 cleanup: 2903 /* Cleanup & return */ 2904 if (ret != KMF_OK) 2905 kmf_free_data(SignedCert); 2906 2907 kmf_free_data(&data_to_sign); 2908 2909 if (subj_cert != NULL) { 2910 kmf_free_signed_cert(subj_cert); 2911 free(subj_cert); 2912 } 2913 2914 return (ret); 2915 } 2916 2917 static KMF_RETURN 2918 verify_cert_with_key(KMF_HANDLE_T handle, 2919 KMF_DATA *derkey, 2920 const KMF_DATA *CertToBeVerified) 2921 { 2922 KMF_RETURN ret = KMF_OK; 2923 KMF_X509_CERTIFICATE *signed_cert = NULL; 2924 KMF_X509_SPKI spki; 2925 KMF_DATA data_to_verify = {0, NULL}; 2926 KMF_DATA signed_data = {0, NULL}; 2927 KMF_DATA signature = { 0, NULL }; 2928 KMF_ALGORITHM_INDEX algid; 2929 2930 /* check the caller and do other setup for this SPI call */ 2931 if (handle == NULL || CertToBeVerified == NULL || 2932 derkey == NULL || derkey->Data == NULL) 2933 return (KMF_ERR_BAD_PARAMETER); 2934 2935 (void) memset(&spki, 0, sizeof (KMF_X509_SPKI)); 2936 2937 ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerified, 2938 &data_to_verify, &signed_data); 2939 2940 if (ret != KMF_OK) 2941 goto cleanup; 2942 2943 ret = DerDecodeSPKI(derkey, &spki); 2944 if (ret != KMF_OK) 2945 goto cleanup; 2946 2947 /* Decode the signer cert so we can get the Algorithm data */ 2948 ret = DerDecodeSignedCertificate(CertToBeVerified, &signed_cert); 2949 if (ret != KMF_OK) 2950 return (ret); 2951 2952 algid = x509_algoid_to_algid(CERT_SIG_OID(signed_cert)); 2953 2954 if (algid == KMF_ALGID_NONE) 2955 return (KMF_ERR_BAD_ALGORITHM); 2956 2957 if (algid == KMF_ALGID_SHA1WithDSA) { 2958 ret = DerDecodeDSASignature(&signed_data, &signature); 2959 if (ret != KMF_OK) 2960 goto cleanup; 2961 } else { 2962 signature.Data = signed_data.Data; 2963 signature.Length = signed_data.Length; 2964 } 2965 2966 ret = PKCS_VerifyData(handle, algid, &spki, 2967 &data_to_verify, &signature); 2968 2969 cleanup: 2970 if (data_to_verify.Data != NULL) 2971 free(data_to_verify.Data); 2972 2973 if (signed_data.Data != NULL) 2974 free(signed_data.Data); 2975 2976 if (signed_cert) { 2977 kmf_free_signed_cert(signed_cert); 2978 free(signed_cert); 2979 } 2980 if (algid == KMF_ALGID_SHA1WithDSA) { 2981 free(signature.Data); 2982 } 2983 2984 kmf_free_algoid(&spki.algorithm); 2985 kmf_free_data(&spki.subjectPublicKey); 2986 2987 return (ret); 2988 } 2989 2990 /* 2991 * Use a signer cert to verify another certificate's signature. 2992 * This code forces the use of the OPENSSL mechanism 2993 * for the verify operation to avoid a circular dependency 2994 * with libelfsign when it attempts to verify the PKCS#11 libraries. 2995 */ 2996 static KMF_RETURN 2997 verify_cert_with_cert(KMF_HANDLE_T handle, 2998 const KMF_DATA *CertToBeVerifiedData, 2999 const KMF_DATA *SignerCertData) 3000 { 3001 KMF_RETURN ret = KMF_OK; 3002 KMF_X509_CERTIFICATE *SignerCert = NULL; 3003 KMF_X509_CERTIFICATE *ToBeVerifiedCert = NULL; 3004 KMF_DATA data_to_verify = {0, NULL}; 3005 KMF_DATA signed_data = {0, NULL}; 3006 KMF_DATA signature; 3007 KMF_ALGORITHM_INDEX algid; 3008 3009 if (!CertToBeVerifiedData || 3010 !CertToBeVerifiedData->Data || 3011 !CertToBeVerifiedData->Length) 3012 return (KMF_ERR_BAD_PARAMETER); 3013 3014 if (!SignerCertData || 3015 !SignerCertData->Data || 3016 !SignerCertData->Length) 3017 return (KMF_ERR_BAD_PARAMETER); 3018 3019 /* Make sure the signer has proper key usage bits */ 3020 ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_CERT); 3021 if (ret != KMF_OK) 3022 return (ret); 3023 3024 /* Decode the cert into parts for verification */ 3025 ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerifiedData, 3026 &data_to_verify, &signed_data); 3027 if (ret != KMF_OK) 3028 goto cleanup; 3029 3030 /* Decode the to-be-verified cert so we know what algorithm to use */ 3031 ret = DerDecodeSignedCertificate(CertToBeVerifiedData, 3032 &ToBeVerifiedCert); 3033 3034 if (ret != KMF_OK) 3035 goto cleanup; 3036 3037 algid = x509_algoid_to_algid(CERT_SIG_OID(ToBeVerifiedCert)); 3038 3039 if (algid == KMF_ALGID_SHA1WithDSA) { 3040 ret = DerDecodeDSASignature(&signed_data, &signature); 3041 if (ret != KMF_OK) 3042 goto cleanup; 3043 } else { 3044 signature.Data = signed_data.Data; 3045 signature.Length = signed_data.Length; 3046 } 3047 3048 /* 3049 * To avoid recursion with kcfd consumer and libpkcs11, 3050 * do the certificate verification using the OpenSSL 3051 * plugin algorithms instead of the crypto framework. 3052 */ 3053 ret = plugin_verify_data_with_cert(handle, KMF_KEYSTORE_OPENSSL, 3054 algid, &data_to_verify, &signature, SignerCertData); 3055 3056 cleanup: 3057 kmf_free_data(&data_to_verify); 3058 kmf_free_data(&signed_data); 3059 3060 if (SignerCert) { 3061 kmf_free_signed_cert(SignerCert); 3062 free(SignerCert); 3063 } 3064 3065 if (ToBeVerifiedCert) { 3066 kmf_free_signed_cert(ToBeVerifiedCert); 3067 free(ToBeVerifiedCert); 3068 } 3069 3070 if (algid == KMF_ALGID_SHA1WithDSA) { 3071 free(signature.Data); 3072 } 3073 3074 return (ret); 3075 } 3076 3077 /* 3078 * Phase 1 APIs still needed to maintain compat with elfsign. 3079 */ 3080 KMF_RETURN 3081 KMF_VerifyDataWithCert(KMF_HANDLE_T handle, 3082 KMF_KEYSTORE_TYPE kstype, 3083 KMF_ALGORITHM_INDEX algid, 3084 KMF_DATA *indata, 3085 KMF_DATA *insig, 3086 const KMF_DATA *SignerCert) 3087 { 3088 KMF_ATTRIBUTE attrlist[8]; 3089 int numattr = 0; 3090 3091 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 3092 &kstype, sizeof (kstype)); 3093 numattr++; 3094 3095 kmf_set_attr_at_index(attrlist, numattr, KMF_DATA_ATTR, 3096 indata, sizeof (KMF_DATA)); 3097 numattr++; 3098 3099 kmf_set_attr_at_index(attrlist, numattr, KMF_IN_SIGN_ATTR, 3100 insig, sizeof (KMF_DATA)); 3101 numattr++; 3102 3103 kmf_set_attr_at_index(attrlist, numattr, KMF_SIGNER_CERT_DATA_ATTR, 3104 (KMF_DATA *)SignerCert, sizeof (KMF_DATA)); 3105 numattr++; 3106 3107 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR, 3108 &algid, sizeof (algid)); 3109 numattr++; 3110 3111 return (kmf_verify_data(handle, numattr, attrlist)); 3112 } 3113 3114 KMF_RETURN 3115 KMF_VerifyCertWithCert(KMF_HANDLE_T handle, 3116 const KMF_DATA *CertToBeVerified, 3117 const KMF_DATA *SignerCert) 3118 { 3119 KMF_RETURN ret; 3120 if (CertToBeVerified == NULL || SignerCert == NULL) 3121 return (KMF_ERR_BAD_PARAMETER); 3122 3123 /* check the keyUsage of signer's certificate */ 3124 ret = check_key_usage(handle, SignerCert, KMF_KU_SIGN_CERT); 3125 if (ret != KMF_OK) 3126 return (ret); 3127 3128 return (verify_cert_with_cert(handle, CertToBeVerified, 3129 SignerCert)); 3130 } 3131 3132 KMF_RETURN 3133 KMF_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *target, 3134 KMF_X509_DER_CERT *kmf_cert, 3135 uint32_t *num_certs) 3136 { 3137 KMF_ATTRIBUTE attrlist[32]; 3138 int i = 0; 3139 3140 if (target == NULL || num_certs == NULL) 3141 return (KMF_ERR_BAD_PARAMETER); /* ILLEGAL ARGS ERROR */ 3142 3143 if ((target->find_cert_validity < KMF_ALL_CERTS) || 3144 (target->find_cert_validity > KMF_EXPIRED_CERTS)) 3145 return (KMF_ERR_BAD_PARAMETER); 3146 3147 kmf_set_attr_at_index(attrlist, i, 3148 KMF_KEYSTORE_TYPE_ATTR, &target->kstype, sizeof (target->kstype)); 3149 i++; 3150 3151 if (kmf_cert != NULL) { 3152 kmf_set_attr_at_index(attrlist, i, 3153 KMF_X509_DER_CERT_ATTR, kmf_cert, 3154 sizeof (KMF_X509_DER_CERT)); 3155 i++; 3156 } 3157 3158 kmf_set_attr_at_index(attrlist, i, 3159 KMF_COUNT_ATTR, num_certs, sizeof (uint32_t)); 3160 i++; 3161 3162 /* Set the optional searching attributes for all 3 plugins. */ 3163 if (target->issuer != NULL) { 3164 kmf_set_attr_at_index(attrlist, i, KMF_ISSUER_NAME_ATTR, 3165 target->issuer, strlen(target->issuer)); 3166 i++; 3167 } 3168 if (target->subject != NULL) { 3169 kmf_set_attr_at_index(attrlist, i, KMF_SUBJECT_NAME_ATTR, 3170 target->subject, strlen(target->subject)); 3171 i++; 3172 } 3173 if (target->serial != NULL) { 3174 kmf_set_attr_at_index(attrlist, i, KMF_BIGINT_ATTR, 3175 target->serial, sizeof (KMF_BIGINT)); 3176 i++; 3177 } 3178 3179 kmf_set_attr_at_index(attrlist, i, KMF_CERT_VALIDITY_ATTR, 3180 &target->find_cert_validity, sizeof (KMF_CERT_VALIDITY)); 3181 i++; 3182 3183 if (target->kstype == KMF_KEYSTORE_NSS) { 3184 if (target->certLabel != NULL) { 3185 kmf_set_attr_at_index(attrlist, i, 3186 KMF_CERT_LABEL_ATTR, 3187 target->certLabel, strlen(target->certLabel)); 3188 i++; 3189 } 3190 3191 if (target->nssparms.slotlabel != NULL) { 3192 kmf_set_attr_at_index(attrlist, i, 3193 KMF_TOKEN_LABEL_ATTR, 3194 target->nssparms.slotlabel, 3195 strlen(target->nssparms.slotlabel)); 3196 i++; 3197 } 3198 3199 } else if (target->kstype == KMF_KEYSTORE_OPENSSL) { 3200 if (target->sslparms.certfile != NULL) { 3201 kmf_set_attr_at_index(attrlist, i, 3202 KMF_CERT_FILENAME_ATTR, 3203 target->sslparms.certfile, 3204 strlen(target->sslparms.certfile)); 3205 i++; 3206 } 3207 3208 if (target->sslparms.dirpath != NULL) { 3209 kmf_set_attr_at_index(attrlist, i, 3210 KMF_DIRPATH_ATTR, 3211 target->sslparms.dirpath, 3212 strlen(target->sslparms.dirpath)); 3213 i++; 3214 } 3215 3216 } else if (target->kstype == KMF_KEYSTORE_PK11TOKEN) { 3217 if (target->certLabel != NULL) { 3218 kmf_set_attr_at_index(attrlist, i, 3219 KMF_CERT_LABEL_ATTR, 3220 target->certLabel, strlen(target->certLabel)); 3221 i++; 3222 } 3223 3224 kmf_set_attr_at_index(attrlist, i, KMF_PRIVATE_BOOL_ATTR, 3225 &target->pkcs11parms.private, 3226 sizeof (target->pkcs11parms.private)); 3227 i++; 3228 } 3229 3230 return (kmf_find_cert(handle, i, attrlist)); 3231 } 3232