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