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