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