openssl_spi.c revision 3171:6a9918e92494
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 * OpenSSL keystore wrapper 22 * 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29#include <kmfapiP.h> 30#include <ber_der.h> 31#include <oidsalg.h> 32#include <fcntl.h> 33#include <sys/stat.h> 34#include <dirent.h> 35#include <cryptoutil.h> 36#include <synch.h> 37#include <thread.h> 38 39/* OPENSSL related headers */ 40#include <openssl/bio.h> 41#include <openssl/bn.h> 42#include <openssl/asn1.h> 43#include <openssl/err.h> 44#include <openssl/bn.h> 45#include <openssl/x509.h> 46#include <openssl/rsa.h> 47#include <openssl/dsa.h> 48#include <openssl/x509v3.h> 49#include <openssl/objects.h> 50#include <openssl/pem.h> 51#include <openssl/pkcs12.h> 52#include <openssl/ocsp.h> 53#include <openssl/des.h> 54#include <openssl/rand.h> 55 56#define PRINT_ANY_EXTENSION (\ 57 KMF_X509_EXT_KEY_USAGE |\ 58 KMF_X509_EXT_CERT_POLICIES |\ 59 KMF_X509_EXT_SUBJALTNAME |\ 60 KMF_X509_EXT_BASIC_CONSTRAINTS |\ 61 KMF_X509_EXT_NAME_CONSTRAINTS |\ 62 KMF_X509_EXT_POLICY_CONSTRAINTS |\ 63 KMF_X509_EXT_EXT_KEY_USAGE |\ 64 KMF_X509_EXT_INHIBIT_ANY_POLICY |\ 65 KMF_X509_EXT_AUTH_KEY_ID |\ 66 KMF_X509_EXT_SUBJ_KEY_ID |\ 67 KMF_X509_EXT_POLICY_MAPPING) 68 69static BIO *bio_err = NULL; 70static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 71 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 72 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 73 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 74 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 75 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 76 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 77 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 78 0x91 }; 79 80static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 81 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 82 0x8e, 0xda, 0xce, 0x91, 0x5f }; 83 84static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 85 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 86 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 87 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 88 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 89 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 90 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 91 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 92 0x02 }; 93 94#define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \ 95 h->lasterr.errcode = c; 96 97#define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c; 98 99mutex_t init_lock = DEFAULTMUTEX; 100static int ssl_initialized = 0; 101 102KMF_RETURN 103OpenSSL_FindCert(KMF_HANDLE_T, 104 KMF_FINDCERT_PARAMS *, 105 KMF_X509_DER_CERT *, 106 uint32_t *); 107 108void 109OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); 110 111KMF_RETURN 112OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *, KMF_DATA *); 113 114KMF_RETURN 115OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *); 116 117KMF_RETURN 118OpenSSL_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, 119 KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); 120 121KMF_RETURN 122OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 123 124KMF_RETURN 125OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 126 KMF_DATA *, KMF_DATA *); 127 128KMF_RETURN 129OpenSSL_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, 130 KMF_KEY_HANDLE *, boolean_t); 131 132KMF_RETURN 133OpenSSL_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *); 134 135KMF_RETURN 136OpenSSL_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *); 137 138KMF_RETURN 139OpenSSL_ListCRL(KMF_HANDLE_T, KMF_LISTCRL_PARAMS *, char **); 140 141KMF_RETURN 142OpenSSL_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *); 143 144KMF_RETURN 145OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *, 146 KMF_PRINTABLE_ITEM, char *); 147 148KMF_RETURN 149OpenSSL_GetErrorString(KMF_HANDLE_T, char **); 150 151KMF_RETURN 152OpenSSL_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, 153 KMF_KEY_HANDLE *, KMF_KEY_ALG); 154 155KMF_RETURN 156OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 157 KMF_DATA *, KMF_DATA *); 158 159KMF_RETURN 160OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, KMF_OCSPREQUEST_PARAMS *, 161 char *reqfile); 162 163KMF_RETURN 164OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, KMF_OCSPRESPONSE_PARAMS_INPUT *, 165 KMF_OCSPRESPONSE_PARAMS_OUTPUT *); 166 167KMF_RETURN 168OpenSSL_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, 169 KMF_KEY_HANDLE *, uint32_t *); 170 171KMF_RETURN 172OpenSSL_ExportP12(KMF_HANDLE_T, 173 KMF_EXPORTP12_PARAMS *, 174 int, KMF_X509_DER_CERT *, 175 int, KMF_KEY_HANDLE *, 176 char *); 177 178KMF_RETURN 179OpenSSL_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, 180 KMF_RAW_KEY_DATA *); 181 182KMF_RETURN 183OpenSSL_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, 184 KMF_KEY_HANDLE *); 185 186KMF_RETURN 187OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 188 189KMF_RETURN 190OpenSSL_VerifyCRLFile(KMF_HANDLE_T, KMF_VERIFYCRL_PARAMS *); 191 192KMF_RETURN 193OpenSSL_CheckCRLDate(KMF_HANDLE_T, KMF_CHECKCRLDATE_PARAMS *); 194 195static 196KMF_PLUGIN_FUNCLIST openssl_plugin_table = 197{ 198 1, /* Version */ 199 NULL, /* ConfigureKeystore */ 200 OpenSSL_FindCert, 201 OpenSSL_FreeKMFCert, 202 OpenSSL_StoreCert, 203 NULL, /* ImportCert */ 204 OpenSSL_ImportCRL, 205 OpenSSL_DeleteCert, 206 OpenSSL_DeleteCRL, 207 OpenSSL_CreateKeypair, 208 OpenSSL_FindKey, 209 OpenSSL_EncodePubKeyData, 210 OpenSSL_SignData, 211 OpenSSL_DeleteKey, 212 OpenSSL_ListCRL, 213 NULL, /* FindCRL */ 214 OpenSSL_FindCertInCRL, 215 OpenSSL_GetErrorString, 216 OpenSSL_GetPrikeyByCert, 217 OpenSSL_DecryptData, 218 OpenSSL_ExportP12, 219 OpenSSL_StorePrivateKey, 220 OpenSSL_CreateSymKey, 221 OpenSSL_GetSymKeyValue, 222 NULL, /* SetTokenPin */ 223 NULL /* Finalize */ 224}; 225 226static mutex_t *lock_cs; 227static long *lock_count; 228 229static void 230/*ARGSUSED*/ 231locking_cb(int mode, int type, char *file, int line) 232{ 233 if (mode & CRYPTO_LOCK) { 234 (void) mutex_lock(&(lock_cs[type])); 235 lock_count[type]++; 236 } else { 237 (void) mutex_unlock(&(lock_cs[type])); 238 } 239} 240 241static unsigned long 242thread_id() 243{ 244 return ((unsigned long)thr_self()); 245} 246 247KMF_PLUGIN_FUNCLIST * 248KMF_Plugin_Initialize() 249{ 250 int i; 251 252 (void) mutex_lock(&init_lock); 253 if (!ssl_initialized) { 254 OpenSSL_add_all_algorithms(); 255 256 /* Enable error strings for reporting */ 257 ERR_load_crypto_strings(); 258 259 /* 260 * Add support for extension OIDs that are not yet in the 261 * openssl default set. 262 */ 263 (void) OBJ_create("2.5.29.30", "nameConstraints", 264 "X509v3 Name Constraints"); 265 (void) OBJ_create("2.5.29.33", "policyMappings", 266 "X509v3 Policy Mappings"); 267 (void) OBJ_create("2.5.29.36", "policyConstraints", 268 "X509v3 Policy Constraints"); 269 (void) OBJ_create("2.5.29.46", "freshestCRL", 270 "X509v3 Freshest CRL"); 271 (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy", 272 "X509v3 Inhibit Any-Policy"); 273 /* 274 * Set up for thread-safe operation. 275 */ 276 lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t)); 277 if (lock_cs == NULL) { 278 (void) mutex_unlock(&init_lock); 279 return (NULL); 280 } 281 282 lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long)); 283 if (lock_count == NULL) { 284 OPENSSL_free(lock_cs); 285 (void) mutex_unlock(&init_lock); 286 return (NULL); 287 } 288 289 for (i = 0; i < CRYPTO_num_locks(); i++) { 290 lock_count[i] = 0; 291 (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL); 292 } 293 294 CRYPTO_set_id_callback((unsigned long (*)())thread_id); 295 CRYPTO_set_locking_callback((void (*)())locking_cb); 296 ssl_initialized = 1; 297 } 298 (void) mutex_unlock(&init_lock); 299 300 return (&openssl_plugin_table); 301} 302/* 303 * Convert an SSL DN to a KMF DN. 304 */ 305static KMF_RETURN 306get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN) 307{ 308 KMF_DATA derdata; 309 KMF_RETURN rv = KMF_OK; 310 uchar_t *tmp; 311 312 /* Convert to raw DER format */ 313 derdata.Length = i2d_X509_NAME(sslDN, NULL); 314 if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length)) 315 == NULL) { 316 return (KMF_ERR_MEMORY); 317 } 318 (void) i2d_X509_NAME(sslDN, &tmp); 319 320 /* Decode to KMF format */ 321 rv = DerDecodeName(&derdata, kmfDN); 322 if (rv != KMF_OK) { 323 rv = KMF_ERR_BAD_CERT_FORMAT; 324 } 325 OPENSSL_free(derdata.Data); 326 327 return (rv); 328} 329 330static int 331isdir(char *path) 332{ 333 struct stat s; 334 335 if (stat(path, &s) == -1) 336 return (0); 337 338 return (s.st_mode & S_IFDIR); 339} 340 341static KMF_RETURN 342ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert) 343{ 344 KMF_RETURN rv = KMF_OK; 345 unsigned char *buf = NULL, *p; 346 int len; 347 348 /* 349 * Convert the X509 internal struct to DER encoded data 350 */ 351 if ((len = i2d_X509(x509cert, NULL)) < 0) { 352 SET_ERROR(kmfh, ERR_get_error()); 353 rv = KMF_ERR_BAD_CERT_FORMAT; 354 goto cleanup; 355 } 356 if ((buf = malloc(len)) == NULL) { 357 SET_SYS_ERROR(kmfh, errno); 358 rv = KMF_ERR_MEMORY; 359 goto cleanup; 360 } 361 362 /* 363 * i2d_X509 will increment the buf pointer so that we need to 364 * save it. 365 */ 366 p = buf; 367 if ((len = i2d_X509(x509cert, &p)) < 0) { 368 SET_ERROR(kmfh, ERR_get_error()); 369 free(buf); 370 rv = KMF_ERR_BAD_CERT_FORMAT; 371 goto cleanup; 372 } 373 374 /* caller's responsibility to free it */ 375 cert->Data = buf; 376 cert->Length = len; 377 378cleanup: 379 if (rv != KMF_OK) { 380 if (buf) 381 free(buf); 382 cert->Data = NULL; 383 cert->Length = 0; 384 } 385 386 return (rv); 387} 388 389static KMF_RETURN 390check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) 391{ 392 KMF_RETURN rv = KMF_OK; 393 boolean_t findIssuer = FALSE; 394 boolean_t findSubject = FALSE; 395 boolean_t findSerial = FALSE; 396 KMF_X509_NAME issuerDN, subjectDN; 397 KMF_X509_NAME certIssuerDN, certSubjectDN; 398 399 *match = FALSE; 400 if (xcert == NULL) { 401 return (KMF_ERR_BAD_PARAMETER); 402 } 403 404 (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME)); 405 (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME)); 406 (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME)); 407 (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME)); 408 409 if (params->issuer != NULL && strlen(params->issuer)) { 410 rv = KMF_DNParser(params->issuer, &issuerDN); 411 if (rv != KMF_OK) 412 return (KMF_ERR_BAD_PARAMETER); 413 414 rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); 415 if (rv != KMF_OK) { 416 KMF_FreeDN(&issuerDN); 417 return (KMF_ERR_BAD_PARAMETER); 418 } 419 420 findIssuer = TRUE; 421 } 422 if (params->subject != NULL && strlen(params->subject)) { 423 rv = KMF_DNParser(params->subject, &subjectDN); 424 if (rv != KMF_OK) { 425 rv = KMF_ERR_BAD_PARAMETER; 426 goto cleanup; 427 } 428 429 rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN); 430 if (rv != KMF_OK) { 431 rv = KMF_ERR_BAD_PARAMETER; 432 goto cleanup; 433 } 434 findSubject = TRUE; 435 } 436 if (params->serial != NULL && params->serial->val != NULL) 437 findSerial = TRUE; 438 439 if (findSerial) { 440 BIGNUM *bn; 441 442 /* Comparing BIGNUMs is a pain! */ 443 bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL); 444 if (bn != NULL) { 445 int bnlen = BN_num_bytes(bn); 446 447 if (bnlen == params->serial->len) { 448 uchar_t *a = malloc(bnlen); 449 if (a == NULL) { 450 rv = KMF_ERR_MEMORY; 451 BN_free(bn); 452 goto cleanup; 453 } 454 bnlen = BN_bn2bin(bn, a); 455 *match = !memcmp(a, 456 params->serial->val, 457 params->serial->len); 458 rv = KMF_OK; 459 free(a); 460 } 461 BN_free(bn); 462 if (!(*match)) 463 goto cleanup; 464 } else { 465 rv = KMF_OK; 466 goto cleanup; 467 } 468 } 469 if (findIssuer) { 470 *match = !KMF_CompareRDNs(&issuerDN, &certIssuerDN); 471 if (!(*match)) { 472 rv = KMF_OK; 473 goto cleanup; 474 } 475 } 476 if (findSubject) { 477 *match = !KMF_CompareRDNs(&subjectDN, &certSubjectDN); 478 if (!(*match)) { 479 rv = KMF_OK; 480 goto cleanup; 481 } 482 } 483 484 *match = TRUE; 485cleanup: 486 if (findIssuer) { 487 KMF_FreeDN(&issuerDN); 488 KMF_FreeDN(&certIssuerDN); 489 } 490 if (findSubject) { 491 KMF_FreeDN(&subjectDN); 492 KMF_FreeDN(&certSubjectDN); 493 } 494 495 return (rv); 496} 497 498static KMF_RETURN 499load_X509cert(KMF_HANDLE *kmfh, 500 KMF_FINDCERT_PARAMS *params, 501 char *pathname, 502 X509 **outcert) 503{ 504 KMF_RETURN rv = KMF_OK; 505 X509 *xcert = NULL; 506 BIO *bcert = NULL; 507 boolean_t match = FALSE; 508 KMF_ENCODE_FORMAT format; 509 510 /* 511 * auto-detect the file format, regardless of what 512 * the 'format' parameters in the params say. 513 */ 514 rv = KMF_GetFileFormat(pathname, &format); 515 if (rv != KMF_OK) { 516 if (rv == KMF_ERR_OPEN_FILE) 517 rv = KMF_ERR_CERT_NOT_FOUND; 518 return (rv); 519 } 520 521 /* Not ASN1(DER) format */ 522 if ((bcert = BIO_new_file(pathname, "rb")) == NULL) { 523 SET_ERROR(kmfh, ERR_get_error()); 524 rv = KMF_ERR_OPEN_FILE; 525 goto cleanup; 526 } 527 528 if (format == KMF_FORMAT_PEM) 529 xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL); 530 else if (format == KMF_FORMAT_ASN1) 531 xcert = d2i_X509_bio(bcert, NULL); 532 else if (format == KMF_FORMAT_PKCS12) { 533 PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL); 534 if (p12 != NULL) { 535 (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL); 536 PKCS12_free(p12); 537 p12 = NULL; 538 } else { 539 SET_ERROR(kmfh, ERR_get_error()); 540 rv = KMF_ERR_BAD_CERT_FORMAT; 541 } 542 } else { 543 rv = KMF_ERR_BAD_PARAMETER; 544 goto cleanup; 545 } 546 547 if (xcert == NULL) { 548 SET_ERROR(kmfh, ERR_get_error()); 549 rv = KMF_ERR_BAD_CERT_FORMAT; 550 goto cleanup; 551 } 552 553 if (check_cert(xcert, params, &match) != KMF_OK || match == FALSE) { 554 rv = KMF_ERR_CERT_NOT_FOUND; 555 goto cleanup; 556 } 557 558 if (outcert != NULL) { 559 *outcert = xcert; 560 } 561 562cleanup: 563 if (bcert != NULL) (void) BIO_free(bcert); 564 if (rv != KMF_OK && xcert != NULL) 565 X509_free(xcert); 566 567 return (rv); 568} 569 570static KMF_RETURN 571kmf_load_cert(KMF_HANDLE *kmfh, 572 KMF_FINDCERT_PARAMS *params, 573 char *pathname, 574 KMF_DATA *cert) 575{ 576 KMF_RETURN rv = KMF_OK; 577 X509 *x509cert = NULL; 578 579 rv = load_X509cert(kmfh, params, pathname, &x509cert); 580 if (rv == KMF_OK && x509cert != NULL && cert != NULL) { 581 rv = ssl_cert2KMFDATA(kmfh, x509cert, cert); 582 if (rv != KMF_OK) { 583 goto cleanup; 584 } 585 if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) { 586 rv = KMF_CheckCertDate(kmfh, cert); 587 } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) { 588 rv = KMF_CheckCertDate(kmfh, cert); 589 if (rv == KMF_OK) { 590 /* 591 * This is a valid cert so skip it. 592 */ 593 rv = KMF_ERR_CERT_NOT_FOUND; 594 } 595 if (rv == KMF_ERR_VALIDITY_PERIOD) { 596 /* 597 * We want to return success when we 598 * find an invalid cert. 599 */ 600 rv = KMF_OK; 601 goto cleanup; 602 } 603 } 604 } 605cleanup: 606 if (x509cert != NULL) 607 X509_free(x509cert); 608 609 return (rv); 610} 611 612static EVP_PKEY * 613openssl_load_key(KMF_HANDLE_T handle, const char *file) 614{ 615 BIO *keyfile = NULL; 616 EVP_PKEY *pkey = NULL; 617 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 618 KMF_ENCODE_FORMAT format; 619 620 if (file == NULL) { 621 return (NULL); 622 } 623 624 if (KMF_GetFileFormat((char *)file, &format) != KMF_OK) 625 return (NULL); 626 627 keyfile = BIO_new_file(file, "rb"); 628 if (keyfile == NULL) { 629 goto end; 630 } 631 632 if (format == KMF_FORMAT_ASN1) 633 pkey = d2i_PrivateKey_bio(keyfile, NULL); 634 else if (format == KMF_FORMAT_PEM) 635 pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL); 636 637end: 638 if (pkey == NULL) 639 SET_ERROR(kmfh, ERR_get_error()); 640 641 if (keyfile != NULL) 642 (void) BIO_free(keyfile); 643 644 return (pkey); 645} 646 647KMF_RETURN 648OpenSSL_FindCert(KMF_HANDLE_T handle, 649 KMF_FINDCERT_PARAMS *params, 650 KMF_X509_DER_CERT *kmf_cert, 651 uint32_t *num_certs) 652{ 653 KMF_RETURN rv = KMF_OK; 654 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 655 KMF_DATA certdata = {NULL, 0}; 656 char *fullpath; 657 658 if (num_certs == NULL || params == NULL) 659 return (KMF_ERR_BAD_PARAMETER); 660 661 *num_certs = 0; 662 663 fullpath = get_fullpath(params->sslparms.dirpath, 664 params->sslparms.certfile); 665 666 if (fullpath == NULL) 667 return (KMF_ERR_BAD_PARAMETER); 668 669 if (isdir(fullpath)) { 670 DIR *dirp; 671 struct dirent *dp; 672 int n = 0; 673 674 /* open all files in the directory and attempt to read them */ 675 if ((dirp = opendir(fullpath)) == NULL) { 676 return (KMF_ERR_BAD_PARAMETER); 677 } 678 while ((dp = readdir(dirp)) != NULL) { 679 char *fname; 680 if (strcmp(dp->d_name, ".") == 0 || 681 strcmp(dp->d_name, "..") == 0) 682 continue; 683 684 fname = get_fullpath(fullpath, 685 (char *)&dp->d_name); 686 687 rv = kmf_load_cert(kmfh, params, fname, 688 &certdata); 689 690 if (rv != KMF_OK) { 691 free(fname); 692 KMF_FreeData(&certdata); 693 continue; 694 } 695 696 /* If load succeeds, add certdata to the list */ 697 if (kmf_cert != NULL) { 698 kmf_cert[n].certificate.Data = certdata.Data; 699 kmf_cert[n].certificate.Length = 700 certdata.Length; 701 702 kmf_cert[n].kmf_private.keystore_type = 703 KMF_KEYSTORE_OPENSSL; 704 kmf_cert[n].kmf_private.flags = 705 KMF_FLAG_CERT_VALID; 706 kmf_cert[n].kmf_private.label = fname; 707 708 certdata.Data = NULL; 709 certdata.Length = 0; 710 } else { 711 free(fname); 712 KMF_FreeData(&certdata); 713 } 714 n++; 715 } 716 (*num_certs) = n; 717 if (*num_certs == 0) 718 rv = KMF_ERR_CERT_NOT_FOUND; 719 if (*num_certs > 0) 720 rv = KMF_OK; 721exit: 722 (void) closedir(dirp); 723 } else { 724 /* Just try to load a single certificate */ 725 rv = kmf_load_cert(kmfh, params, fullpath, &certdata); 726 if (rv != KMF_OK) { 727 free(fullpath); 728 KMF_FreeData(&certdata); 729 return (rv); 730 } 731 732 if (kmf_cert != NULL) { 733 kmf_cert->certificate.Data = certdata.Data; 734 kmf_cert->certificate.Length = certdata.Length; 735 kmf_cert->kmf_private.keystore_type = 736 KMF_KEYSTORE_OPENSSL; 737 kmf_cert->kmf_private.flags = KMF_FLAG_CERT_VALID; 738 kmf_cert->kmf_private.label = fullpath; 739 } else { 740 KMF_FreeData(&certdata); 741 } 742 743 *num_certs = 1; 744 } 745 746 if (kmf_cert == NULL || rv != KMF_OK) 747 free(fullpath); 748 749 return (rv); 750 751} 752 753void 754/*ARGSUSED*/ 755OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, 756 KMF_X509_DER_CERT *kmf_cert) 757{ 758 if (kmf_cert != NULL) { 759 if (kmf_cert->certificate.Data != NULL) { 760 free(kmf_cert->certificate.Data); 761 kmf_cert->certificate.Data = NULL; 762 kmf_cert->certificate.Length = 0; 763 } 764 if (kmf_cert->kmf_private.label) 765 free(kmf_cert->kmf_private.label); 766 } 767} 768 769KMF_RETURN 770OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, 771 KMF_DATA * pcert) 772{ 773 KMF_RETURN ret = KMF_OK; 774 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 775 X509 *xcert = NULL; 776 FILE *fp; 777 unsigned char *outbuf; 778 unsigned char *outbuf_p; 779 char *fullpath; 780 int outbuflen; 781 int len; 782 KMF_ENCODE_FORMAT format; 783 784 if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) { 785 return (KMF_ERR_BAD_PARAMETER); 786 } 787 788 /* 789 * check if the cert output format is supported by OPENSSL. 790 * however, since the keystore for OPENSSL is just a file, we have 791 * no way to store the format along with the file. 792 */ 793 format = params->sslparms.format; 794 if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) 795 return (KMF_ERR_BAD_CERT_FORMAT); 796 797 798 fullpath = get_fullpath(params->sslparms.dirpath, 799 params->sslparms.certfile); 800 if (fullpath == NULL) 801 return (KMF_ERR_BAD_PARAMETER); 802 803 /* 804 * When storing a certificate, you must specify a filename. 805 */ 806 if (isdir(fullpath)) { 807 free(fullpath); 808 return (KMF_ERR_BAD_PARAMETER); 809 } 810 811 /* copy cert data to outbuf */ 812 outbuflen = pcert->Length; 813 outbuf = malloc(outbuflen); 814 if (outbuf == NULL) { 815 free(fullpath); 816 return (KMF_ERR_MEMORY); 817 } 818 (void) memcpy(outbuf, pcert->Data, pcert->Length); 819 820 if ((fp = fopen(fullpath, "w")) == 821 NULL) { 822 SET_SYS_ERROR(kmfh, errno); 823 ret = KMF_ERR_INTERNAL; 824 goto out; 825 } 826 827 if (format == KMF_FORMAT_ASN1) { 828 len = fwrite(outbuf, 1, outbuflen, fp); 829 if (len != outbuflen) { 830 SET_SYS_ERROR(kmfh, errno); 831 ret = KMF_ERR_WRITE_FILE; 832 } else { 833 ret = KMF_OK; 834 } 835 goto out; 836 } 837 838 /* 839 * The output format is not KMF_FORMAT_ASN1, so we will 840 * Convert the cert data to OpenSSL internal X509 first. 841 */ 842 outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 843 xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen); 844 if (xcert == NULL) { 845 SET_ERROR(kmfh, ERR_get_error()); 846 ret = KMF_ERR_ENCODING; 847 goto out; 848 } 849 850 if (format == KMF_FORMAT_PEM) { 851 /* Convert to the PEM format and write it out */ 852 if (!PEM_write_X509(fp, xcert)) { 853 SET_ERROR(kmfh, ERR_get_error()); 854 ret = KMF_ERR_ENCODING; 855 } else { 856 ret = KMF_OK; 857 } 858 goto out; 859 } 860 861out: 862 if (fullpath != NULL) 863 free(fullpath); 864 865 if (outbuf != NULL) { 866 free(outbuf); 867 } 868 if (fp != NULL) { 869 (void) fclose(fp); 870 } 871 872 if (xcert != NULL) { 873 X509_free(xcert); 874 } 875 876 return (ret); 877} 878 879KMF_RETURN 880OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) 881{ 882 KMF_RETURN rv; 883 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 884 char *fullpath = NULL; 885 KMF_DATA certdata = {NULL, 0}; 886 887 if (params == NULL) { 888 return (KMF_ERR_BAD_PARAMETER); 889 } 890 891 fullpath = get_fullpath(params->sslparms.dirpath, 892 params->sslparms.certfile); 893 894 if (fullpath == NULL) 895 return (KMF_ERR_BAD_PARAMETER); 896 897 if (isdir(fullpath)) { 898 DIR *dirp; 899 struct dirent *dp; 900 901 /* open all files in the directory and attempt to read them */ 902 if ((dirp = opendir(fullpath)) == NULL) { 903 return (KMF_ERR_BAD_PARAMETER); 904 } 905 906 while ((dp = readdir(dirp)) != NULL) { 907 if (strcmp(dp->d_name, ".") != 0 && 908 strcmp(dp->d_name, "..") != 0) { 909 char *fname; 910 911 fname = get_fullpath(fullpath, 912 (char *)&dp->d_name); 913 914 if (fname == NULL) { 915 rv = KMF_ERR_MEMORY; 916 break; 917 } 918 919 rv = kmf_load_cert(kmfh, params, fname, 920 &certdata); 921 922 if (rv == KMF_ERR_CERT_NOT_FOUND) { 923 free(fname); 924 if (certdata.Data) 925 free(certdata.Data); 926 rv = KMF_OK; 927 continue; 928 } else if (rv != KMF_OK) { 929 free(fname); 930 break; 931 } 932 933 if (unlink(fname) != 0) { 934 SET_SYS_ERROR(kmfh, errno); 935 rv = KMF_ERR_INTERNAL; 936 free(fname); 937 break; 938 } 939 free(fname); 940 if (certdata.Data) 941 free(certdata.Data); 942 } 943 } 944 (void) closedir(dirp); 945 } else { 946 /* Just try to load a single certificate */ 947 rv = kmf_load_cert(kmfh, params, fullpath, &certdata); 948 if (rv == KMF_OK) { 949 if (unlink(fullpath) != 0) { 950 SET_SYS_ERROR(kmfh, errno); 951 rv = KMF_ERR_INTERNAL; 952 } 953 } 954 } 955 956out: 957 if (fullpath != NULL) 958 free(fullpath); 959 960 if (certdata.Data) 961 free(certdata.Data); 962 963 return (rv); 964} 965 966KMF_RETURN 967OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 968 KMF_DATA *keydata) 969{ 970 KMF_RETURN rv = KMF_OK; 971 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 972 int n; 973 974 if (key == NULL || keydata == NULL || 975 key->keyp == NULL) 976 return (KMF_ERR_BAD_PARAMETER); 977 978 if (key->keyalg == KMF_RSA) { 979 RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp); 980 981 if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) { 982 SET_ERROR(kmfh, ERR_get_error()); 983 return (KMF_ERR_ENCODING); 984 } 985 RSA_free(pubkey); 986 } else if (key->keyalg == KMF_DSA) { 987 DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp); 988 989 if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) { 990 SET_ERROR(kmfh, ERR_get_error()); 991 return (KMF_ERR_ENCODING); 992 } 993 DSA_free(pubkey); 994 } else { 995 return (KMF_ERR_BAD_PARAMETER); 996 } 997 keydata->Length = n; 998 999cleanup: 1000 if (rv != KMF_OK) { 1001 if (keydata->Data) 1002 free(keydata->Data); 1003 keydata->Data = NULL; 1004 keydata->Length = 0; 1005 } 1006 1007 return (rv); 1008} 1009 1010static KMF_RETURN 1011ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, 1012 KMF_CREDENTIAL *cred, EVP_PKEY *pkey) 1013{ 1014 int rv = 0; 1015 RSA *rsa; 1016 DSA *dsa; 1017 1018 switch (format) { 1019 case KMF_FORMAT_ASN1: 1020 if (pkey->type == EVP_PKEY_RSA) { 1021 rsa = EVP_PKEY_get1_RSA(pkey); 1022 rv = i2d_RSAPrivateKey_bio(out, rsa); 1023 RSA_free(rsa); 1024 } else if (pkey->type == EVP_PKEY_DSA) { 1025 dsa = EVP_PKEY_get1_DSA(pkey); 1026 rv = i2d_DSAPrivateKey_bio(out, dsa); 1027 DSA_free(dsa); 1028 } 1029 if (rv == 1) { 1030 rv = KMF_OK; 1031 } else { 1032 SET_ERROR(kmfh, rv); 1033 } 1034 break; 1035 case KMF_FORMAT_PEM: 1036 if (pkey->type == EVP_PKEY_RSA) { 1037 rsa = EVP_PKEY_get1_RSA(pkey); 1038 rv = PEM_write_bio_RSAPrivateKey(out, 1039 rsa, 1040 NULL /* encryption type */, 1041 NULL, 0, NULL, 1042 cred->cred); 1043 RSA_free(rsa); 1044 } else if (pkey->type == EVP_PKEY_DSA) { 1045 dsa = EVP_PKEY_get1_DSA(pkey); 1046 rv = PEM_write_bio_DSAPrivateKey(out, 1047 dsa, 1048 NULL /* encryption type */, 1049 NULL, 0, NULL, 1050 cred->cred); 1051 DSA_free(dsa); 1052 } 1053 1054 if (rv == 1) { 1055 rv = KMF_OK; 1056 } else { 1057 SET_ERROR(kmfh, rv); 1058 } 1059 break; 1060 1061 default: 1062 rv = KMF_ERR_BAD_PARAMETER; 1063 } 1064 1065 return (rv); 1066} 1067 1068KMF_RETURN 1069OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, 1070 KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) 1071{ 1072 KMF_RETURN rv = KMF_OK; 1073 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1074 int format; 1075 uint32_t eValue = 0x010001; 1076 RSA *sslPrivKey = NULL; 1077 DSA *sslDSAKey = NULL; 1078 EVP_PKEY *eprikey = NULL; 1079 EVP_PKEY *epubkey = NULL; 1080 BIO *out = NULL; 1081 char *fullpath = NULL; 1082 1083 if (params == NULL || params->sslparms.keyfile == NULL) { 1084 return (KMF_ERR_BAD_PARAMETER); 1085 } 1086 1087 fullpath = get_fullpath(params->sslparms.dirpath, 1088 params->sslparms.keyfile); 1089 1090 if (fullpath == NULL) 1091 return (KMF_ERR_BAD_PARAMETER); 1092 1093 /* If the requested file exists, return an error */ 1094 if (access(fullpath, F_OK) == 0) { 1095 free(fullpath); 1096 return (KMF_ERR_DUPLICATE_KEYFILE); 1097 } 1098 1099 eprikey = EVP_PKEY_new(); 1100 if (eprikey == NULL) { 1101 SET_ERROR(kmfh, ERR_get_error()); 1102 rv = KMF_ERR_KEYGEN_FAILED; 1103 goto cleanup; 1104 } 1105 epubkey = EVP_PKEY_new(); 1106 if (epubkey == NULL) { 1107 SET_ERROR(kmfh, ERR_get_error()); 1108 rv = KMF_ERR_KEYGEN_FAILED; 1109 goto cleanup; 1110 } 1111 if (params->keytype == KMF_RSA) { 1112 if (params->rsa_exponent.len > 0 && 1113 params->rsa_exponent.len <= sizeof (eValue) && 1114 params->rsa_exponent.val != NULL) 1115 /*LINTED*/ 1116 eValue = *(uint32_t *)params->rsa_exponent.val; 1117 1118 sslPrivKey = RSA_generate_key(params->keylength, eValue, 1119 NULL, NULL); 1120 if (sslPrivKey == NULL) { 1121 SET_ERROR(kmfh, ERR_get_error()); 1122 rv = KMF_ERR_KEYGEN_FAILED; 1123 } else { 1124 if (privkey != NULL && 1125 EVP_PKEY_set1_RSA(eprikey, sslPrivKey)) { 1126 privkey->kstype = KMF_KEYSTORE_OPENSSL; 1127 privkey->keyalg = KMF_RSA; 1128 privkey->keyclass = KMF_ASYM_PRI; 1129 privkey->israw = FALSE; 1130 privkey->keylabel = (char *)strdup(fullpath); 1131 privkey->keyp = (void *)eprikey; 1132 } 1133 /* OpenSSL derives the public key from the private */ 1134 if (pubkey != NULL && 1135 EVP_PKEY_set1_RSA(epubkey, sslPrivKey)) { 1136 pubkey->kstype = KMF_KEYSTORE_OPENSSL; 1137 pubkey->keyalg = KMF_RSA; 1138 pubkey->israw = FALSE; 1139 pubkey->keyclass = KMF_ASYM_PUB; 1140 pubkey->keylabel = (char *)strdup(fullpath); 1141 pubkey->keyp = (void *)epubkey; 1142 } 1143 } 1144 } else if (params->keytype == KMF_DSA) { 1145 sslDSAKey = DSA_new(); 1146 if (sslDSAKey == NULL) { 1147 SET_ERROR(kmfh, ERR_get_error()); 1148 return (KMF_ERR_MEMORY); 1149 } 1150 1151 if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) == 1152 NULL) { 1153 SET_ERROR(kmfh, ERR_get_error()); 1154 rv = KMF_ERR_KEYGEN_FAILED; 1155 goto cleanup; 1156 } 1157 if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) == 1158 NULL) { 1159 SET_ERROR(kmfh, ERR_get_error()); 1160 rv = KMF_ERR_KEYGEN_FAILED; 1161 goto cleanup; 1162 } 1163 if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) == 1164 NULL) { 1165 SET_ERROR(kmfh, ERR_get_error()); 1166 rv = KMF_ERR_KEYGEN_FAILED; 1167 goto cleanup; 1168 } 1169 1170 if (!DSA_generate_key(sslDSAKey)) { 1171 SET_ERROR(kmfh, ERR_get_error()); 1172 rv = KMF_ERR_KEYGEN_FAILED; 1173 goto cleanup; 1174 } 1175 1176 if (privkey != NULL) { 1177 privkey->kstype = KMF_KEYSTORE_OPENSSL; 1178 privkey->keyalg = KMF_DSA; 1179 privkey->keyclass = KMF_ASYM_PRI; 1180 privkey->israw = FALSE; 1181 privkey->keylabel = (char *)strdup(fullpath); 1182 if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { 1183 privkey->keyp = (void *)eprikey; 1184 } else { 1185 SET_ERROR(kmfh, ERR_get_error()); 1186 rv = KMF_ERR_KEYGEN_FAILED; 1187 goto cleanup; 1188 } 1189 } 1190 if (pubkey != NULL) { 1191 DSA *dp = DSA_new(); 1192 /* Make a copy for the public key */ 1193 if (dp != NULL) { 1194 if ((dp->p = BN_new()) == NULL) { 1195 SET_ERROR(kmfh, ERR_get_error()); 1196 rv = KMF_ERR_MEMORY; 1197 DSA_free(dp); 1198 goto cleanup; 1199 } 1200 if ((dp->q = BN_new()) == NULL) { 1201 SET_ERROR(kmfh, ERR_get_error()); 1202 rv = KMF_ERR_MEMORY; 1203 BN_free(dp->p); 1204 DSA_free(dp); 1205 goto cleanup; 1206 } 1207 if ((dp->g = BN_new()) == NULL) { 1208 SET_ERROR(kmfh, ERR_get_error()); 1209 rv = KMF_ERR_MEMORY; 1210 BN_free(dp->q); 1211 BN_free(dp->p); 1212 DSA_free(dp); 1213 goto cleanup; 1214 } 1215 if ((dp->pub_key = BN_new()) == NULL) { 1216 SET_ERROR(kmfh, ERR_get_error()); 1217 rv = KMF_ERR_MEMORY; 1218 BN_free(dp->q); 1219 BN_free(dp->p); 1220 BN_free(dp->g); 1221 DSA_free(dp); 1222 goto cleanup; 1223 } 1224 (void) BN_copy(dp->p, sslDSAKey->p); 1225 (void) BN_copy(dp->q, sslDSAKey->q); 1226 (void) BN_copy(dp->g, sslDSAKey->g); 1227 (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); 1228 1229 pubkey->kstype = KMF_KEYSTORE_OPENSSL; 1230 pubkey->keyalg = KMF_DSA; 1231 pubkey->keyclass = KMF_ASYM_PUB; 1232 pubkey->israw = FALSE; 1233 pubkey->keylabel = (char *)strdup(fullpath); 1234 1235 if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { 1236 pubkey->keyp = (void *)epubkey; 1237 } else { 1238 SET_ERROR(kmfh, ERR_get_error()); 1239 rv = KMF_ERR_KEYGEN_FAILED; 1240 goto cleanup; 1241 } 1242 } 1243 } 1244 } 1245 1246 if (rv != KMF_OK) { 1247 goto cleanup; 1248 } 1249 1250 /* Store the private key to the keyfile */ 1251 format = params->sslparms.format; 1252 out = BIO_new_file(fullpath, "wb"); 1253 if (out == NULL) { 1254 SET_ERROR(kmfh, ERR_get_error()); 1255 rv = KMF_ERR_OPEN_FILE; 1256 goto cleanup; 1257 } 1258 rv = ssl_write_private_key(kmfh, format, out, ¶ms->cred, eprikey); 1259 1260cleanup: 1261 if (rv != KMF_OK) { 1262 if (eprikey != NULL) 1263 EVP_PKEY_free(eprikey); 1264 1265 if (epubkey != NULL) 1266 EVP_PKEY_free(epubkey); 1267 1268 if (pubkey->keylabel) { 1269 free(pubkey->keylabel); 1270 pubkey->keylabel = NULL; 1271 } 1272 1273 if (privkey->keylabel) { 1274 free(privkey->keylabel); 1275 privkey->keylabel = NULL; 1276 } 1277 1278 pubkey->keyp = NULL; 1279 privkey->keyp = NULL; 1280 } 1281 1282 if (sslPrivKey) 1283 RSA_free(sslPrivKey); 1284 1285 if (sslDSAKey) 1286 DSA_free(sslDSAKey); 1287 1288 1289 if (out != NULL) 1290 (void) BIO_free(out); 1291 1292 if (fullpath) 1293 free(fullpath); 1294 1295 /* Protect the file by making it read-only */ 1296 if (rv == KMF_OK) { 1297 (void) chmod(fullpath, 0400); 1298 } 1299 return (rv); 1300} 1301 1302KMF_RETURN 1303OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1304 KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output) 1305{ 1306 KMF_RETURN ret = KMF_OK; 1307 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1308 KMF_ALGORITHM_INDEX AlgId; 1309 EVP_MD_CTX ctx; 1310 const EVP_MD *md; 1311 if (key == NULL || AlgOID == NULL || 1312 tobesigned == NULL || output == NULL || 1313 tobesigned->Data == NULL || 1314 output->Data == NULL) 1315 return (KMF_ERR_BAD_PARAMETER); 1316 1317 /* Map the OID to an OpenSSL algorithm */ 1318 AlgId = X509_AlgorithmOidToAlgId(AlgOID); 1319 if (AlgId == KMF_ALGID_NONE) 1320 return (KMF_ERR_BAD_PARAMETER); 1321 1322 if (key->keyalg == KMF_RSA) { 1323 EVP_PKEY *pkey = (EVP_PKEY *)key->keyp; 1324 uchar_t *p; 1325 uint32_t len; 1326 if (AlgId == KMF_ALGID_MD5WithRSA) 1327 md = EVP_md5(); 1328 else if (AlgId == KMF_ALGID_MD2WithRSA) 1329 md = EVP_md2(); 1330 else if (AlgId == KMF_ALGID_SHA1WithRSA) 1331 md = EVP_sha1(); 1332 else 1333 return (KMF_ERR_BAD_PARAMETER); 1334 1335 if (md == NULL) { 1336 SET_ERROR(kmfh, ERR_get_error()); 1337 return (KMF_ERR_MEMORY); 1338 } 1339 1340 (void) EVP_MD_CTX_init(&ctx); 1341 (void) EVP_SignInit_ex(&ctx, md, NULL); 1342 (void) EVP_SignUpdate(&ctx, tobesigned->Data, 1343 (uint32_t)tobesigned->Length); 1344 len = (uint32_t)output->Length; 1345 p = output->Data; 1346 if (!EVP_SignFinal(&ctx, p, &len, pkey)) { 1347 SET_ERROR(kmfh, ERR_get_error()); 1348 output->Length = 0; 1349 } 1350 output->Length = len; 1351 (void) EVP_MD_CTX_cleanup(&ctx); 1352 } else if (key->keyalg == KMF_DSA) { 1353 DSA *dsa = EVP_PKEY_get1_DSA(key->keyp); 1354 1355 uchar_t hash[EVP_MAX_MD_SIZE]; 1356 uint32_t hashlen; 1357 DSA_SIG *dsasig; 1358 1359 /* 1360 * OpenSSL EVP_Sign operation automatically converts to 1361 * ASN.1 output so we do the operations separately so we 1362 * are assured of NOT getting ASN.1 output returned. 1363 * KMF does not want ASN.1 encoded results because 1364 * not all mechanisms return ASN.1 encodings (PKCS#11 1365 * and NSS return raw signature data). 1366 */ 1367 md = EVP_sha1(); 1368 EVP_MD_CTX_init(&ctx); 1369 (void) EVP_DigestInit_ex(&ctx, md, NULL); 1370 (void) EVP_DigestUpdate(&ctx, tobesigned->Data, 1371 tobesigned->Length); 1372 (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen); 1373 (void) EVP_MD_CTX_cleanup(&ctx); 1374 1375 dsasig = DSA_do_sign(hash, hashlen, dsa); 1376 if (dsasig != NULL) { 1377 int i; 1378 output->Length = i = BN_bn2bin(dsasig->r, output->Data); 1379 output->Length += BN_bn2bin(dsasig->s, 1380 &output->Data[i]); 1381 DSA_SIG_free(dsasig); 1382 } else { 1383 SET_ERROR(kmfh, ERR_get_error()); 1384 } 1385 } else { 1386 return (KMF_ERR_BAD_PARAMETER); 1387 } 1388cleanup: 1389 return (ret); 1390} 1391 1392KMF_RETURN 1393/*ARGSUSED*/ 1394OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, 1395 KMF_KEY_HANDLE *key, boolean_t destroy) 1396{ 1397 KMF_RETURN rv = KMF_OK; 1398 if (key == NULL || key->keyp == NULL) 1399 return (KMF_ERR_BAD_PARAMETER); 1400 1401 if (key->keyclass != KMF_ASYM_PUB && 1402 key->keyclass != KMF_ASYM_PRI && 1403 key->keyclass != KMF_SYMMETRIC) 1404 return (KMF_ERR_BAD_KEY_CLASS); 1405 1406 if (key->keyclass == KMF_SYMMETRIC) { 1407 KMF_FreeRawSymKey((KMF_RAW_SYM_KEY *)key->keyp); 1408 key->keyp = NULL; 1409 } else { 1410 if (key->keyp != NULL) { 1411 EVP_PKEY_free(key->keyp); 1412 key->keyp = NULL; 1413 } 1414 } 1415 1416 if (key->keylabel != NULL) { 1417 EVP_PKEY *pkey = NULL; 1418 /* If the file exists, make sure it is a proper key. */ 1419 pkey = openssl_load_key(handle, key->keylabel); 1420 if (pkey == NULL) { 1421 free(key->keylabel); 1422 key->keylabel = NULL; 1423 return (KMF_ERR_KEY_NOT_FOUND); 1424 } 1425 EVP_PKEY_free(pkey); 1426 1427 if (destroy) { 1428 if (unlink(key->keylabel) != 0) { 1429 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1430 SET_SYS_ERROR(kmfh, errno); 1431 rv = KMF_ERR_INTERNAL; 1432 } 1433 } 1434 if (key->keylabel != NULL) { 1435 free(key->keylabel); 1436 key->keylabel = NULL; 1437 } 1438 } 1439 return (rv); 1440} 1441 1442KMF_RETURN 1443OpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) 1444{ 1445 KMF_RETURN ret = KMF_OK; 1446 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1447 X509_CRL *xcrl = NULL; 1448 X509 *xcert = NULL; 1449 EVP_PKEY *pkey; 1450 KMF_ENCODE_FORMAT format; 1451 BIO *in = NULL, *out = NULL; 1452 int openssl_ret = 0; 1453 char *outcrlfile = NULL; 1454 KMF_ENCODE_FORMAT outformat; 1455 1456 if (params == NULL || params->sslparms.crlfile == NULL) { 1457 return (KMF_ERR_BAD_PARAMETER); 1458 } 1459 1460 if (params->sslparms.crl_check == B_TRUE && 1461 params->sslparms.certfile == NULL) { 1462 return (KMF_ERR_BAD_PARAMETER); 1463 } 1464 1465 outcrlfile = get_fullpath(params->sslparms.dirpath, 1466 params->sslparms.outcrlfile); 1467 1468 if (outcrlfile == NULL) 1469 return (KMF_ERR_BAD_PARAMETER); 1470 1471 if (isdir(outcrlfile)) { 1472 free(outcrlfile); 1473 return (KMF_ERR_BAD_PARAMETER); 1474 } 1475 1476 ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); 1477 if (ret != KMF_OK) { 1478 free(outcrlfile); 1479 return (ret); 1480 } 1481 1482 in = BIO_new_file(params->sslparms.crlfile, "rb"); 1483 if (in == NULL) { 1484 SET_ERROR(kmfh, ERR_get_error()); 1485 ret = KMF_ERR_OPEN_FILE; 1486 goto end; 1487 } 1488 1489 if (format == KMF_FORMAT_ASN1) { 1490 xcrl = d2i_X509_CRL_bio(in, NULL); 1491 } else if (format == KMF_FORMAT_PEM) { 1492 xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 1493 } 1494 1495 if (xcrl == NULL) { 1496 SET_ERROR(kmfh, ERR_get_error()); 1497 ret = KMF_ERR_BAD_CRLFILE; 1498 goto end; 1499 } 1500 1501 /* If bypasscheck is specified, no need to verify. */ 1502 if (params->sslparms.crl_check == B_FALSE) { 1503 goto output; 1504 } 1505 1506 ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); 1507 if (ret != KMF_OK) 1508 goto end; 1509 1510 /* Read in the CA cert file and convert to X509 */ 1511 if (BIO_read_filename(in, params->sslparms.certfile) <= 0) { 1512 SET_ERROR(kmfh, ERR_get_error()); 1513 ret = KMF_ERR_OPEN_FILE; 1514 goto end; 1515 } 1516 1517 if (format == KMF_FORMAT_ASN1) { 1518 xcert = d2i_X509_bio(in, NULL); 1519 } else if (format == KMF_FORMAT_PEM) { 1520 xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 1521 } else { 1522 ret = KMF_ERR_BAD_CERT_FORMAT; 1523 goto end; 1524 } 1525 1526 if (xcert == NULL) { 1527 SET_ERROR(kmfh, ERR_get_error()); 1528 ret = KMF_ERR_BAD_CERT_FORMAT; 1529 goto end; 1530 } 1531 /* Now get the public key from the CA cert */ 1532 pkey = X509_get_pubkey(xcert); 1533 if (!pkey) { 1534 SET_ERROR(kmfh, ERR_get_error()); 1535 ret = KMF_ERR_BAD_CERTFILE; 1536 goto end; 1537 } 1538 1539 /* Verify the CRL with the CA's public key */ 1540 openssl_ret = X509_CRL_verify(xcrl, pkey); 1541 EVP_PKEY_free(pkey); 1542 if (openssl_ret > 0) { 1543 ret = KMF_OK; /* verify succeed */ 1544 } else { 1545 SET_ERROR(kmfh, openssl_ret); 1546 ret = KMF_ERR_BAD_CRLFILE; 1547 } 1548 1549output: 1550 outformat = params->sslparms.format; 1551 1552 out = BIO_new_file(outcrlfile, "wb"); 1553 if (out == NULL) { 1554 SET_ERROR(kmfh, ERR_get_error()); 1555 ret = KMF_ERR_OPEN_FILE; 1556 goto end; 1557 } 1558 1559 if (outformat == KMF_FORMAT_ASN1) { 1560 openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); 1561 } else if (outformat == KMF_FORMAT_PEM) { 1562 openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); 1563 } else { 1564 ret = KMF_ERR_BAD_PARAMETER; 1565 goto end; 1566 } 1567 1568 if (openssl_ret <= 0) { 1569 SET_ERROR(kmfh, ERR_get_error()); 1570 ret = KMF_ERR_WRITE_FILE; 1571 } else { 1572 ret = KMF_OK; 1573 } 1574 1575end: 1576 if (xcrl != NULL) 1577 X509_CRL_free(xcrl); 1578 1579 if (xcert != NULL) 1580 X509_free(xcert); 1581 1582 if (in != NULL) 1583 (void) BIO_free(in); 1584 1585 if (out != NULL) 1586 (void) BIO_free(out); 1587 1588 if (outcrlfile != NULL) 1589 free(outcrlfile); 1590 1591 return (ret); 1592} 1593 1594KMF_RETURN 1595OpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, 1596 char **crldata) 1597{ 1598 KMF_RETURN ret = KMF_OK; 1599 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1600 X509_CRL *x = NULL; 1601 KMF_ENCODE_FORMAT format; 1602 char *crlfile = NULL; 1603 BIO *in = NULL; 1604 BIO *mem = NULL; 1605 long len; 1606 char *memptr; 1607 char *data = NULL; 1608 1609 if (params == NULL || params->sslparms.crlfile == NULL) { 1610 return (KMF_ERR_BAD_PARAMETER); 1611 } 1612 1613 crlfile = get_fullpath(params->sslparms.dirpath, 1614 params->sslparms.crlfile); 1615 1616 if (crlfile == NULL) 1617 return (KMF_ERR_BAD_PARAMETER); 1618 1619 if (isdir(crlfile)) { 1620 free(crlfile); 1621 return (KMF_ERR_BAD_PARAMETER); 1622 } 1623 1624 ret = KMF_IsCRLFile(handle, crlfile, &format); 1625 if (ret != KMF_OK) { 1626 free(crlfile); 1627 return (ret); 1628 } 1629 1630 if (bio_err == NULL) 1631 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 1632 1633 in = BIO_new_file(crlfile, "rb"); 1634 if (in == NULL) { 1635 SET_ERROR(kmfh, ERR_get_error()); 1636 ret = KMF_ERR_OPEN_FILE; 1637 goto end; 1638 } 1639 1640 if (format == KMF_FORMAT_ASN1) { 1641 x = d2i_X509_CRL_bio(in, NULL); 1642 } else if (format == KMF_FORMAT_PEM) { 1643 x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 1644 } 1645 1646 if (x == NULL) { /* should not happen */ 1647 SET_ERROR(kmfh, ERR_get_error()); 1648 ret = KMF_ERR_OPEN_FILE; 1649 goto end; 1650 } 1651 1652 mem = BIO_new(BIO_s_mem()); 1653 if (mem == NULL) { 1654 SET_ERROR(kmfh, ERR_get_error()); 1655 ret = KMF_ERR_MEMORY; 1656 goto end; 1657 } 1658 1659 (void) X509_CRL_print(mem, x); 1660 len = BIO_get_mem_data(mem, &memptr); 1661 if (len <= 0) { 1662 SET_ERROR(kmfh, ERR_get_error()); 1663 ret = KMF_ERR_MEMORY; 1664 goto end; 1665 } 1666 1667 data = malloc(len + 1); 1668 if (data == NULL) { 1669 ret = KMF_ERR_MEMORY; 1670 goto end; 1671 } 1672 1673 (void) memcpy(data, memptr, len); 1674 data[len] = '\0'; 1675 *crldata = data; 1676 1677end: 1678 if (x != NULL) 1679 X509_CRL_free(x); 1680 1681 if (crlfile != NULL) 1682 free(crlfile); 1683 1684 if (in != NULL) 1685 (void) BIO_free(in); 1686 1687 if (mem != NULL) 1688 (void) BIO_free(mem); 1689 1690 return (ret); 1691} 1692 1693KMF_RETURN 1694OpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) 1695{ 1696 KMF_RETURN ret = KMF_OK; 1697 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1698 KMF_ENCODE_FORMAT format; 1699 char *crlfile = NULL; 1700 BIO *in = NULL; 1701 1702 if (params == NULL || params->sslparms.crlfile == NULL) { 1703 return (KMF_ERR_BAD_PARAMETER); 1704 } 1705 1706 crlfile = get_fullpath(params->sslparms.dirpath, 1707 params->sslparms.crlfile); 1708 1709 if (crlfile == NULL) 1710 return (KMF_ERR_BAD_PARAMETER); 1711 1712 if (isdir(crlfile)) { 1713 ret = KMF_ERR_BAD_PARAMETER; 1714 goto end; 1715 } 1716 1717 ret = KMF_IsCRLFile(handle, crlfile, &format); 1718 if (ret != KMF_OK) 1719 goto end; 1720 1721 if (unlink(crlfile) != 0) { 1722 SET_SYS_ERROR(kmfh, errno); 1723 ret = KMF_ERR_INTERNAL; 1724 goto end; 1725 } 1726 1727end: 1728 if (in != NULL) 1729 (void) BIO_free(in); 1730 if (crlfile != NULL) 1731 free(crlfile); 1732 1733 return (ret); 1734} 1735 1736 1737KMF_RETURN 1738OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) 1739{ 1740 KMF_RETURN ret = KMF_OK; 1741 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1742 KMF_ENCODE_FORMAT format; 1743 BIO *in = NULL; 1744 X509 *xcert = NULL; 1745 X509_CRL *xcrl = NULL; 1746 STACK_OF(X509_REVOKED) *revoke_stack = NULL; 1747 X509_REVOKED *revoke; 1748 int i; 1749 1750 if (params == NULL || params->sslparms.crlfile == NULL || 1751 params->sslparms.certfile == NULL) { 1752 return (KMF_ERR_BAD_PARAMETER); 1753 } 1754 1755 ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); 1756 if (ret != KMF_OK) 1757 return (ret); 1758 1759 /* Read the CRL file and load it into a X509_CRL structure */ 1760 in = BIO_new_file(params->sslparms.crlfile, "rb"); 1761 if (in == NULL) { 1762 SET_ERROR(kmfh, ERR_get_error()); 1763 ret = KMF_ERR_OPEN_FILE; 1764 goto end; 1765 } 1766 1767 if (format == KMF_FORMAT_ASN1) { 1768 xcrl = d2i_X509_CRL_bio(in, NULL); 1769 } else if (format == KMF_FORMAT_PEM) { 1770 xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 1771 } 1772 1773 if (xcrl == NULL) { 1774 SET_ERROR(kmfh, ERR_get_error()); 1775 ret = KMF_ERR_BAD_CRLFILE; 1776 goto end; 1777 } 1778 (void) BIO_free(in); 1779 1780 /* Read the Certificate file and load it into a X509 structure */ 1781 ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); 1782 if (ret != KMF_OK) 1783 goto end; 1784 1785 in = BIO_new_file(params->sslparms.certfile, "rb"); 1786 if (in == NULL) { 1787 SET_ERROR(kmfh, ERR_get_error()); 1788 ret = KMF_ERR_OPEN_FILE; 1789 goto end; 1790 } 1791 1792 if (format == KMF_FORMAT_ASN1) { 1793 xcert = d2i_X509_bio(in, NULL); 1794 } else if (format == KMF_FORMAT_PEM) { 1795 xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 1796 } 1797 1798 if (xcert == NULL) { 1799 SET_ERROR(kmfh, ERR_get_error()); 1800 ret = KMF_ERR_BAD_CERTFILE; 1801 goto end; 1802 } 1803 1804 /* Check if the certificate and the CRL have same issuer */ 1805 if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { 1806 ret = KMF_ERR_ISSUER; 1807 goto end; 1808 } 1809 1810 /* Check to see if the certificate serial number is revoked */ 1811 revoke_stack = X509_CRL_get_REVOKED(xcrl); 1812 if (sk_X509_REVOKED_num(revoke_stack) <= 0) { 1813 /* No revoked certificates in the CRL file */ 1814 SET_ERROR(kmfh, ERR_get_error()); 1815 ret = KMF_ERR_EMPTY_CRL; 1816 goto end; 1817 } 1818 1819 for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { 1820 /*LINTED*/ 1821 revoke = sk_X509_REVOKED_value(revoke_stack, i); 1822 if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, 1823 revoke->serialNumber) == 0) { 1824 break; 1825 } 1826 } 1827 1828 if (i < sk_X509_REVOKED_num(revoke_stack)) { 1829 ret = KMF_OK; 1830 } else { 1831 ret = KMF_ERR_NOT_REVOKED; 1832 } 1833 1834end: 1835 if (in != NULL) 1836 (void) BIO_free(in); 1837 if (xcrl != NULL) 1838 X509_CRL_free(xcrl); 1839 if (xcert != NULL) 1840 X509_free(xcert); 1841 1842 return (ret); 1843} 1844 1845KMF_RETURN 1846OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 1847{ 1848 KMF_RETURN ret = KMF_OK; 1849 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1850 char str[256]; /* OpenSSL needs at least 120 byte buffer */ 1851 1852 ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str)); 1853 if (strlen(str)) { 1854 *msgstr = (char *)strdup(str); 1855 if ((*msgstr) == NULL) 1856 ret = KMF_ERR_MEMORY; 1857 } else { 1858 *msgstr = NULL; 1859 } 1860 1861 return (ret); 1862} 1863 1864static int 1865ext2NID(int kmfext) 1866{ 1867 switch (kmfext) { 1868 case KMF_X509_EXT_KEY_USAGE: 1869 return (NID_key_usage); 1870 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 1871 return (NID_private_key_usage_period); 1872 case KMF_X509_EXT_CERT_POLICIES: 1873 return (NID_certificate_policies); 1874 case KMF_X509_EXT_SUBJ_ALTNAME: 1875 return (NID_subject_alt_name); 1876 case KMF_X509_EXT_ISSUER_ALTNAME: 1877 return (NID_issuer_alt_name); 1878 case KMF_X509_EXT_BASIC_CONSTRAINTS: 1879 return (NID_basic_constraints); 1880 case KMF_X509_EXT_EXT_KEY_USAGE: 1881 return (NID_ext_key_usage); 1882 case KMF_X509_EXT_AUTH_KEY_ID: 1883 return (NID_authority_key_identifier); 1884 case KMF_X509_EXT_CRL_DIST_POINTS: 1885 return (NID_crl_distribution_points); 1886 case KMF_X509_EXT_SUBJ_KEY_ID: 1887 return (NID_subject_key_identifier); 1888 case KMF_X509_EXT_POLICY_MAPPINGS: 1889 return (OBJ_sn2nid("policyMappings")); 1890 case KMF_X509_EXT_NAME_CONSTRAINTS: 1891 return (OBJ_sn2nid("nameConstraints")); 1892 case KMF_X509_EXT_POLICY_CONSTRAINTS: 1893 return (OBJ_sn2nid("policyConstraints")); 1894 case KMF_X509_EXT_INHIBIT_ANY_POLICY: 1895 return (OBJ_sn2nid("inhibitAnyPolicy")); 1896 case KMF_X509_EXT_FRESHEST_CRL: 1897 return (OBJ_sn2nid("freshestCRL")); 1898 default: 1899 return (NID_undef); 1900 } 1901} 1902 1903KMF_RETURN 1904OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, 1905 KMF_PRINTABLE_ITEM flag, char *resultStr) 1906{ 1907 KMF_RETURN ret = KMF_OK; 1908 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1909 X509 *xcert = NULL; 1910 unsigned char *outbuf = NULL; 1911 unsigned char *outbuf_p; 1912 char *tmpstr = NULL; 1913 int j; 1914 int ext_index, nid, len; 1915 BIO *mem = NULL; 1916 STACK *emlst = NULL; 1917 X509_EXTENSION *ex; 1918 X509_CINF *ci; 1919 1920 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) { 1921 return (KMF_ERR_BAD_PARAMETER); 1922 } 1923 1924 /* copy cert data to outbuf */ 1925 outbuf = malloc(pcert->Length); 1926 if (outbuf == NULL) { 1927 return (KMF_ERR_MEMORY); 1928 } 1929 (void) memcpy(outbuf, pcert->Data, pcert->Length); 1930 1931 outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 1932 xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length); 1933 if (xcert == NULL) { 1934 SET_ERROR(kmfh, ERR_get_error()); 1935 ret = KMF_ERR_ENCODING; 1936 goto out; 1937 } 1938 1939 mem = BIO_new(BIO_s_mem()); 1940 if (mem == NULL) { 1941 SET_ERROR(kmfh, ERR_get_error()); 1942 ret = KMF_ERR_MEMORY; 1943 goto out; 1944 } 1945 1946 switch (flag) { 1947 case KMF_CERT_ISSUER: 1948 (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0, 1949 XN_FLAG_SEP_CPLUS_SPC); 1950 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 1951 break; 1952 1953 case KMF_CERT_SUBJECT: 1954 (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0, 1955 XN_FLAG_SEP_CPLUS_SPC); 1956 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 1957 break; 1958 1959 case KMF_CERT_VERSION: 1960 tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version); 1961 (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN); 1962 OPENSSL_free(tmpstr); 1963 len = strlen(resultStr); 1964 break; 1965 1966 case KMF_CERT_SERIALNUM: 1967 if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) { 1968 (void) strcpy(resultStr, "0x"); 1969 len = BIO_gets(mem, &resultStr[2], 1970 KMF_CERT_PRINTABLE_LEN - 2); 1971 } 1972 break; 1973 1974 case KMF_CERT_NOTBEFORE: 1975 (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert)); 1976 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 1977 break; 1978 1979 case KMF_CERT_NOTAFTER: 1980 (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert)); 1981 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 1982 break; 1983 1984 case KMF_CERT_PUBKEY_DATA: 1985 { 1986 EVP_PKEY *pkey = X509_get_pubkey(xcert); 1987 if (pkey == NULL) { 1988 SET_ERROR(kmfh, ERR_get_error()); 1989 ret = KMF_ERR_ENCODING; 1990 goto out; 1991 } 1992 1993 if (pkey->type == EVP_PKEY_RSA) { 1994 (void) BIO_printf(mem, 1995 "RSA Public Key: (%d bit)\n", 1996 BN_num_bits(pkey->pkey.rsa->n)); 1997 (void) RSA_print(mem, pkey->pkey.rsa, 0); 1998 } else if (pkey->type == EVP_PKEY_DSA) { 1999 (void) BIO_printf(mem, 2000 "%12sDSA Public Key:\n", ""); 2001 (void) DSA_print(mem, pkey->pkey.dsa, 0); 2002 } else { 2003 (void) BIO_printf(mem, 2004 "%12sUnknown Public Key:\n", ""); 2005 } 2006 (void) BIO_printf(mem, "\n"); 2007 EVP_PKEY_free(pkey); 2008 } 2009 len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2010 break; 2011 case KMF_CERT_SIGNATURE_ALG: 2012 case KMF_CERT_PUBKEY_ALG: 2013 if (flag == KMF_CERT_SIGNATURE_ALG) { 2014 len = i2a_ASN1_OBJECT(mem, 2015 xcert->sig_alg->algorithm); 2016 } else { 2017 len = i2a_ASN1_OBJECT(mem, 2018 xcert->cert_info->key->algor->algorithm); 2019 } 2020 2021 if (len > 0) { 2022 len = BIO_read(mem, resultStr, 2023 KMF_CERT_PRINTABLE_LEN); 2024 } 2025 break; 2026 2027 case KMF_CERT_EMAIL: 2028 emlst = X509_get1_email(xcert); 2029 for (j = 0; j < sk_num(emlst); j++) 2030 (void) BIO_printf(mem, "%s\n", sk_value(emlst, j)); 2031 2032 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2033 X509_email_free(emlst); 2034 break; 2035 case KMF_X509_EXT_ISSUER_ALTNAME: 2036 case KMF_X509_EXT_SUBJ_ALTNAME: 2037 case KMF_X509_EXT_KEY_USAGE: 2038 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 2039 case KMF_X509_EXT_CERT_POLICIES: 2040 case KMF_X509_EXT_BASIC_CONSTRAINTS: 2041 case KMF_X509_EXT_NAME_CONSTRAINTS: 2042 case KMF_X509_EXT_POLICY_CONSTRAINTS: 2043 case KMF_X509_EXT_EXT_KEY_USAGE: 2044 case KMF_X509_EXT_INHIBIT_ANY_POLICY: 2045 case KMF_X509_EXT_AUTH_KEY_ID: 2046 case KMF_X509_EXT_SUBJ_KEY_ID: 2047 case KMF_X509_EXT_POLICY_MAPPINGS: 2048 case KMF_X509_EXT_CRL_DIST_POINTS: 2049 case KMF_X509_EXT_FRESHEST_CRL: 2050 nid = ext2NID(flag); 2051 if (nid == NID_undef) { 2052 ret = KMF_ERR_EXTENSION_NOT_FOUND; 2053 goto out; 2054 } 2055 ci = xcert->cert_info; 2056 2057 ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1); 2058 if (ext_index == -1) { 2059 SET_ERROR(kmfh, ERR_get_error()); 2060 2061 ret = KMF_ERR_EXTENSION_NOT_FOUND; 2062 goto out; 2063 } 2064 ex = X509v3_get_ext(ci->extensions, ext_index); 2065 2066 (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); 2067 2068 if (BIO_printf(mem, ": %s\n", 2069 X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 2070 0) { 2071 SET_ERROR(kmfh, ERR_get_error()); 2072 ret = KMF_ERR_ENCODING; 2073 goto out; 2074 } 2075 if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) { 2076 (void) BIO_printf(mem, "%*s", 4, ""); 2077 (void) M_ASN1_OCTET_STRING_print(mem, ex->value); 2078 } 2079 if (BIO_write(mem, "\n", 1) <= 0) { 2080 SET_ERROR(kmfh, ERR_get_error()); 2081 ret = KMF_ERR_ENCODING; 2082 goto out; 2083 } 2084 len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2085 } 2086 if (len <= 0) { 2087 SET_ERROR(kmfh, ERR_get_error()); 2088 ret = KMF_ERR_ENCODING; 2089 } 2090 2091out: 2092 if (outbuf != NULL) { 2093 free(outbuf); 2094 } 2095 2096 if (xcert != NULL) { 2097 X509_free(xcert); 2098 } 2099 2100 if (mem != NULL) { 2101 (void) BIO_free(mem); 2102 } 2103 2104 return (ret); 2105} 2106KMF_RETURN 2107/*ARGSUSED*/ 2108OpenSSL_GetPrikeyByCert(KMF_HANDLE_T handle, 2109 KMF_CRYPTOWITHCERT_PARAMS *params, 2110 KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, 2111 KMF_KEY_ALG keytype) 2112{ 2113 KMF_RETURN rv = KMF_OK; 2114 KMF_FINDKEY_PARAMS fkparms; 2115 uint32_t numkeys = 0; 2116 2117 if (params == NULL && params->sslparms.keyfile == NULL) 2118 return (KMF_ERR_BAD_PARAMETER); 2119 2120 /* 2121 * This is really just a FindKey operation, reuse the 2122 * FindKey function. 2123 */ 2124 (void *)memset(&fkparms, 0, sizeof (fkparms)); 2125 fkparms.kstype = KMF_KEYSTORE_OPENSSL; 2126 fkparms.keyclass = KMF_ASYM_PRI; 2127 fkparms.keytype = keytype; 2128 fkparms.format = params->format; 2129 fkparms.sslparms = params->sslparms; 2130 2131 rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys); 2132 2133 return (rv); 2134} 2135 2136KMF_RETURN 2137/*ARGSUSED*/ 2138OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 2139 KMF_OID *AlgOID, KMF_DATA *ciphertext, 2140 KMF_DATA *output) 2141{ 2142 KMF_RETURN ret = KMF_OK; 2143 RSA *rsa = NULL; 2144 unsigned int in_len = 0, out_len = 0; 2145 unsigned int total_decrypted = 0, modulus_len = 0; 2146 uint8_t *in_data, *out_data; 2147 int i, blocks; 2148 2149 if (key == NULL || AlgOID == NULL || 2150 ciphertext == NULL || output == NULL || 2151 ciphertext->Data == NULL || 2152 output->Data == NULL) 2153 return (KMF_ERR_BAD_PARAMETER); 2154 2155 if (key->keyalg == KMF_RSA) { 2156 rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp); 2157 modulus_len = RSA_size(rsa); 2158 } else { 2159 return (KMF_ERR_BAD_PARAMETER); 2160 } 2161 2162 blocks = ciphertext->Length/modulus_len; 2163 out_data = output->Data; 2164 in_data = ciphertext->Data; 2165 out_len = modulus_len - 11; 2166 in_len = modulus_len; 2167 2168 for (i = 0; i < blocks; i++) { 2169 out_len = RSA_private_decrypt(in_len, 2170 in_data, out_data, rsa, RSA_PKCS1_PADDING); 2171 2172 if (out_len == 0) { 2173 ret = KMF_ERR_INTERNAL; 2174 goto cleanup; 2175 } 2176 2177 out_data += out_len; 2178 total_decrypted += out_len; 2179 in_data += in_len; 2180 } 2181 2182 output->Length = total_decrypted; 2183 2184cleanup: 2185 RSA_free(rsa); 2186 if (ret != KMF_OK) 2187 output->Length = 0; 2188 2189 return (ret); 2190 2191} 2192 2193/* 2194 * This function will create a certid from issuer_cert and user_cert. 2195 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate 2196 * certid memory after use. 2197 */ 2198static KMF_RETURN 2199create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert, 2200 const KMF_DATA *user_cert, OCSP_CERTID **certid) 2201{ 2202 KMF_RETURN ret = KMF_OK; 2203 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2204 X509 *issuer = NULL; 2205 X509 *cert = NULL; 2206 unsigned char *ptmp; 2207 2208 if (issuer_cert == NULL || user_cert == NULL) { 2209 return (KMF_ERR_BAD_PARAMETER); 2210 } 2211 2212 /* convert the DER-encoded issuer cert to an internal X509 */ 2213 ptmp = issuer_cert->Data; 2214 issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2215 issuer_cert->Length); 2216 if (issuer == NULL) { 2217 SET_ERROR(kmfh, ERR_get_error()); 2218 ret = KMF_ERR_OCSP_BAD_ISSUER; 2219 goto end; 2220 } 2221 2222 /* convert the DER-encoded user cert to an internal X509 */ 2223 ptmp = user_cert->Data; 2224 cert = d2i_X509(NULL, (const uchar_t **)&ptmp, 2225 user_cert->Length); 2226 if (cert == NULL) { 2227 SET_ERROR(kmfh, ERR_get_error()); 2228 2229 ret = KMF_ERR_OCSP_BAD_CERT; 2230 goto end; 2231 } 2232 2233 /* create a CERTID */ 2234 *certid = OCSP_cert_to_id(NULL, cert, issuer); 2235 if (*certid == NULL) { 2236 SET_ERROR(kmfh, ERR_get_error()); 2237 ret = KMF_ERR_OCSP_CERTID; 2238 goto end; 2239 } 2240 2241end: 2242 if (issuer != NULL) { 2243 X509_free(issuer); 2244 } 2245 2246 if (cert != NULL) { 2247 X509_free(cert); 2248 } 2249 2250 return (ret); 2251} 2252 2253KMF_RETURN 2254OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, 2255 char *reqfile) 2256{ 2257 KMF_RETURN ret = KMF_OK; 2258 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2259 OCSP_CERTID *id = NULL; 2260 OCSP_REQUEST *req = NULL; 2261 BIO *derbio = NULL; 2262 2263 if (params->user_cert == NULL || params->issuer_cert == NULL || 2264 reqfile == NULL) { 2265 return (KMF_ERR_BAD_PARAMETER); 2266 } 2267 2268 ret = create_certid(handle, params->issuer_cert, params->user_cert, 2269 &id); 2270 if (ret != KMF_OK) { 2271 return (ret); 2272 } 2273 2274 /* Create an OCSP request */ 2275 req = OCSP_REQUEST_new(); 2276 if (req == NULL) { 2277 SET_ERROR(kmfh, ERR_get_error()); 2278 ret = KMF_ERR_OCSP_CREATE_REQUEST; 2279 goto end; 2280 } 2281 2282 if (!OCSP_request_add0_id(req, id)) { 2283 ret = KMF_ERR_OCSP_CREATE_REQUEST; 2284 goto end; 2285 } 2286 2287 /* Write the request to the output file with DER encoding */ 2288 derbio = BIO_new_file(reqfile, "wb"); 2289 if (!derbio) { 2290 SET_ERROR(kmfh, ERR_get_error()); 2291 ret = KMF_ERR_OPEN_FILE; 2292 goto end; 2293 } 2294 if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) { 2295 ret = KMF_ERR_ENCODING; 2296 } 2297 2298end: 2299 /* 2300 * We don't need to free "id" explicitely, because OCSP_REQUEST_free() 2301 * will deallocate certid's space also. 2302 */ 2303 if (req != NULL) { 2304 OCSP_REQUEST_free(req); 2305 } 2306 2307 if (derbio != NULL) { 2308 (void) BIO_free(derbio); 2309 } 2310 2311 return (ret); 2312} 2313 2314/* ocsp_find_signer_sk() is copied from openssl source */ 2315static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 2316{ 2317 int i; 2318 unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 2319 2320 /* Easy if lookup by name */ 2321 if (id->type == V_OCSP_RESPID_NAME) 2322 return (X509_find_by_subject(certs, id->value.byName)); 2323 2324 /* Lookup by key hash */ 2325 2326 /* If key hash isn't SHA1 length then forget it */ 2327 if (id->value.byKey->length != SHA_DIGEST_LENGTH) 2328 return (NULL); 2329 2330 keyhash = id->value.byKey->data; 2331 /* Calculate hash of each key and compare */ 2332 for (i = 0; i < sk_X509_num(certs); i++) { 2333 /*LINTED*/ 2334 X509 *x = sk_X509_value(certs, i); 2335 (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 2336 if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 2337 return (x); 2338 } 2339 return (NULL); 2340} 2341 2342/* ocsp_find_signer() is copied from openssl source */ 2343/*ARGSUSED*/ 2344static int 2345ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, 2346 X509_STORE *st, unsigned long flags) 2347{ 2348 X509 *signer; 2349 OCSP_RESPID *rid = bs->tbsResponseData->responderId; 2350 if ((signer = ocsp_find_signer_sk(certs, rid))) { 2351 *psigner = signer; 2352 return (2); 2353 } 2354 if (!(flags & OCSP_NOINTERN) && 2355 (signer = ocsp_find_signer_sk(bs->certs, rid))) { 2356 *psigner = signer; 2357 return (1); 2358 } 2359 /* Maybe lookup from store if by subject name */ 2360 2361 *psigner = NULL; 2362 return (0); 2363} 2364 2365/* 2366 * This function will verify the signature of a basic response, using 2367 * the public key from the OCSP responder certificate. 2368 */ 2369static KMF_RETURN 2370check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, 2371 KMF_DATA *signer_cert, KMF_DATA *issuer_cert) 2372{ 2373 KMF_RETURN ret = KMF_OK; 2374 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2375 STACK_OF(X509) *cert_stack = NULL; 2376 X509 *signer = NULL; 2377 X509 *issuer = NULL; 2378 EVP_PKEY *skey = NULL; 2379 unsigned char *ptmp; 2380 2381 2382 if (bs == NULL || issuer_cert == NULL) 2383 return (KMF_ERR_BAD_PARAMETER); 2384 2385 /* 2386 * Find the certificate that signed the basic response. 2387 * 2388 * If signer_cert is not NULL, we will use that as the signer cert. 2389 * Otherwise, we will check if the issuer cert is actually the signer. 2390 * If we still do not find a signer, we will look for it from the 2391 * certificate list came with the response file. 2392 */ 2393 if (signer_cert != NULL) { 2394 ptmp = signer_cert->Data; 2395 signer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2396 signer_cert->Length); 2397 if (signer == NULL) { 2398 SET_ERROR(kmfh, ERR_get_error()); 2399 ret = KMF_ERR_OCSP_BAD_SIGNER; 2400 goto end; 2401 } 2402 } else { 2403 /* 2404 * Convert the issuer cert into X509 and push it into a 2405 * stack to be used by ocsp_find_signer(). 2406 */ 2407 ptmp = issuer_cert->Data; 2408 issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2409 issuer_cert->Length); 2410 if (issuer == NULL) { 2411 SET_ERROR(kmfh, ERR_get_error()); 2412 ret = KMF_ERR_OCSP_BAD_ISSUER; 2413 goto end; 2414 } 2415 2416 if ((cert_stack = sk_X509_new_null()) == NULL) { 2417 ret = KMF_ERR_INTERNAL; 2418 goto end; 2419 } 2420 2421 if (sk_X509_push(cert_stack, issuer) == NULL) { 2422 ret = KMF_ERR_INTERNAL; 2423 goto end; 2424 } 2425 2426 ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0); 2427 if (!ret) { 2428 /* can not find the signer */ 2429 ret = KMF_ERR_OCSP_BAD_SIGNER; 2430 goto end; 2431 } 2432 } 2433 2434 /* Verify the signature of the response */ 2435 skey = X509_get_pubkey(signer); 2436 if (skey == NULL) { 2437 ret = KMF_ERR_OCSP_BAD_SIGNER; 2438 goto end; 2439 } 2440 2441 ret = OCSP_BASICRESP_verify(bs, skey, 0); 2442 if (ret == 0) { 2443 ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE; 2444 goto end; 2445 } 2446 2447end: 2448 if (issuer != NULL) { 2449 X509_free(issuer); 2450 } 2451 2452 if (signer != NULL) { 2453 X509_free(signer); 2454 } 2455 2456 if (skey != NULL) { 2457 EVP_PKEY_free(skey); 2458 } 2459 2460 if (cert_stack != NULL) { 2461 sk_X509_free(cert_stack); 2462 } 2463 2464 return (ret); 2465} 2466 2467 2468 2469KMF_RETURN 2470OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, 2471 KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 2472 KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) 2473{ 2474 KMF_RETURN ret = KMF_OK; 2475 BIO *derbio = NULL; 2476 OCSP_RESPONSE *resp = NULL; 2477 OCSP_BASICRESP *bs = NULL; 2478 OCSP_CERTID *id = NULL; 2479 OCSP_SINGLERESP *single = NULL; 2480 ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 2481 int index, status, reason; 2482 2483 if (params_in == NULL || params_in->issuer_cert == NULL || 2484 params_in->user_cert == NULL || params_in->response == NULL) { 2485 return (KMF_ERR_BAD_PARAMETER); 2486 } 2487 2488 if (params_out == NULL) { 2489 return (KMF_ERR_BAD_PARAMETER); 2490 } 2491 2492 /* Read in the response */ 2493 derbio = BIO_new_mem_buf(params_in->response->Data, 2494 params_in->response->Length); 2495 if (!derbio) { 2496 ret = KMF_ERR_MEMORY; 2497 return (ret); 2498 } 2499 2500 resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 2501 if (resp == NULL) { 2502 ret = KMF_ERR_OCSP_MALFORMED_RESPONSE; 2503 goto end; 2504 } 2505 2506 /* Check the response status */ 2507 status = OCSP_response_status(resp); 2508 params_out->response_status = status; 2509 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 2510 ret = KMF_ERR_OCSP_RESPONSE_STATUS; 2511 goto end; 2512 } 2513 2514#ifdef DEBUG 2515 printf("Successfully checked the response file status.\n"); 2516#endif /* DEBUG */ 2517 2518 /* Extract basic response */ 2519 bs = OCSP_response_get1_basic(resp); 2520 if (bs == NULL) { 2521 ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE; 2522 goto end; 2523 } 2524 2525#ifdef DEBUG 2526 printf("Successfully retrieved the basic response.\n"); 2527#endif /* DEBUG */ 2528 2529 /* Check the basic response signature if required */ 2530 if (params_in->ignore_response_sign == B_FALSE) { 2531 ret = check_response_signature(handle, bs, 2532 params_in->signer_cert, params_in->issuer_cert); 2533 if (ret != KMF_OK) 2534 goto end; 2535 } 2536 2537#ifdef DEBUG 2538 printf("Successfully verified the response signature.\n"); 2539#endif /* DEBUG */ 2540 2541 /* Create a certid for the certificate in question */ 2542 ret = create_certid(handle, params_in->issuer_cert, 2543 params_in->user_cert, &id); 2544 if (ret != KMF_OK) { 2545 ret = KMF_ERR_OCSP_CERTID; 2546 goto end; 2547 } 2548 2549#ifdef DEBUG 2550 printf("successfully created a certid for the cert.\n"); 2551#endif /* DEBUG */ 2552 2553 /* Find the index of the single response for the certid */ 2554 index = OCSP_resp_find(bs, id, -1); 2555 if (index < 0) { 2556 /* cound not find this certificate in the response */ 2557 ret = KMF_ERR_OCSP_UNKNOWN_CERT; 2558 goto end; 2559 } 2560 2561#ifdef DEBUG 2562 printf("Successfully found the single response index for the cert.\n"); 2563#endif /* DEBUG */ 2564 2565 /* Retrieve the single response and get the cert status */ 2566 single = OCSP_resp_get0(bs, index); 2567 status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, 2568 &nextupd); 2569 if (status == V_OCSP_CERTSTATUS_GOOD) { 2570 params_out->cert_status = OCSP_GOOD; 2571 } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { 2572 params_out->cert_status = OCSP_UNKNOWN; 2573 } else { /* revoked */ 2574 params_out->cert_status = OCSP_REVOKED; 2575 params_out->reason = reason; 2576 } 2577 ret = KMF_OK; 2578 2579 /* Verify the time */ 2580 if (!OCSP_check_validity(thisupd, nextupd, 300, 2581 params_in->response_lifetime)) { 2582 ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; 2583 goto end; 2584 } 2585 2586#ifdef DEBUG 2587 printf("Successfully verify the time.\n"); 2588#endif /* DEBUG */ 2589 2590end: 2591 if (derbio != NULL) 2592 (void) BIO_free(derbio); 2593 2594 if (resp != NULL) 2595 OCSP_RESPONSE_free(resp); 2596 2597 if (bs != NULL) 2598 OCSP_BASICRESP_free(bs); 2599 2600 if (id != NULL) 2601 OCSP_CERTID_free(id); 2602 2603 return (ret); 2604} 2605 2606static KMF_RETURN 2607fetch_key(KMF_HANDLE_T handle, char *path, 2608 KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) 2609{ 2610 KMF_RETURN rv = KMF_OK; 2611 EVP_PKEY *pkey; 2612 KMF_RAW_SYM_KEY *rkey = NULL; 2613 2614 /* Make sure the requested file actually exists. */ 2615 if (access(path, F_OK) != 0) { 2616 return (KMF_ERR_KEY_NOT_FOUND); 2617 } 2618 2619 if (keyclass == KMF_ASYM_PRI || 2620 keyclass == KMF_ASYM_PUB) { 2621 pkey = openssl_load_key(handle, path); 2622 if (pkey == NULL) { 2623 return (KMF_ERR_KEY_NOT_FOUND); 2624 } 2625 if (key != NULL) { 2626 if (pkey->type == EVP_PKEY_RSA) 2627 key->keyalg = KMF_RSA; 2628 else if (pkey->type == EVP_PKEY_DSA) 2629 key->keyalg = KMF_DSA; 2630 2631 key->kstype = KMF_KEYSTORE_OPENSSL; 2632 key->keyclass = keyclass; 2633 key->keyp = (void *)pkey; 2634 key->israw = FALSE; 2635 key->keylabel = path; 2636 } else { 2637 EVP_PKEY_free(pkey); 2638 pkey = NULL; 2639 } 2640 } else if (keyclass == KMF_SYMMETRIC) { 2641 KMF_ENCODE_FORMAT fmt; 2642 /* 2643 * If the file is a recognized format, 2644 * then it is NOT a symmetric key. 2645 */ 2646 rv = KMF_GetFileFormat(path, &fmt); 2647 if (rv == KMF_OK || fmt != 0) { 2648 return (KMF_ERR_KEY_NOT_FOUND); 2649 } else if (rv == KMF_ERR_ENCODING) { 2650 /* 2651 * If we don't know the encoding, 2652 * it is probably a symmetric key. 2653 */ 2654 rv = KMF_OK; 2655 } 2656 2657 if (key != NULL) { 2658 KMF_DATA keyvalue; 2659 rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 2660 if (rkey == NULL) { 2661 rv = KMF_ERR_MEMORY; 2662 goto out; 2663 } 2664 2665 (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 2666 rv = KMF_ReadInputFile(handle, path, &keyvalue); 2667 if (rv != KMF_OK) 2668 goto out; 2669 2670 rkey->keydata.len = keyvalue.Length; 2671 rkey->keydata.val = keyvalue.Data; 2672 2673 key->kstype = KMF_KEYSTORE_OPENSSL; 2674 key->keyclass = keyclass; 2675 key->israw = TRUE; 2676 key->keylabel = path; 2677 key->keyp = (void *)rkey; 2678 } 2679 } 2680out: 2681 if (rv != KMF_OK) { 2682 if (rkey != NULL) { 2683 KMF_FreeRawSymKey(rkey); 2684 } 2685 if (pkey != NULL) 2686 EVP_PKEY_free(pkey); 2687 2688 if (key != NULL) { 2689 key->keyalg = KMF_KEYALG_NONE; 2690 key->keyclass = KMF_KEYCLASS_NONE; 2691 key->keyp = NULL; 2692 } 2693 } 2694 2695 return (rv); 2696} 2697 2698KMF_RETURN 2699OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, 2700 KMF_KEY_HANDLE *key, uint32_t *numkeys) 2701{ 2702 KMF_RETURN rv = KMF_OK; 2703 char *fullpath = NULL; 2704 2705 if (handle == NULL || params == NULL || numkeys == NULL) 2706 return (KMF_ERR_BAD_PARAMETER); 2707 2708 if (params->keyclass != KMF_ASYM_PUB && 2709 params->keyclass != KMF_ASYM_PRI && 2710 params->keyclass != KMF_SYMMETRIC) 2711 return (KMF_ERR_BAD_KEY_CLASS); 2712 2713 fullpath = get_fullpath(params->sslparms.dirpath, 2714 params->sslparms.keyfile); 2715 2716 if (fullpath == NULL) 2717 return (KMF_ERR_BAD_PARAMETER); 2718 2719 *numkeys = 0; 2720 2721 if (isdir(fullpath)) { 2722 DIR *dirp; 2723 struct dirent *dp; 2724 int n = 0; 2725 2726 /* open all files in the directory and attempt to read them */ 2727 if ((dirp = opendir(fullpath)) == NULL) { 2728 return (KMF_ERR_BAD_PARAMETER); 2729 } 2730 rewinddir(dirp); 2731 while ((dp = readdir(dirp)) != NULL) { 2732 if (strcmp(dp->d_name, ".") && 2733 strcmp(dp->d_name, "..")) { 2734 char *fname; 2735 2736 fname = get_fullpath(fullpath, 2737 (char *)&dp->d_name); 2738 2739 rv = fetch_key(handle, fname, 2740 params->keyclass, 2741 key ? &key[n] : NULL); 2742 2743 if (rv == KMF_OK) 2744 n++; 2745 2746 if (rv != KMF_OK || key == NULL) 2747 free(fname); 2748 } 2749 } 2750 (void) closedir(dirp); 2751 free(fullpath); 2752 (*numkeys) = n; 2753 } else { 2754 rv = fetch_key(handle, fullpath, params->keyclass, key); 2755 if (rv == KMF_OK) 2756 (*numkeys) = 1; 2757 2758 if (rv != KMF_OK || key == NULL) 2759 free(fullpath); 2760 } 2761 2762 if ((*numkeys) == 0) 2763 rv = KMF_ERR_KEY_NOT_FOUND; 2764 2765 return (rv); 2766} 2767 2768#define HANDLE_PK12_ERROR { \ 2769 SET_ERROR(kmfh, ERR_get_error()); \ 2770 rv = KMF_ERR_ENCODING; \ 2771 goto out; \ 2772} 2773 2774static KMF_RETURN 2775write_pkcs12(KMF_HANDLE *kmfh, 2776 BIO *bio, 2777 KMF_CREDENTIAL *cred, 2778 EVP_PKEY *pkey, 2779 X509 *sslcert) 2780{ 2781 KMF_RETURN rv = KMF_OK; 2782 STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 2783 PKCS12_SAFEBAG *bag = NULL; 2784 PKCS7 *cert_authsafe = NULL; 2785 PKCS8_PRIV_KEY_INFO *p8 = NULL; 2786 PKCS7 *key_authsafe = NULL; 2787 STACK_OF(PKCS7) *authsafe_stack = NULL; 2788 PKCS12 *p12_elem = NULL; 2789 char *lab = NULL; 2790 int lab_len = 0; 2791 unsigned char keyid[EVP_MAX_MD_SIZE]; 2792 unsigned int keyidlen = 0; 2793 2794 /* Must have at least a cert OR a key */ 2795 if (sslcert == NULL && pkey == NULL) 2796 return (KMF_ERR_BAD_PARAMETER); 2797 2798 (void) memset(keyid, 0, sizeof (keyid)); 2799 /* 2800 * Section 1: 2801 * 2802 * The first PKCS#12 container (safebag) will hold the certificates 2803 * associated with this key. The result of this section is a 2804 * PIN-encrypted PKCS#7 container (authsafe). If there are no 2805 * certificates, there is no point in creating the "safebag" or the 2806 * "authsafe" so we go to the next section. 2807 */ 2808 if (sslcert != NULL && pkey != NULL) { 2809 if (X509_check_private_key(sslcert, pkey)) { 2810 (void) X509_digest(sslcert, EVP_sha1(), keyid, 2811 &keyidlen); 2812 } else { 2813 /* The key doesn't match the cert */ 2814 HANDLE_PK12_ERROR 2815 } 2816 } 2817 2818 bag_stack = sk_PKCS12_SAFEBAG_new_null(); 2819 if (bag_stack == NULL) 2820 return (KMF_ERR_MEMORY); 2821 2822 if (sslcert != NULL) { 2823 /* Convert cert from X509 struct to PKCS#12 bag */ 2824 bag = PKCS12_x5092certbag(sslcert); 2825 if (bag == NULL) { 2826 HANDLE_PK12_ERROR 2827 } 2828 2829 /* Add the key id to the certificate bag. */ 2830 if (keyidlen > 0 && 2831 !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 2832 HANDLE_PK12_ERROR 2833 } 2834 2835 /* Pile it on the bag_stack. */ 2836 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 2837 HANDLE_PK12_ERROR 2838 } 2839#if 0 2840 /* No support for CA certs yet */ 2841 if (cacerts != NULL && ncacerts > 0) { 2842 int i; 2843 for (i = 0; i < ncacerts; i++) { 2844 KMF_X509_DER_CERT *c = &cacerts[i]; 2845 X509 *ca = NULL; 2846 2847 uchar_t *p = (uchar_t *)c->certificate.Data; 2848 ca = d2i_X509(NULL, &p, 2849 c->certificate.Length); 2850 if (ca == NULL) { 2851 HANDLE_PK12_ERROR 2852 } 2853 /* Convert CA cert to PKCS#12 bag. */ 2854 bag = PKCS12_x5092certbag(ca); 2855 if (bag == NULL) { 2856 sk_PKCS12_SAFEBAG_pop_free(bag_stack, 2857 PKCS12_SAFEBAG_free); 2858 HANDLE_PK12_ERROR 2859 } 2860 /* Pile it onto the bag_stack. */ 2861 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 2862 HANDLE_PK12_ERROR 2863 } 2864 } 2865 } 2866#endif 2867 /* Turn bag_stack of certs into encrypted authsafe. */ 2868 cert_authsafe = PKCS12_pack_p7encdata( 2869 NID_pbe_WithSHA1And40BitRC2_CBC, 2870 cred->cred, 2871 cred->credlen, NULL, 0, 2872 PKCS12_DEFAULT_ITER, 2873 bag_stack); 2874 2875 /* Clear away this bag_stack, we're done with it. */ 2876 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 2877 bag_stack = NULL; 2878 2879 if (cert_authsafe == NULL) { 2880 HANDLE_PK12_ERROR 2881 } 2882 } 2883 /* 2884 * Section 2: 2885 * 2886 * The second PKCS#12 container (safebag) will hold the private key 2887 * that goes with the certificates above. The results of this section 2888 * is an unencrypted PKCS#7 container (authsafe). If there is no 2889 * private key, there is no point in creating the "safebag" or the 2890 * "authsafe" so we go to the next section. 2891 */ 2892 if (pkey != NULL) { 2893 p8 = EVP_PKEY2PKCS8(pkey); 2894 if (p8 == NULL) { 2895 HANDLE_PK12_ERROR 2896 } 2897 /* Put the shrouded key into a PKCS#12 bag. */ 2898 bag = PKCS12_MAKE_SHKEYBAG( 2899 NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 2900 cred->cred, cred->credlen, 2901 NULL, 0, PKCS12_DEFAULT_ITER, p8); 2902 2903 /* Clean up the PKCS#8 shrouded key, don't need it now. */ 2904 PKCS8_PRIV_KEY_INFO_free(p8); 2905 p8 = NULL; 2906 2907 if (bag == NULL) { 2908 HANDLE_PK12_ERROR 2909 } 2910 if (keyidlen && 2911 !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 2912 HANDLE_PK12_ERROR 2913 } 2914 if (lab != NULL) { 2915 if (!PKCS12_add_friendlyname(bag, 2916 (char *)lab, lab_len)) { 2917 HANDLE_PK12_ERROR 2918 } 2919 } 2920 /* Start a PKCS#12 safebag container for the private key. */ 2921 bag_stack = sk_PKCS12_SAFEBAG_new_null(); 2922 if (bag_stack == NULL) { 2923 HANDLE_PK12_ERROR 2924 } 2925 2926 /* Pile on the private key on the bag_stack. */ 2927 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 2928 HANDLE_PK12_ERROR 2929 } 2930 key_authsafe = PKCS12_pack_p7data(bag_stack); 2931 2932 /* Clear away this bag_stack, we're done with it. */ 2933 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 2934 bag_stack = NULL; 2935 2936 if (key_authsafe == NULL) { 2937 HANDLE_PK12_ERROR 2938 } 2939 } 2940 /* 2941 * Section 3: 2942 * 2943 * This is where the two PKCS#7 containers, one for the certificates 2944 * and one for the private key, are put together into a PKCS#12 2945 * element. This final PKCS#12 element is written to the export file. 2946 */ 2947 2948 /* Start a PKCS#7 stack. */ 2949 authsafe_stack = sk_PKCS7_new_null(); 2950 if (authsafe_stack == NULL) { 2951 HANDLE_PK12_ERROR 2952 } 2953 if (key_authsafe != NULL) { 2954 if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) { 2955 HANDLE_PK12_ERROR 2956 } 2957 } 2958 if (cert_authsafe != NULL) { 2959 if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) { 2960 HANDLE_PK12_ERROR 2961 } 2962 } 2963 p12_elem = PKCS12_init(NID_pkcs7_data); 2964 if (p12_elem == NULL) { 2965 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 2966 HANDLE_PK12_ERROR 2967 } 2968 2969 /* Put the PKCS#7 stack into the PKCS#12 element. */ 2970 if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) { 2971 HANDLE_PK12_ERROR 2972 } 2973 /* Clear away the PKCS#7 stack, we're done with it. */ 2974 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 2975 authsafe_stack = NULL; 2976 2977 /* Set the integrity MAC on the PKCS#12 element. */ 2978 if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen, 2979 NULL, 0, PKCS12_DEFAULT_ITER, NULL)) { 2980 HANDLE_PK12_ERROR 2981 } 2982 2983 /* Write the PKCS#12 element to the export file. */ 2984 if (!i2d_PKCS12_bio(bio, p12_elem)) { 2985 HANDLE_PK12_ERROR 2986 } 2987 2988 PKCS12_free(p12_elem); 2989out: 2990 if (rv != KMF_OK) { 2991 /* Clear away this bag_stack, we're done with it. */ 2992 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 2993 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 2994 } 2995 return (rv); 2996} 2997 2998static EVP_PKEY * 2999ImportRawRSAKey(KMF_RAW_RSA_KEY *key) 3000{ 3001 RSA *rsa = NULL; 3002 EVP_PKEY *newkey = NULL; 3003 3004 if ((rsa = RSA_new()) == NULL) 3005 return (NULL); 3006 3007 if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL) 3008 return (NULL); 3009 3010 if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) == 3011 NULL) 3012 return (NULL); 3013 3014 if (key->priexp.val != NULL) 3015 if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len, 3016 rsa->d)) == NULL) 3017 return (NULL); 3018 3019 if (key->prime1.val != NULL) 3020 if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len, 3021 rsa->p)) == NULL) 3022 return (NULL); 3023 3024 if (key->prime2.val != NULL) 3025 if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len, 3026 rsa->q)) == NULL) 3027 return (NULL); 3028 3029 if (key->exp1.val != NULL) 3030 if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, 3031 rsa->dmp1)) == NULL) 3032 return (NULL); 3033 3034 if (key->exp2.val != NULL) 3035 if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, 3036 rsa->dmq1)) == NULL) 3037 return (NULL); 3038 3039 if (key->coef.val != NULL) 3040 if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len, 3041 rsa->iqmp)) == NULL) 3042 return (NULL); 3043 3044 if ((newkey = EVP_PKEY_new()) == NULL) 3045 return (NULL); 3046 3047 (void) EVP_PKEY_set1_RSA(newkey, rsa); 3048 3049 /* The original key must be freed once here or it leaks memory */ 3050 RSA_free(rsa); 3051 3052 return (newkey); 3053} 3054 3055static EVP_PKEY * 3056ImportRawDSAKey(KMF_RAW_DSA_KEY *key) 3057{ 3058 DSA *dsa = NULL; 3059 EVP_PKEY *newkey = NULL; 3060 3061 if ((dsa = DSA_new()) == NULL) 3062 return (NULL); 3063 3064 if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len, 3065 dsa->p)) == NULL) 3066 return (NULL); 3067 3068 if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len, 3069 dsa->q)) == NULL) 3070 return (NULL); 3071 3072 if ((dsa->g = BN_bin2bn(key->base.val, key->base.len, 3073 dsa->g)) == NULL) 3074 return (NULL); 3075 3076 if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len, 3077 dsa->priv_key)) == NULL) 3078 return (NULL); 3079 3080 if ((newkey = EVP_PKEY_new()) == NULL) 3081 return (NULL); 3082 3083 (void) EVP_PKEY_set1_DSA(newkey, dsa); 3084 3085 /* The original key must be freed once here or it leaks memory */ 3086 DSA_free(dsa); 3087 return (newkey); 3088} 3089 3090static KMF_RETURN 3091ExportPK12FromRawData(KMF_HANDLE_T handle, 3092 KMF_CREDENTIAL *cred, 3093 int numcerts, KMF_X509_DER_CERT *certlist, 3094 int numkeys, KMF_KEY_HANDLE *keylist, 3095 char *filename) 3096{ 3097 KMF_RETURN rv = KMF_OK; 3098 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3099 BIO *bio = NULL; 3100 X509 *xcert = NULL; 3101 EVP_PKEY *pkey = NULL; 3102 int i; 3103 3104 /* 3105 * Open the output file. 3106 */ 3107 if ((bio = BIO_new_file(filename, "wb")) == NULL) { 3108 SET_ERROR(kmfh, ERR_get_error()); 3109 rv = KMF_ERR_OPEN_FILE; 3110 goto cleanup; 3111 } 3112 3113 if (numcerts > 0 && numkeys > 0) { 3114 for (i = 0; rv == KMF_OK && i < numcerts; i++) { 3115 KMF_RAW_KEY_DATA *key = NULL; 3116 const uchar_t *p = certlist[i].certificate.Data; 3117 long len = certlist[i].certificate.Length; 3118 3119 if (i < numkeys) { 3120 key = (KMF_RAW_KEY_DATA *)keylist[i].keyp; 3121 3122 if (key->keytype == KMF_RSA) { 3123 pkey = ImportRawRSAKey( 3124 &key->rawdata.rsa); 3125 } else if (key->keytype == KMF_DSA) { 3126 pkey = ImportRawDSAKey( 3127 &key->rawdata.dsa); 3128 } else { 3129 rv = KMF_ERR_BAD_PARAMETER; 3130 } 3131 } 3132 3133 xcert = d2i_X509(NULL, &p, len); 3134 if (xcert == NULL) { 3135 SET_ERROR(kmfh, ERR_get_error()); 3136 rv = KMF_ERR_ENCODING; 3137 } 3138 /* Stick the key and the cert into a PKCS#12 file */ 3139 rv = write_pkcs12(kmfh, bio, cred, pkey, xcert); 3140 if (xcert) 3141 X509_free(xcert); 3142 if (pkey) 3143 EVP_PKEY_free(pkey); 3144 } 3145 } 3146 3147cleanup: 3148 3149 if (bio != NULL) 3150 (void) BIO_free_all(bio); 3151 3152 return (rv); 3153} 3154 3155KMF_RETURN 3156OpenSSL_ExportP12(KMF_HANDLE_T handle, 3157 KMF_EXPORTP12_PARAMS *params, 3158 int numcerts, KMF_X509_DER_CERT *certlist, 3159 int numkeys, KMF_KEY_HANDLE *keylist, 3160 char *filename) 3161{ 3162 KMF_RETURN rv; 3163 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3164 KMF_FINDCERT_PARAMS fcargs; 3165 BIO *bio = NULL; 3166 X509 *xcert = NULL; 3167 char *fullpath = NULL; 3168 EVP_PKEY *pkey = NULL; 3169 3170 /* 3171 * First, find the certificate. 3172 */ 3173 if (params == NULL) 3174 return (KMF_ERR_BAD_PARAMETER); 3175 3176 /* 3177 * If the caller already sent the raw keys and certs, 3178 * shortcut the search and just export that 3179 * data. 3180 * 3181 * One *may* export a key OR a cert by itself. 3182 */ 3183 if (certlist != NULL || keylist != NULL) { 3184 rv = ExportPK12FromRawData(handle, 3185 ¶ms->p12cred, 3186 numcerts, certlist, 3187 numkeys, keylist, 3188 filename); 3189 return (rv); 3190 } 3191 3192 if (params->sslparms.certfile != NULL) { 3193 fullpath = get_fullpath(params->sslparms.dirpath, 3194 params->sslparms.certfile); 3195 3196 if (fullpath == NULL) 3197 return (KMF_ERR_BAD_PARAMETER); 3198 3199 if (isdir(fullpath)) { 3200 free(fullpath); 3201 return (KMF_ERR_AMBIGUOUS_PATHNAME); 3202 } 3203 3204 (void *)memset(&fcargs, 0, sizeof (fcargs)); 3205 fcargs.kstype = params->kstype; 3206 fcargs.certLabel = params->certLabel; 3207 fcargs.issuer = params->issuer; 3208 fcargs.subject = params->subject; 3209 fcargs.serial = params->serial; 3210 fcargs.idstr = params->idstr; 3211 fcargs.sslparms.dirpath = NULL; 3212 fcargs.sslparms.certfile = fullpath; 3213 fcargs.sslparms.format = params->sslparms.format; 3214 3215 rv = load_X509cert(kmfh, &fcargs, fullpath, &xcert); 3216 if (rv != KMF_OK) 3217 goto end; 3218 } 3219 3220 /* 3221 * Now find the private key. 3222 */ 3223 if (params->sslparms.keyfile != NULL) { 3224 fullpath = get_fullpath(params->sslparms.dirpath, 3225 params->sslparms.keyfile); 3226 3227 if (fullpath == NULL) 3228 return (KMF_ERR_BAD_PARAMETER); 3229 3230 if (isdir(fullpath)) { 3231 free(fullpath); 3232 return (KMF_ERR_AMBIGUOUS_PATHNAME); 3233 } 3234 3235 pkey = openssl_load_key(handle, fullpath); 3236 if (pkey == NULL) { 3237 rv = KMF_ERR_KEY_NOT_FOUND; 3238 goto end; 3239 } 3240 } 3241 3242 /* 3243 * Open the output file. 3244 */ 3245 if ((bio = BIO_new_file(filename, "wb")) == NULL) { 3246 SET_ERROR(kmfh, ERR_get_error()); 3247 rv = KMF_ERR_OPEN_FILE; 3248 goto end; 3249 } 3250 3251 /* Stick the key and the cert into a PKCS#12 file */ 3252 rv = write_pkcs12(kmfh, bio, ¶ms->p12cred, 3253 pkey, xcert); 3254 3255end: 3256 if (fullpath) 3257 free(fullpath); 3258 if (xcert) 3259 X509_free(xcert); 3260 if (pkey) 3261 EVP_PKEY_free(pkey); 3262 if (bio) 3263 (void) BIO_free(bio); 3264 3265 return (rv); 3266} 3267 3268/* 3269 * Helper function to decrypt and parse PKCS#12 import file. 3270 */ 3271static KMF_RETURN 3272extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 3273 EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca) 3274/* ARGSUSED */ 3275{ 3276 PKCS12 *pk12, *pk12_tmp; 3277 EVP_PKEY *temp_pkey = NULL; 3278 X509 *temp_cert = NULL; 3279 STACK_OF(X509) *temp_ca = NULL; 3280 3281 if ((pk12 = PKCS12_new()) == NULL) { 3282 return (KMF_ERR_MEMORY); 3283 } 3284 3285 if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) { 3286 /* This is ok; it seems to mean there is no more to read. */ 3287 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 && 3288 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG) 3289 goto end_extract_pkcs12; 3290 3291 PKCS12_free(pk12); 3292 return (KMF_ERR_PKCS12_FORMAT); 3293 } 3294 pk12 = pk12_tmp; 3295 3296 if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert, 3297 &temp_ca) <= 0) { 3298 PKCS12_free(pk12); 3299 return (KMF_ERR_PKCS12_FORMAT); 3300 } 3301 3302end_extract_pkcs12: 3303 3304 *priv_key = temp_pkey; 3305 *cert = temp_cert; 3306 *ca = temp_ca; 3307 3308 PKCS12_free(pk12); 3309 return (KMF_OK); 3310} 3311 3312static KMF_RETURN 3313sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to) 3314{ 3315 KMF_RETURN rv = KMF_OK; 3316 uint32_t sz; 3317 3318 sz = BN_num_bytes(from); 3319 to->val = (uchar_t *)malloc(sz); 3320 if (to->val == NULL) 3321 return (KMF_ERR_MEMORY); 3322 3323 if ((to->len = BN_bn2bin(from, to->val)) != sz) { 3324 free(to->val); 3325 to->val = NULL; 3326 to->len = 0; 3327 rv = KMF_ERR_MEMORY; 3328 } 3329 3330 return (rv); 3331} 3332 3333static KMF_RETURN 3334exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) 3335{ 3336 KMF_RETURN rv; 3337 KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa; 3338 3339 (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY)); 3340 if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK) 3341 goto cleanup; 3342 3343 if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK) 3344 goto cleanup; 3345 3346 if (rsa->d != NULL) 3347 if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK) 3348 goto cleanup; 3349 3350 if (rsa->p != NULL) 3351 if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK) 3352 goto cleanup; 3353 3354 if (rsa->q != NULL) 3355 if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK) 3356 goto cleanup; 3357 3358 if (rsa->dmp1 != NULL) 3359 if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK) 3360 goto cleanup; 3361 3362 if (rsa->dmq1 != NULL) 3363 if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK) 3364 goto cleanup; 3365 3366 if (rsa->iqmp != NULL) 3367 if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK) 3368 goto cleanup; 3369cleanup: 3370 if (rv != KMF_OK) 3371 KMF_FreeRawKey(key); 3372 else 3373 key->keytype = KMF_RSA; 3374 3375 /* 3376 * Free the reference to this key, SSL will not actually free 3377 * the memory until the refcount == 0, so this is safe. 3378 */ 3379 RSA_free(rsa); 3380 3381 return (rv); 3382} 3383 3384static KMF_RETURN 3385exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) 3386{ 3387 KMF_RETURN rv; 3388 KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa; 3389 3390 (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY)); 3391 if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK) 3392 goto cleanup; 3393 3394 if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK) 3395 goto cleanup; 3396 3397 if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK) 3398 goto cleanup; 3399 3400 if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK) 3401 goto cleanup; 3402 3403cleanup: 3404 if (rv != KMF_OK) 3405 KMF_FreeRawKey(key); 3406 else 3407 key->keytype = KMF_DSA; 3408 3409 /* 3410 * Free the reference to this key, SSL will not actually free 3411 * the memory until the refcount == 0, so this is safe. 3412 */ 3413 DSA_free(dsa); 3414 3415 return (rv); 3416} 3417 3418static KMF_RETURN 3419add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert, 3420 KMF_DATA **certlist, int *ncerts) 3421{ 3422 KMF_RETURN rv = KMF_OK; 3423 KMF_DATA *list = (*certlist); 3424 KMF_DATA cert; 3425 int n = (*ncerts); 3426 3427 if (list == NULL) { 3428 list = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 3429 } else { 3430 list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1)); 3431 } 3432 3433 if (list == NULL) 3434 return (KMF_ERR_MEMORY); 3435 3436 rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert); 3437 if (rv == KMF_OK) { 3438 list[n] = cert; 3439 (*ncerts) = n + 1; 3440 3441 *certlist = list; 3442 } else { 3443 free(list); 3444 } 3445 3446 return (rv); 3447} 3448 3449static KMF_RETURN 3450add_key_to_list(KMF_RAW_KEY_DATA **keylist, 3451 KMF_RAW_KEY_DATA *newkey, int *nkeys) 3452{ 3453 KMF_RAW_KEY_DATA *list = (*keylist); 3454 int n = (*nkeys); 3455 3456 if (list == NULL) { 3457 list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA)); 3458 } else { 3459 list = (KMF_RAW_KEY_DATA *)realloc(list, 3460 sizeof (KMF_RAW_KEY_DATA) * (n + 1)); 3461 } 3462 3463 if (list == NULL) 3464 return (KMF_ERR_MEMORY); 3465 3466 list[n] = *newkey; 3467 (*nkeys) = n + 1; 3468 3469 *keylist = list; 3470 3471 return (KMF_OK); 3472} 3473 3474 3475static KMF_RETURN 3476convertPK12Objects( 3477 KMF_HANDLE *kmfh, 3478 EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts, 3479 KMF_RAW_KEY_DATA **keylist, int *nkeys, 3480 KMF_DATA **certlist, int *ncerts) 3481{ 3482 KMF_RETURN rv = KMF_OK; 3483 KMF_RAW_KEY_DATA key; 3484 int i; 3485 3486 if (sslkey != NULL) { 3487 /* Convert SSL key to raw key */ 3488 switch (sslkey->type) { 3489 case EVP_PKEY_RSA: 3490 rv = exportRawRSAKey(EVP_PKEY_get1_RSA(sslkey), 3491 &key); 3492 if (rv != KMF_OK) 3493 return (rv); 3494 3495 break; 3496 case EVP_PKEY_DSA: 3497 rv = exportRawDSAKey(EVP_PKEY_get1_DSA(sslkey), 3498 &key); 3499 if (rv != KMF_OK) 3500 return (rv); 3501 3502 break; 3503 default: 3504 return (KMF_ERR_BAD_PARAMETER); 3505 } 3506 3507 rv = add_key_to_list(keylist, &key, nkeys); 3508 if (rv != KMF_OK) 3509 return (rv); 3510 } 3511 3512 /* Now add the certificate to the certlist */ 3513 if (sslcert != NULL) { 3514 rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts); 3515 if (rv != KMF_OK) 3516 return (rv); 3517 } 3518 3519 /* Also add any included CA certs to the list */ 3520 for (i = 0; i != sk_X509_num(sslcacerts); i++) { 3521 X509 *c; 3522 /* 3523 * sk_X509_value() is macro that embeds a cast to (X509 *). 3524 * Here it translates into ((X509 *)sk_value((ca), (i))). 3525 * Lint is complaining about the embedded casting, and 3526 * to fix it, you need to fix openssl header files. 3527 */ 3528 /* LINTED E_BAD_PTR_CAST_ALIGN */ 3529 c = sk_X509_value(sslcacerts, i); 3530 3531 /* Now add the ca cert to the certlist */ 3532 rv = add_cert_to_list(kmfh, c, certlist, ncerts); 3533 if (rv != KMF_OK) 3534 return (rv); 3535 } 3536 return (rv); 3537} 3538 3539KMF_RETURN 3540openssl_read_pkcs12(KMF_HANDLE *kmfh, 3541 char *filename, KMF_CREDENTIAL *cred, 3542 KMF_DATA **certlist, int *ncerts, 3543 KMF_RAW_KEY_DATA **keylist, int *nkeys) 3544{ 3545 KMF_RETURN rv = KMF_OK; 3546 BIO *bio = NULL; 3547 EVP_PKEY *privkey = NULL; 3548 X509 *cert = NULL; 3549 STACK_OF(X509) *cacerts = NULL; 3550 3551 bio = BIO_new_file(filename, "rb"); 3552 if (bio == NULL) { 3553 SET_ERROR(kmfh, ERR_get_error()); 3554 rv = KMF_ERR_OPEN_FILE; 3555 goto end; 3556 } 3557 3558 *certlist = NULL; 3559 *keylist = NULL; 3560 *ncerts = 0; 3561 *nkeys = 0; 3562 while (rv == KMF_OK) { 3563 rv = extract_pkcs12(bio, 3564 (uchar_t *)cred->cred, 3565 (uint32_t)cred->credlen, 3566 &privkey, &cert, &cacerts); 3567 3568 /* Reached end of import file? */ 3569 if (rv == KMF_OK && privkey == NULL && 3570 cert == NULL && cacerts == NULL) 3571 break; 3572 3573 if (rv == KMF_OK) 3574 /* Convert keys and certs to exportable format */ 3575 rv = convertPK12Objects(kmfh, privkey, cert, cacerts, 3576 keylist, nkeys, certlist, ncerts); 3577 3578 if (privkey) 3579 EVP_PKEY_free(privkey); 3580 3581 if (cert) 3582 X509_free(cert); 3583 3584 if (cacerts) 3585 sk_X509_free(cacerts); 3586 } 3587end: 3588 if (bio != NULL) 3589 (void) BIO_free(bio); 3590 3591 if (privkey) 3592 EVP_PKEY_free(privkey); 3593 3594 if (cert) 3595 X509_free(cert); 3596 3597 if (cacerts) 3598 sk_X509_free(cacerts); 3599 3600 return (rv); 3601} 3602 3603KMF_RETURN 3604OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, 3605 KMF_RAW_KEY_DATA *key) 3606{ 3607 KMF_RETURN rv = KMF_OK; 3608 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3609 char *fullpath; 3610 EVP_PKEY *pkey = NULL; 3611 BIO *bio = NULL; 3612 3613 if (key != NULL) { 3614 if (key->keytype == KMF_RSA) { 3615 pkey = ImportRawRSAKey(&key->rawdata.rsa); 3616 } else if (key->keytype == KMF_DSA) { 3617 pkey = ImportRawDSAKey(&key->rawdata.dsa); 3618 } else { 3619 rv = KMF_ERR_BAD_PARAMETER; 3620 } 3621 } else { 3622 rv = KMF_ERR_BAD_PARAMETER; 3623 } 3624 if (rv != KMF_OK || pkey == NULL) 3625 return (rv); 3626 3627 fullpath = get_fullpath(params->sslparms.dirpath, 3628 params->sslparms.keyfile); 3629 3630 if (fullpath == NULL) 3631 return (KMF_ERR_BAD_PARAMETER); 3632 3633 /* If the requested file exists, return an error */ 3634 if (access(fullpath, F_OK) == 0) { 3635 free(fullpath); 3636 return (KMF_ERR_DUPLICATE_KEYFILE); 3637 } 3638 3639 bio = BIO_new_file(fullpath, "wb"); 3640 if (bio == NULL) { 3641 SET_ERROR(kmfh, ERR_get_error()); 3642 rv = KMF_ERR_OPEN_FILE; 3643 goto cleanup; 3644 } 3645 3646 rv = ssl_write_private_key(kmfh, 3647 params->sslparms.format, 3648 bio, ¶ms->cred, pkey); 3649 3650cleanup: 3651 if (fullpath) 3652 free(fullpath); 3653 3654 if (pkey) 3655 EVP_PKEY_free(pkey); 3656 3657 if (bio) 3658 (void) BIO_free(bio); 3659 3660 /* Protect the file by making it read-only */ 3661 if (rv == KMF_OK) { 3662 (void) chmod(fullpath, 0400); 3663 } 3664 return (rv); 3665} 3666 3667static KMF_RETURN 3668create_deskey(DES_cblock **deskey) 3669{ 3670 DES_cblock *key; 3671 3672 key = (DES_cblock *) malloc(sizeof (DES_cblock)); 3673 if (key == NULL) { 3674 return (KMF_ERR_MEMORY); 3675 } 3676 3677 if (DES_random_key(key) == 0) { 3678 free(key); 3679 return (KMF_ERR_KEYGEN_FAILED); 3680 } 3681 3682 *deskey = key; 3683 return (KMF_OK); 3684} 3685 3686#define KEYGEN_RETRY 3 3687#define DES3_KEY_SIZE 24 3688 3689static KMF_RETURN 3690create_des3key(unsigned char **des3key) 3691{ 3692 KMF_RETURN ret = KMF_OK; 3693 DES_cblock *deskey1 = NULL; 3694 DES_cblock *deskey2 = NULL; 3695 DES_cblock *deskey3 = NULL; 3696 unsigned char *newkey = NULL; 3697 int retry; 3698 3699 if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) { 3700 return (KMF_ERR_MEMORY); 3701 } 3702 3703 /* create the 1st DES key */ 3704 if ((ret = create_deskey(&deskey1)) != KMF_OK) { 3705 goto out; 3706 } 3707 3708 /* 3709 * Create the 2nd DES key and make sure its value is different 3710 * from the 1st DES key. 3711 */ 3712 retry = 0; 3713 do { 3714 if (deskey2 != NULL) { 3715 free(deskey2); 3716 deskey2 = NULL; 3717 } 3718 3719 if ((ret = create_deskey(&deskey2)) != KMF_OK) { 3720 goto out; 3721 } 3722 3723 if (memcmp((const void *) deskey1, (const void *) deskey2, 8) 3724 == 0) { 3725 ret = KMF_ERR_KEYGEN_FAILED; 3726 retry++; 3727 } 3728 } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 3729 3730 if (ret != KMF_OK) { 3731 goto out; 3732 } 3733 3734 /* 3735 * Create the 3rd DES key and make sure its value is different 3736 * from the 2nd DES key. 3737 */ 3738 retry = 0; 3739 do { 3740 if (deskey3 != NULL) { 3741 free(deskey3); 3742 deskey3 = NULL; 3743 } 3744 3745 if ((ret = create_deskey(&deskey3)) != KMF_OK) { 3746 goto out; 3747 } 3748 3749 if (memcmp((const void *)deskey2, (const void *)deskey3, 8) 3750 == 0) { 3751 ret = KMF_ERR_KEYGEN_FAILED; 3752 retry++; 3753 } 3754 } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 3755 3756 if (ret != KMF_OK) { 3757 goto out; 3758 } 3759 3760 /* Concatenate 3 DES keys into a DES3 key */ 3761 (void) memcpy((void *)newkey, (const void *)deskey1, 8); 3762 (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8); 3763 (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8); 3764 *des3key = newkey; 3765 3766out: 3767 if (deskey1 != NULL) 3768 free(deskey1); 3769 3770 if (deskey2 != NULL) 3771 free(deskey2); 3772 3773 if (deskey3 != NULL) 3774 free(deskey3); 3775 3776 if (ret != KMF_OK && newkey != NULL) 3777 free(newkey); 3778 3779 return (ret); 3780} 3781 3782KMF_RETURN 3783OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, 3784 KMF_KEY_HANDLE *symkey) 3785{ 3786 KMF_RETURN ret = KMF_OK; 3787 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3788 char *fullpath = NULL; 3789 KMF_RAW_SYM_KEY *rkey = NULL; 3790 DES_cblock *deskey = NULL; 3791 unsigned char *des3key = NULL; 3792 unsigned char *random = NULL; 3793 int fd = -1; 3794 3795 if (kmfh == NULL) 3796 return (KMF_ERR_UNINITIALIZED); 3797 3798 if (params == NULL || params->sslparms.keyfile == NULL) { 3799 return (KMF_ERR_BAD_PARAMETER); 3800 } 3801 3802 fullpath = get_fullpath(params->sslparms.dirpath, 3803 params->sslparms.keyfile); 3804 if (fullpath == NULL) 3805 return (KMF_ERR_BAD_PARAMETER); 3806 3807 /* If the requested file exists, return an error */ 3808 if (access(fullpath, F_OK) == 0) { 3809 free(fullpath); 3810 return (KMF_ERR_DUPLICATE_KEYFILE); 3811 } 3812 3813 fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400); 3814 if (fd == -1) { 3815 ret = KMF_ERR_OPEN_FILE; 3816 goto out; 3817 } 3818 3819 rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 3820 if (rkey == NULL) { 3821 ret = KMF_ERR_MEMORY; 3822 goto out; 3823 } 3824 (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 3825 3826 if (params->keytype == KMF_DES) { 3827 if ((ret = create_deskey(&deskey)) != KMF_OK) { 3828 goto out; 3829 } 3830 rkey->keydata.val = (uchar_t *)deskey; 3831 rkey->keydata.len = 8; 3832 3833 symkey->keyalg = KMF_DES; 3834 3835 } else if (params->keytype == KMF_DES3) { 3836 if ((ret = create_des3key(&des3key)) != KMF_OK) { 3837 goto out; 3838 } 3839 rkey->keydata.val = (uchar_t *)des3key; 3840 rkey->keydata.len = DES3_KEY_SIZE; 3841 symkey->keyalg = KMF_DES3; 3842 3843 } else if (params->keytype == KMF_AES || params->keytype == KMF_RC4) { 3844 int bytes; 3845 3846 if (params->keylength % 8 != 0) { 3847 ret = KMF_ERR_BAD_KEY_SIZE; 3848 goto out; 3849 } 3850 3851 if (params->keytype == KMF_AES) { 3852 if (params->keylength != 128 && 3853 params->keylength != 192 && 3854 params->keylength != 256) { 3855 ret = KMF_ERR_BAD_KEY_SIZE; 3856 goto out; 3857 } 3858 } 3859 3860 bytes = params->keylength/8; 3861 random = malloc(bytes); 3862 if (random == NULL) { 3863 ret = KMF_ERR_MEMORY; 3864 goto out; 3865 } 3866 if (RAND_bytes(random, bytes) != 1) { 3867 ret = KMF_ERR_KEYGEN_FAILED; 3868 goto out; 3869 } 3870 3871 rkey->keydata.val = (uchar_t *)random; 3872 rkey->keydata.len = bytes; 3873 symkey->keyalg = params->keytype; 3874 3875 } else { 3876 ret = KMF_ERR_BAD_KEY_TYPE; 3877 goto out; 3878 } 3879 3880 (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len); 3881 3882 symkey->kstype = KMF_KEYSTORE_OPENSSL; 3883 symkey->keyclass = KMF_SYMMETRIC; 3884 symkey->keylabel = (char *)fullpath; 3885 symkey->israw = TRUE; 3886 symkey->keyp = rkey; 3887 3888out: 3889 if (fd != -1) 3890 (void) close(fd); 3891 3892 if (ret != KMF_OK && fullpath != NULL) { 3893 free(fullpath); 3894 } 3895 if (ret != KMF_OK) { 3896 KMF_FreeRawSymKey(rkey); 3897 symkey->keyp = NULL; 3898 symkey->keyalg = KMF_KEYALG_NONE; 3899 } 3900 3901 return (ret); 3902} 3903 3904 3905KMF_RETURN 3906OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params) 3907{ 3908 KMF_RETURN ret = KMF_OK; 3909 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3910 BIO *bcrl = NULL; 3911 X509_CRL *xcrl = NULL; 3912 X509 *xcert = NULL; 3913 EVP_PKEY *pkey; 3914 int sslret; 3915 KMF_ENCODE_FORMAT crl_format; 3916 unsigned char *p; 3917 long len; 3918 3919 if (params->crl_name == NULL || params->tacert == NULL) { 3920 return (KMF_ERR_BAD_PARAMETER); 3921 } 3922 3923 ret = KMF_GetFileFormat(params->crl_name, &crl_format); 3924 if (ret != KMF_OK) 3925 return (ret); 3926 3927 bcrl = BIO_new_file(params->crl_name, "rb"); 3928 if (bcrl == NULL) { 3929 SET_ERROR(kmfh, ERR_get_error()); 3930 ret = KMF_ERR_OPEN_FILE; 3931 goto cleanup; 3932 } 3933 3934 if (crl_format == KMF_FORMAT_ASN1) { 3935 xcrl = d2i_X509_CRL_bio(bcrl, NULL); 3936 } else if (crl_format == KMF_FORMAT_PEM) { 3937 xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 3938 } else { 3939 ret = KMF_ERR_BAD_PARAMETER; 3940 goto cleanup; 3941 } 3942 3943 if (xcrl == NULL) { 3944 SET_ERROR(kmfh, ERR_get_error()); 3945 ret = KMF_ERR_BAD_CRLFILE; 3946 goto cleanup; 3947 } 3948 3949 p = params->tacert->Data; 3950 len = params->tacert->Length; 3951 xcert = d2i_X509(NULL, (const uchar_t **)&p, len); 3952 3953 if (xcert == NULL) { 3954 SET_ERROR(kmfh, ERR_get_error()); 3955 ret = KMF_ERR_BAD_CERTFILE; 3956 goto cleanup; 3957 } 3958 3959 /* Get issuer certificate public key */ 3960 pkey = X509_get_pubkey(xcert); 3961 if (!pkey) { 3962 SET_ERROR(kmfh, ERR_get_error()); 3963 ret = KMF_ERR_BAD_CERT_FORMAT; 3964 goto cleanup; 3965 } 3966 3967 /* Verify CRL signature */ 3968 sslret = X509_CRL_verify(xcrl, pkey); 3969 EVP_PKEY_free(pkey); 3970 if (sslret > 0) { 3971 ret = KMF_OK; 3972 } else { 3973 SET_ERROR(kmfh, sslret); 3974 ret = KMF_ERR_BAD_CRLFILE; 3975 } 3976 3977cleanup: 3978 if (bcrl != NULL) 3979 (void) BIO_free(bcrl); 3980 3981 if (xcrl != NULL) 3982 X509_CRL_free(xcrl); 3983 3984 if (xcert != NULL) 3985 X509_free(xcert); 3986 3987 return (ret); 3988 3989} 3990 3991KMF_RETURN 3992OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, 3993 KMF_CHECKCRLDATE_PARAMS *params) 3994{ 3995 3996 KMF_RETURN ret = KMF_OK; 3997 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3998 KMF_ENCODE_FORMAT crl_format; 3999 BIO *bcrl = NULL; 4000 X509_CRL *xcrl = NULL; 4001 int i; 4002 4003 if (params == NULL || params->crl_name == NULL) { 4004 return (KMF_ERR_BAD_PARAMETER); 4005 } 4006 4007 ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format); 4008 if (ret != KMF_OK) 4009 return (ret); 4010 4011 bcrl = BIO_new_file(params->crl_name, "rb"); 4012 if (bcrl == NULL) { 4013 SET_ERROR(kmfh, ERR_get_error()); 4014 ret = KMF_ERR_OPEN_FILE; 4015 goto cleanup; 4016 } 4017 4018 if (crl_format == KMF_FORMAT_ASN1) { 4019 xcrl = d2i_X509_CRL_bio(bcrl, NULL); 4020 } else if (crl_format == KMF_FORMAT_PEM) { 4021 xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 4022 } 4023 4024 if (xcrl == NULL) { 4025 SET_ERROR(kmfh, ERR_get_error()); 4026 ret = KMF_ERR_BAD_CRLFILE; 4027 goto cleanup; 4028 } 4029 4030 i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); 4031 if (i >= 0) { 4032 ret = KMF_ERR_VALIDITY_PERIOD; 4033 goto cleanup; 4034 } 4035 4036 if (X509_CRL_get_nextUpdate(xcrl)) { 4037 i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); 4038 4039 if (i <= 0) { 4040 ret = KMF_ERR_VALIDITY_PERIOD; 4041 goto cleanup; 4042 } 4043 } 4044 4045 ret = KMF_OK; 4046 4047cleanup: 4048 if (bcrl != NULL) 4049 (void) BIO_free(bcrl); 4050 4051 if (xcrl != NULL) 4052 X509_CRL_free(xcrl); 4053 4054 return (ret); 4055} 4056 4057/* 4058 * Check a file to see if it is a CRL file with PEM or DER format. 4059 * If success, return its format in the "pformat" argument. 4060 */ 4061KMF_RETURN 4062OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat) 4063{ 4064 KMF_RETURN ret = KMF_OK; 4065 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4066 BIO *bio = NULL; 4067 X509_CRL *xcrl = NULL; 4068 4069 if (filename == NULL) { 4070 return (KMF_ERR_BAD_PARAMETER); 4071 } 4072 4073 bio = BIO_new_file(filename, "rb"); 4074 if (bio == NULL) { 4075 SET_ERROR(kmfh, ERR_get_error()); 4076 ret = KMF_ERR_OPEN_FILE; 4077 goto out; 4078 } 4079 4080 if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) { 4081 *pformat = KMF_FORMAT_PEM; 4082 goto out; 4083 } 4084 (void) BIO_free(bio); 4085 4086 /* 4087 * Now try to read it as raw DER data. 4088 */ 4089 bio = BIO_new_file(filename, "rb"); 4090 if (bio == NULL) { 4091 SET_ERROR(kmfh, ERR_get_error()); 4092 ret = KMF_ERR_OPEN_FILE; 4093 goto out; 4094 } 4095 4096 if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) { 4097 *pformat = KMF_FORMAT_ASN1; 4098 } else { 4099 ret = KMF_ERR_BAD_CRLFILE; 4100 } 4101 4102out: 4103 if (bio != NULL) 4104 (void) BIO_free(bio); 4105 4106 if (xcrl != NULL) 4107 X509_CRL_free(xcrl); 4108 4109 return (ret); 4110} 4111 4112/* 4113 * Check a file to see if it is a certficate file with PEM or DER format. 4114 * If success, return its format in the pformat argument. 4115 */ 4116KMF_RETURN 4117OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, 4118 KMF_ENCODE_FORMAT *pformat) 4119{ 4120 KMF_RETURN ret = KMF_OK; 4121 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4122 BIO *bio = NULL; 4123 X509 *xcert = NULL; 4124 4125 if (filename == NULL) { 4126 return (KMF_ERR_BAD_PARAMETER); 4127 } 4128 4129 ret = KMF_GetFileFormat(filename, pformat); 4130 if (ret != KMF_OK) 4131 return (ret); 4132 4133 bio = BIO_new_file(filename, "rb"); 4134 if (bio == NULL) { 4135 SET_ERROR(kmfh, ERR_get_error()); 4136 ret = KMF_ERR_OPEN_FILE; 4137 goto out; 4138 } 4139 4140 if ((*pformat) == KMF_FORMAT_PEM) { 4141 if ((xcert = PEM_read_bio_X509(bio, NULL, 4142 NULL, NULL)) == NULL) { 4143 ret = KMF_ERR_BAD_CERTFILE; 4144 } 4145 } else if ((*pformat) == KMF_FORMAT_ASN1) { 4146 if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) { 4147 ret = KMF_ERR_BAD_CERTFILE; 4148 } 4149 } else { 4150 ret = KMF_ERR_BAD_CERTFILE; 4151 } 4152 4153out: 4154 if (bio != NULL) 4155 (void) BIO_free(bio); 4156 4157 if (xcert != NULL) 4158 X509_free(xcert); 4159 4160 return (ret); 4161} 4162 4163KMF_RETURN 4164OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 4165 KMF_RAW_SYM_KEY *rkey) 4166{ 4167 KMF_RETURN rv = KMF_OK; 4168 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4169 KMF_DATA keyvalue; 4170 4171 if (kmfh == NULL) 4172 return (KMF_ERR_UNINITIALIZED); 4173 4174 if (symkey == NULL || rkey == NULL) 4175 return (KMF_ERR_BAD_PARAMETER); 4176 else if (symkey->keyclass != KMF_SYMMETRIC) 4177 return (KMF_ERR_BAD_KEY_CLASS); 4178 4179 if (symkey->israw) { 4180 KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp; 4181 4182 if (rawkey == NULL || 4183 rawkey->keydata.val == NULL || 4184 rawkey->keydata.len == 0) 4185 return (KMF_ERR_BAD_KEYHANDLE); 4186 4187 rkey->keydata.len = rawkey->keydata.len; 4188 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 4189 return (KMF_ERR_MEMORY); 4190 (void) memcpy(rkey->keydata.val, rawkey->keydata.val, 4191 rkey->keydata.len); 4192 } else { 4193 rv = KMF_ReadInputFile(handle, symkey->keylabel, &keyvalue); 4194 if (rv != KMF_OK) 4195 return (rv); 4196 rkey->keydata.len = keyvalue.Length; 4197 rkey->keydata.val = keyvalue.Data; 4198 } 4199 4200 return (rv); 4201} 4202