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