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