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 = {NULL, 0}; 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 ret = kmf_hexstr_to_bytes((uchar_t *)policy->ta_serial, 2279 &bytes, &bytelen); 2280 if (ret != KMF_OK || bytes == NULL) { 2281 ret = KMF_ERR_TA_POLICY; 2282 goto out; 2283 } 2284 serial.val = bytes; 2285 serial.len = bytelen; 2286 2287 /* set up fc_attrlist for kmf_find_cert */ 2288 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR, 2289 kstype, sizeof (KMF_KEYSTORE_TYPE)); 2290 fc_numattr++; 2291 2292 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR, 2293 ta_name, strlen(ta_name)); 2294 fc_numattr++; 2295 2296 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR, 2297 &serial, sizeof (KMF_BIGINT)); 2298 fc_numattr++; 2299 2300 if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) { 2301 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2302 KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel)); 2303 fc_numattr++; 2304 } 2305 2306 if (*kstype == KMF_KEYSTORE_OPENSSL) { 2307 if (dirpath == NULL) { 2308 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2309 KMF_DIRPATH_ATTR, dir, strlen(dir)); 2310 fc_numattr++; 2311 } else { 2312 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2313 KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); 2314 fc_numattr++; 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 fc_numattr++; 2322 2323 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 2324 if (ret != KMF_OK || num != 1) { 2325 if (num == 0) 2326 ret = KMF_ERR_CERT_NOT_FOUND; 2327 if (num > 1) 2328 ret = KMF_ERR_CERT_MULTIPLE_FOUND; 2329 goto out; 2330 } 2331 2332 kmf_set_attr_at_index(fc_attrlist, fc_numattr, 2333 KMF_X509_DER_CERT_ATTR, &ta_retrCert, sizeof (KMF_X509_DER_CERT)); 2334 fc_numattr++; 2335 2336 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist); 2337 if (ret == KMF_OK) { 2338 ta_cert->Length = ta_retrCert.certificate.Length; 2339 ta_cert->Data = malloc(ta_retrCert.certificate.Length); 2340 if (ta_cert->Data == NULL) { 2341 ret = KMF_ERR_MEMORY; 2342 goto out; 2343 } 2344 (void) memcpy(ta_cert->Data, ta_retrCert.certificate.Data, 2345 ta_retrCert.certificate.Length); 2346 } else { 2347 goto out; 2348 } 2349 2350 /* 2351 * The found TA's name must be matching with issuer name in 2352 * subscriber's certificate. 2353 */ 2354 (void) memset(&ta_subjectDN, 0, sizeof (ta_subjectDN)); 2355 2356 ret = kmf_get_cert_subject_str(handle, ta_cert, &ta_subject); 2357 if (ret != KMF_OK) 2358 goto out; 2359 2360 ret = kmf_dn_parser(ta_subject, &ta_subjectDN); 2361 if (ret != KMF_OK) 2362 goto out; 2363 2364 if (kmf_compare_rdns(user_issuerDN, &ta_subjectDN) != 0) 2365 ret = KMF_ERR_CERT_NOT_FOUND; 2366 2367 kmf_free_dn(&ta_subjectDN); 2368 2369 /* Make sure the TA cert has the correct extensions */ 2370 if (ret == KMF_OK) { 2371 ret = check_key_usage(handle, ta_cert, KMF_KU_SIGN_CERT); 2372 if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0) 2373 ret = KMF_OK; 2374 } 2375 out: 2376 if (ta_retrCert.certificate.Data) 2377 kmf_free_kmf_cert(handle, &ta_retrCert); 2378 2379 if ((ret != KMF_OK) && (ta_cert->Data != NULL)) 2380 free(ta_cert->Data); 2381 2382 if (serial.val != NULL) 2383 free(serial.val); 2384 2385 if (ta_subject) 2386 free(ta_subject); 2387 2388 return (ret); 2389 } 2390 2391 KMF_RETURN 2392 kmf_validate_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 2393 { 2394 KMF_RETURN ret = KMF_OK; 2395 KMF_KEYSTORE_TYPE *kstype = NULL; 2396 KMF_DATA *pcert = NULL; 2397 int *result = NULL; 2398 char *slotlabel = NULL; 2399 char *dirpath = NULL; 2400 KMF_DATA *ocsp_response = NULL; 2401 KMF_DATA ta_cert = {0, NULL}; 2402 KMF_DATA issuer_cert = {0, NULL}; 2403 char *user_issuer = NULL, *user_subject = NULL; 2404 KMF_X509_NAME user_issuerDN, user_subjectDN; 2405 boolean_t self_signed = B_FALSE; 2406 KMF_POLICY_RECORD *policy; 2407 2408 KMF_ATTRIBUTE_TESTER required_attrs[] = { 2409 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 2410 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, 2411 {KMF_VALIDATE_RESULT_ATTR, FALSE, 1, sizeof (int)} 2412 }; 2413 int num_req_attrs = sizeof (required_attrs) / 2414 sizeof (KMF_ATTRIBUTE_TESTER); 2415 2416 if (handle == NULL) 2417 return (KMF_ERR_BAD_PARAMETER); 2418 2419 CLEAR_ERROR(handle, ret); 2420 2421 ret = test_attributes(num_req_attrs, required_attrs, 2422 0, NULL, numattr, attrlist); 2423 if (ret != KMF_OK) 2424 return (ret); 2425 2426 policy = handle->policy; 2427 2428 /* Get the attribute values */ 2429 kstype = kmf_get_attr_ptr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr); 2430 pcert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 2431 result = kmf_get_attr_ptr(KMF_VALIDATE_RESULT_ATTR, attrlist, numattr); 2432 if (kstype == NULL || pcert == NULL || result == NULL) 2433 return (KMF_ERR_BAD_PARAMETER); 2434 2435 slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr); 2436 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 2437 ocsp_response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, attrlist, 2438 numattr); 2439 2440 /* Initialize the returned result */ 2441 *result = KMF_CERT_VALIDATE_OK; 2442 2443 /* 2444 * Get the issuer information from the input certficate first. 2445 */ 2446 if ((ret = kmf_get_cert_issuer_str(handle, pcert, 2447 &user_issuer)) != KMF_OK) { 2448 *result |= KMF_CERT_VALIDATE_ERR_USER; 2449 goto out; 2450 } 2451 2452 if ((ret = kmf_dn_parser(user_issuer, &user_issuerDN)) != KMF_OK) { 2453 *result |= KMF_CERT_VALIDATE_ERR_USER; 2454 goto out; 2455 } 2456 2457 /* 2458 * Check if the certificate is a self-signed cert. 2459 */ 2460 if ((ret = kmf_get_cert_subject_str(handle, pcert, 2461 &user_subject)) != KMF_OK) { 2462 *result |= KMF_CERT_VALIDATE_ERR_USER; 2463 kmf_free_dn(&user_issuerDN); 2464 goto out; 2465 } 2466 2467 if ((ret = kmf_dn_parser(user_subject, &user_subjectDN)) != KMF_OK) { 2468 *result |= KMF_CERT_VALIDATE_ERR_USER; 2469 kmf_free_dn(&user_issuerDN); 2470 goto out; 2471 } 2472 2473 if ((kmf_compare_rdns(&user_issuerDN, &user_subjectDN)) == 0) { 2474 /* 2475 * this is a self-signed cert 2476 */ 2477 self_signed = B_TRUE; 2478 } 2479 2480 kmf_free_dn(&user_subjectDN); 2481 2482 /* 2483 * Check KeyUsage extension of the subscriber's certificate 2484 */ 2485 ret = cert_ku_check(handle, pcert); 2486 if (ret != KMF_OK) { 2487 *result |= KMF_CERT_VALIDATE_ERR_KEYUSAGE; 2488 goto out; 2489 } 2490 2491 /* 2492 * Validate Extended KeyUsage extension 2493 */ 2494 ret = cert_eku_check(handle, pcert); 2495 if (ret != KMF_OK) { 2496 *result |= KMF_CERT_VALIDATE_ERR_EXT_KEYUSAGE; 2497 goto out; 2498 } 2499 2500 /* 2501 * Check the certificate's validity period 2502 * 2503 * This step is needed when "ignore_date" in policy is set 2504 * to false. 2505 */ 2506 if (!policy->ignore_date) { 2507 /* 2508 * Validate expiration date 2509 */ 2510 ret = kmf_check_cert_date(handle, pcert); 2511 if (ret != KMF_OK) { 2512 *result |= KMF_CERT_VALIDATE_ERR_TIME; 2513 goto out; 2514 } 2515 } 2516 2517 /* 2518 * When "ignore_trust_anchor" in policy is set to FALSE, 2519 * we will try to find the TA cert based on the TA policy 2520 * attributes. 2521 * 2522 * TA's subject name (ta_name) and serial number (ta_serial) 2523 * are defined as optional attributes in policy dtd, but they 2524 * should exist in policy when "ignore_trust_anchor" is set 2525 * to FALSE. The policy verification code has enforced that. 2526 */ 2527 if (policy->ignore_trust_anchor) { 2528 goto check_revocation; 2529 } 2530 2531 /* 2532 * Verify the signature of subscriber's certificate using 2533 * TA certificate. 2534 */ 2535 if (self_signed) { 2536 ret = verify_cert_with_cert(handle, pcert, pcert); 2537 } else { 2538 ret = find_ta_cert(handle, kstype, &ta_cert, 2539 &user_issuerDN, slotlabel, dirpath); 2540 if (ret != KMF_OK) { 2541 *result |= KMF_CERT_VALIDATE_ERR_TA; 2542 goto out; 2543 } 2544 2545 ret = verify_cert_with_cert(handle, pcert, &ta_cert); 2546 } 2547 if (ret != KMF_OK) { 2548 *result |= KMF_CERT_VALIDATE_ERR_SIGNATURE; 2549 goto out; 2550 } 2551 2552 check_revocation: 2553 /* 2554 * Check certificate revocation 2555 */ 2556 if (self_signed) { 2557 /* skip revocation checking */ 2558 goto out; 2559 } 2560 2561 /* 2562 * When CRL or OCSP revocation method is set in the policy, 2563 * we will try to find the issuer of the subscriber certificate 2564 * using the issuer name of the subscriber certificate. The 2565 * issuer certificate will be used to do the CRL checking 2566 * and OCSP checking. 2567 */ 2568 if (!(policy->revocation & KMF_REVOCATION_METHOD_CRL) && 2569 !(policy->revocation & KMF_REVOCATION_METHOD_OCSP)) { 2570 goto out; 2571 } 2572 2573 ret = find_issuer_cert(handle, kstype, user_issuer, &issuer_cert, 2574 slotlabel, dirpath); 2575 if (ret != KMF_OK) { 2576 *result |= KMF_CERT_VALIDATE_ERR_ISSUER; 2577 goto out; 2578 } 2579 2580 if (policy->revocation & KMF_REVOCATION_METHOD_CRL) { 2581 ret = cert_crl_check(handle, kstype, pcert, &issuer_cert); 2582 if (ret != KMF_OK) { 2583 *result |= KMF_CERT_VALIDATE_ERR_CRL; 2584 goto out; 2585 } 2586 } 2587 2588 if (policy->revocation & KMF_REVOCATION_METHOD_OCSP) { 2589 ret = cert_ocsp_check(handle, kstype, pcert, &issuer_cert, 2590 ocsp_response, slotlabel, dirpath); 2591 if (ret != KMF_OK) { 2592 *result |= KMF_CERT_VALIDATE_ERR_OCSP; 2593 goto out; 2594 } 2595 } 2596 2597 out: 2598 if (user_issuer) { 2599 kmf_free_dn(&user_issuerDN); 2600 free(user_issuer); 2601 } 2602 2603 if (user_subject) 2604 free(user_subject); 2605 2606 if (ta_cert.Data) 2607 free(ta_cert.Data); 2608 2609 if (issuer_cert.Data) 2610 free(issuer_cert.Data); 2611 2612 return (ret); 2613 2614 } 2615 2616 KMF_RETURN 2617 kmf_create_cert_file(const KMF_DATA *certdata, KMF_ENCODE_FORMAT format, 2618 char *certfile) 2619 { 2620 KMF_RETURN rv = KMF_OK; 2621 int fd = -1; 2622 KMF_DATA pemdata = {NULL, 0}; 2623 2624 if (certdata == NULL || certfile == NULL) 2625 return (KMF_ERR_BAD_PARAMETER); 2626 2627 if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1) 2628 return (KMF_ERR_BAD_PARAMETER); 2629 2630 if (format == KMF_FORMAT_PEM) { 2631 int len; 2632 rv = kmf_der_to_pem(KMF_CERT, 2633 certdata->Data, certdata->Length, 2634 &pemdata.Data, &len); 2635 if (rv != KMF_OK) 2636 goto cleanup; 2637 pemdata.Length = (size_t)len; 2638 } 2639 2640 if ((fd = open(certfile, O_CREAT | O_RDWR | O_TRUNC, 0644)) == -1) { 2641 rv = KMF_ERR_OPEN_FILE; 2642 goto cleanup; 2643 } 2644 2645 if (format == KMF_FORMAT_PEM) { 2646 if (write(fd, pemdata.Data, pemdata.Length) != 2647 pemdata.Length) { 2648 rv = KMF_ERR_WRITE_FILE; 2649 } 2650 } else { 2651 if (write(fd, certdata->Data, certdata->Length) != 2652 certdata->Length) { 2653 rv = KMF_ERR_WRITE_FILE; 2654 } 2655 } 2656 2657 cleanup: 2658 if (fd != -1) 2659 (void) close(fd); 2660 2661 kmf_free_data(&pemdata); 2662 2663 return (rv); 2664 } 2665 2666 /* 2667 * kmf_is_cert_data 2668 * 2669 * Determine if a KMF_DATA buffer contains an encoded X.509 certificate. 2670 * 2671 * Return: 2672 * KMF_OK if it is a certificate 2673 * KMF_ERR_ENCODING (or other error) if not. 2674 */ 2675 KMF_RETURN 2676 kmf_is_cert_data(KMF_DATA *data, KMF_ENCODE_FORMAT *fmt) 2677 { 2678 KMF_RETURN rv = KMF_OK; 2679 KMF_X509_CERTIFICATE *x509 = NULL; 2680 KMF_DATA oldpem = {0, NULL}; 2681 uchar_t *d = NULL; 2682 int len = 0; 2683 2684 if (data == NULL || fmt == NULL) 2685 return (KMF_ERR_BAD_PARAMETER); 2686 2687 rv = kmf_get_data_format(data, fmt); 2688 if (rv != KMF_OK) 2689 return (rv); 2690 switch (*fmt) { 2691 case KMF_FORMAT_ASN1: 2692 rv = DerDecodeSignedCertificate(data, &x509); 2693 break; 2694 case KMF_FORMAT_PEM: 2695 /* Convert to ASN.1 DER first */ 2696 rv = kmf_pem_to_der(data->Data, data->Length, 2697 &d, &len); 2698 if (rv != KMF_OK) 2699 return (rv); 2700 oldpem.Data = d; 2701 oldpem.Length = len; 2702 rv = DerDecodeSignedCertificate(&oldpem, &x509); 2703 kmf_free_data(&oldpem); 2704 break; 2705 case KMF_FORMAT_PKCS12: 2706 case KMF_FORMAT_UNDEF: 2707 default: 2708 return (KMF_ERR_ENCODING); 2709 } 2710 2711 if (x509 != NULL) { 2712 kmf_free_signed_cert(x509); 2713 free(x509); 2714 } 2715 return (rv); 2716 } 2717 2718 KMF_RETURN 2719 kmf_is_cert_file(KMF_HANDLE_T handle, char *filename, 2720 KMF_ENCODE_FORMAT *pformat) 2721 { 2722 KMF_RETURN ret; 2723 KMF_DATA filedata; 2724 2725 CLEAR_ERROR(handle, ret); 2726 if (ret != KMF_OK) 2727 return (ret); 2728 2729 if (filename == NULL || pformat == NULL) 2730 return (KMF_ERR_BAD_PARAMETER); 2731 2732 ret = kmf_read_input_file(handle, filename, &filedata); 2733 if (ret != KMF_OK) 2734 return (ret); 2735 2736 ret = kmf_is_cert_data(&filedata, pformat); 2737 if (ret == KMF_ERR_BAD_CERT_FORMAT) 2738 ret = KMF_ERR_BAD_CERTFILE; 2739 2740 kmf_free_data(&filedata); 2741 return (ret); 2742 } 2743 2744 /* 2745 * This function checks the validity period of a der-encoded certificate. 2746 */ 2747 KMF_RETURN 2748 kmf_check_cert_date(KMF_HANDLE_T handle, const KMF_DATA *cert) 2749 { 2750 KMF_RETURN rv; 2751 struct tm *gmt; 2752 time_t t_now; 2753 time_t t_notbefore; 2754 time_t t_notafter; 2755 KMF_POLICY_RECORD *policy; 2756 uint32_t adj; 2757 2758 CLEAR_ERROR(handle, rv); 2759 if (rv != KMF_OK) 2760 return (rv); 2761 2762 if (cert == NULL || cert->Data == NULL || cert->Length == 0) 2763 return (KMF_ERR_BAD_PARAMETER); 2764 2765 policy = handle->policy; 2766 rv = kmf_get_cert_validity(cert, &t_notbefore, &t_notafter); 2767 if (rv != KMF_OK) 2768 return (rv); 2769 2770 /* 2771 * Get the current time. The time returned from time() is local which 2772 * cannot be used directly. It must be converted to UTC/GMT first. 2773 */ 2774 t_now = time(NULL); 2775 gmt = gmtime(&t_now); 2776 t_now = mktime(gmt); 2777 2778 /* 2779 * Adjust the validity time 2780 */ 2781 if (policy->validity_adjusttime != NULL) { 2782 if (str2lifetime(policy->validity_adjusttime, &adj) < 0) 2783 return (KMF_ERR_VALIDITY_PERIOD); 2784 } else { 2785 adj = 0; 2786 } 2787 2788 t_notafter += adj; 2789 t_notbefore -= adj; 2790 2791 if (t_now <= t_notafter && t_now >= t_notbefore) { 2792 rv = KMF_OK; 2793 } else { 2794 rv = KMF_ERR_VALIDITY_PERIOD; 2795 } 2796 2797 return (rv); 2798 } 2799 2800 KMF_RETURN 2801 kmf_export_pk12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 2802 { 2803 KMF_PLUGIN *plugin; 2804 KMF_RETURN ret = KMF_OK; 2805 KMF_KEYSTORE_TYPE kstype; 2806 2807 KMF_ATTRIBUTE_TESTER required_attrs[] = { 2808 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 2809 {KMF_OUTPUT_FILENAME_ATTR, TRUE, 1, 0}, 2810 }; 2811 2812 int num_req_attrs = sizeof (required_attrs) / 2813 sizeof (KMF_ATTRIBUTE_TESTER); 2814 2815 if (handle == NULL) 2816 return (KMF_ERR_BAD_PARAMETER); 2817 2818 CLEAR_ERROR(handle, ret); 2819 2820 ret = test_attributes(num_req_attrs, required_attrs, 0, NULL, 2821 numattr, attrlist); 2822 if (ret != KMF_OK) 2823 return (ret); 2824 2825 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, 2826 &kstype, NULL); 2827 if (ret != KMF_OK) 2828 return (ret); 2829 2830 plugin = FindPlugin(handle, kstype); 2831 if (plugin == NULL || plugin->funclist->ExportPK12 == NULL) 2832 return (KMF_ERR_PLUGIN_NOTFOUND); 2833 2834 return (plugin->funclist->ExportPK12(handle, numattr, attrlist)); 2835 } 2836 2837 2838 KMF_RETURN 2839 kmf_build_pk12(KMF_HANDLE_T handle, int numcerts, 2840 KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist, 2841 KMF_CREDENTIAL *p12cred, char *filename) 2842 { 2843 KMF_RETURN rv; 2844 KMF_PLUGIN *plugin; 2845 KMF_RETURN (*buildpk12)(KMF_HANDLE *, int, KMF_X509_DER_CERT *, 2846 int, KMF_KEY_HANDLE *, KMF_CREDENTIAL *, char *); 2847 2848 CLEAR_ERROR(handle, rv); 2849 if (rv != KMF_OK) 2850 return (rv); 2851 2852 if (filename == NULL || p12cred == NULL || 2853 (certlist == NULL && keylist == NULL)) 2854 return (KMF_ERR_BAD_PARAMETER); 2855 2856 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 2857 if (plugin == NULL || plugin->dldesc == NULL) { 2858 return (KMF_ERR_PLUGIN_NOTFOUND); 2859 } 2860 2861 buildpk12 = (KMF_RETURN(*)())dlsym(plugin->dldesc, 2862 "openssl_build_pk12"); 2863 if (buildpk12 == NULL) { 2864 return (KMF_ERR_FUNCTION_NOT_FOUND); 2865 } 2866 2867 rv = buildpk12(handle, numcerts, certlist, numkeys, keylist, p12cred, 2868 filename); 2869 2870 return (rv); 2871 } 2872 2873 2874 KMF_RETURN 2875 kmf_import_objects(KMF_HANDLE_T handle, char *filename, 2876 KMF_CREDENTIAL *cred, 2877 KMF_X509_DER_CERT **certs, int *ncerts, 2878 KMF_RAW_KEY_DATA **rawkeys, int *nkeys) 2879 { 2880 KMF_RETURN rv; 2881 KMF_PLUGIN *plugin; 2882 KMF_RETURN (*import_objects)(KMF_HANDLE *, char *, KMF_CREDENTIAL *, 2883 KMF_X509_DER_CERT **, int *, KMF_RAW_KEY_DATA **, int *); 2884 2885 CLEAR_ERROR(handle, rv); 2886 if (rv != KMF_OK) 2887 return (rv); 2888 2889 if (filename == NULL || cred == NULL || certs == NULL || 2890 ncerts == NULL ||rawkeys == NULL || nkeys == NULL) 2891 return (KMF_ERR_BAD_PARAMETER); 2892 2893 /* 2894 * Use the Keypair reader from the OpenSSL plugin. 2895 */ 2896 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 2897 if (plugin == NULL || plugin->dldesc == NULL) { 2898 return (KMF_ERR_PLUGIN_NOTFOUND); 2899 } 2900 2901 import_objects = (KMF_RETURN(*)())dlsym(plugin->dldesc, 2902 "openssl_import_objects"); 2903 if (import_objects == NULL) { 2904 return (KMF_ERR_FUNCTION_NOT_FOUND); 2905 } 2906 2907 /* Use OpenSSL interfaces to get raw key and cert data */ 2908 rv = import_objects(handle, filename, cred, certs, ncerts, 2909 rawkeys, nkeys); 2910 2911 return (rv); 2912 } 2913 2914 KMF_BOOL 2915 IsEqualOid(KMF_OID *Oid1, KMF_OID *Oid2) 2916 { 2917 return ((Oid1->Length == Oid2->Length) && 2918 !memcmp(Oid1->Data, Oid2->Data, Oid1->Length)); 2919 } 2920 2921 static KMF_RETURN 2922 set_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, 2923 KMF_OID *newoid) 2924 { 2925 if (destid == NULL || newoid == NULL) 2926 return (KMF_ERR_BAD_PARAMETER); 2927 2928 destid->algorithm.Length = newoid->Length; 2929 destid->algorithm.Data = malloc(destid->algorithm.Length); 2930 if (destid->algorithm.Data == NULL) 2931 return (KMF_ERR_MEMORY); 2932 2933 (void) memcpy(destid->algorithm.Data, newoid->Data, 2934 destid->algorithm.Length); 2935 2936 return (KMF_OK); 2937 } 2938 2939 KMF_RETURN 2940 copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, 2941 KMF_X509_ALGORITHM_IDENTIFIER *srcid) 2942 { 2943 KMF_RETURN ret = KMF_OK; 2944 if (!destid || !srcid) 2945 return (KMF_ERR_BAD_PARAMETER); 2946 2947 destid->algorithm.Length = srcid->algorithm.Length; 2948 destid->algorithm.Data = malloc(destid->algorithm.Length); 2949 if (destid->algorithm.Data == NULL) 2950 return (KMF_ERR_MEMORY); 2951 2952 (void) memcpy(destid->algorithm.Data, srcid->algorithm.Data, 2953 destid->algorithm.Length); 2954 2955 destid->parameters.Length = srcid->parameters.Length; 2956 if (destid->parameters.Length > 0) { 2957 destid->parameters.Data = malloc(destid->parameters.Length); 2958 if (destid->parameters.Data == NULL) 2959 return (KMF_ERR_MEMORY); 2960 2961 (void) memcpy(destid->parameters.Data, srcid->parameters.Data, 2962 destid->parameters.Length); 2963 } else { 2964 destid->parameters.Data = NULL; 2965 } 2966 return (ret); 2967 } 2968 2969 static KMF_RETURN 2970 sign_cert(KMF_HANDLE_T handle, 2971 const KMF_DATA *SubjectCert, 2972 KMF_KEY_HANDLE *Signkey, 2973 KMF_OID *signature_oid, 2974 KMF_DATA *SignedCert) 2975 { 2976 KMF_X509_CERTIFICATE *subj_cert = NULL; 2977 KMF_DATA data_to_sign = {0, NULL}; 2978 KMF_DATA signed_data = {0, NULL}; 2979 KMF_RETURN ret = KMF_OK; 2980 KMF_ALGORITHM_INDEX algid; 2981 int i = 0; 2982 KMF_ATTRIBUTE attrlist[8]; 2983 2984 if (!SignedCert) 2985 return (KMF_ERR_BAD_PARAMETER); 2986 2987 SignedCert->Length = 0; 2988 SignedCert->Data = NULL; 2989 2990 if (!SubjectCert) 2991 return (KMF_ERR_BAD_PARAMETER); 2992 2993 if (!SubjectCert->Data || !SubjectCert->Length) 2994 return (KMF_ERR_BAD_PARAMETER); 2995 2996 /* 2997 * Shortcut - just extract the already encoded TBS cert data from 2998 * the original data buffer. Since we haven't changed anything, 2999 * there is no need to re-encode it. 3000 */ 3001 ret = ExtractX509CertParts((KMF_DATA *)SubjectCert, 3002 &data_to_sign, NULL); 3003 if (ret != KMF_OK) { 3004 goto cleanup; 3005 } 3006 3007 /* Estimate the signed data length generously */ 3008 signed_data.Length = data_to_sign.Length*2; 3009 signed_data.Data = calloc(1, signed_data.Length); 3010 if (!signed_data.Data) { 3011 ret = KMF_ERR_MEMORY; 3012 goto cleanup; 3013 } 3014 3015 /* 3016 * If we got here OK, decode into a structure and then re-encode 3017 * the complete certificate. 3018 */ 3019 ret = DerDecodeSignedCertificate(SubjectCert, &subj_cert); 3020 if (ret != KMF_OK) { 3021 goto cleanup; 3022 } 3023 3024 /* We are re-signing this cert, so clear out old signature data */ 3025 if (!IsEqualOid(&subj_cert->signature.algorithmIdentifier.algorithm, 3026 signature_oid)) { 3027 kmf_free_algoid(&subj_cert->signature.algorithmIdentifier); 3028 ret = set_algoid(&subj_cert->signature.algorithmIdentifier, 3029 signature_oid); 3030 if (ret != KMF_OK) 3031 goto cleanup; 3032 ret = set_algoid(&subj_cert->certificate.signature, 3033 signature_oid); 3034 if (ret) 3035 goto cleanup; 3036 3037 /* Free the previous "data to be signed" block */ 3038 kmf_free_data(&data_to_sign); 3039 3040 /* 3041 * We changed the cert (updated the signature OID), so we 3042 * need to re-encode it so the correct data gets signed. 3043 */ 3044 ret = DerEncodeTbsCertificate(&subj_cert->certificate, 3045 &data_to_sign); 3046 if (ret != KMF_OK) 3047 goto cleanup; 3048 } 3049 kmf_set_attr_at_index(attrlist, i, KMF_KEYSTORE_TYPE_ATTR, 3050 &Signkey->kstype, sizeof (KMF_KEYSTORE_TYPE)); 3051 i++; 3052 kmf_set_attr_at_index(attrlist, i, KMF_KEY_HANDLE_ATTR, 3053 Signkey, sizeof (KMF_KEY_HANDLE)); 3054 i++; 3055 kmf_set_attr_at_index(attrlist, i, KMF_DATA_ATTR, 3056 &data_to_sign, sizeof (KMF_DATA)); 3057 i++; 3058 kmf_set_attr_at_index(attrlist, i, KMF_OUT_DATA_ATTR, 3059 &signed_data, sizeof (KMF_DATA)); 3060 i++; 3061 kmf_set_attr_at_index(attrlist, i, KMF_OID_ATTR, 3062 signature_oid, sizeof (KMF_OID)); 3063 i++; 3064 3065 /* Sign the data */ 3066 ret = kmf_sign_data(handle, i, attrlist); 3067 3068 if (ret != KMF_OK) 3069 goto cleanup; 3070 3071 algid = x509_algoid_to_algid(signature_oid); 3072 3073 if (algid == KMF_ALGID_SHA1WithECDSA || 3074 algid == KMF_ALGID_SHA256WithECDSA || 3075 algid == KMF_ALGID_SHA384WithECDSA || 3076 algid == KMF_ALGID_SHA512WithECDSA) { 3077 /* ASN.1 encode ECDSA signature */ 3078 KMF_DATA signature; 3079 3080 ret = DerEncodeECDSASignature(&signed_data, &signature); 3081 kmf_free_data(&signed_data); 3082 3083 if (ret != KMF_OK) 3084 goto cleanup; 3085 3086 subj_cert->signature.encrypted = signature; 3087 } else if (algid == KMF_ALGID_SHA1WithDSA || 3088 algid == KMF_ALGID_SHA256WithDSA) { 3089 /* 3090 * For DSA, kmf_sign_data() returns a 40-byte 3091 * signature. We must encode the signature correctly. 3092 */ 3093 KMF_DATA signature; 3094 3095 ret = DerEncodeDSASignature(&signed_data, &signature); 3096 kmf_free_data(&signed_data); 3097 3098 if (ret != KMF_OK) 3099 goto cleanup; 3100 3101 subj_cert->signature.encrypted = signature; 3102 } else { 3103 ret = copy_data(&subj_cert->signature.encrypted, &signed_data); 3104 kmf_free_data(&signed_data); 3105 3106 if (ret != KMF_OK) 3107 goto cleanup; 3108 } 3109 3110 /* Now, re-encode the cert with the new signature */ 3111 ret = DerEncodeSignedCertificate(subj_cert, SignedCert); 3112 3113 cleanup: 3114 /* Cleanup & return */ 3115 if (ret != KMF_OK) 3116 kmf_free_data(SignedCert); 3117 3118 kmf_free_data(&data_to_sign); 3119 3120 if (subj_cert != NULL) { 3121 kmf_free_signed_cert(subj_cert); 3122 free(subj_cert); 3123 } 3124 3125 return (ret); 3126 } 3127 3128 static KMF_RETURN 3129 verify_cert_with_key(KMF_HANDLE_T handle, 3130 KMF_DATA *derkey, 3131 const KMF_DATA *CertToBeVerified) 3132 { 3133 KMF_RETURN ret = KMF_OK; 3134 KMF_X509_CERTIFICATE *signed_cert = NULL; 3135 KMF_X509_SPKI spki; 3136 KMF_DATA data_to_verify = {0, NULL}; 3137 KMF_DATA signed_data = {0, NULL}; 3138 KMF_DATA signature = { 0, NULL }; 3139 KMF_ALGORITHM_INDEX algid; 3140 3141 /* check the caller and do other setup for this SPI call */ 3142 if (handle == NULL || CertToBeVerified == NULL || 3143 derkey == NULL || derkey->Data == NULL) 3144 return (KMF_ERR_BAD_PARAMETER); 3145 3146 (void) memset(&spki, 0, sizeof (KMF_X509_SPKI)); 3147 3148 ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerified, 3149 &data_to_verify, &signed_data); 3150 3151 if (ret != KMF_OK) 3152 goto cleanup; 3153 3154 ret = DerDecodeSPKI(derkey, &spki); 3155 if (ret != KMF_OK) 3156 goto cleanup; 3157 3158 /* Decode the signer cert so we can get the Algorithm data */ 3159 ret = DerDecodeSignedCertificate(CertToBeVerified, &signed_cert); 3160 if (ret != KMF_OK) 3161 return (ret); 3162 3163 algid = x509_algoid_to_algid(CERT_SIG_OID(signed_cert)); 3164 3165 if (algid == KMF_ALGID_NONE) 3166 return (KMF_ERR_BAD_ALGORITHM); 3167 3168 if (algid == KMF_ALGID_SHA1WithDSA || 3169 algid == KMF_ALGID_SHA256WithDSA) { 3170 ret = DerDecodeDSASignature(&signed_data, &signature); 3171 if (ret != KMF_OK) 3172 goto cleanup; 3173 } else if (algid == KMF_ALGID_SHA1WithECDSA || 3174 algid == KMF_ALGID_SHA256WithECDSA || 3175 algid == KMF_ALGID_SHA384WithECDSA || 3176 algid == KMF_ALGID_SHA512WithECDSA) { 3177 ret = DerDecodeECDSASignature(&signed_data, &signature); 3178 if (ret != KMF_OK) 3179 goto cleanup; 3180 } else { 3181 signature.Data = signed_data.Data; 3182 signature.Length = signed_data.Length; 3183 } 3184 3185 ret = PKCS_VerifyData(handle, algid, &spki, 3186 &data_to_verify, &signature); 3187 3188 cleanup: 3189 if (data_to_verify.Data != NULL) 3190 free(data_to_verify.Data); 3191 3192 if (signed_data.Data != NULL) 3193 free(signed_data.Data); 3194 3195 if (signed_cert) { 3196 kmf_free_signed_cert(signed_cert); 3197 free(signed_cert); 3198 } 3199 if (algid == KMF_ALGID_SHA1WithDSA || 3200 algid == KMF_ALGID_SHA256WithDSA || 3201 algid == KMF_ALGID_SHA1WithECDSA || 3202 algid == KMF_ALGID_SHA256WithECDSA || 3203 algid == KMF_ALGID_SHA384WithECDSA || 3204 algid == KMF_ALGID_SHA512WithECDSA) { 3205 free(signature.Data); 3206 } 3207 3208 kmf_free_algoid(&spki.algorithm); 3209 kmf_free_data(&spki.subjectPublicKey); 3210 3211 return (ret); 3212 } 3213 3214 /* 3215 * Use a signer cert to verify another certificate's signature. 3216 * This code forces the use of the PKCS11 mechanism for the verify 3217 * operation for the Cryptographic Framework's FIPS-140 boundary. 3218 */ 3219 static KMF_RETURN 3220 verify_cert_with_cert(KMF_HANDLE_T handle, 3221 const KMF_DATA *CertToBeVerifiedData, 3222 const KMF_DATA *SignerCertData) 3223 { 3224 KMF_RETURN ret = KMF_OK; 3225 KMF_X509_CERTIFICATE *SignerCert = NULL; 3226 KMF_X509_CERTIFICATE *ToBeVerifiedCert = NULL; 3227 KMF_DATA data_to_verify = {0, NULL}; 3228 KMF_DATA signed_data = {0, NULL}; 3229 KMF_DATA signature; 3230 KMF_ALGORITHM_INDEX algid; 3231 KMF_POLICY_RECORD *policy; 3232 3233 if (handle == NULL || 3234 !CertToBeVerifiedData || 3235 !CertToBeVerifiedData->Data || 3236 !CertToBeVerifiedData->Length) 3237 return (KMF_ERR_BAD_PARAMETER); 3238 3239 if (!SignerCertData || 3240 !SignerCertData->Data || 3241 !SignerCertData->Length) 3242 return (KMF_ERR_BAD_PARAMETER); 3243 3244 policy = handle->policy; 3245 3246 /* Make sure the signer has proper key usage bits */ 3247 ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_CERT); 3248 if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0) 3249 ret = KMF_OK; 3250 if (ret != KMF_OK) 3251 return (ret); 3252 3253 /* Decode the cert into parts for verification */ 3254 ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerifiedData, 3255 &data_to_verify, &signed_data); 3256 if (ret != KMF_OK) 3257 goto cleanup; 3258 3259 /* Decode the to-be-verified cert so we know what algorithm to use */ 3260 ret = DerDecodeSignedCertificate(CertToBeVerifiedData, 3261 &ToBeVerifiedCert); 3262 if (ret != KMF_OK) 3263 goto cleanup; 3264 3265 algid = x509_algoid_to_algid(CERT_SIG_OID(ToBeVerifiedCert)); 3266 3267 if (algid == KMF_ALGID_SHA1WithDSA || 3268 algid == KMF_ALGID_SHA256WithDSA) { 3269 ret = DerDecodeDSASignature(&signed_data, &signature); 3270 if (ret != KMF_OK) 3271 goto cleanup; 3272 } else if (algid == KMF_ALGID_SHA1WithECDSA || 3273 algid == KMF_ALGID_SHA256WithECDSA || 3274 algid == KMF_ALGID_SHA384WithECDSA || 3275 algid == KMF_ALGID_SHA512WithECDSA) { 3276 ret = DerDecodeECDSASignature(&signed_data, &signature); 3277 if (ret != KMF_OK) 3278 goto cleanup; 3279 } else { 3280 signature.Data = signed_data.Data; 3281 signature.Length = signed_data.Length; 3282 } 3283 3284 ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert); 3285 if (ret != KMF_OK) 3286 goto cleanup; 3287 3288 /* 3289 * Force use of PKCS11 API for kcfd/libelfsign. This is 3290 * required for the Cryptographic Framework's FIPS-140 boundary. 3291 */ 3292 ret = PKCS_VerifyData(handle, algid, 3293 &SignerCert->certificate.subjectPublicKeyInfo, 3294 &data_to_verify, &signature); 3295 3296 cleanup: 3297 kmf_free_data(&data_to_verify); 3298 kmf_free_data(&signed_data); 3299 3300 if (SignerCert) { 3301 kmf_free_signed_cert(SignerCert); 3302 free(SignerCert); 3303 } 3304 3305 if (ToBeVerifiedCert) { 3306 kmf_free_signed_cert(ToBeVerifiedCert); 3307 free(ToBeVerifiedCert); 3308 } 3309 3310 if (algid == KMF_ALGID_SHA1WithDSA || 3311 algid == KMF_ALGID_SHA256WithDSA || 3312 algid == KMF_ALGID_SHA1WithECDSA || 3313 algid == KMF_ALGID_SHA256WithECDSA || 3314 algid == KMF_ALGID_SHA384WithECDSA || 3315 algid == KMF_ALGID_SHA512WithECDSA) { 3316 free(signature.Data); 3317 } 3318 3319 return (ret); 3320 } 3321