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