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