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 2007 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 cert_crl_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, 1354 KMF_DATA *user_cert, KMF_DATA *issuer_cert) 1355 { 1356 KMF_POLICY_RECORD *policy; 1357 KMF_RETURN ret = KMF_OK; 1358 KMF_ATTRIBUTE attrlist[16]; 1359 int numattr = 0; 1360 boolean_t crlchk; 1361 char user_certfile[MAXPATHLEN]; 1362 char crlfile_tmp[MAXPATHLEN]; 1363 char *basefilename = NULL; 1364 char *dir = NULL; 1365 char *crlfilename = NULL; 1366 char *proxy = NULL; 1367 char *uri = NULL; 1368 KMF_ENCODE_FORMAT format; 1369 1370 if (handle == NULL || kstype == NULL || user_cert == NULL || 1371 issuer_cert == NULL) 1372 return (KMF_ERR_BAD_PARAMETER); 1373 1374 if (!VALID_KEYSTORE_TYPE(*kstype)) 1375 return (KMF_ERR_BAD_PARAMETER); 1376 1377 policy = handle->policy; 1378 1379 /* 1380 * If the get-crl-uri policy is TRUE, then download the CRL 1381 * file first. The newly downloaded file will be stored in the 1382 * NSS internal database for NSS keystore, and stored in a file for 1383 * the File-based CRL plugins (OpenSSL and PKCS11). 1384 * 1385 * For file-based plugins, if the get-crl-uri policy is FALSE, 1386 * then the caller should provide a CRL file in the policy. 1387 * Also, after this step is done, the "crlfilename" variable should 1388 * contain the proper CRL file to be used for the rest of CRL 1389 * validation process. 1390 */ 1391 basefilename = policy->validation_info.crl_info.basefilename; 1392 dir = policy->validation_info.crl_info.directory; 1393 if (policy->validation_info.crl_info.get_crl_uri) { 1394 /* 1395 * Create a temporary file to hold the new CRL file initially. 1396 */ 1397 (void) strlcpy(crlfile_tmp, CRLFILE_TEMPNAME, 1398 sizeof (crlfile_tmp)); 1399 if (mkstemp(crlfile_tmp) == -1) { 1400 ret = KMF_ERR_INTERNAL; 1401 goto cleanup; 1402 } 1403 1404 /* 1405 * Get the URI entry from the certificate's CRL distribution 1406 * points extension and download the CRL file. 1407 */ 1408 proxy = policy->validation_info.crl_info.proxy; 1409 ret = cert_get_crl(handle, user_cert, proxy, crlfile_tmp, 1410 &uri, &format); 1411 if (ret != KMF_OK) { 1412 (void) unlink(crlfile_tmp); 1413 goto cleanup; 1414 } 1415 1416 /* Cache the CRL file. */ 1417 if (*kstype == KMF_KEYSTORE_NSS) { 1418 /* 1419 * For NSS keystore, import this CRL file into th 1420 * internal database. 1421 */ 1422 numattr = 0; 1423 kmf_set_attr_at_index(attrlist, numattr, 1424 KMF_KEYSTORE_TYPE_ATTR, kstype, sizeof (kstype)); 1425 numattr++; 1426 1427 kmf_set_attr_at_index(attrlist, numattr, 1428 KMF_CRL_FILENAME_ATTR, crlfile_tmp, 1429 strlen(crlfile_tmp)); 1430 numattr++; 1431 1432 crlchk = B_FALSE; 1433 kmf_set_attr_at_index(attrlist, numattr, 1434 KMF_CRL_CHECK_ATTR, &crlchk, sizeof (boolean_t)); 1435 numattr++; 1436 1437 ret = kmf_import_crl(handle, numattr, attrlist); 1438 (void) unlink(crlfile_tmp); 1439 if (ret != KMF_OK) 1440 goto cleanup; 1441 } else { 1442 /* 1443 * For File-based CRL plugin's, find the cache 1444 * location from the CRL policy's attributes and 1445 * cache it. 1446 */ 1447 if (basefilename == NULL) 1448 basefilename = basename(uri); 1449 1450 crlfilename = get_fullpath(dir == NULL ? "./" : dir, 1451 basefilename); 1452 if (crlfilename == NULL) { 1453 (void) unlink(crlfile_tmp); 1454 ret = KMF_ERR_BAD_CRLFILE; 1455 goto cleanup; 1456 } 1457 1458 if (rename(crlfile_tmp, crlfilename) == -1) { 1459 (void) unlink(crlfile_tmp); 1460 ret = KMF_ERR_WRITE_FILE; 1461 goto cleanup; 1462 } 1463 } 1464 } else { 1465 /* 1466 * If the get_crl_uri policy is FALSE, for File-based CRL 1467 * plugins, get the input CRL file from the policy. 1468 */ 1469 if (*kstype != KMF_KEYSTORE_NSS) { 1470 if (basefilename == NULL) { 1471 ret = KMF_ERR_BAD_PARAMETER; 1472 goto cleanup; 1473 } 1474 1475 crlfilename = get_fullpath(dir == NULL ? "./" : dir, 1476 basefilename); 1477 if (crlfilename == NULL) { 1478 ret = KMF_ERR_BAD_CRLFILE; 1479 goto cleanup; 1480 } 1481 } 1482 } 1483 1484 /* 1485 * Check the CRL signature if needed. 1486 */ 1487 if (!policy->validation_info.crl_info.ignore_crl_sign) { 1488 /* 1489 * NSS CRL is not file based, and its signature 1490 * has been verified during CRL import. 1491 */ 1492 if (*kstype != KMF_KEYSTORE_NSS) { 1493 ret = kmf_verify_crl_file(handle, crlfilename, 1494 issuer_cert); 1495 if (ret != KMF_OK) { 1496 goto cleanup; 1497 } 1498 } 1499 } 1500 1501 /* 1502 * Check the CRL validity if needed. 1503 */ 1504 if (!policy->validation_info.crl_info.ignore_crl_date) { 1505 /* 1506 * This is for file-based CRL, but not for NSS CRL. 1507 */ 1508 if (*kstype != KMF_KEYSTORE_NSS) { 1509 ret = kmf_check_crl_date(handle, crlfilename); 1510 if (ret != KMF_OK) { 1511 goto cleanup; 1512 } 1513 } 1514 } 1515 1516 /* 1517 * Check the CRL revocation for the certificate. 1518 */ 1519 numattr = 0; 1520 1521 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 1522 kstype, sizeof (kstype)); 1523 numattr++; 1524 1525 switch (*kstype) { 1526 case KMF_KEYSTORE_NSS: 1527 kmf_set_attr_at_index(attrlist, numattr, 1528 KMF_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA)); 1529 numattr++; 1530 break; 1531 case KMF_KEYSTORE_PK11TOKEN: 1532 case KMF_KEYSTORE_OPENSSL: 1533 /* 1534 * Create temporary file to hold the user certificate. 1535 */ 1536 (void) strlcpy(user_certfile, CERTFILE_TEMPNAME, 1537 sizeof (user_certfile)); 1538 if (mkstemp(user_certfile) == -1) { 1539 ret = KMF_ERR_INTERNAL; 1540 goto cleanup; 1541 } 1542 1543 ret = kmf_create_cert_file(user_cert, KMF_FORMAT_ASN1, 1544 user_certfile); 1545 if (ret != KMF_OK) { 1546 goto cleanup; 1547 } 1548 1549 kmf_set_attr_at_index(attrlist, numattr, 1550 KMF_CERT_FILENAME_ATTR, 1551 user_certfile, strlen(user_certfile)); 1552 numattr++; 1553 1554 kmf_set_attr_at_index(attrlist, numattr, 1555 KMF_CRL_FILENAME_ATTR, 1556 crlfilename, strlen(crlfilename)); 1557 numattr++; 1558 break; 1559 default: 1560 ret = KMF_ERR_PLUGIN_NOTFOUND; 1561 goto cleanup; 1562 } 1563 1564 ret = kmf_find_cert_in_crl(handle, numattr, attrlist); 1565 if (ret == KMF_ERR_NOT_REVOKED) { 1566 ret = KMF_OK; 1567 } 1568 1569 cleanup: 1570 (void) unlink(user_certfile); 1571 1572 if (crlfilename != NULL) 1573 free(crlfilename); 1574 1575 if (uri != NULL) 1576 free(uri); 1577 1578 return (ret); 1579 } 1580 1581 static KMF_RETURN 1582 cert_ocsp_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, 1583 KMF_DATA *user_cert, KMF_DATA *issuer_cert, KMF_DATA *response, 1584 char *slotlabel, char *dirpath) 1585 { 1586 KMF_RETURN ret = KMF_OK; 1587 KMF_POLICY_RECORD *policy; 1588 KMF_DATA *new_response = NULL; 1589 boolean_t ignore_response_sign = B_FALSE; 1590 uint32_t ltime = 0; 1591 KMF_DATA *signer_cert = NULL; 1592 KMF_BIGINT sernum = { NULL, 0 }; 1593 int response_status; 1594 int reason; 1595 int cert_status; 1596 KMF_ATTRIBUTE attrlist[32]; 1597 int numattr; 1598 1599 if (handle == NULL || kstype == NULL || user_cert == NULL || 1600 issuer_cert == NULL) 1601 return (KMF_ERR_BAD_PARAMETER); 1602 1603 policy = handle->policy; 1604 1605 /* 1606 * Get the response lifetime from policy. 1607 */ 1608 if (policy->VAL_OCSP_BASIC.response_lifetime != NULL && 1609 (str2lifetime(policy->VAL_OCSP_BASIC.response_lifetime, <ime) 1610 < 0)) 1611 return (KMF_ERR_OCSP_RESPONSE_LIFETIME); 1612 1613 /* 1614 * Get the ignore_response_sign policy. 1615 * 1616 * If ignore_response_sign is FALSE, we need to verify the response. 1617 * Find the OCSP Responder certificate if it is specified in the OCSP 1618 * policy. 1619 */ 1620 ignore_response_sign = policy->VAL_OCSP_BASIC.ignore_response_sign; 1621 1622 if (ignore_response_sign == B_FALSE && 1623 policy->VAL_OCSP.has_resp_cert == B_TRUE) { 1624 char *signer_name; 1625 KMF_X509_DER_CERT signer_retrcert; 1626 uchar_t *bytes = NULL; 1627 size_t bytelen; 1628 uint32_t num = 0; 1629 KMF_ATTRIBUTE fc_attrlist[16]; 1630 int fc_numattr = 0; 1631 char *dir = "./"; 1632 1633 if (policy->VAL_OCSP_RESP_CERT.name == NULL || 1634 policy->VAL_OCSP_RESP_CERT.serial == NULL) 1635 return (KMF_ERR_POLICY_NOT_FOUND); 1636 1637 signer_cert = malloc(sizeof (KMF_DATA)); 1638 if (signer_cert == NULL) { 1639 ret = KMF_ERR_MEMORY; 1640 goto out; 1641 } 1642 (void) memset(signer_cert, 0, sizeof (KMF_DATA)); 1643 1644 signer_name = policy->VAL_OCSP_RESP_CERT.name; 1645 ret = kmf_hexstr_to_bytes( 1646 (uchar_t *)policy->VAL_OCSP_RESP_CERT.serial, 1647 &bytes, &bytelen); 1648 if (ret != KMF_OK || bytes == NULL) { 1649 ret = KMF_ERR_OCSP_POLICY; 1650 goto out; 1651 } 1652 sernum.val = bytes; 1653 sernum.len = bytelen; 1654 1655 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1656 KMF_KEYSTORE_TYPE_ATTR, kstype, 1657 sizeof (KMF_KEYSTORE_TYPE)); 1658 fc_numattr++; 1659 1660 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1661 KMF_SUBJECT_NAME_ATTR, signer_name, strlen(signer_name)); 1662 fc_numattr++; 1663 1664 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR, 1665 &sernum, sizeof (KMF_BIGINT)); 1666 fc_numattr++; 1667 1668 if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) { 1669 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1670 KMF_TOKEN_LABEL_ATTR, slotlabel, 1671 strlen(slotlabel)); 1672 fc_numattr++; 1673 } 1674 1675 if (*kstype == KMF_KEYSTORE_OPENSSL) { 1676 if (dirpath == NULL) { 1677 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1678 KMF_DIRPATH_ATTR, dir, strlen(dir)); 1679 fc_numattr++; 1680 } else { 1681 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1682 KMF_DIRPATH_ATTR, dirpath, 1683 strlen(dirpath)); 1684 fc_numattr++; 1685 } 1686 } 1687 1688 num = 0; 1689 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1690 KMF_COUNT_ATTR, &num, sizeof (uint32_t)); 1691 fc_numattr++; 1692 1693 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 1694 if (ret != KMF_OK || num != 1) { 1695 if (num == 0) 1696 ret = KMF_ERR_CERT_NOT_FOUND; 1697 if (num > 0) 1698 ret = KMF_ERR_CERT_MULTIPLE_FOUND; 1699 goto out; 1700 } 1701 1702 (void) memset(&signer_retrcert, 0, sizeof (KMF_X509_DER_CERT)); 1703 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 1704 KMF_X509_DER_CERT_ATTR, &signer_retrcert, 1705 sizeof (KMF_X509_DER_CERT)); 1706 fc_numattr++; 1707 1708 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 1709 if (ret == KMF_OK) { 1710 signer_cert->Length = 1711 signer_retrcert.certificate.Length; 1712 signer_cert->Data = signer_retrcert.certificate.Data; 1713 } else { 1714 goto out; 1715 } 1716 } 1717 1718 /* 1719 * If the caller provides an OCSP response, we will use it directly. 1720 * Otherwise, we will try to fetch an OCSP response for the given 1721 * certificate now. 1722 */ 1723 if (response == NULL) { 1724 new_response = (KMF_DATA *) malloc(sizeof (KMF_DATA)); 1725 if (new_response == NULL) { 1726 ret = KMF_ERR_MEMORY; 1727 goto out; 1728 } 1729 new_response->Data = NULL; 1730 new_response->Length = 0; 1731 1732 ret = kmf_get_ocsp_for_cert(handle, user_cert, issuer_cert, 1733 new_response); 1734 if (ret != KMF_OK) 1735 goto out; 1736 } 1737 1738 /* 1739 * Process the OCSP response and retrieve the certificate status. 1740 */ 1741 numattr = 0; 1742 kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_CERT_DATA_ATTR, 1743 issuer_cert, sizeof (KMF_DATA)); 1744 numattr++; 1745 1746 kmf_set_attr_at_index(attrlist, numattr, KMF_USER_CERT_DATA_ATTR, 1747 user_cert, sizeof (KMF_DATA)); 1748 numattr++; 1749 1750 if (signer_cert != NULL) { 1751 kmf_set_attr_at_index(attrlist, numattr, 1752 KMF_SIGNER_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA)); 1753 numattr++; 1754 } 1755 1756 kmf_set_attr_at_index(attrlist, numattr, KMF_OCSP_RESPONSE_DATA_ATTR, 1757 response == NULL ? new_response : response, sizeof (KMF_DATA)); 1758 numattr++; 1759 1760 kmf_set_attr_at_index(attrlist, numattr, KMF_RESPONSE_LIFETIME_ATTR, 1761 <ime, sizeof (uint32_t)); 1762 numattr++; 1763 1764 kmf_set_attr_at_index(attrlist, numattr, 1765 KMF_IGNORE_RESPONSE_SIGN_ATTR, &ignore_response_sign, 1766 sizeof (boolean_t)); 1767 numattr++; 1768 1769 kmf_set_attr_at_index(attrlist, numattr, 1770 KMF_OCSP_RESPONSE_STATUS_ATTR, &response_status, sizeof (int)); 1771 numattr++; 1772 1773 kmf_set_attr_at_index(attrlist, numattr, 1774 KMF_OCSP_RESPONSE_REASON_ATTR, &reason, sizeof (int)); 1775 numattr++; 1776 1777 kmf_set_attr_at_index(attrlist, numattr, 1778 KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, &cert_status, sizeof (int)); 1779 numattr++; 1780 1781 ret = kmf_get_ocsp_status_for_cert(handle, numattr, attrlist); 1782 if (ret == KMF_OK) { 1783 switch (cert_status) { 1784 case OCSP_GOOD: 1785 break; 1786 case OCSP_UNKNOWN: 1787 ret = KMF_ERR_OCSP_UNKNOWN_CERT; 1788 break; 1789 case OCSP_REVOKED: 1790 ret = KMF_ERR_OCSP_REVOKED; 1791 break; 1792 } 1793 } 1794 1795 out: 1796 if (new_response) { 1797 kmf_free_data(new_response); 1798 free(new_response); 1799 } 1800 1801 if (signer_cert) { 1802 kmf_free_data(signer_cert); 1803 free(signer_cert); 1804 } 1805 1806 if (sernum.val != NULL) 1807 free(sernum.val); 1808 1809 return (ret); 1810 } 1811 1812 static KMF_RETURN 1813 cert_ku_check(KMF_HANDLE_T handle, KMF_DATA *cert) 1814 { 1815 KMF_POLICY_RECORD *policy; 1816 KMF_X509EXT_KEY_USAGE keyusage; 1817 KMF_RETURN ret = KMF_OK; 1818 KMF_X509EXT_BASICCONSTRAINTS constraint; 1819 KMF_BOOL critical = B_FALSE; 1820 1821 if (handle == NULL || cert == NULL) 1822 return (KMF_ERR_BAD_PARAMETER); 1823 1824 policy = handle->policy; 1825 (void) memset(&keyusage, 0, sizeof (keyusage)); 1826 ret = kmf_get_cert_ku(cert, &keyusage); 1827 1828 if (ret == KMF_ERR_EXTENSION_NOT_FOUND) { 1829 if (policy->ku_bits) { 1830 /* keyusage is not set in cert but is set in policy */ 1831 return (KMF_ERR_KEYUSAGE); 1832 } else { 1833 /* no keyusage set in both cert and policy */ 1834 return (KMF_OK); 1835 } 1836 } 1837 1838 if (ret != KMF_OK) { 1839 /* real error */ 1840 return (ret); 1841 } 1842 1843 /* 1844 * If KeyCertSign is set, then constraints.cA must be TRUE and 1845 * marked critical. 1846 */ 1847 if ((keyusage.KeyUsageBits & KMF_keyCertSign)) { 1848 (void) memset(&constraint, 0, sizeof (constraint)); 1849 ret = kmf_get_cert_basic_constraint(cert, 1850 &critical, &constraint); 1851 1852 if (ret != KMF_OK) { 1853 /* real error */ 1854 return (ret); 1855 } 1856 if (!constraint.cA || !critical) 1857 return (KMF_ERR_KEYUSAGE); 1858 } 1859 1860 /* 1861 * Rule: if the KU bit is set in policy, the corresponding KU bit 1862 * must be set in the certificate (but not vice versa). 1863 */ 1864 if ((policy->ku_bits & keyusage.KeyUsageBits) == policy->ku_bits) { 1865 return (KMF_OK); 1866 } else { 1867 return (KMF_ERR_KEYUSAGE); 1868 } 1869 1870 } 1871 1872 static KMF_RETURN 1873 cert_eku_check(KMF_HANDLE_T handle, KMF_DATA *cert) 1874 { 1875 KMF_POLICY_RECORD *policy; 1876 KMF_RETURN ret = KMF_OK; 1877 KMF_X509EXT_EKU eku; 1878 uint16_t cert_eku = 0, policy_eku = 0; 1879 int i; 1880 1881 if (handle == NULL || cert == NULL) 1882 return (KMF_ERR_BAD_PARAMETER); 1883 policy = handle->policy; 1884 1885 /* 1886 * If the policy does not have any EKU, then there is 1887 * nothing further to check. 1888 */ 1889 if (policy->eku_set.eku_count == 0) 1890 return (KMF_OK); 1891 1892 ret = kmf_get_cert_eku(cert, &eku); 1893 if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) { 1894 /* real error */ 1895 return (ret); 1896 } 1897 1898 if (ret == KMF_ERR_EXTENSION_NOT_FOUND) { 1899 cert_eku = 0; 1900 } else { 1901 /* 1902 * Build the EKU bitmap based on the certificate 1903 */ 1904 for (i = 0; i < eku.nEKUs; i++) { 1905 if (IsEqualOid(&eku.keyPurposeIdList[i], 1906 (KMF_OID *)&KMFOID_PKIX_KP_ServerAuth)) { 1907 cert_eku |= KMF_EKU_SERVERAUTH; 1908 } else if (IsEqualOid(&eku.keyPurposeIdList[i], 1909 (KMF_OID *)&KMFOID_PKIX_KP_ClientAuth)) { 1910 cert_eku |= KMF_EKU_CLIENTAUTH; 1911 } else if (IsEqualOid(&eku.keyPurposeIdList[i], 1912 (KMF_OID *)&KMFOID_PKIX_KP_CodeSigning)) { 1913 cert_eku |= KMF_EKU_CODESIGNING; 1914 } else if (IsEqualOid(&eku.keyPurposeIdList[i], 1915 (KMF_OID *)&KMFOID_PKIX_KP_EmailProtection)) { 1916 cert_eku |= KMF_EKU_EMAIL; 1917 } else if (IsEqualOid(&eku.keyPurposeIdList[i], 1918 (KMF_OID *)&KMFOID_PKIX_KP_TimeStamping)) { 1919 cert_eku |= KMF_EKU_TIMESTAMP; 1920 } else if (IsEqualOid(&eku.keyPurposeIdList[i], 1921 (KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning)) { 1922 cert_eku |= KMF_EKU_OCSPSIGNING; 1923 } else if (!policy->ignore_unknown_ekus) { 1924 return (KMF_ERR_KEYUSAGE); 1925 } 1926 } /* for */ 1927 } 1928 1929 1930 /* 1931 * Build the EKU bitmap based on the policy 1932 */ 1933 for (i = 0; i < policy->eku_set.eku_count; i++) { 1934 if (IsEqualOid(&policy->eku_set.ekulist[i], 1935 (KMF_OID *)&KMFOID_PKIX_KP_ServerAuth)) { 1936 policy_eku |= KMF_EKU_SERVERAUTH; 1937 } else if (IsEqualOid(&policy->eku_set.ekulist[i], 1938 (KMF_OID *)&KMFOID_PKIX_KP_ClientAuth)) { 1939 policy_eku |= KMF_EKU_CLIENTAUTH; 1940 } else if (IsEqualOid(&policy->eku_set.ekulist[i], 1941 (KMF_OID *)&KMFOID_PKIX_KP_CodeSigning)) { 1942 policy_eku |= KMF_EKU_CODESIGNING; 1943 } else if (IsEqualOid(&policy->eku_set.ekulist[i], 1944 (KMF_OID *)&KMFOID_PKIX_KP_EmailProtection)) { 1945 policy_eku |= KMF_EKU_EMAIL; 1946 } else if (IsEqualOid(&policy->eku_set.ekulist[i], 1947 (KMF_OID *)&KMFOID_PKIX_KP_TimeStamping)) { 1948 policy_eku |= KMF_EKU_TIMESTAMP; 1949 } else if (IsEqualOid(&policy->eku_set.ekulist[i], 1950 (KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning)) { 1951 policy_eku |= KMF_EKU_OCSPSIGNING; 1952 } else if (!policy->ignore_unknown_ekus) { 1953 return (KMF_ERR_KEYUSAGE); 1954 } 1955 } /* for */ 1956 1957 /* 1958 * Rule: if the EKU OID is set in policy, the corresponding EKU OID 1959 * must be set in the certificate (but not vice versa). 1960 */ 1961 if ((policy_eku & cert_eku) == policy_eku) { 1962 return (KMF_OK); 1963 } else { 1964 return (KMF_ERR_KEYUSAGE); 1965 } 1966 } 1967 1968 static KMF_RETURN 1969 find_issuer_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, 1970 char *user_issuer, KMF_DATA *issuer_cert, 1971 char *slotlabel, char *dirpath) 1972 { 1973 KMF_RETURN ret = KMF_OK; 1974 KMF_X509_DER_CERT *certlist = NULL; 1975 uint32_t i, num = 0; 1976 time_t t_notbefore; 1977 time_t t_notafter; 1978 time_t latest; 1979 KMF_DATA tmp_cert = {0, NULL}; 1980 KMF_ATTRIBUTE fc_attrlist[16]; 1981 int fc_numattr = 0; 1982 char *dir = "./"; 1983 1984 if (handle == NULL || kstype == NULL || user_issuer == NULL || 1985 issuer_cert == NULL) 1986 return (KMF_ERR_BAD_PARAMETER); 1987 1988 if (!VALID_KEYSTORE_TYPE(*kstype)) 1989 return (KMF_ERR_BAD_PARAMETER); 1990 1991 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR, 1992 kstype, sizeof (KMF_KEYSTORE_TYPE)); 1993 fc_numattr++; 1994 1995 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR, 1996 user_issuer, strlen(user_issuer)); 1997 fc_numattr++; 1998 1999 if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) { 2000 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2001 KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel)); 2002 fc_numattr++; 2003 } 2004 2005 if (*kstype == KMF_KEYSTORE_OPENSSL) { 2006 if (dirpath == NULL) { 2007 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2008 KMF_DIRPATH_ATTR, dir, strlen(dir)); 2009 fc_numattr++; 2010 } else { 2011 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2012 KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); 2013 fc_numattr++; 2014 } 2015 } 2016 2017 num = 0; 2018 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2019 KMF_COUNT_ATTR, &num, sizeof (uint32_t)); 2020 fc_numattr++; 2021 2022 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 2023 2024 if (ret == KMF_OK && num > 0) { 2025 certlist = (KMF_X509_DER_CERT *)malloc(num * 2026 sizeof (KMF_X509_DER_CERT)); 2027 2028 if (certlist == NULL) { 2029 ret = KMF_ERR_MEMORY; 2030 goto out; 2031 } 2032 2033 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2034 KMF_X509_DER_CERT_ATTR, certlist, 2035 sizeof (KMF_X509_DER_CERT)); 2036 fc_numattr++; 2037 2038 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 2039 if (ret != KMF_OK) { 2040 free(certlist); 2041 certlist = NULL; 2042 goto out; 2043 } 2044 } else { 2045 goto out; 2046 } 2047 2048 if (num == 1) { 2049 /* only one issuer cert is found */ 2050 tmp_cert.Length = certlist[0].certificate.Length; 2051 tmp_cert.Data = certlist[0].certificate.Data; 2052 } else { 2053 /* 2054 * More than one issuer certs are found. We will 2055 * pick the latest one. 2056 */ 2057 latest = 0; 2058 for (i = 0; i < num; i++) { 2059 ret = kmf_get_cert_validity(&certlist[i].certificate, 2060 &t_notbefore, &t_notafter); 2061 if (ret != KMF_OK) { 2062 ret = KMF_ERR_VALIDITY_PERIOD; 2063 goto out; 2064 } 2065 2066 if (t_notbefore > latest) { 2067 tmp_cert.Length = 2068 certlist[i].certificate.Length; 2069 tmp_cert.Data = 2070 certlist[i].certificate.Data; 2071 latest = t_notbefore; 2072 } 2073 2074 } 2075 } 2076 2077 issuer_cert->Length = tmp_cert.Length; 2078 issuer_cert->Data = malloc(tmp_cert.Length); 2079 if (issuer_cert->Data == NULL) { 2080 ret = KMF_ERR_MEMORY; 2081 goto out; 2082 } 2083 (void) memcpy(issuer_cert->Data, tmp_cert.Data, 2084 tmp_cert.Length); 2085 2086 out: 2087 if (certlist != NULL) { 2088 for (i = 0; i < num; i++) 2089 kmf_free_kmf_cert(handle, &certlist[i]); 2090 free(certlist); 2091 } 2092 2093 return (ret); 2094 2095 } 2096 2097 static KMF_RETURN 2098 find_ta_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, 2099 KMF_DATA *ta_cert, KMF_X509_NAME *user_issuerDN, 2100 char *slotlabel, char *dirpath) 2101 { 2102 KMF_POLICY_RECORD *policy; 2103 KMF_RETURN ret = KMF_OK; 2104 uint32_t num = 0; 2105 char *ta_name; 2106 KMF_BIGINT serial = { NULL, 0 }; 2107 uchar_t *bytes = NULL; 2108 size_t bytelen; 2109 KMF_X509_DER_CERT ta_retrCert; 2110 char *ta_subject = NULL; 2111 KMF_X509_NAME ta_subjectDN; 2112 KMF_ATTRIBUTE fc_attrlist[16]; 2113 int fc_numattr = 0; 2114 char *dir = "./"; 2115 2116 if (handle == NULL || kstype == NULL || ta_cert == NULL || 2117 user_issuerDN == NULL) 2118 return (KMF_ERR_BAD_PARAMETER); 2119 2120 if (!VALID_KEYSTORE_TYPE(*kstype)) 2121 return (KMF_ERR_BAD_PARAMETER); 2122 2123 /* Get the TA name and serial number from the policy */ 2124 policy = handle->policy; 2125 ta_name = policy->ta_name; 2126 ret = kmf_hexstr_to_bytes((uchar_t *)policy->ta_serial, 2127 &bytes, &bytelen); 2128 if (ret != KMF_OK || bytes == NULL) { 2129 ret = KMF_ERR_TA_POLICY; 2130 goto out; 2131 } 2132 serial.val = bytes; 2133 serial.len = bytelen; 2134 2135 /* set up fc_attrlist for kmf_find_cert */ 2136 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR, 2137 kstype, sizeof (KMF_KEYSTORE_TYPE)); 2138 fc_numattr++; 2139 2140 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR, 2141 ta_name, strlen(ta_name)); 2142 fc_numattr++; 2143 2144 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR, 2145 &serial, sizeof (KMF_BIGINT)); 2146 fc_numattr++; 2147 2148 if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) { 2149 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2150 KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel)); 2151 fc_numattr++; 2152 } 2153 2154 if (*kstype == KMF_KEYSTORE_OPENSSL) { 2155 if (dirpath == NULL) { 2156 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2157 KMF_DIRPATH_ATTR, dir, strlen(dir)); 2158 fc_numattr++; 2159 } else { 2160 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2161 KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); 2162 fc_numattr++; 2163 } 2164 } 2165 2166 num = 0; 2167 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2168 KMF_COUNT_ATTR, &num, sizeof (uint32_t)); 2169 fc_numattr++; 2170 2171 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 2172 if (ret != KMF_OK || num != 1) { 2173 if (num == 0) 2174 ret = KMF_ERR_CERT_NOT_FOUND; 2175 if (num > 1) 2176 ret = KMF_ERR_CERT_MULTIPLE_FOUND; 2177 goto out; 2178 } 2179 2180 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2181 KMF_X509_DER_CERT_ATTR, &ta_retrCert, sizeof (KMF_X509_DER_CERT)); 2182 fc_numattr++; 2183 2184 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 2185 if (ret == KMF_OK) { 2186 ta_cert->Length = ta_retrCert.certificate.Length; 2187 ta_cert->Data = malloc(ta_retrCert.certificate.Length); 2188 if (ta_cert->Data == NULL) { 2189 ret = KMF_ERR_MEMORY; 2190 goto out; 2191 } 2192 (void) memcpy(ta_cert->Data, ta_retrCert.certificate.Data, 2193 ta_retrCert.certificate.Length); 2194 } else { 2195 goto out; 2196 } 2197 2198 /* 2199 * The found TA's name must be matching with issuer name in 2200 * subscriber's certificate. 2201 */ 2202 (void) memset(&ta_subjectDN, 0, sizeof (ta_subjectDN)); 2203 2204 ret = kmf_get_cert_subject_str(handle, ta_cert, &ta_subject); 2205 if (ret != KMF_OK) 2206 goto out; 2207 2208 ret = kmf_dn_parser(ta_subject, &ta_subjectDN); 2209 if (ret != KMF_OK) 2210 goto out; 2211 2212 if (kmf_compare_rdns(user_issuerDN, &ta_subjectDN) != 0) 2213 ret = KMF_ERR_CERT_NOT_FOUND; 2214 2215 kmf_free_dn(&ta_subjectDN); 2216 2217 /* Make sure the TA cert has the correct extensions */ 2218 if (ret == KMF_OK) 2219 ret = check_key_usage(handle, ta_cert, KMF_KU_SIGN_CERT); 2220 out: 2221 if (ta_retrCert.certificate.Data) 2222 kmf_free_kmf_cert(handle, &ta_retrCert); 2223 2224 if ((ret != KMF_OK) && (ta_cert->Data != NULL)) 2225 free(ta_cert->Data); 2226 2227 if (serial.val != NULL) 2228 free(serial.val); 2229 2230 if (ta_subject) 2231 free(ta_subject); 2232 2233 return (ret); 2234 } 2235 2236 KMF_RETURN 2237 kmf_validate_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 2238 { 2239 KMF_RETURN ret = KMF_OK; 2240 KMF_KEYSTORE_TYPE *kstype = NULL; 2241 KMF_DATA *pcert = NULL; 2242 int *result = NULL; 2243 char *slotlabel = NULL; 2244 char *dirpath = NULL; 2245 KMF_DATA *ocsp_response = NULL; 2246 KMF_DATA ta_cert = {0, NULL}; 2247 KMF_DATA issuer_cert = {0, NULL}; 2248 char *user_issuer = NULL, *user_subject = NULL; 2249 KMF_X509_NAME user_issuerDN, user_subjectDN; 2250 boolean_t self_signed = B_FALSE; 2251 KMF_POLICY_RECORD *policy; 2252 2253 KMF_ATTRIBUTE_TESTER required_attrs[] = { 2254 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 2255 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, 2256 {KMF_VALIDATE_RESULT_ATTR, FALSE, 1, sizeof (int)} 2257 }; 2258 int num_req_attrs = sizeof (required_attrs) / 2259 sizeof (KMF_ATTRIBUTE_TESTER); 2260 2261 if (handle == NULL) 2262 return (KMF_ERR_BAD_PARAMETER); 2263 2264 CLEAR_ERROR(handle, ret); 2265 2266 ret = test_attributes(num_req_attrs, required_attrs, 2267 0, NULL, numattr, attrlist); 2268 if (ret != KMF_OK) 2269 return (ret); 2270 2271 policy = handle->policy; 2272 2273 /* Get the attribute values */ 2274 kstype = kmf_get_attr_ptr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr); 2275 pcert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 2276 result = kmf_get_attr_ptr(KMF_VALIDATE_RESULT_ATTR, attrlist, numattr); 2277 if (kstype == NULL || pcert == NULL || result == NULL) 2278 return (KMF_ERR_BAD_PARAMETER); 2279 2280 slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr); 2281 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 2282 ocsp_response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, attrlist, 2283 numattr); 2284 2285 /* Initialize the returned result */ 2286 *result = KMF_CERT_VALIDATE_OK; 2287 2288 /* 2289 * Get the issuer information from the input certficate first. 2290 */ 2291 if ((ret = kmf_get_cert_issuer_str(handle, pcert, 2292 &user_issuer)) != KMF_OK) { 2293 *result |= KMF_CERT_VALIDATE_ERR_USER; 2294 goto out; 2295 } 2296 2297 if ((ret = kmf_dn_parser(user_issuer, &user_issuerDN)) != KMF_OK) { 2298 *result |= KMF_CERT_VALIDATE_ERR_USER; 2299 goto out; 2300 } 2301 2302 /* 2303 * Check if the certificate is a self-signed cert. 2304 */ 2305 if ((ret = kmf_get_cert_subject_str(handle, pcert, 2306 &user_subject)) != KMF_OK) { 2307 *result |= KMF_CERT_VALIDATE_ERR_USER; 2308 kmf_free_dn(&user_issuerDN); 2309 goto out; 2310 } 2311 2312 if ((ret = kmf_dn_parser(user_subject, &user_subjectDN)) != KMF_OK) { 2313 *result |= KMF_CERT_VALIDATE_ERR_USER; 2314 kmf_free_dn(&user_issuerDN); 2315 goto out; 2316 } 2317 2318 if ((kmf_compare_rdns(&user_issuerDN, &user_subjectDN)) == 0) { 2319 /* 2320 * this is a self-signed cert 2321 */ 2322 self_signed = B_TRUE; 2323 } 2324 2325 kmf_free_dn(&user_subjectDN); 2326 2327 /* 2328 * Check KeyUsage extension of the subscriber's certificate 2329 */ 2330 ret = cert_ku_check(handle, pcert); 2331 if (ret != KMF_OK) { 2332 *result |= KMF_CERT_VALIDATE_ERR_KEYUSAGE; 2333 goto out; 2334 } 2335 2336 /* 2337 * Validate Extended KeyUsage extension 2338 */ 2339 ret = cert_eku_check(handle, pcert); 2340 if (ret != KMF_OK) { 2341 *result |= KMF_CERT_VALIDATE_ERR_EXT_KEYUSAGE; 2342 goto out; 2343 } 2344 2345 /* 2346 * Check the certificate's validity period 2347 * 2348 * This step is needed when "ignore_date" in policy is set 2349 * to false. 2350 */ 2351 if (!policy->ignore_date) { 2352 /* 2353 * Validate expiration date 2354 */ 2355 ret = kmf_check_cert_date(handle, pcert); 2356 if (ret != KMF_OK) { 2357 *result |= KMF_CERT_VALIDATE_ERR_TIME; 2358 goto out; 2359 } 2360 } 2361 2362 /* 2363 * When "ignore_trust_anchor" in policy is set to FALSE, 2364 * we will try to find the TA cert based on the TA policy 2365 * attributes. 2366 * 2367 * TA's subject name (ta_name) and serial number (ta_serial) 2368 * are defined as optional attributes in policy dtd, but they 2369 * should exist in policy when "ignore_trust_anchor" is set 2370 * to FALSE. The policy verification code has enforced that. 2371 */ 2372 if (policy->ignore_trust_anchor) { 2373 goto check_revocation; 2374 } 2375 2376 /* 2377 * Verify the signature of subscriber's certificate using 2378 * TA certificate. 2379 */ 2380 if (self_signed) { 2381 ret = verify_cert_with_cert(handle, pcert, pcert); 2382 } else { 2383 ret = find_ta_cert(handle, kstype, &ta_cert, 2384 &user_issuerDN, slotlabel, dirpath); 2385 if (ret != KMF_OK) { 2386 *result |= KMF_CERT_VALIDATE_ERR_TA; 2387 goto out; 2388 } 2389 2390 ret = check_key_usage(handle, &ta_cert, KMF_KU_SIGN_CERT); 2391 if (ret != KMF_OK) 2392 goto out; 2393 2394 ret = verify_cert_with_cert(handle, pcert, &ta_cert); 2395 } 2396 if (ret != KMF_OK) { 2397 *result |= KMF_CERT_VALIDATE_ERR_SIGNATURE; 2398 goto out; 2399 } 2400 2401 check_revocation: 2402 /* 2403 * Check certificate revocation 2404 */ 2405 if (self_signed) { 2406 /* skip revocation checking */ 2407 goto out; 2408 } 2409 2410 /* 2411 * When CRL or OCSP revocation method is set in the policy, 2412 * we will try to find the issuer of the subscriber certificate 2413 * using the issuer name of the subscriber certificate. The 2414 * issuer certificate will be used to do the CRL checking 2415 * and OCSP checking. 2416 */ 2417 if (!(policy->revocation & KMF_REVOCATION_METHOD_CRL) && 2418 !(policy->revocation & KMF_REVOCATION_METHOD_OCSP)) { 2419 goto out; 2420 } 2421 2422 ret = find_issuer_cert(handle, kstype, user_issuer, &issuer_cert, 2423 slotlabel, dirpath); 2424 if (ret != KMF_OK) { 2425 *result |= KMF_CERT_VALIDATE_ERR_ISSUER; 2426 goto out; 2427 } 2428 2429 if (policy->revocation & KMF_REVOCATION_METHOD_CRL) { 2430 ret = cert_crl_check(handle, kstype, pcert, &issuer_cert); 2431 if (ret != KMF_OK) { 2432 *result |= KMF_CERT_VALIDATE_ERR_CRL; 2433 goto out; 2434 } 2435 } 2436 2437 if (policy->revocation & KMF_REVOCATION_METHOD_OCSP) { 2438 ret = cert_ocsp_check(handle, kstype, pcert, &issuer_cert, 2439 ocsp_response, slotlabel, dirpath); 2440 if (ret != KMF_OK) { 2441 *result |= KMF_CERT_VALIDATE_ERR_OCSP; 2442 goto out; 2443 } 2444 } 2445 2446 out: 2447 if (user_issuer) { 2448 kmf_free_dn(&user_issuerDN); 2449 free(user_issuer); 2450 } 2451 2452 if (user_subject) 2453 free(user_subject); 2454 2455 if (ta_cert.Data) 2456 free(ta_cert.Data); 2457 2458 if (issuer_cert.Data) 2459 free(issuer_cert.Data); 2460 2461 return (ret); 2462 2463 } 2464 2465 KMF_RETURN 2466 kmf_create_cert_file(const KMF_DATA *certdata, KMF_ENCODE_FORMAT format, 2467 char *certfile) 2468 { 2469 KMF_RETURN rv = KMF_OK; 2470 int fd = -1; 2471 KMF_DATA pemdata = {NULL, 0}; 2472 2473 if (certdata == NULL || certfile == NULL) 2474 return (KMF_ERR_BAD_PARAMETER); 2475 2476 if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1) 2477 return (KMF_ERR_BAD_PARAMETER); 2478 2479 if (format == KMF_FORMAT_PEM) { 2480 int len; 2481 rv = kmf_der_to_pem(KMF_CERT, 2482 certdata->Data, certdata->Length, 2483 &pemdata.Data, &len); 2484 if (rv != KMF_OK) 2485 goto cleanup; 2486 pemdata.Length = (size_t)len; 2487 } 2488 2489 if ((fd = open(certfile, O_CREAT | O_RDWR | O_TRUNC, 0644)) == -1) { 2490 rv = KMF_ERR_OPEN_FILE; 2491 goto cleanup; 2492 } 2493 2494 if (format == KMF_FORMAT_PEM) { 2495 if (write(fd, pemdata.Data, pemdata.Length) != 2496 pemdata.Length) { 2497 rv = KMF_ERR_WRITE_FILE; 2498 } 2499 } else { 2500 if (write(fd, certdata->Data, certdata->Length) != 2501 certdata->Length) { 2502 rv = KMF_ERR_WRITE_FILE; 2503 } 2504 } 2505 2506 cleanup: 2507 if (fd != -1) 2508 (void) close(fd); 2509 2510 kmf_free_data(&pemdata); 2511 2512 return (rv); 2513 } 2514 2515 KMF_RETURN 2516 kmf_is_cert_file(KMF_HANDLE_T handle, char *filename, 2517 KMF_ENCODE_FORMAT *pformat) 2518 { 2519 KMF_PLUGIN *plugin; 2520 KMF_RETURN (*IsCertFileFn)(void *, char *, KMF_ENCODE_FORMAT *); 2521 2522 KMF_RETURN ret; 2523 2524 CLEAR_ERROR(handle, ret); 2525 if (ret != KMF_OK) 2526 return (ret); 2527 2528 if (filename == NULL || pformat == NULL) { 2529 return (KMF_ERR_BAD_PARAMETER); 2530 } 2531 2532 /* 2533 * This framework function is actually implemented in the openssl 2534 * plugin library, so we find the function address and call it. 2535 */ 2536 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 2537 if (plugin == NULL || plugin->dldesc == NULL) { 2538 return (KMF_ERR_PLUGIN_NOTFOUND); 2539 } 2540 2541 IsCertFileFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 2542 "OpenSSL_IsCertFile"); 2543 if (IsCertFileFn == NULL) { 2544 return (KMF_ERR_FUNCTION_NOT_FOUND); 2545 } 2546 2547 return (IsCertFileFn(handle, filename, pformat)); 2548 } 2549 2550 /* 2551 * This function checks the validity period of a der-encoded certificate. 2552 */ 2553 KMF_RETURN 2554 kmf_check_cert_date(KMF_HANDLE_T handle, const KMF_DATA *cert) 2555 { 2556 KMF_RETURN rv; 2557 struct tm *gmt; 2558 time_t t_now; 2559 time_t t_notbefore; 2560 time_t t_notafter; 2561 KMF_POLICY_RECORD *policy; 2562 uint32_t adj; 2563 2564 CLEAR_ERROR(handle, rv); 2565 if (rv != KMF_OK) 2566 return (rv); 2567 2568 if (cert == NULL || cert->Data == NULL || cert->Length == 0) 2569 return (KMF_ERR_BAD_PARAMETER); 2570 2571 policy = handle->policy; 2572 rv = kmf_get_cert_validity(cert, &t_notbefore, &t_notafter); 2573 if (rv != KMF_OK) 2574 return (rv); 2575 2576 /* 2577 * Get the current time. The time returned from time() is local which 2578 * cannot be used directly. It must be converted to UTC/GMT first. 2579 */ 2580 t_now = time(NULL); 2581 gmt = gmtime(&t_now); 2582 t_now = mktime(gmt); 2583 2584 /* 2585 * Adjust the validity time 2586 */ 2587 if (policy->validity_adjusttime != NULL) { 2588 if (str2lifetime(policy->validity_adjusttime, &adj) < 0) 2589 return (KMF_ERR_VALIDITY_PERIOD); 2590 } else { 2591 adj = 0; 2592 } 2593 2594 t_notafter += adj; 2595 t_notbefore -= adj; 2596 2597 if (t_now <= t_notafter && t_now >= t_notbefore) { 2598 rv = KMF_OK; 2599 } else { 2600 rv = KMF_ERR_VALIDITY_PERIOD; 2601 } 2602 2603 return (rv); 2604 } 2605 2606 KMF_RETURN 2607 kmf_export_pk12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 2608 { 2609 KMF_PLUGIN *plugin; 2610 KMF_RETURN ret = KMF_OK; 2611 KMF_KEYSTORE_TYPE kstype; 2612 2613 KMF_ATTRIBUTE_TESTER required_attrs[] = { 2614 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 2615 {KMF_OUTPUT_FILENAME_ATTR, TRUE, 1, 0}, 2616 }; 2617 2618 int num_req_attrs = sizeof (required_attrs) / 2619 sizeof (KMF_ATTRIBUTE_TESTER); 2620 2621 if (handle == NULL) 2622 return (KMF_ERR_BAD_PARAMETER); 2623 2624 CLEAR_ERROR(handle, ret); 2625 2626 ret = test_attributes(num_req_attrs, required_attrs, 0, NULL, 2627 numattr, attrlist); 2628 if (ret != KMF_OK) 2629 return (ret); 2630 2631 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, 2632 &kstype, NULL); 2633 if (ret != KMF_OK) 2634 return (ret); 2635 2636 plugin = FindPlugin(handle, kstype); 2637 if (plugin == NULL || plugin->funclist->ExportPK12 == NULL) 2638 return (KMF_ERR_PLUGIN_NOTFOUND); 2639 2640 return (plugin->funclist->ExportPK12(handle, numattr, attrlist)); 2641 } 2642 2643 2644 KMF_RETURN 2645 kmf_build_pk12(KMF_HANDLE_T handle, int numcerts, 2646 KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist, 2647 KMF_CREDENTIAL *p12cred, char *filename) 2648 { 2649 KMF_RETURN rv; 2650 KMF_PLUGIN *plugin; 2651 KMF_RETURN (*buildpk12)(KMF_HANDLE *, int, KMF_X509_DER_CERT *, 2652 int, KMF_KEY_HANDLE *, KMF_CREDENTIAL *, char *); 2653 2654 CLEAR_ERROR(handle, rv); 2655 if (rv != KMF_OK) 2656 return (rv); 2657 2658 if (filename == NULL || p12cred == NULL || 2659 (certlist == NULL && keylist == NULL)) 2660 return (KMF_ERR_BAD_PARAMETER); 2661 2662 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 2663 if (plugin == NULL || plugin->dldesc == NULL) { 2664 return (KMF_ERR_PLUGIN_NOTFOUND); 2665 } 2666 2667 buildpk12 = (KMF_RETURN(*)())dlsym(plugin->dldesc, 2668 "openssl_build_pk12"); 2669 if (buildpk12 == NULL) { 2670 return (KMF_ERR_FUNCTION_NOT_FOUND); 2671 } 2672 2673 rv = buildpk12(handle, numcerts, certlist, numkeys, keylist, p12cred, 2674 filename); 2675 2676 return (rv); 2677 } 2678 2679 2680 KMF_RETURN 2681 kmf_import_objects(KMF_HANDLE_T handle, char *filename, 2682 KMF_CREDENTIAL *cred, 2683 KMF_DATA **certs, int *ncerts, 2684 KMF_RAW_KEY_DATA **rawkeys, int *nkeys) 2685 { 2686 KMF_RETURN rv; 2687 KMF_PLUGIN *plugin; 2688 KMF_RETURN (*import_objects)(KMF_HANDLE *, char *, KMF_CREDENTIAL *, 2689 KMF_DATA **, int *, KMF_RAW_KEY_DATA **, int *); 2690 2691 CLEAR_ERROR(handle, rv); 2692 if (rv != KMF_OK) 2693 return (rv); 2694 2695 if (filename == NULL || cred == NULL || certs == NULL || 2696 ncerts == NULL ||rawkeys == NULL || nkeys == NULL) 2697 return (KMF_ERR_BAD_PARAMETER); 2698 2699 /* 2700 * Use the Keypair reader from the OpenSSL plugin. 2701 */ 2702 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 2703 if (plugin == NULL || plugin->dldesc == NULL) { 2704 return (KMF_ERR_PLUGIN_NOTFOUND); 2705 } 2706 2707 import_objects = (KMF_RETURN(*)())dlsym(plugin->dldesc, 2708 "openssl_import_objects"); 2709 if (import_objects == NULL) { 2710 return (KMF_ERR_FUNCTION_NOT_FOUND); 2711 } 2712 2713 /* Use OpenSSL interfaces to get raw key and cert data */ 2714 rv = import_objects(handle, filename, cred, certs, ncerts, 2715 rawkeys, nkeys); 2716 2717 return (rv); 2718 } 2719 2720 KMF_BOOL 2721 IsEqualOid(KMF_OID *Oid1, KMF_OID *Oid2) 2722 { 2723 return ((Oid1->Length == Oid2->Length) && 2724 !memcmp(Oid1->Data, Oid2->Data, Oid1->Length)); 2725 } 2726 2727 KMF_RETURN 2728 copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, 2729 KMF_X509_ALGORITHM_IDENTIFIER *srcid) 2730 { 2731 KMF_RETURN ret = KMF_OK; 2732 if (!destid || !srcid) 2733 return (KMF_ERR_BAD_PARAMETER); 2734 2735 destid->algorithm.Length = srcid->algorithm.Length; 2736 destid->algorithm.Data = malloc(destid->algorithm.Length); 2737 if (destid->algorithm.Data == NULL) 2738 return (KMF_ERR_MEMORY); 2739 2740 (void) memcpy(destid->algorithm.Data, srcid->algorithm.Data, 2741 destid->algorithm.Length); 2742 2743 destid->parameters.Length = srcid->parameters.Length; 2744 if (destid->parameters.Length > 0) { 2745 destid->parameters.Data = malloc(destid->parameters.Length); 2746 if (destid->parameters.Data == NULL) 2747 return (KMF_ERR_MEMORY); 2748 2749 (void) memcpy(destid->parameters.Data, srcid->parameters.Data, 2750 destid->parameters.Length); 2751 } else { 2752 destid->parameters.Data = NULL; 2753 } 2754 return (ret); 2755 } 2756 2757 static KMF_RETURN 2758 sign_cert(KMF_HANDLE_T handle, 2759 const KMF_DATA *SubjectCert, 2760 KMF_KEY_HANDLE *Signkey, 2761 KMF_DATA *SignedCert) 2762 { 2763 KMF_X509_CERTIFICATE *subj_cert = NULL; 2764 KMF_DATA data_to_sign = {0, NULL}; 2765 KMF_DATA signed_data = {0, NULL}; 2766 KMF_RETURN ret = KMF_OK; 2767 KMF_ALGORITHM_INDEX algid; 2768 int i = 0; 2769 KMF_ATTRIBUTE attrlist[8]; 2770 KMF_OID *oid; 2771 2772 if (!SignedCert) 2773 return (KMF_ERR_BAD_PARAMETER); 2774 2775 SignedCert->Length = 0; 2776 SignedCert->Data = NULL; 2777 2778 if (!SubjectCert) 2779 return (KMF_ERR_BAD_PARAMETER); 2780 2781 if (!SubjectCert->Data || !SubjectCert->Length) 2782 return (KMF_ERR_BAD_PARAMETER); 2783 2784 /* 2785 * Shortcut - just extract the already encoded TBS cert data from 2786 * the original data buffer. Since we haven't changed anything, 2787 * there is no need to re-encode it. 2788 */ 2789 ret = ExtractX509CertParts((KMF_DATA *)SubjectCert, 2790 &data_to_sign, NULL); 2791 if (ret != KMF_OK) { 2792 goto cleanup; 2793 } 2794 2795 /* Estimate the signed data length generously */ 2796 signed_data.Length = data_to_sign.Length*2; 2797 signed_data.Data = calloc(1, signed_data.Length); 2798 if (!signed_data.Data) { 2799 ret = KMF_ERR_MEMORY; 2800 goto cleanup; 2801 } 2802 2803 /* 2804 * If we got here OK, decode into a structure and then re-encode 2805 * the complete certificate. 2806 */ 2807 ret = DerDecodeSignedCertificate(SubjectCert, &subj_cert); 2808 if (ret != KMF_OK) { 2809 goto cleanup; 2810 } 2811 2812 /* We are re-signing this cert, so clear out old signature data */ 2813 if (subj_cert->signature.algorithmIdentifier.algorithm.Length == 0) { 2814 kmf_free_algoid(&subj_cert->signature.algorithmIdentifier); 2815 ret = copy_algoid(&subj_cert->signature.algorithmIdentifier, 2816 &subj_cert->certificate.signature); 2817 } 2818 2819 if (ret) 2820 goto cleanup; 2821 2822 kmf_set_attr_at_index(attrlist, i, KMF_KEYSTORE_TYPE_ATTR, 2823 &Signkey->kstype, sizeof (KMF_KEYSTORE_TYPE)); 2824 i++; 2825 kmf_set_attr_at_index(attrlist, i, KMF_KEY_HANDLE_ATTR, 2826 Signkey, sizeof (KMF_KEY_HANDLE)); 2827 i++; 2828 kmf_set_attr_at_index(attrlist, i, KMF_DATA_ATTR, 2829 &data_to_sign, sizeof (KMF_DATA)); 2830 i++; 2831 kmf_set_attr_at_index(attrlist, i, KMF_OUT_DATA_ATTR, 2832 &signed_data, sizeof (KMF_DATA)); 2833 i++; 2834 oid = CERT_ALG_OID(subj_cert); 2835 kmf_set_attr_at_index(attrlist, i, KMF_OID_ATTR, 2836 oid, sizeof (KMF_OID)); 2837 i++; 2838 2839 /* Sign the data */ 2840 ret = kmf_sign_data(handle, i, attrlist); 2841 2842 if (ret != KMF_OK) 2843 goto cleanup; 2844 2845 algid = x509_algoid_to_algid(CERT_SIG_OID(subj_cert)); 2846 2847 /* 2848 * For DSA, KMF_SignDataWithKey() returns a 40-bytes decoded 2849 * signature. So we must encode the signature correctly. 2850 */ 2851 if (algid == KMF_ALGID_SHA1WithDSA) { 2852 2853 KMF_DATA signature; 2854 2855 ret = DerEncodeDSASignature(&signed_data, &signature); 2856 kmf_free_data(&signed_data); 2857 2858 if (ret != KMF_OK) 2859 goto cleanup; 2860 2861 subj_cert->signature.encrypted = signature; 2862 } else { 2863 subj_cert->signature.encrypted = signed_data; 2864 } 2865 2866 /* Now, re-encode the cert with the new signature */ 2867 ret = DerEncodeSignedCertificate(subj_cert, SignedCert); 2868 2869 cleanup: 2870 /* Cleanup & return */ 2871 if (ret != KMF_OK) 2872 kmf_free_data(SignedCert); 2873 2874 kmf_free_data(&data_to_sign); 2875 2876 if (subj_cert != NULL) { 2877 kmf_free_signed_cert(subj_cert); 2878 free(subj_cert); 2879 } 2880 2881 return (ret); 2882 } 2883 2884 static KMF_RETURN 2885 verify_cert_with_key(KMF_HANDLE_T handle, 2886 KMF_DATA *derkey, 2887 const KMF_DATA *CertToBeVerified) 2888 { 2889 KMF_RETURN ret = KMF_OK; 2890 KMF_X509_CERTIFICATE *signed_cert = NULL; 2891 KMF_X509_SPKI spki; 2892 KMF_DATA data_to_verify = {0, NULL}; 2893 KMF_DATA signed_data = {0, NULL}; 2894 KMF_DATA signature = { 0, NULL }; 2895 KMF_ALGORITHM_INDEX algid; 2896 2897 /* check the caller and do other setup for this SPI call */ 2898 if (handle == NULL || CertToBeVerified == NULL || 2899 derkey == NULL || derkey->Data == NULL) 2900 return (KMF_ERR_BAD_PARAMETER); 2901 2902 (void) memset(&spki, 0, sizeof (KMF_X509_SPKI)); 2903 2904 ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerified, 2905 &data_to_verify, &signed_data); 2906 2907 if (ret != KMF_OK) 2908 goto cleanup; 2909 2910 ret = DerDecodeSPKI(derkey, &spki); 2911 if (ret != KMF_OK) 2912 goto cleanup; 2913 2914 /* Decode the signer cert so we can get the Algorithm data */ 2915 ret = DerDecodeSignedCertificate(CertToBeVerified, &signed_cert); 2916 if (ret != KMF_OK) 2917 return (ret); 2918 2919 algid = x509_algoid_to_algid(CERT_SIG_OID(signed_cert)); 2920 2921 if (algid == KMF_ALGID_NONE) 2922 return (KMF_ERR_BAD_ALGORITHM); 2923 2924 if (algid == KMF_ALGID_SHA1WithDSA) { 2925 ret = DerDecodeDSASignature(&signed_data, &signature); 2926 if (ret != KMF_OK) 2927 goto cleanup; 2928 } else { 2929 signature.Data = signed_data.Data; 2930 signature.Length = signed_data.Length; 2931 } 2932 2933 ret = PKCS_VerifyData(handle, algid, &spki, 2934 &data_to_verify, &signature); 2935 2936 cleanup: 2937 if (data_to_verify.Data != NULL) 2938 free(data_to_verify.Data); 2939 2940 if (signed_data.Data != NULL) 2941 free(signed_data.Data); 2942 2943 if (signed_cert) { 2944 kmf_free_signed_cert(signed_cert); 2945 free(signed_cert); 2946 } 2947 if (algid == KMF_ALGID_SHA1WithDSA) { 2948 free(signature.Data); 2949 } 2950 2951 kmf_free_algoid(&spki.algorithm); 2952 kmf_free_data(&spki.subjectPublicKey); 2953 2954 return (ret); 2955 } 2956 2957 /* 2958 * Use a signer cert to verify another certificate's signature. 2959 * This code forces the use of the OPENSSL mechanism 2960 * for the verify operation to avoid a circular dependency 2961 * with libelfsign when it attempts to verify the PKCS#11 libraries. 2962 */ 2963 static KMF_RETURN 2964 verify_cert_with_cert(KMF_HANDLE_T handle, 2965 const KMF_DATA *CertToBeVerifiedData, 2966 const KMF_DATA *SignerCertData) 2967 { 2968 KMF_RETURN ret = KMF_OK; 2969 KMF_X509_CERTIFICATE *SignerCert = NULL; 2970 KMF_X509_CERTIFICATE *ToBeVerifiedCert = NULL; 2971 KMF_DATA data_to_verify = {0, NULL}; 2972 KMF_DATA signed_data = {0, NULL}; 2973 KMF_DATA signature; 2974 KMF_ALGORITHM_INDEX algid; 2975 2976 if (!CertToBeVerifiedData || 2977 !CertToBeVerifiedData->Data || 2978 !CertToBeVerifiedData->Length) 2979 return (KMF_ERR_BAD_PARAMETER); 2980 2981 if (!SignerCertData || 2982 !SignerCertData->Data || 2983 !SignerCertData->Length) 2984 return (KMF_ERR_BAD_PARAMETER); 2985 2986 /* Make sure the signer has proper key usage bits */ 2987 ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_CERT); 2988 if (ret != KMF_OK) 2989 return (ret); 2990 2991 /* Decode the cert into parts for verification */ 2992 ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerifiedData, 2993 &data_to_verify, &signed_data); 2994 if (ret != KMF_OK) 2995 goto cleanup; 2996 2997 /* Decode the to-be-verified cert so we know what algorithm to use */ 2998 ret = DerDecodeSignedCertificate(CertToBeVerifiedData, 2999 &ToBeVerifiedCert); 3000 3001 if (ret != KMF_OK) 3002 goto cleanup; 3003 3004 algid = x509_algoid_to_algid(CERT_SIG_OID(ToBeVerifiedCert)); 3005 3006 if (algid == KMF_ALGID_SHA1WithDSA) { 3007 ret = DerDecodeDSASignature(&signed_data, &signature); 3008 if (ret != KMF_OK) 3009 goto cleanup; 3010 } else { 3011 signature.Data = signed_data.Data; 3012 signature.Length = signed_data.Length; 3013 } 3014 3015 /* 3016 * To avoid recursion with kcfd consumer and libpkcs11, 3017 * do the certificate verification using the OpenSSL 3018 * plugin algorithms instead of the crypto framework. 3019 */ 3020 ret = plugin_verify_data_with_cert(handle, KMF_KEYSTORE_OPENSSL, 3021 algid, &data_to_verify, &signature, SignerCertData); 3022 3023 cleanup: 3024 kmf_free_data(&data_to_verify); 3025 kmf_free_data(&signed_data); 3026 3027 if (SignerCert) { 3028 kmf_free_signed_cert(SignerCert); 3029 free(SignerCert); 3030 } 3031 3032 if (ToBeVerifiedCert) { 3033 kmf_free_signed_cert(ToBeVerifiedCert); 3034 free(ToBeVerifiedCert); 3035 } 3036 3037 if (algid == KMF_ALGID_SHA1WithDSA) { 3038 free(signature.Data); 3039 } 3040 3041 return (ret); 3042 } 3043 3044 /* 3045 * Phase 1 APIs still needed to maintain compat with elfsign. 3046 */ 3047 KMF_RETURN 3048 KMF_VerifyDataWithCert(KMF_HANDLE_T handle, 3049 KMF_KEYSTORE_TYPE kstype, 3050 KMF_ALGORITHM_INDEX algid, 3051 KMF_DATA *indata, 3052 KMF_DATA *insig, 3053 const KMF_DATA *SignerCert) 3054 { 3055 KMF_ATTRIBUTE attrlist[8]; 3056 int numattr = 0; 3057 3058 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 3059 &kstype, sizeof (kstype)); 3060 numattr++; 3061 3062 kmf_set_attr_at_index(attrlist, numattr, KMF_DATA_ATTR, 3063 indata, sizeof (KMF_DATA)); 3064 numattr++; 3065 3066 kmf_set_attr_at_index(attrlist, numattr, KMF_IN_SIGN_ATTR, 3067 insig, sizeof (KMF_DATA)); 3068 numattr++; 3069 3070 kmf_set_attr_at_index(attrlist, numattr, KMF_SIGNER_CERT_DATA_ATTR, 3071 (KMF_DATA *)SignerCert, sizeof (KMF_DATA)); 3072 numattr++; 3073 3074 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR, 3075 &algid, sizeof (algid)); 3076 numattr++; 3077 3078 return (kmf_verify_data(handle, numattr, attrlist)); 3079 } 3080 3081 KMF_RETURN 3082 KMF_VerifyCertWithCert(KMF_HANDLE_T handle, 3083 const KMF_DATA *CertToBeVerified, 3084 const KMF_DATA *SignerCert) 3085 { 3086 KMF_RETURN ret; 3087 if (CertToBeVerified == NULL || SignerCert == NULL) 3088 return (KMF_ERR_BAD_PARAMETER); 3089 3090 /* check the keyUsage of signer's certificate */ 3091 ret = check_key_usage(handle, SignerCert, KMF_KU_SIGN_CERT); 3092 if (ret != KMF_OK) 3093 return (ret); 3094 3095 return (verify_cert_with_cert(handle, CertToBeVerified, 3096 SignerCert)); 3097 } 3098 3099 KMF_RETURN 3100 KMF_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *target, 3101 KMF_X509_DER_CERT *kmf_cert, 3102 uint32_t *num_certs) 3103 { 3104 KMF_ATTRIBUTE attrlist[32]; 3105 int i = 0; 3106 3107 if (target == NULL || num_certs == NULL) 3108 return (KMF_ERR_BAD_PARAMETER); /* ILLEGAL ARGS ERROR */ 3109 3110 if ((target->find_cert_validity < KMF_ALL_CERTS) || 3111 (target->find_cert_validity > KMF_EXPIRED_CERTS)) 3112 return (KMF_ERR_BAD_PARAMETER); 3113 3114 kmf_set_attr_at_index(attrlist, i, 3115 KMF_KEYSTORE_TYPE_ATTR, &target->kstype, sizeof (target->kstype)); 3116 i++; 3117 3118 if (kmf_cert != NULL) { 3119 kmf_set_attr_at_index(attrlist, i, 3120 KMF_X509_DER_CERT_ATTR, kmf_cert, 3121 sizeof (KMF_X509_DER_CERT)); 3122 i++; 3123 } 3124 3125 kmf_set_attr_at_index(attrlist, i, 3126 KMF_COUNT_ATTR, num_certs, sizeof (uint32_t)); 3127 i++; 3128 3129 /* Set the optional searching attributes for all 3 plugins. */ 3130 if (target->issuer != NULL) { 3131 kmf_set_attr_at_index(attrlist, i, KMF_ISSUER_NAME_ATTR, 3132 target->issuer, strlen(target->issuer)); 3133 i++; 3134 } 3135 if (target->subject != NULL) { 3136 kmf_set_attr_at_index(attrlist, i, KMF_SUBJECT_NAME_ATTR, 3137 target->subject, strlen(target->subject)); 3138 i++; 3139 } 3140 if (target->serial != NULL) { 3141 kmf_set_attr_at_index(attrlist, i, KMF_BIGINT_ATTR, 3142 target->serial, sizeof (KMF_BIGINT)); 3143 i++; 3144 } 3145 3146 kmf_set_attr_at_index(attrlist, i, KMF_CERT_VALIDITY_ATTR, 3147 &target->find_cert_validity, sizeof (KMF_CERT_VALIDITY)); 3148 i++; 3149 3150 if (target->kstype == KMF_KEYSTORE_NSS) { 3151 if (target->certLabel != NULL) { 3152 kmf_set_attr_at_index(attrlist, i, 3153 KMF_CERT_LABEL_ATTR, 3154 target->certLabel, strlen(target->certLabel)); 3155 i++; 3156 } 3157 3158 if (target->nssparms.slotlabel != NULL) { 3159 kmf_set_attr_at_index(attrlist, i, 3160 KMF_TOKEN_LABEL_ATTR, 3161 target->nssparms.slotlabel, 3162 strlen(target->nssparms.slotlabel)); 3163 i++; 3164 } 3165 3166 } else if (target->kstype == KMF_KEYSTORE_OPENSSL) { 3167 if (target->sslparms.certfile != NULL) { 3168 kmf_set_attr_at_index(attrlist, i, 3169 KMF_CERT_FILENAME_ATTR, 3170 target->sslparms.certfile, 3171 strlen(target->sslparms.certfile)); 3172 i++; 3173 } 3174 3175 if (target->sslparms.dirpath != NULL) { 3176 kmf_set_attr_at_index(attrlist, i, 3177 KMF_DIRPATH_ATTR, 3178 target->sslparms.dirpath, 3179 strlen(target->sslparms.dirpath)); 3180 i++; 3181 } 3182 3183 } else if (target->kstype == KMF_KEYSTORE_PK11TOKEN) { 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 kmf_set_attr_at_index(attrlist, i, KMF_PRIVATE_BOOL_ATTR, 3192 &target->pkcs11parms.private, 3193 sizeof (target->pkcs11parms.private)); 3194 i++; 3195 } 3196 3197 return (kmf_find_cert(handle, i, attrlist)); 3198 } 3199