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