openssl_spi.c revision 4025:d8be2f0444ab
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, n; 1001 uint32_t maxcerts = 0; 1002 1003 if (num_certs == NULL || params == NULL) 1004 return (KMF_ERR_BAD_PARAMETER); 1005 1006 maxcerts = *num_certs; 1007 if (maxcerts == 0) 1008 maxcerts = 0xFFFFFFFF; 1009 *num_certs = 0; 1010 1011 fullpath = get_fullpath(params->sslparms.dirpath, 1012 params->sslparms.certfile); 1013 1014 if (fullpath == NULL) 1015 return (KMF_ERR_BAD_PARAMETER); 1016 1017 if (isdir(fullpath)) { 1018 DIR *dirp; 1019 struct dirent *dp; 1020 1021 n = 0; 1022 /* open all files in the directory and attempt to read them */ 1023 if ((dirp = opendir(fullpath)) == NULL) { 1024 return (KMF_ERR_BAD_PARAMETER); 1025 } 1026 while ((dp = readdir(dirp)) != NULL) { 1027 char *fname; 1028 KMF_DATA *certlist = NULL; 1029 uint32_t loaded_certs = 0; 1030 1031 if (strcmp(dp->d_name, ".") == 0 || 1032 strcmp(dp->d_name, "..") == 0) 1033 continue; 1034 1035 fname = get_fullpath(fullpath, 1036 (char *)&dp->d_name); 1037 1038 rv = load_certs(kmfh, params, fname, &certlist, 1039 &loaded_certs); 1040 1041 if (rv != KMF_OK) { 1042 free(fname); 1043 if (certlist != NULL) { 1044 for (i = 0; i < loaded_certs; i++) 1045 KMF_FreeData(&certlist[i]); 1046 free(certlist); 1047 } 1048 continue; 1049 } 1050 1051 /* If load succeeds, add certdata to the list */ 1052 if (kmf_cert != NULL) { 1053 for (i = 0; i < loaded_certs && 1054 i < maxcerts; i++) { 1055 kmf_cert[n].certificate.Data = 1056 certlist[i].Data; 1057 kmf_cert[n].certificate.Length = 1058 certlist[i].Length; 1059 1060 kmf_cert[n].kmf_private.keystore_type = 1061 KMF_KEYSTORE_OPENSSL; 1062 kmf_cert[n].kmf_private.flags = 1063 KMF_FLAG_CERT_VALID; 1064 kmf_cert[n].kmf_private.label = 1065 strdup(fname); 1066 n++; 1067 } 1068 /* If maxcerts < loaded_certs, clean up */ 1069 for (; i < loaded_certs; i++) 1070 KMF_FreeData(&certlist[i]); 1071 } else { 1072 for (i = 0; i < loaded_certs; i++) 1073 KMF_FreeData(&certlist[i]); 1074 n += loaded_certs; 1075 } 1076 free(certlist); 1077 free(fname); 1078 } 1079 (*num_certs) = n; 1080 if (*num_certs == 0) 1081 rv = KMF_ERR_CERT_NOT_FOUND; 1082 else 1083 rv = KMF_OK; 1084exit: 1085 (void) closedir(dirp); 1086 } else { 1087 KMF_DATA *certlist = NULL; 1088 uint32_t loaded_certs = 0; 1089 1090 rv = load_certs(kmfh, params, fullpath, 1091 &certlist, &loaded_certs); 1092 if (rv != KMF_OK) { 1093 free(fullpath); 1094 return (rv); 1095 } 1096 1097 n = 0; 1098 if (kmf_cert != NULL && certlist != NULL) { 1099 for (i = 0; i < loaded_certs && i < maxcerts; i++) { 1100 kmf_cert[n].certificate.Data = 1101 certlist[i].Data; 1102 kmf_cert[n].certificate.Length = 1103 certlist[i].Length; 1104 kmf_cert[n].kmf_private.keystore_type = 1105 KMF_KEYSTORE_OPENSSL; 1106 kmf_cert[n].kmf_private.flags = 1107 KMF_FLAG_CERT_VALID; 1108 kmf_cert[n].kmf_private.label = 1109 strdup(fullpath); 1110 n++; 1111 } 1112 /* If maxcerts < loaded_certs, clean up */ 1113 for (; i < loaded_certs; i++) 1114 KMF_FreeData(&certlist[i]); 1115 } else if (certlist != NULL) { 1116 for (i = 0; i < loaded_certs; i++) 1117 KMF_FreeData(&certlist[i]); 1118 n = loaded_certs; 1119 } 1120 if (certlist) 1121 free(certlist); 1122 1123 *num_certs = n; 1124 } 1125 1126 free(fullpath); 1127 1128 return (rv); 1129} 1130 1131void 1132/*ARGSUSED*/ 1133OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, 1134 KMF_X509_DER_CERT *kmf_cert) 1135{ 1136 if (kmf_cert != NULL) { 1137 if (kmf_cert->certificate.Data != NULL) { 1138 free(kmf_cert->certificate.Data); 1139 kmf_cert->certificate.Data = NULL; 1140 kmf_cert->certificate.Length = 0; 1141 } 1142 if (kmf_cert->kmf_private.label) 1143 free(kmf_cert->kmf_private.label); 1144 } 1145} 1146 1147KMF_RETURN 1148OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, 1149 KMF_DATA * pcert) 1150{ 1151 KMF_RETURN ret = KMF_OK; 1152 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1153 X509 *xcert = NULL; 1154 FILE *fp; 1155 unsigned char *outbuf; 1156 unsigned char *outbuf_p; 1157 char *fullpath; 1158 int outbuflen; 1159 int len; 1160 KMF_ENCODE_FORMAT format; 1161 1162 if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) { 1163 return (KMF_ERR_BAD_PARAMETER); 1164 } 1165 1166 /* 1167 * check if the cert output format is supported by OPENSSL. 1168 * however, since the keystore for OPENSSL is just a file, we have 1169 * no way to store the format along with the file. 1170 */ 1171 format = params->sslparms.format; 1172 if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) 1173 return (KMF_ERR_BAD_CERT_FORMAT); 1174 1175 1176 fullpath = get_fullpath(params->sslparms.dirpath, 1177 params->sslparms.certfile); 1178 if (fullpath == NULL) 1179 return (KMF_ERR_BAD_PARAMETER); 1180 1181 /* 1182 * When storing a certificate, you must specify a filename. 1183 */ 1184 if (isdir(fullpath)) { 1185 free(fullpath); 1186 return (KMF_ERR_BAD_PARAMETER); 1187 } 1188 1189 /* copy cert data to outbuf */ 1190 outbuflen = pcert->Length; 1191 outbuf = malloc(outbuflen); 1192 if (outbuf == NULL) { 1193 free(fullpath); 1194 return (KMF_ERR_MEMORY); 1195 } 1196 (void) memcpy(outbuf, pcert->Data, pcert->Length); 1197 1198 if ((fp = fopen(fullpath, "w")) == 1199 NULL) { 1200 SET_SYS_ERROR(kmfh, errno); 1201 ret = KMF_ERR_INTERNAL; 1202 goto out; 1203 } 1204 1205 if (format == KMF_FORMAT_ASN1) { 1206 len = fwrite(outbuf, 1, outbuflen, fp); 1207 if (len != outbuflen) { 1208 SET_SYS_ERROR(kmfh, errno); 1209 ret = KMF_ERR_WRITE_FILE; 1210 } else { 1211 ret = KMF_OK; 1212 } 1213 goto out; 1214 } 1215 1216 /* 1217 * The output format is not KMF_FORMAT_ASN1, so we will 1218 * Convert the cert data to OpenSSL internal X509 first. 1219 */ 1220 outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 1221 xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen); 1222 if (xcert == NULL) { 1223 SET_ERROR(kmfh, ERR_get_error()); 1224 ret = KMF_ERR_ENCODING; 1225 goto out; 1226 } 1227 1228 if (format == KMF_FORMAT_PEM) { 1229 /* Convert to the PEM format and write it out */ 1230 if (!PEM_write_X509(fp, xcert)) { 1231 SET_ERROR(kmfh, ERR_get_error()); 1232 ret = KMF_ERR_ENCODING; 1233 } else { 1234 ret = KMF_OK; 1235 } 1236 goto out; 1237 } 1238 1239out: 1240 if (fullpath != NULL) 1241 free(fullpath); 1242 1243 if (outbuf != NULL) { 1244 free(outbuf); 1245 } 1246 if (fp != NULL) { 1247 (void) fclose(fp); 1248 } 1249 1250 if (xcert != NULL) { 1251 X509_free(xcert); 1252 } 1253 1254 return (ret); 1255} 1256 1257KMF_RETURN 1258OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) 1259{ 1260 KMF_RETURN rv; 1261 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1262 char *fullpath = NULL; 1263 KMF_DATA certdata = {NULL, 0}; 1264 1265 if (params == NULL) { 1266 return (KMF_ERR_BAD_PARAMETER); 1267 } 1268 1269 fullpath = get_fullpath(params->sslparms.dirpath, 1270 params->sslparms.certfile); 1271 1272 if (fullpath == NULL) 1273 return (KMF_ERR_BAD_PARAMETER); 1274 1275 if (isdir(fullpath)) { 1276 DIR *dirp; 1277 struct dirent *dp; 1278 1279 /* open all files in the directory and attempt to read them */ 1280 if ((dirp = opendir(fullpath)) == NULL) { 1281 return (KMF_ERR_BAD_PARAMETER); 1282 } 1283 1284 while ((dp = readdir(dirp)) != NULL) { 1285 if (strcmp(dp->d_name, ".") != 0 && 1286 strcmp(dp->d_name, "..") != 0) { 1287 char *fname; 1288 1289 fname = get_fullpath(fullpath, 1290 (char *)&dp->d_name); 1291 1292 if (fname == NULL) { 1293 rv = KMF_ERR_MEMORY; 1294 break; 1295 } 1296 1297 rv = kmf_load_cert(kmfh, params, fname, 1298 &certdata); 1299 1300 if (rv == KMF_ERR_CERT_NOT_FOUND) { 1301 free(fname); 1302 if (certdata.Data) 1303 free(certdata.Data); 1304 rv = KMF_OK; 1305 continue; 1306 } else if (rv != KMF_OK) { 1307 free(fname); 1308 break; 1309 } 1310 1311 if (unlink(fname) != 0) { 1312 SET_SYS_ERROR(kmfh, errno); 1313 rv = KMF_ERR_INTERNAL; 1314 free(fname); 1315 break; 1316 } 1317 free(fname); 1318 if (certdata.Data) 1319 free(certdata.Data); 1320 } 1321 } 1322 (void) closedir(dirp); 1323 } else { 1324 /* Just try to load a single certificate */ 1325 rv = kmf_load_cert(kmfh, params, fullpath, &certdata); 1326 if (rv == KMF_OK) { 1327 if (unlink(fullpath) != 0) { 1328 SET_SYS_ERROR(kmfh, errno); 1329 rv = KMF_ERR_INTERNAL; 1330 } 1331 } 1332 } 1333 1334out: 1335 if (fullpath != NULL) 1336 free(fullpath); 1337 1338 if (certdata.Data) 1339 free(certdata.Data); 1340 1341 return (rv); 1342} 1343 1344KMF_RETURN 1345OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1346 KMF_DATA *keydata) 1347{ 1348 KMF_RETURN rv = KMF_OK; 1349 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1350 int n; 1351 1352 if (key == NULL || keydata == NULL || 1353 key->keyp == NULL) 1354 return (KMF_ERR_BAD_PARAMETER); 1355 1356 if (key->keyalg == KMF_RSA) { 1357 RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp); 1358 1359 if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) { 1360 SET_ERROR(kmfh, ERR_get_error()); 1361 return (KMF_ERR_ENCODING); 1362 } 1363 RSA_free(pubkey); 1364 } else if (key->keyalg == KMF_DSA) { 1365 DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp); 1366 1367 if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) { 1368 SET_ERROR(kmfh, ERR_get_error()); 1369 return (KMF_ERR_ENCODING); 1370 } 1371 DSA_free(pubkey); 1372 } else { 1373 return (KMF_ERR_BAD_PARAMETER); 1374 } 1375 keydata->Length = n; 1376 1377cleanup: 1378 if (rv != KMF_OK) { 1379 if (keydata->Data) 1380 free(keydata->Data); 1381 keydata->Data = NULL; 1382 keydata->Length = 0; 1383 } 1384 1385 return (rv); 1386} 1387 1388static KMF_RETURN 1389ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, 1390 KMF_CREDENTIAL *cred, EVP_PKEY *pkey) 1391{ 1392 int rv = 0; 1393 RSA *rsa; 1394 DSA *dsa; 1395 1396 switch (format) { 1397 case KMF_FORMAT_ASN1: 1398 if (pkey->type == EVP_PKEY_RSA) { 1399 rsa = EVP_PKEY_get1_RSA(pkey); 1400 rv = i2d_RSAPrivateKey_bio(out, rsa); 1401 RSA_free(rsa); 1402 } else if (pkey->type == EVP_PKEY_DSA) { 1403 dsa = EVP_PKEY_get1_DSA(pkey); 1404 rv = i2d_DSAPrivateKey_bio(out, dsa); 1405 DSA_free(dsa); 1406 } 1407 if (rv == 1) { 1408 rv = KMF_OK; 1409 } else { 1410 SET_ERROR(kmfh, rv); 1411 } 1412 break; 1413 case KMF_FORMAT_PEM: 1414 if (pkey->type == EVP_PKEY_RSA) { 1415 rsa = EVP_PKEY_get1_RSA(pkey); 1416 rv = PEM_write_bio_RSAPrivateKey(out, 1417 rsa, 1418 NULL /* encryption type */, 1419 NULL, 0, NULL, 1420 cred->cred); 1421 RSA_free(rsa); 1422 } else if (pkey->type == EVP_PKEY_DSA) { 1423 dsa = EVP_PKEY_get1_DSA(pkey); 1424 rv = PEM_write_bio_DSAPrivateKey(out, 1425 dsa, 1426 NULL /* encryption type */, 1427 NULL, 0, NULL, 1428 cred->cred); 1429 DSA_free(dsa); 1430 } 1431 1432 if (rv == 1) { 1433 rv = KMF_OK; 1434 } else { 1435 SET_ERROR(kmfh, rv); 1436 } 1437 break; 1438 1439 default: 1440 rv = KMF_ERR_BAD_PARAMETER; 1441 } 1442 1443 return (rv); 1444} 1445 1446KMF_RETURN 1447OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, 1448 KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) 1449{ 1450 KMF_RETURN rv = KMF_OK; 1451 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1452 int format; 1453 uint32_t eValue = 0x010001; 1454 RSA *sslPrivKey = NULL; 1455 DSA *sslDSAKey = NULL; 1456 EVP_PKEY *eprikey = NULL; 1457 EVP_PKEY *epubkey = NULL; 1458 BIO *out = NULL; 1459 char *fullpath = NULL; 1460 1461 if (params == NULL || params->sslparms.keyfile == NULL) { 1462 return (KMF_ERR_BAD_PARAMETER); 1463 } 1464 1465 fullpath = get_fullpath(params->sslparms.dirpath, 1466 params->sslparms.keyfile); 1467 1468 if (fullpath == NULL) 1469 return (KMF_ERR_BAD_PARAMETER); 1470 1471 /* If the requested file exists, return an error */ 1472 if (access(fullpath, F_OK) == 0) { 1473 free(fullpath); 1474 return (KMF_ERR_DUPLICATE_KEYFILE); 1475 } 1476 1477 eprikey = EVP_PKEY_new(); 1478 if (eprikey == NULL) { 1479 SET_ERROR(kmfh, ERR_get_error()); 1480 rv = KMF_ERR_KEYGEN_FAILED; 1481 goto cleanup; 1482 } 1483 epubkey = EVP_PKEY_new(); 1484 if (epubkey == NULL) { 1485 SET_ERROR(kmfh, ERR_get_error()); 1486 rv = KMF_ERR_KEYGEN_FAILED; 1487 goto cleanup; 1488 } 1489 if (params->keytype == KMF_RSA) { 1490 if (params->rsa_exponent.len > 0 && 1491 params->rsa_exponent.len <= sizeof (eValue) && 1492 params->rsa_exponent.val != NULL) 1493 /*LINTED*/ 1494 eValue = *(uint32_t *)params->rsa_exponent.val; 1495 1496 sslPrivKey = RSA_generate_key(params->keylength, eValue, 1497 NULL, NULL); 1498 if (sslPrivKey == NULL) { 1499 SET_ERROR(kmfh, ERR_get_error()); 1500 rv = KMF_ERR_KEYGEN_FAILED; 1501 } else { 1502 if (privkey != NULL && 1503 EVP_PKEY_set1_RSA(eprikey, sslPrivKey)) { 1504 privkey->kstype = KMF_KEYSTORE_OPENSSL; 1505 privkey->keyalg = KMF_RSA; 1506 privkey->keyclass = KMF_ASYM_PRI; 1507 privkey->israw = FALSE; 1508 privkey->keylabel = (char *)strdup(fullpath); 1509 privkey->keyp = (void *)eprikey; 1510 } 1511 /* OpenSSL derives the public key from the private */ 1512 if (pubkey != NULL && 1513 EVP_PKEY_set1_RSA(epubkey, sslPrivKey)) { 1514 pubkey->kstype = KMF_KEYSTORE_OPENSSL; 1515 pubkey->keyalg = KMF_RSA; 1516 pubkey->israw = FALSE; 1517 pubkey->keyclass = KMF_ASYM_PUB; 1518 pubkey->keylabel = (char *)strdup(fullpath); 1519 pubkey->keyp = (void *)epubkey; 1520 } 1521 } 1522 } else if (params->keytype == KMF_DSA) { 1523 sslDSAKey = DSA_new(); 1524 if (sslDSAKey == NULL) { 1525 SET_ERROR(kmfh, ERR_get_error()); 1526 return (KMF_ERR_MEMORY); 1527 } 1528 1529 if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) == 1530 NULL) { 1531 SET_ERROR(kmfh, ERR_get_error()); 1532 rv = KMF_ERR_KEYGEN_FAILED; 1533 goto cleanup; 1534 } 1535 if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) == 1536 NULL) { 1537 SET_ERROR(kmfh, ERR_get_error()); 1538 rv = KMF_ERR_KEYGEN_FAILED; 1539 goto cleanup; 1540 } 1541 if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) == 1542 NULL) { 1543 SET_ERROR(kmfh, ERR_get_error()); 1544 rv = KMF_ERR_KEYGEN_FAILED; 1545 goto cleanup; 1546 } 1547 1548 if (!DSA_generate_key(sslDSAKey)) { 1549 SET_ERROR(kmfh, ERR_get_error()); 1550 rv = KMF_ERR_KEYGEN_FAILED; 1551 goto cleanup; 1552 } 1553 1554 if (privkey != NULL) { 1555 privkey->kstype = KMF_KEYSTORE_OPENSSL; 1556 privkey->keyalg = KMF_DSA; 1557 privkey->keyclass = KMF_ASYM_PRI; 1558 privkey->israw = FALSE; 1559 privkey->keylabel = (char *)strdup(fullpath); 1560 if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { 1561 privkey->keyp = (void *)eprikey; 1562 } else { 1563 SET_ERROR(kmfh, ERR_get_error()); 1564 rv = KMF_ERR_KEYGEN_FAILED; 1565 goto cleanup; 1566 } 1567 } 1568 if (pubkey != NULL) { 1569 DSA *dp = DSA_new(); 1570 /* Make a copy for the public key */ 1571 if (dp != NULL) { 1572 if ((dp->p = BN_new()) == NULL) { 1573 SET_ERROR(kmfh, ERR_get_error()); 1574 rv = KMF_ERR_MEMORY; 1575 DSA_free(dp); 1576 goto cleanup; 1577 } 1578 if ((dp->q = BN_new()) == NULL) { 1579 SET_ERROR(kmfh, ERR_get_error()); 1580 rv = KMF_ERR_MEMORY; 1581 BN_free(dp->p); 1582 DSA_free(dp); 1583 goto cleanup; 1584 } 1585 if ((dp->g = BN_new()) == NULL) { 1586 SET_ERROR(kmfh, ERR_get_error()); 1587 rv = KMF_ERR_MEMORY; 1588 BN_free(dp->q); 1589 BN_free(dp->p); 1590 DSA_free(dp); 1591 goto cleanup; 1592 } 1593 if ((dp->pub_key = BN_new()) == NULL) { 1594 SET_ERROR(kmfh, ERR_get_error()); 1595 rv = KMF_ERR_MEMORY; 1596 BN_free(dp->q); 1597 BN_free(dp->p); 1598 BN_free(dp->g); 1599 DSA_free(dp); 1600 goto cleanup; 1601 } 1602 (void) BN_copy(dp->p, sslDSAKey->p); 1603 (void) BN_copy(dp->q, sslDSAKey->q); 1604 (void) BN_copy(dp->g, sslDSAKey->g); 1605 (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); 1606 1607 pubkey->kstype = KMF_KEYSTORE_OPENSSL; 1608 pubkey->keyalg = KMF_DSA; 1609 pubkey->keyclass = KMF_ASYM_PUB; 1610 pubkey->israw = FALSE; 1611 pubkey->keylabel = (char *)strdup(fullpath); 1612 1613 if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { 1614 pubkey->keyp = (void *)epubkey; 1615 } else { 1616 SET_ERROR(kmfh, ERR_get_error()); 1617 rv = KMF_ERR_KEYGEN_FAILED; 1618 goto cleanup; 1619 } 1620 } 1621 } 1622 } 1623 1624 if (rv != KMF_OK) { 1625 goto cleanup; 1626 } 1627 1628 /* Store the private key to the keyfile */ 1629 format = params->sslparms.format; 1630 out = BIO_new_file(fullpath, "wb"); 1631 if (out == NULL) { 1632 SET_ERROR(kmfh, ERR_get_error()); 1633 rv = KMF_ERR_OPEN_FILE; 1634 goto cleanup; 1635 } 1636 rv = ssl_write_private_key(kmfh, format, out, ¶ms->cred, eprikey); 1637 1638cleanup: 1639 if (rv != KMF_OK) { 1640 if (eprikey != NULL) 1641 EVP_PKEY_free(eprikey); 1642 1643 if (epubkey != NULL) 1644 EVP_PKEY_free(epubkey); 1645 1646 if (pubkey->keylabel) { 1647 free(pubkey->keylabel); 1648 pubkey->keylabel = NULL; 1649 } 1650 1651 if (privkey->keylabel) { 1652 free(privkey->keylabel); 1653 privkey->keylabel = NULL; 1654 } 1655 1656 pubkey->keyp = NULL; 1657 privkey->keyp = NULL; 1658 } 1659 1660 if (sslPrivKey) 1661 RSA_free(sslPrivKey); 1662 1663 if (sslDSAKey) 1664 DSA_free(sslDSAKey); 1665 1666 1667 if (out != NULL) 1668 (void) BIO_free(out); 1669 1670 if (fullpath) 1671 free(fullpath); 1672 1673 /* Protect the file by making it read-only */ 1674 if (rv == KMF_OK) { 1675 (void) chmod(fullpath, 0400); 1676 } 1677 return (rv); 1678} 1679 1680KMF_RETURN 1681OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1682 KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output) 1683{ 1684 KMF_RETURN ret = KMF_OK; 1685 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1686 KMF_ALGORITHM_INDEX AlgId; 1687 EVP_MD_CTX ctx; 1688 const EVP_MD *md; 1689 1690 if (key == NULL || AlgOID == NULL || 1691 tobesigned == NULL || output == NULL || 1692 tobesigned->Data == NULL || 1693 output->Data == NULL) 1694 return (KMF_ERR_BAD_PARAMETER); 1695 1696 /* Map the OID to an OpenSSL algorithm */ 1697 AlgId = X509_AlgorithmOidToAlgId(AlgOID); 1698 if (AlgId == KMF_ALGID_NONE) 1699 return (KMF_ERR_BAD_PARAMETER); 1700 1701 if (key->keyalg == KMF_RSA) { 1702 EVP_PKEY *pkey = (EVP_PKEY *)key->keyp; 1703 uchar_t *p; 1704 int len; 1705 if (AlgId == KMF_ALGID_MD5WithRSA) 1706 md = EVP_md5(); 1707 else if (AlgId == KMF_ALGID_MD2WithRSA) 1708 md = EVP_md2(); 1709 else if (AlgId == KMF_ALGID_SHA1WithRSA) 1710 md = EVP_sha1(); 1711 else if (AlgId == KMF_ALGID_RSA) 1712 md = NULL; 1713 else 1714 return (KMF_ERR_BAD_PARAMETER); 1715 1716 if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) { 1717 RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey); 1718 1719 p = output->Data; 1720 if ((len = RSA_private_encrypt(tobesigned->Length, 1721 tobesigned->Data, p, rsa, 1722 RSA_PKCS1_PADDING)) <= 0) { 1723 SET_ERROR(kmfh, ERR_get_error()); 1724 ret = KMF_ERR_INTERNAL; 1725 } 1726 output->Length = len; 1727 } else { 1728 (void) EVP_MD_CTX_init(&ctx); 1729 (void) EVP_SignInit_ex(&ctx, md, NULL); 1730 (void) EVP_SignUpdate(&ctx, tobesigned->Data, 1731 (uint32_t)tobesigned->Length); 1732 len = (uint32_t)output->Length; 1733 p = output->Data; 1734 if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) { 1735 SET_ERROR(kmfh, ERR_get_error()); 1736 len = 0; 1737 ret = KMF_ERR_INTERNAL; 1738 } 1739 output->Length = len; 1740 (void) EVP_MD_CTX_cleanup(&ctx); 1741 } 1742 } else if (key->keyalg == KMF_DSA) { 1743 DSA *dsa = EVP_PKEY_get1_DSA(key->keyp); 1744 1745 uchar_t hash[EVP_MAX_MD_SIZE]; 1746 uint32_t hashlen; 1747 DSA_SIG *dsasig; 1748 1749 /* 1750 * OpenSSL EVP_Sign operation automatically converts to 1751 * ASN.1 output so we do the operations separately so we 1752 * are assured of NOT getting ASN.1 output returned. 1753 * KMF does not want ASN.1 encoded results because 1754 * not all mechanisms return ASN.1 encodings (PKCS#11 1755 * and NSS return raw signature data). 1756 */ 1757 md = EVP_sha1(); 1758 EVP_MD_CTX_init(&ctx); 1759 (void) EVP_DigestInit_ex(&ctx, md, NULL); 1760 (void) EVP_DigestUpdate(&ctx, tobesigned->Data, 1761 tobesigned->Length); 1762 (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen); 1763 (void) EVP_MD_CTX_cleanup(&ctx); 1764 1765 dsasig = DSA_do_sign(hash, hashlen, dsa); 1766 if (dsasig != NULL) { 1767 int i; 1768 output->Length = i = BN_bn2bin(dsasig->r, output->Data); 1769 output->Length += BN_bn2bin(dsasig->s, 1770 &output->Data[i]); 1771 DSA_SIG_free(dsasig); 1772 } else { 1773 SET_ERROR(kmfh, ERR_get_error()); 1774 } 1775 } else { 1776 return (KMF_ERR_BAD_PARAMETER); 1777 } 1778cleanup: 1779 return (ret); 1780} 1781 1782KMF_RETURN 1783/*ARGSUSED*/ 1784OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, 1785 KMF_KEY_HANDLE *key, boolean_t destroy) 1786{ 1787 KMF_RETURN rv = KMF_OK; 1788 if (key == NULL || key->keyp == NULL) 1789 return (KMF_ERR_BAD_PARAMETER); 1790 1791 if (key->keyclass != KMF_ASYM_PUB && 1792 key->keyclass != KMF_ASYM_PRI && 1793 key->keyclass != KMF_SYMMETRIC) 1794 return (KMF_ERR_BAD_KEY_CLASS); 1795 1796 if (key->keyclass == KMF_SYMMETRIC) { 1797 KMF_FreeRawSymKey((KMF_RAW_SYM_KEY *)key->keyp); 1798 key->keyp = NULL; 1799 } else { 1800 if (key->keyp != NULL) { 1801 EVP_PKEY_free(key->keyp); 1802 key->keyp = NULL; 1803 } 1804 } 1805 1806 if (key->keylabel != NULL) { 1807 EVP_PKEY *pkey = NULL; 1808 /* If the file exists, make sure it is a proper key. */ 1809 pkey = openssl_load_key(handle, key->keylabel); 1810 if (pkey == NULL) { 1811 free(key->keylabel); 1812 key->keylabel = NULL; 1813 return (KMF_ERR_KEY_NOT_FOUND); 1814 } 1815 EVP_PKEY_free(pkey); 1816 1817 if (destroy) { 1818 if (unlink(key->keylabel) != 0) { 1819 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1820 SET_SYS_ERROR(kmfh, errno); 1821 rv = KMF_ERR_INTERNAL; 1822 } 1823 } 1824 if (key->keylabel != NULL) { 1825 free(key->keylabel); 1826 key->keylabel = NULL; 1827 } 1828 } 1829 return (rv); 1830} 1831 1832KMF_RETURN 1833OpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) 1834{ 1835 KMF_RETURN ret = KMF_OK; 1836 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1837 X509_CRL *xcrl = NULL; 1838 X509 *xcert = NULL; 1839 EVP_PKEY *pkey; 1840 KMF_ENCODE_FORMAT format; 1841 BIO *in = NULL, *out = NULL; 1842 int openssl_ret = 0; 1843 char *outcrlfile = NULL; 1844 KMF_ENCODE_FORMAT outformat; 1845 1846 if (params == NULL || params->sslparms.crlfile == NULL) { 1847 return (KMF_ERR_BAD_PARAMETER); 1848 } 1849 1850 if (params->sslparms.crl_check == B_TRUE && 1851 params->sslparms.certfile == NULL) { 1852 return (KMF_ERR_BAD_PARAMETER); 1853 } 1854 1855 outcrlfile = get_fullpath(params->sslparms.dirpath, 1856 params->sslparms.outcrlfile); 1857 1858 if (outcrlfile == NULL) 1859 return (KMF_ERR_BAD_PARAMETER); 1860 1861 if (isdir(outcrlfile)) { 1862 free(outcrlfile); 1863 return (KMF_ERR_BAD_PARAMETER); 1864 } 1865 1866 ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); 1867 if (ret != KMF_OK) { 1868 free(outcrlfile); 1869 return (ret); 1870 } 1871 1872 in = BIO_new_file(params->sslparms.crlfile, "rb"); 1873 if (in == NULL) { 1874 SET_ERROR(kmfh, ERR_get_error()); 1875 ret = KMF_ERR_OPEN_FILE; 1876 goto end; 1877 } 1878 1879 if (format == KMF_FORMAT_ASN1) { 1880 xcrl = d2i_X509_CRL_bio(in, NULL); 1881 } else if (format == KMF_FORMAT_PEM) { 1882 xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 1883 } 1884 1885 if (xcrl == NULL) { 1886 SET_ERROR(kmfh, ERR_get_error()); 1887 ret = KMF_ERR_BAD_CRLFILE; 1888 goto end; 1889 } 1890 1891 /* If bypasscheck is specified, no need to verify. */ 1892 if (params->sslparms.crl_check == B_FALSE) { 1893 goto output; 1894 } 1895 1896 ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); 1897 if (ret != KMF_OK) 1898 goto end; 1899 1900 /* Read in the CA cert file and convert to X509 */ 1901 if (BIO_read_filename(in, params->sslparms.certfile) <= 0) { 1902 SET_ERROR(kmfh, ERR_get_error()); 1903 ret = KMF_ERR_OPEN_FILE; 1904 goto end; 1905 } 1906 1907 if (format == KMF_FORMAT_ASN1) { 1908 xcert = d2i_X509_bio(in, NULL); 1909 } else if (format == KMF_FORMAT_PEM) { 1910 xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 1911 } else { 1912 ret = KMF_ERR_BAD_CERT_FORMAT; 1913 goto end; 1914 } 1915 1916 if (xcert == NULL) { 1917 SET_ERROR(kmfh, ERR_get_error()); 1918 ret = KMF_ERR_BAD_CERT_FORMAT; 1919 goto end; 1920 } 1921 /* Now get the public key from the CA cert */ 1922 pkey = X509_get_pubkey(xcert); 1923 if (!pkey) { 1924 SET_ERROR(kmfh, ERR_get_error()); 1925 ret = KMF_ERR_BAD_CERTFILE; 1926 goto end; 1927 } 1928 1929 /* Verify the CRL with the CA's public key */ 1930 openssl_ret = X509_CRL_verify(xcrl, pkey); 1931 EVP_PKEY_free(pkey); 1932 if (openssl_ret > 0) { 1933 ret = KMF_OK; /* verify succeed */ 1934 } else { 1935 SET_ERROR(kmfh, openssl_ret); 1936 ret = KMF_ERR_BAD_CRLFILE; 1937 } 1938 1939output: 1940 outformat = params->sslparms.format; 1941 1942 out = BIO_new_file(outcrlfile, "wb"); 1943 if (out == NULL) { 1944 SET_ERROR(kmfh, ERR_get_error()); 1945 ret = KMF_ERR_OPEN_FILE; 1946 goto end; 1947 } 1948 1949 if (outformat == KMF_FORMAT_ASN1) { 1950 openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); 1951 } else if (outformat == KMF_FORMAT_PEM) { 1952 openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); 1953 } else { 1954 ret = KMF_ERR_BAD_PARAMETER; 1955 goto end; 1956 } 1957 1958 if (openssl_ret <= 0) { 1959 SET_ERROR(kmfh, ERR_get_error()); 1960 ret = KMF_ERR_WRITE_FILE; 1961 } else { 1962 ret = KMF_OK; 1963 } 1964 1965end: 1966 if (xcrl != NULL) 1967 X509_CRL_free(xcrl); 1968 1969 if (xcert != NULL) 1970 X509_free(xcert); 1971 1972 if (in != NULL) 1973 (void) BIO_free(in); 1974 1975 if (out != NULL) 1976 (void) BIO_free(out); 1977 1978 if (outcrlfile != NULL) 1979 free(outcrlfile); 1980 1981 return (ret); 1982} 1983 1984KMF_RETURN 1985OpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, 1986 char **crldata) 1987{ 1988 KMF_RETURN ret = KMF_OK; 1989 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1990 X509_CRL *x = NULL; 1991 KMF_ENCODE_FORMAT format; 1992 char *crlfile = NULL; 1993 BIO *in = NULL; 1994 BIO *mem = NULL; 1995 long len; 1996 char *memptr; 1997 char *data = NULL; 1998 1999 if (params == NULL || params->sslparms.crlfile == NULL) { 2000 return (KMF_ERR_BAD_PARAMETER); 2001 } 2002 2003 crlfile = get_fullpath(params->sslparms.dirpath, 2004 params->sslparms.crlfile); 2005 2006 if (crlfile == NULL) 2007 return (KMF_ERR_BAD_PARAMETER); 2008 2009 if (isdir(crlfile)) { 2010 free(crlfile); 2011 return (KMF_ERR_BAD_PARAMETER); 2012 } 2013 2014 ret = KMF_IsCRLFile(handle, crlfile, &format); 2015 if (ret != KMF_OK) { 2016 free(crlfile); 2017 return (ret); 2018 } 2019 2020 if (bio_err == NULL) 2021 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 2022 2023 in = BIO_new_file(crlfile, "rb"); 2024 if (in == NULL) { 2025 SET_ERROR(kmfh, ERR_get_error()); 2026 ret = KMF_ERR_OPEN_FILE; 2027 goto end; 2028 } 2029 2030 if (format == KMF_FORMAT_ASN1) { 2031 x = d2i_X509_CRL_bio(in, NULL); 2032 } else if (format == KMF_FORMAT_PEM) { 2033 x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 2034 } 2035 2036 if (x == NULL) { /* should not happen */ 2037 SET_ERROR(kmfh, ERR_get_error()); 2038 ret = KMF_ERR_OPEN_FILE; 2039 goto end; 2040 } 2041 2042 mem = BIO_new(BIO_s_mem()); 2043 if (mem == NULL) { 2044 SET_ERROR(kmfh, ERR_get_error()); 2045 ret = KMF_ERR_MEMORY; 2046 goto end; 2047 } 2048 2049 (void) X509_CRL_print(mem, x); 2050 len = BIO_get_mem_data(mem, &memptr); 2051 if (len <= 0) { 2052 SET_ERROR(kmfh, ERR_get_error()); 2053 ret = KMF_ERR_MEMORY; 2054 goto end; 2055 } 2056 2057 data = malloc(len + 1); 2058 if (data == NULL) { 2059 ret = KMF_ERR_MEMORY; 2060 goto end; 2061 } 2062 2063 (void) memcpy(data, memptr, len); 2064 data[len] = '\0'; 2065 *crldata = data; 2066 2067end: 2068 if (x != NULL) 2069 X509_CRL_free(x); 2070 2071 if (crlfile != NULL) 2072 free(crlfile); 2073 2074 if (in != NULL) 2075 (void) BIO_free(in); 2076 2077 if (mem != NULL) 2078 (void) BIO_free(mem); 2079 2080 return (ret); 2081} 2082 2083KMF_RETURN 2084OpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) 2085{ 2086 KMF_RETURN ret = KMF_OK; 2087 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2088 KMF_ENCODE_FORMAT format; 2089 char *crlfile = NULL; 2090 BIO *in = NULL; 2091 2092 if (params == NULL || params->sslparms.crlfile == NULL) { 2093 return (KMF_ERR_BAD_PARAMETER); 2094 } 2095 2096 crlfile = get_fullpath(params->sslparms.dirpath, 2097 params->sslparms.crlfile); 2098 2099 if (crlfile == NULL) 2100 return (KMF_ERR_BAD_PARAMETER); 2101 2102 if (isdir(crlfile)) { 2103 ret = KMF_ERR_BAD_PARAMETER; 2104 goto end; 2105 } 2106 2107 ret = KMF_IsCRLFile(handle, crlfile, &format); 2108 if (ret != KMF_OK) 2109 goto end; 2110 2111 if (unlink(crlfile) != 0) { 2112 SET_SYS_ERROR(kmfh, errno); 2113 ret = KMF_ERR_INTERNAL; 2114 goto end; 2115 } 2116 2117end: 2118 if (in != NULL) 2119 (void) BIO_free(in); 2120 if (crlfile != NULL) 2121 free(crlfile); 2122 2123 return (ret); 2124} 2125 2126 2127KMF_RETURN 2128OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) 2129{ 2130 KMF_RETURN ret = KMF_OK; 2131 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2132 KMF_ENCODE_FORMAT format; 2133 BIO *in = NULL; 2134 X509 *xcert = NULL; 2135 X509_CRL *xcrl = NULL; 2136 STACK_OF(X509_REVOKED) *revoke_stack = NULL; 2137 X509_REVOKED *revoke; 2138 int i; 2139 2140 if (params == NULL || params->sslparms.crlfile == NULL || 2141 params->sslparms.certfile == NULL) { 2142 return (KMF_ERR_BAD_PARAMETER); 2143 } 2144 2145 ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); 2146 if (ret != KMF_OK) 2147 return (ret); 2148 2149 /* Read the CRL file and load it into a X509_CRL structure */ 2150 in = BIO_new_file(params->sslparms.crlfile, "rb"); 2151 if (in == NULL) { 2152 SET_ERROR(kmfh, ERR_get_error()); 2153 ret = KMF_ERR_OPEN_FILE; 2154 goto end; 2155 } 2156 2157 if (format == KMF_FORMAT_ASN1) { 2158 xcrl = d2i_X509_CRL_bio(in, NULL); 2159 } else if (format == KMF_FORMAT_PEM) { 2160 xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 2161 } 2162 2163 if (xcrl == NULL) { 2164 SET_ERROR(kmfh, ERR_get_error()); 2165 ret = KMF_ERR_BAD_CRLFILE; 2166 goto end; 2167 } 2168 (void) BIO_free(in); 2169 2170 /* Read the Certificate file and load it into a X509 structure */ 2171 ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); 2172 if (ret != KMF_OK) 2173 goto end; 2174 2175 in = BIO_new_file(params->sslparms.certfile, "rb"); 2176 if (in == NULL) { 2177 SET_ERROR(kmfh, ERR_get_error()); 2178 ret = KMF_ERR_OPEN_FILE; 2179 goto end; 2180 } 2181 2182 if (format == KMF_FORMAT_ASN1) { 2183 xcert = d2i_X509_bio(in, NULL); 2184 } else if (format == KMF_FORMAT_PEM) { 2185 xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 2186 } 2187 2188 if (xcert == NULL) { 2189 SET_ERROR(kmfh, ERR_get_error()); 2190 ret = KMF_ERR_BAD_CERTFILE; 2191 goto end; 2192 } 2193 2194 /* Check if the certificate and the CRL have same issuer */ 2195 if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { 2196 ret = KMF_ERR_ISSUER; 2197 goto end; 2198 } 2199 2200 /* Check to see if the certificate serial number is revoked */ 2201 revoke_stack = X509_CRL_get_REVOKED(xcrl); 2202 if (sk_X509_REVOKED_num(revoke_stack) <= 0) { 2203 /* No revoked certificates in the CRL file */ 2204 SET_ERROR(kmfh, ERR_get_error()); 2205 ret = KMF_ERR_EMPTY_CRL; 2206 goto end; 2207 } 2208 2209 for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { 2210 /*LINTED*/ 2211 revoke = sk_X509_REVOKED_value(revoke_stack, i); 2212 if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, 2213 revoke->serialNumber) == 0) { 2214 break; 2215 } 2216 } 2217 2218 if (i < sk_X509_REVOKED_num(revoke_stack)) { 2219 ret = KMF_OK; 2220 } else { 2221 ret = KMF_ERR_NOT_REVOKED; 2222 } 2223 2224end: 2225 if (in != NULL) 2226 (void) BIO_free(in); 2227 if (xcrl != NULL) 2228 X509_CRL_free(xcrl); 2229 if (xcert != NULL) 2230 X509_free(xcert); 2231 2232 return (ret); 2233} 2234 2235KMF_RETURN 2236OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 2237{ 2238 KMF_RETURN ret = KMF_OK; 2239 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2240 char str[256]; /* OpenSSL needs at least 120 byte buffer */ 2241 2242 ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str)); 2243 if (strlen(str)) { 2244 *msgstr = (char *)strdup(str); 2245 if ((*msgstr) == NULL) 2246 ret = KMF_ERR_MEMORY; 2247 } else { 2248 *msgstr = NULL; 2249 } 2250 2251 return (ret); 2252} 2253 2254static int 2255ext2NID(int kmfext) 2256{ 2257 switch (kmfext) { 2258 case KMF_X509_EXT_KEY_USAGE: 2259 return (NID_key_usage); 2260 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 2261 return (NID_private_key_usage_period); 2262 case KMF_X509_EXT_CERT_POLICIES: 2263 return (NID_certificate_policies); 2264 case KMF_X509_EXT_SUBJ_ALTNAME: 2265 return (NID_subject_alt_name); 2266 case KMF_X509_EXT_ISSUER_ALTNAME: 2267 return (NID_issuer_alt_name); 2268 case KMF_X509_EXT_BASIC_CONSTRAINTS: 2269 return (NID_basic_constraints); 2270 case KMF_X509_EXT_EXT_KEY_USAGE: 2271 return (NID_ext_key_usage); 2272 case KMF_X509_EXT_AUTH_KEY_ID: 2273 return (NID_authority_key_identifier); 2274 case KMF_X509_EXT_CRL_DIST_POINTS: 2275 return (NID_crl_distribution_points); 2276 case KMF_X509_EXT_SUBJ_KEY_ID: 2277 return (NID_subject_key_identifier); 2278 case KMF_X509_EXT_POLICY_MAPPINGS: 2279 return (OBJ_sn2nid("policyMappings")); 2280 case KMF_X509_EXT_NAME_CONSTRAINTS: 2281 return (OBJ_sn2nid("nameConstraints")); 2282 case KMF_X509_EXT_POLICY_CONSTRAINTS: 2283 return (OBJ_sn2nid("policyConstraints")); 2284 case KMF_X509_EXT_INHIBIT_ANY_POLICY: 2285 return (OBJ_sn2nid("inhibitAnyPolicy")); 2286 case KMF_X509_EXT_FRESHEST_CRL: 2287 return (OBJ_sn2nid("freshestCRL")); 2288 default: 2289 return (NID_undef); 2290 } 2291} 2292 2293KMF_RETURN 2294OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, 2295 KMF_PRINTABLE_ITEM flag, char *resultStr) 2296{ 2297 KMF_RETURN ret = KMF_OK; 2298 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2299 X509 *xcert = NULL; 2300 unsigned char *outbuf = NULL; 2301 unsigned char *outbuf_p; 2302 char *tmpstr = NULL; 2303 int j; 2304 int ext_index, nid, len; 2305 BIO *mem = NULL; 2306 STACK *emlst = NULL; 2307 X509_EXTENSION *ex; 2308 X509_CINF *ci; 2309 2310 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) { 2311 return (KMF_ERR_BAD_PARAMETER); 2312 } 2313 2314 /* copy cert data to outbuf */ 2315 outbuf = malloc(pcert->Length); 2316 if (outbuf == NULL) { 2317 return (KMF_ERR_MEMORY); 2318 } 2319 (void) memcpy(outbuf, pcert->Data, pcert->Length); 2320 2321 outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 2322 xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length); 2323 if (xcert == NULL) { 2324 SET_ERROR(kmfh, ERR_get_error()); 2325 ret = KMF_ERR_ENCODING; 2326 goto out; 2327 } 2328 2329 mem = BIO_new(BIO_s_mem()); 2330 if (mem == NULL) { 2331 SET_ERROR(kmfh, ERR_get_error()); 2332 ret = KMF_ERR_MEMORY; 2333 goto out; 2334 } 2335 2336 switch (flag) { 2337 case KMF_CERT_ISSUER: 2338 (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0, 2339 XN_FLAG_SEP_CPLUS_SPC); 2340 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2341 break; 2342 2343 case KMF_CERT_SUBJECT: 2344 (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0, 2345 XN_FLAG_SEP_CPLUS_SPC); 2346 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2347 break; 2348 2349 case KMF_CERT_VERSION: 2350 tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version); 2351 (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN); 2352 OPENSSL_free(tmpstr); 2353 len = strlen(resultStr); 2354 break; 2355 2356 case KMF_CERT_SERIALNUM: 2357 if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) { 2358 (void) strcpy(resultStr, "0x"); 2359 len = BIO_gets(mem, &resultStr[2], 2360 KMF_CERT_PRINTABLE_LEN - 2); 2361 } 2362 break; 2363 2364 case KMF_CERT_NOTBEFORE: 2365 (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert)); 2366 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2367 break; 2368 2369 case KMF_CERT_NOTAFTER: 2370 (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert)); 2371 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2372 break; 2373 2374 case KMF_CERT_PUBKEY_DATA: 2375 { 2376 EVP_PKEY *pkey = X509_get_pubkey(xcert); 2377 if (pkey == NULL) { 2378 SET_ERROR(kmfh, ERR_get_error()); 2379 ret = KMF_ERR_ENCODING; 2380 goto out; 2381 } 2382 2383 if (pkey->type == EVP_PKEY_RSA) { 2384 (void) BIO_printf(mem, 2385 "RSA Public Key: (%d bit)\n", 2386 BN_num_bits(pkey->pkey.rsa->n)); 2387 (void) RSA_print(mem, pkey->pkey.rsa, 0); 2388 } else if (pkey->type == EVP_PKEY_DSA) { 2389 (void) BIO_printf(mem, 2390 "%12sDSA Public Key:\n", ""); 2391 (void) DSA_print(mem, pkey->pkey.dsa, 0); 2392 } else { 2393 (void) BIO_printf(mem, 2394 "%12sUnknown Public Key:\n", ""); 2395 } 2396 (void) BIO_printf(mem, "\n"); 2397 EVP_PKEY_free(pkey); 2398 } 2399 len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2400 break; 2401 case KMF_CERT_SIGNATURE_ALG: 2402 case KMF_CERT_PUBKEY_ALG: 2403 if (flag == KMF_CERT_SIGNATURE_ALG) { 2404 len = i2a_ASN1_OBJECT(mem, 2405 xcert->sig_alg->algorithm); 2406 } else { 2407 len = i2a_ASN1_OBJECT(mem, 2408 xcert->cert_info->key->algor->algorithm); 2409 } 2410 2411 if (len > 0) { 2412 len = BIO_read(mem, resultStr, 2413 KMF_CERT_PRINTABLE_LEN); 2414 } 2415 break; 2416 2417 case KMF_CERT_EMAIL: 2418 emlst = X509_get1_email(xcert); 2419 for (j = 0; j < sk_num(emlst); j++) 2420 (void) BIO_printf(mem, "%s\n", sk_value(emlst, j)); 2421 2422 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2423 X509_email_free(emlst); 2424 break; 2425 case KMF_X509_EXT_ISSUER_ALTNAME: 2426 case KMF_X509_EXT_SUBJ_ALTNAME: 2427 case KMF_X509_EXT_KEY_USAGE: 2428 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 2429 case KMF_X509_EXT_CERT_POLICIES: 2430 case KMF_X509_EXT_BASIC_CONSTRAINTS: 2431 case KMF_X509_EXT_NAME_CONSTRAINTS: 2432 case KMF_X509_EXT_POLICY_CONSTRAINTS: 2433 case KMF_X509_EXT_EXT_KEY_USAGE: 2434 case KMF_X509_EXT_INHIBIT_ANY_POLICY: 2435 case KMF_X509_EXT_AUTH_KEY_ID: 2436 case KMF_X509_EXT_SUBJ_KEY_ID: 2437 case KMF_X509_EXT_POLICY_MAPPINGS: 2438 case KMF_X509_EXT_CRL_DIST_POINTS: 2439 case KMF_X509_EXT_FRESHEST_CRL: 2440 nid = ext2NID(flag); 2441 if (nid == NID_undef) { 2442 ret = KMF_ERR_EXTENSION_NOT_FOUND; 2443 goto out; 2444 } 2445 ci = xcert->cert_info; 2446 2447 ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1); 2448 if (ext_index == -1) { 2449 SET_ERROR(kmfh, ERR_get_error()); 2450 2451 ret = KMF_ERR_EXTENSION_NOT_FOUND; 2452 goto out; 2453 } 2454 ex = X509v3_get_ext(ci->extensions, ext_index); 2455 2456 (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); 2457 2458 if (BIO_printf(mem, ": %s\n", 2459 X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 2460 0) { 2461 SET_ERROR(kmfh, ERR_get_error()); 2462 ret = KMF_ERR_ENCODING; 2463 goto out; 2464 } 2465 if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) { 2466 (void) BIO_printf(mem, "%*s", 4, ""); 2467 (void) M_ASN1_OCTET_STRING_print(mem, ex->value); 2468 } 2469 if (BIO_write(mem, "\n", 1) <= 0) { 2470 SET_ERROR(kmfh, ERR_get_error()); 2471 ret = KMF_ERR_ENCODING; 2472 goto out; 2473 } 2474 len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2475 } 2476 if (len <= 0) { 2477 SET_ERROR(kmfh, ERR_get_error()); 2478 ret = KMF_ERR_ENCODING; 2479 } 2480 2481out: 2482 if (outbuf != NULL) { 2483 free(outbuf); 2484 } 2485 2486 if (xcert != NULL) { 2487 X509_free(xcert); 2488 } 2489 2490 if (mem != NULL) { 2491 (void) BIO_free(mem); 2492 } 2493 2494 return (ret); 2495} 2496KMF_RETURN 2497/*ARGSUSED*/ 2498OpenSSL_GetPrikeyByCert(KMF_HANDLE_T handle, 2499 KMF_CRYPTOWITHCERT_PARAMS *params, 2500 KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, 2501 KMF_KEY_ALG keytype) 2502{ 2503 KMF_RETURN rv = KMF_OK; 2504 KMF_FINDKEY_PARAMS fkparms; 2505 uint32_t numkeys = 0; 2506 2507 if (params == NULL || params->sslparms.keyfile == NULL) 2508 return (KMF_ERR_BAD_PARAMETER); 2509 2510 /* 2511 * This is really just a FindKey operation, reuse the 2512 * FindKey function. 2513 */ 2514 (void *)memset(&fkparms, 0, sizeof (fkparms)); 2515 fkparms.kstype = KMF_KEYSTORE_OPENSSL; 2516 fkparms.keyclass = KMF_ASYM_PRI; 2517 fkparms.keytype = keytype; 2518 fkparms.format = params->format; 2519 fkparms.sslparms = params->sslparms; 2520 2521 rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys); 2522 2523 return (rv); 2524} 2525 2526KMF_RETURN 2527/*ARGSUSED*/ 2528OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 2529 KMF_OID *AlgOID, KMF_DATA *ciphertext, 2530 KMF_DATA *output) 2531{ 2532 KMF_RETURN ret = KMF_OK; 2533 RSA *rsa = NULL; 2534 unsigned int in_len = 0, out_len = 0; 2535 unsigned int total_decrypted = 0, modulus_len = 0; 2536 uint8_t *in_data, *out_data; 2537 int i, blocks; 2538 2539 if (key == NULL || AlgOID == NULL || 2540 ciphertext == NULL || output == NULL || 2541 ciphertext->Data == NULL || 2542 output->Data == NULL) 2543 return (KMF_ERR_BAD_PARAMETER); 2544 2545 if (key->keyalg == KMF_RSA) { 2546 rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp); 2547 modulus_len = RSA_size(rsa); 2548 } else { 2549 return (KMF_ERR_BAD_PARAMETER); 2550 } 2551 2552 blocks = ciphertext->Length/modulus_len; 2553 out_data = output->Data; 2554 in_data = ciphertext->Data; 2555 out_len = modulus_len - 11; 2556 in_len = modulus_len; 2557 2558 for (i = 0; i < blocks; i++) { 2559 out_len = RSA_private_decrypt(in_len, 2560 in_data, out_data, rsa, RSA_PKCS1_PADDING); 2561 2562 if (out_len == 0) { 2563 ret = KMF_ERR_INTERNAL; 2564 goto cleanup; 2565 } 2566 2567 out_data += out_len; 2568 total_decrypted += out_len; 2569 in_data += in_len; 2570 } 2571 2572 output->Length = total_decrypted; 2573 2574cleanup: 2575 RSA_free(rsa); 2576 if (ret != KMF_OK) 2577 output->Length = 0; 2578 2579 return (ret); 2580 2581} 2582 2583/* 2584 * This function will create a certid from issuer_cert and user_cert. 2585 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate 2586 * certid memory after use. 2587 */ 2588static KMF_RETURN 2589create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert, 2590 const KMF_DATA *user_cert, OCSP_CERTID **certid) 2591{ 2592 KMF_RETURN ret = KMF_OK; 2593 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2594 X509 *issuer = NULL; 2595 X509 *cert = NULL; 2596 unsigned char *ptmp; 2597 2598 if (issuer_cert == NULL || user_cert == NULL) { 2599 return (KMF_ERR_BAD_PARAMETER); 2600 } 2601 2602 /* convert the DER-encoded issuer cert to an internal X509 */ 2603 ptmp = issuer_cert->Data; 2604 issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2605 issuer_cert->Length); 2606 if (issuer == NULL) { 2607 SET_ERROR(kmfh, ERR_get_error()); 2608 ret = KMF_ERR_OCSP_BAD_ISSUER; 2609 goto end; 2610 } 2611 2612 /* convert the DER-encoded user cert to an internal X509 */ 2613 ptmp = user_cert->Data; 2614 cert = d2i_X509(NULL, (const uchar_t **)&ptmp, 2615 user_cert->Length); 2616 if (cert == NULL) { 2617 SET_ERROR(kmfh, ERR_get_error()); 2618 2619 ret = KMF_ERR_OCSP_BAD_CERT; 2620 goto end; 2621 } 2622 2623 /* create a CERTID */ 2624 *certid = OCSP_cert_to_id(NULL, cert, issuer); 2625 if (*certid == NULL) { 2626 SET_ERROR(kmfh, ERR_get_error()); 2627 ret = KMF_ERR_OCSP_CERTID; 2628 goto end; 2629 } 2630 2631end: 2632 if (issuer != NULL) { 2633 X509_free(issuer); 2634 } 2635 2636 if (cert != NULL) { 2637 X509_free(cert); 2638 } 2639 2640 return (ret); 2641} 2642 2643KMF_RETURN 2644OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, 2645 char *reqfile) 2646{ 2647 KMF_RETURN ret = KMF_OK; 2648 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2649 OCSP_CERTID *id = NULL; 2650 OCSP_REQUEST *req = NULL; 2651 BIO *derbio = NULL; 2652 2653 if (params->user_cert == NULL || params->issuer_cert == NULL || 2654 reqfile == NULL) { 2655 return (KMF_ERR_BAD_PARAMETER); 2656 } 2657 2658 ret = create_certid(handle, params->issuer_cert, params->user_cert, 2659 &id); 2660 if (ret != KMF_OK) { 2661 return (ret); 2662 } 2663 2664 /* Create an OCSP request */ 2665 req = OCSP_REQUEST_new(); 2666 if (req == NULL) { 2667 SET_ERROR(kmfh, ERR_get_error()); 2668 ret = KMF_ERR_OCSP_CREATE_REQUEST; 2669 goto end; 2670 } 2671 2672 if (!OCSP_request_add0_id(req, id)) { 2673 ret = KMF_ERR_OCSP_CREATE_REQUEST; 2674 goto end; 2675 } 2676 2677 /* Write the request to the output file with DER encoding */ 2678 derbio = BIO_new_file(reqfile, "wb"); 2679 if (!derbio) { 2680 SET_ERROR(kmfh, ERR_get_error()); 2681 ret = KMF_ERR_OPEN_FILE; 2682 goto end; 2683 } 2684 if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) { 2685 ret = KMF_ERR_ENCODING; 2686 } 2687 2688end: 2689 /* 2690 * We don't need to free "id" explicitely, because OCSP_REQUEST_free() 2691 * will deallocate certid's space also. 2692 */ 2693 if (req != NULL) { 2694 OCSP_REQUEST_free(req); 2695 } 2696 2697 if (derbio != NULL) { 2698 (void) BIO_free(derbio); 2699 } 2700 2701 return (ret); 2702} 2703 2704/* ocsp_find_signer_sk() is copied from openssl source */ 2705static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 2706{ 2707 int i; 2708 unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 2709 2710 /* Easy if lookup by name */ 2711 if (id->type == V_OCSP_RESPID_NAME) 2712 return (X509_find_by_subject(certs, id->value.byName)); 2713 2714 /* Lookup by key hash */ 2715 2716 /* If key hash isn't SHA1 length then forget it */ 2717 if (id->value.byKey->length != SHA_DIGEST_LENGTH) 2718 return (NULL); 2719 2720 keyhash = id->value.byKey->data; 2721 /* Calculate hash of each key and compare */ 2722 for (i = 0; i < sk_X509_num(certs); i++) { 2723 /*LINTED*/ 2724 X509 *x = sk_X509_value(certs, i); 2725 (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 2726 if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 2727 return (x); 2728 } 2729 return (NULL); 2730} 2731 2732/* ocsp_find_signer() is copied from openssl source */ 2733/*ARGSUSED*/ 2734static int 2735ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, 2736 X509_STORE *st, unsigned long flags) 2737{ 2738 X509 *signer; 2739 OCSP_RESPID *rid = bs->tbsResponseData->responderId; 2740 if ((signer = ocsp_find_signer_sk(certs, rid))) { 2741 *psigner = signer; 2742 return (2); 2743 } 2744 if (!(flags & OCSP_NOINTERN) && 2745 (signer = ocsp_find_signer_sk(bs->certs, rid))) { 2746 *psigner = signer; 2747 return (1); 2748 } 2749 /* Maybe lookup from store if by subject name */ 2750 2751 *psigner = NULL; 2752 return (0); 2753} 2754 2755/* 2756 * This function will verify the signature of a basic response, using 2757 * the public key from the OCSP responder certificate. 2758 */ 2759static KMF_RETURN 2760check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, 2761 KMF_DATA *signer_cert, KMF_DATA *issuer_cert) 2762{ 2763 KMF_RETURN ret = KMF_OK; 2764 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2765 STACK_OF(X509) *cert_stack = NULL; 2766 X509 *signer = NULL; 2767 X509 *issuer = NULL; 2768 EVP_PKEY *skey = NULL; 2769 unsigned char *ptmp; 2770 2771 2772 if (bs == NULL || issuer_cert == NULL) 2773 return (KMF_ERR_BAD_PARAMETER); 2774 2775 /* 2776 * Find the certificate that signed the basic response. 2777 * 2778 * If signer_cert is not NULL, we will use that as the signer cert. 2779 * Otherwise, we will check if the issuer cert is actually the signer. 2780 * If we still do not find a signer, we will look for it from the 2781 * certificate list came with the response file. 2782 */ 2783 if (signer_cert != NULL) { 2784 ptmp = signer_cert->Data; 2785 signer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2786 signer_cert->Length); 2787 if (signer == NULL) { 2788 SET_ERROR(kmfh, ERR_get_error()); 2789 ret = KMF_ERR_OCSP_BAD_SIGNER; 2790 goto end; 2791 } 2792 } else { 2793 /* 2794 * Convert the issuer cert into X509 and push it into a 2795 * stack to be used by ocsp_find_signer(). 2796 */ 2797 ptmp = issuer_cert->Data; 2798 issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2799 issuer_cert->Length); 2800 if (issuer == NULL) { 2801 SET_ERROR(kmfh, ERR_get_error()); 2802 ret = KMF_ERR_OCSP_BAD_ISSUER; 2803 goto end; 2804 } 2805 2806 if ((cert_stack = sk_X509_new_null()) == NULL) { 2807 ret = KMF_ERR_INTERNAL; 2808 goto end; 2809 } 2810 2811 if (sk_X509_push(cert_stack, issuer) == NULL) { 2812 ret = KMF_ERR_INTERNAL; 2813 goto end; 2814 } 2815 2816 ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0); 2817 if (!ret) { 2818 /* can not find the signer */ 2819 ret = KMF_ERR_OCSP_BAD_SIGNER; 2820 goto end; 2821 } 2822 } 2823 2824 /* Verify the signature of the response */ 2825 skey = X509_get_pubkey(signer); 2826 if (skey == NULL) { 2827 ret = KMF_ERR_OCSP_BAD_SIGNER; 2828 goto end; 2829 } 2830 2831 ret = OCSP_BASICRESP_verify(bs, skey, 0); 2832 if (ret == 0) { 2833 ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE; 2834 goto end; 2835 } 2836 2837end: 2838 if (issuer != NULL) { 2839 X509_free(issuer); 2840 } 2841 2842 if (signer != NULL) { 2843 X509_free(signer); 2844 } 2845 2846 if (skey != NULL) { 2847 EVP_PKEY_free(skey); 2848 } 2849 2850 if (cert_stack != NULL) { 2851 sk_X509_free(cert_stack); 2852 } 2853 2854 return (ret); 2855} 2856 2857 2858 2859KMF_RETURN 2860OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, 2861 KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 2862 KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) 2863{ 2864 KMF_RETURN ret = KMF_OK; 2865 BIO *derbio = NULL; 2866 OCSP_RESPONSE *resp = NULL; 2867 OCSP_BASICRESP *bs = NULL; 2868 OCSP_CERTID *id = NULL; 2869 OCSP_SINGLERESP *single = NULL; 2870 ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 2871 int index, status, reason; 2872 2873 if (params_in == NULL || params_in->issuer_cert == NULL || 2874 params_in->user_cert == NULL || params_in->response == NULL) { 2875 return (KMF_ERR_BAD_PARAMETER); 2876 } 2877 2878 if (params_out == NULL) { 2879 return (KMF_ERR_BAD_PARAMETER); 2880 } 2881 2882 /* Read in the response */ 2883 derbio = BIO_new_mem_buf(params_in->response->Data, 2884 params_in->response->Length); 2885 if (!derbio) { 2886 ret = KMF_ERR_MEMORY; 2887 return (ret); 2888 } 2889 2890 resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 2891 if (resp == NULL) { 2892 ret = KMF_ERR_OCSP_MALFORMED_RESPONSE; 2893 goto end; 2894 } 2895 2896 /* Check the response status */ 2897 status = OCSP_response_status(resp); 2898 params_out->response_status = status; 2899 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 2900 ret = KMF_ERR_OCSP_RESPONSE_STATUS; 2901 goto end; 2902 } 2903 2904#ifdef DEBUG 2905 printf("Successfully checked the response file status.\n"); 2906#endif /* DEBUG */ 2907 2908 /* Extract basic response */ 2909 bs = OCSP_response_get1_basic(resp); 2910 if (bs == NULL) { 2911 ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE; 2912 goto end; 2913 } 2914 2915#ifdef DEBUG 2916 printf("Successfully retrieved the basic response.\n"); 2917#endif /* DEBUG */ 2918 2919 /* Check the basic response signature if required */ 2920 if (params_in->ignore_response_sign == B_FALSE) { 2921 ret = check_response_signature(handle, bs, 2922 params_in->signer_cert, params_in->issuer_cert); 2923 if (ret != KMF_OK) 2924 goto end; 2925 } 2926 2927#ifdef DEBUG 2928 printf("Successfully verified the response signature.\n"); 2929#endif /* DEBUG */ 2930 2931 /* Create a certid for the certificate in question */ 2932 ret = create_certid(handle, params_in->issuer_cert, 2933 params_in->user_cert, &id); 2934 if (ret != KMF_OK) { 2935 ret = KMF_ERR_OCSP_CERTID; 2936 goto end; 2937 } 2938 2939#ifdef DEBUG 2940 printf("successfully created a certid for the cert.\n"); 2941#endif /* DEBUG */ 2942 2943 /* Find the index of the single response for the certid */ 2944 index = OCSP_resp_find(bs, id, -1); 2945 if (index < 0) { 2946 /* cound not find this certificate in the response */ 2947 ret = KMF_ERR_OCSP_UNKNOWN_CERT; 2948 goto end; 2949 } 2950 2951#ifdef DEBUG 2952 printf("Successfully found the single response index for the cert.\n"); 2953#endif /* DEBUG */ 2954 2955 /* Retrieve the single response and get the cert status */ 2956 single = OCSP_resp_get0(bs, index); 2957 status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, 2958 &nextupd); 2959 if (status == V_OCSP_CERTSTATUS_GOOD) { 2960 params_out->cert_status = OCSP_GOOD; 2961 } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { 2962 params_out->cert_status = OCSP_UNKNOWN; 2963 } else { /* revoked */ 2964 params_out->cert_status = OCSP_REVOKED; 2965 params_out->reason = reason; 2966 } 2967 ret = KMF_OK; 2968 2969 /* Verify the time */ 2970 if (!OCSP_check_validity(thisupd, nextupd, 300, 2971 params_in->response_lifetime)) { 2972 ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; 2973 goto end; 2974 } 2975 2976#ifdef DEBUG 2977 printf("Successfully verify the time.\n"); 2978#endif /* DEBUG */ 2979 2980end: 2981 if (derbio != NULL) 2982 (void) BIO_free(derbio); 2983 2984 if (resp != NULL) 2985 OCSP_RESPONSE_free(resp); 2986 2987 if (bs != NULL) 2988 OCSP_BASICRESP_free(bs); 2989 2990 if (id != NULL) 2991 OCSP_CERTID_free(id); 2992 2993 return (ret); 2994} 2995 2996static KMF_RETURN 2997fetch_key(KMF_HANDLE_T handle, char *path, 2998 KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) 2999{ 3000 KMF_RETURN rv = KMF_OK; 3001 EVP_PKEY *pkey; 3002 KMF_RAW_SYM_KEY *rkey = NULL; 3003 3004 /* Make sure the requested file actually exists. */ 3005 if (access(path, F_OK) != 0) { 3006 return (KMF_ERR_KEY_NOT_FOUND); 3007 } 3008 3009 if (keyclass == KMF_ASYM_PRI || 3010 keyclass == KMF_ASYM_PUB) { 3011 pkey = openssl_load_key(handle, path); 3012 if (pkey == NULL) { 3013 return (KMF_ERR_KEY_NOT_FOUND); 3014 } 3015 if (key != NULL) { 3016 if (pkey->type == EVP_PKEY_RSA) 3017 key->keyalg = KMF_RSA; 3018 else if (pkey->type == EVP_PKEY_DSA) 3019 key->keyalg = KMF_DSA; 3020 3021 key->kstype = KMF_KEYSTORE_OPENSSL; 3022 key->keyclass = keyclass; 3023 key->keyp = (void *)pkey; 3024 key->israw = FALSE; 3025 key->keylabel = path; 3026 } else { 3027 EVP_PKEY_free(pkey); 3028 pkey = NULL; 3029 } 3030 } else if (keyclass == KMF_SYMMETRIC) { 3031 KMF_ENCODE_FORMAT fmt; 3032 /* 3033 * If the file is a recognized format, 3034 * then it is NOT a symmetric key. 3035 */ 3036 rv = KMF_GetFileFormat(path, &fmt); 3037 if (rv == KMF_OK || fmt != 0) { 3038 return (KMF_ERR_KEY_NOT_FOUND); 3039 } else if (rv == KMF_ERR_ENCODING) { 3040 /* 3041 * If we don't know the encoding, 3042 * it is probably a symmetric key. 3043 */ 3044 rv = KMF_OK; 3045 } 3046 3047 if (key != NULL) { 3048 KMF_DATA keyvalue; 3049 rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 3050 if (rkey == NULL) { 3051 rv = KMF_ERR_MEMORY; 3052 goto out; 3053 } 3054 3055 (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 3056 rv = KMF_ReadInputFile(handle, path, &keyvalue); 3057 if (rv != KMF_OK) 3058 goto out; 3059 3060 rkey->keydata.len = keyvalue.Length; 3061 rkey->keydata.val = keyvalue.Data; 3062 3063 key->kstype = KMF_KEYSTORE_OPENSSL; 3064 key->keyclass = keyclass; 3065 key->israw = TRUE; 3066 key->keylabel = path; 3067 key->keyp = (void *)rkey; 3068 } 3069 } 3070out: 3071 if (rv != KMF_OK) { 3072 if (rkey != NULL) { 3073 KMF_FreeRawSymKey(rkey); 3074 } 3075 if (pkey != NULL) 3076 EVP_PKEY_free(pkey); 3077 3078 if (key != NULL) { 3079 key->keyalg = KMF_KEYALG_NONE; 3080 key->keyclass = KMF_KEYCLASS_NONE; 3081 key->keyp = NULL; 3082 } 3083 } 3084 3085 return (rv); 3086} 3087 3088KMF_RETURN 3089OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, 3090 KMF_KEY_HANDLE *key, uint32_t *numkeys) 3091{ 3092 KMF_RETURN rv = KMF_OK; 3093 char *fullpath = NULL; 3094 uint32_t maxkeys; 3095 3096 if (handle == NULL || params == NULL || numkeys == NULL) 3097 return (KMF_ERR_BAD_PARAMETER); 3098 3099 if (params->keyclass != KMF_ASYM_PUB && 3100 params->keyclass != KMF_ASYM_PRI && 3101 params->keyclass != KMF_SYMMETRIC) 3102 return (KMF_ERR_BAD_KEY_CLASS); 3103 3104 fullpath = get_fullpath(params->sslparms.dirpath, 3105 params->sslparms.keyfile); 3106 3107 if (fullpath == NULL) 3108 return (KMF_ERR_BAD_PARAMETER); 3109 3110 maxkeys = *numkeys; 3111 if (maxkeys == 0) 3112 maxkeys = 0xFFFFFFFF; 3113 3114 *numkeys = 0; 3115 3116 if (isdir(fullpath)) { 3117 DIR *dirp; 3118 struct dirent *dp; 3119 int n = 0; 3120 3121 /* open all files in the directory and attempt to read them */ 3122 if ((dirp = opendir(fullpath)) == NULL) { 3123 return (KMF_ERR_BAD_PARAMETER); 3124 } 3125 rewinddir(dirp); 3126 while ((dp = readdir(dirp)) != NULL && n < maxkeys) { 3127 if (strcmp(dp->d_name, ".") && 3128 strcmp(dp->d_name, "..")) { 3129 char *fname; 3130 3131 fname = get_fullpath(fullpath, 3132 (char *)&dp->d_name); 3133 3134 rv = fetch_key(handle, fname, 3135 params->keyclass, 3136 key ? &key[n] : NULL); 3137 3138 if (rv == KMF_OK) 3139 n++; 3140 3141 if (rv != KMF_OK || key == NULL) 3142 free(fname); 3143 } 3144 } 3145 (void) closedir(dirp); 3146 free(fullpath); 3147 (*numkeys) = n; 3148 } else { 3149 rv = fetch_key(handle, fullpath, params->keyclass, key); 3150 if (rv == KMF_OK) 3151 (*numkeys) = 1; 3152 3153 if (rv != KMF_OK || key == NULL) 3154 free(fullpath); 3155 } 3156 3157 if (rv == KMF_OK && (*numkeys) == 0) 3158 rv = KMF_ERR_KEY_NOT_FOUND; 3159 3160 return (rv); 3161} 3162 3163#define HANDLE_PK12_ERROR { \ 3164 SET_ERROR(kmfh, ERR_get_error()); \ 3165 rv = KMF_ERR_ENCODING; \ 3166 goto out; \ 3167} 3168 3169static KMF_RETURN 3170write_pkcs12(KMF_HANDLE *kmfh, 3171 BIO *bio, 3172 KMF_CREDENTIAL *cred, 3173 EVP_PKEY *pkey, 3174 X509 *sslcert) 3175{ 3176 KMF_RETURN rv = KMF_OK; 3177 STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 3178 PKCS12_SAFEBAG *bag = NULL; 3179 PKCS7 *cert_authsafe = NULL; 3180 PKCS8_PRIV_KEY_INFO *p8 = NULL; 3181 PKCS7 *key_authsafe = NULL; 3182 STACK_OF(PKCS7) *authsafe_stack = NULL; 3183 PKCS12 *p12_elem = NULL; 3184 char *lab = NULL; 3185 int lab_len = 0; 3186 unsigned char keyid[EVP_MAX_MD_SIZE]; 3187 unsigned int keyidlen = 0; 3188 3189 /* Must have at least a cert OR a key */ 3190 if (sslcert == NULL && pkey == NULL) 3191 return (KMF_ERR_BAD_PARAMETER); 3192 3193 (void) memset(keyid, 0, sizeof (keyid)); 3194 /* 3195 * Section 1: 3196 * 3197 * The first PKCS#12 container (safebag) will hold the certificates 3198 * associated with this key. The result of this section is a 3199 * PIN-encrypted PKCS#7 container (authsafe). If there are no 3200 * certificates, there is no point in creating the "safebag" or the 3201 * "authsafe" so we go to the next section. 3202 */ 3203 if (sslcert != NULL && pkey != NULL) { 3204 if (X509_check_private_key(sslcert, pkey)) { 3205 (void) X509_digest(sslcert, EVP_sha1(), keyid, 3206 &keyidlen); 3207 } else { 3208 /* The key doesn't match the cert */ 3209 HANDLE_PK12_ERROR 3210 } 3211 } 3212 3213 bag_stack = sk_PKCS12_SAFEBAG_new_null(); 3214 if (bag_stack == NULL) 3215 return (KMF_ERR_MEMORY); 3216 3217 if (sslcert != NULL) { 3218 /* Convert cert from X509 struct to PKCS#12 bag */ 3219 bag = PKCS12_x5092certbag(sslcert); 3220 if (bag == NULL) { 3221 HANDLE_PK12_ERROR 3222 } 3223 3224 /* Add the key id to the certificate bag. */ 3225 if (keyidlen > 0 && 3226 !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 3227 HANDLE_PK12_ERROR 3228 } 3229 3230 /* Pile it on the bag_stack. */ 3231 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 3232 HANDLE_PK12_ERROR 3233 } 3234#if 0 3235 /* No support for CA certs yet */ 3236 if (cacerts != NULL && ncacerts > 0) { 3237 int i; 3238 for (i = 0; i < ncacerts; i++) { 3239 KMF_X509_DER_CERT *c = &cacerts[i]; 3240 X509 *ca = NULL; 3241 3242 uchar_t *p = (uchar_t *)c->certificate.Data; 3243 ca = d2i_X509(NULL, &p, 3244 c->certificate.Length); 3245 if (ca == NULL) { 3246 HANDLE_PK12_ERROR 3247 } 3248 /* Convert CA cert to PKCS#12 bag. */ 3249 bag = PKCS12_x5092certbag(ca); 3250 if (bag == NULL) { 3251 sk_PKCS12_SAFEBAG_pop_free(bag_stack, 3252 PKCS12_SAFEBAG_free); 3253 HANDLE_PK12_ERROR 3254 } 3255 /* Pile it onto the bag_stack. */ 3256 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 3257 HANDLE_PK12_ERROR 3258 } 3259 } 3260 } 3261#endif 3262 /* Turn bag_stack of certs into encrypted authsafe. */ 3263 cert_authsafe = PKCS12_pack_p7encdata( 3264 NID_pbe_WithSHA1And40BitRC2_CBC, 3265 cred->cred, 3266 cred->credlen, NULL, 0, 3267 PKCS12_DEFAULT_ITER, 3268 bag_stack); 3269 3270 /* Clear away this bag_stack, we're done with it. */ 3271 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 3272 bag_stack = NULL; 3273 3274 if (cert_authsafe == NULL) { 3275 HANDLE_PK12_ERROR 3276 } 3277 } 3278 /* 3279 * Section 2: 3280 * 3281 * The second PKCS#12 container (safebag) will hold the private key 3282 * that goes with the certificates above. The results of this section 3283 * is an unencrypted PKCS#7 container (authsafe). If there is no 3284 * private key, there is no point in creating the "safebag" or the 3285 * "authsafe" so we go to the next section. 3286 */ 3287 if (pkey != NULL) { 3288 p8 = EVP_PKEY2PKCS8(pkey); 3289 if (p8 == NULL) { 3290 HANDLE_PK12_ERROR 3291 } 3292 /* Put the shrouded key into a PKCS#12 bag. */ 3293 bag = PKCS12_MAKE_SHKEYBAG( 3294 NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 3295 cred->cred, cred->credlen, 3296 NULL, 0, PKCS12_DEFAULT_ITER, p8); 3297 3298 /* Clean up the PKCS#8 shrouded key, don't need it now. */ 3299 PKCS8_PRIV_KEY_INFO_free(p8); 3300 p8 = NULL; 3301 3302 if (bag == NULL) { 3303 HANDLE_PK12_ERROR 3304 } 3305 if (keyidlen && 3306 !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 3307 HANDLE_PK12_ERROR 3308 } 3309 if (lab != NULL) { 3310 if (!PKCS12_add_friendlyname(bag, 3311 (char *)lab, lab_len)) { 3312 HANDLE_PK12_ERROR 3313 } 3314 } 3315 /* Start a PKCS#12 safebag container for the private key. */ 3316 bag_stack = sk_PKCS12_SAFEBAG_new_null(); 3317 if (bag_stack == NULL) { 3318 HANDLE_PK12_ERROR 3319 } 3320 3321 /* Pile on the private key on the bag_stack. */ 3322 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 3323 HANDLE_PK12_ERROR 3324 } 3325 key_authsafe = PKCS12_pack_p7data(bag_stack); 3326 3327 /* Clear away this bag_stack, we're done with it. */ 3328 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 3329 bag_stack = NULL; 3330 3331 if (key_authsafe == NULL) { 3332 HANDLE_PK12_ERROR 3333 } 3334 } 3335 /* 3336 * Section 3: 3337 * 3338 * This is where the two PKCS#7 containers, one for the certificates 3339 * and one for the private key, are put together into a PKCS#12 3340 * element. This final PKCS#12 element is written to the export file. 3341 */ 3342 3343 /* Start a PKCS#7 stack. */ 3344 authsafe_stack = sk_PKCS7_new_null(); 3345 if (authsafe_stack == NULL) { 3346 HANDLE_PK12_ERROR 3347 } 3348 if (key_authsafe != NULL) { 3349 if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) { 3350 HANDLE_PK12_ERROR 3351 } 3352 } 3353 if (cert_authsafe != NULL) { 3354 if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) { 3355 HANDLE_PK12_ERROR 3356 } 3357 } 3358 p12_elem = PKCS12_init(NID_pkcs7_data); 3359 if (p12_elem == NULL) { 3360 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 3361 HANDLE_PK12_ERROR 3362 } 3363 3364 /* Put the PKCS#7 stack into the PKCS#12 element. */ 3365 if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) { 3366 HANDLE_PK12_ERROR 3367 } 3368 /* Clear away the PKCS#7 stack, we're done with it. */ 3369 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 3370 authsafe_stack = NULL; 3371 3372 /* Set the integrity MAC on the PKCS#12 element. */ 3373 if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen, 3374 NULL, 0, PKCS12_DEFAULT_ITER, NULL)) { 3375 HANDLE_PK12_ERROR 3376 } 3377 3378 /* Write the PKCS#12 element to the export file. */ 3379 if (!i2d_PKCS12_bio(bio, p12_elem)) { 3380 HANDLE_PK12_ERROR 3381 } 3382 3383 PKCS12_free(p12_elem); 3384out: 3385 if (rv != KMF_OK) { 3386 /* Clear away this bag_stack, we're done with it. */ 3387 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 3388 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 3389 } 3390 return (rv); 3391} 3392 3393static EVP_PKEY * 3394ImportRawRSAKey(KMF_RAW_RSA_KEY *key) 3395{ 3396 RSA *rsa = NULL; 3397 EVP_PKEY *newkey = NULL; 3398 3399 if ((rsa = RSA_new()) == NULL) 3400 return (NULL); 3401 3402 if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL) 3403 return (NULL); 3404 3405 if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) == 3406 NULL) 3407 return (NULL); 3408 3409 if (key->priexp.val != NULL) 3410 if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len, 3411 rsa->d)) == NULL) 3412 return (NULL); 3413 3414 if (key->prime1.val != NULL) 3415 if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len, 3416 rsa->p)) == NULL) 3417 return (NULL); 3418 3419 if (key->prime2.val != NULL) 3420 if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len, 3421 rsa->q)) == NULL) 3422 return (NULL); 3423 3424 if (key->exp1.val != NULL) 3425 if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, 3426 rsa->dmp1)) == NULL) 3427 return (NULL); 3428 3429 if (key->exp2.val != NULL) 3430 if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, 3431 rsa->dmq1)) == NULL) 3432 return (NULL); 3433 3434 if (key->coef.val != NULL) 3435 if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len, 3436 rsa->iqmp)) == NULL) 3437 return (NULL); 3438 3439 if ((newkey = EVP_PKEY_new()) == NULL) 3440 return (NULL); 3441 3442 (void) EVP_PKEY_set1_RSA(newkey, rsa); 3443 3444 /* The original key must be freed once here or it leaks memory */ 3445 RSA_free(rsa); 3446 3447 return (newkey); 3448} 3449 3450static EVP_PKEY * 3451ImportRawDSAKey(KMF_RAW_DSA_KEY *key) 3452{ 3453 DSA *dsa = NULL; 3454 EVP_PKEY *newkey = NULL; 3455 3456 if ((dsa = DSA_new()) == NULL) 3457 return (NULL); 3458 3459 if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len, 3460 dsa->p)) == NULL) 3461 return (NULL); 3462 3463 if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len, 3464 dsa->q)) == NULL) 3465 return (NULL); 3466 3467 if ((dsa->g = BN_bin2bn(key->base.val, key->base.len, 3468 dsa->g)) == NULL) 3469 return (NULL); 3470 3471 if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len, 3472 dsa->priv_key)) == NULL) 3473 return (NULL); 3474 3475 if ((newkey = EVP_PKEY_new()) == NULL) 3476 return (NULL); 3477 3478 (void) EVP_PKEY_set1_DSA(newkey, dsa); 3479 3480 /* The original key must be freed once here or it leaks memory */ 3481 DSA_free(dsa); 3482 return (newkey); 3483} 3484 3485static KMF_RETURN 3486ExportPK12FromRawData(KMF_HANDLE_T handle, 3487 KMF_CREDENTIAL *cred, 3488 int numcerts, KMF_X509_DER_CERT *certlist, 3489 int numkeys, KMF_KEY_HANDLE *keylist, 3490 char *filename) 3491{ 3492 KMF_RETURN rv = KMF_OK; 3493 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3494 BIO *bio = NULL; 3495 X509 *xcert = NULL; 3496 EVP_PKEY *pkey = NULL; 3497 int i; 3498 3499 /* 3500 * Open the output file. 3501 */ 3502 if ((bio = BIO_new_file(filename, "wb")) == NULL) { 3503 SET_ERROR(kmfh, ERR_get_error()); 3504 rv = KMF_ERR_OPEN_FILE; 3505 goto cleanup; 3506 } 3507 3508 if (numcerts > 0 && numkeys > 0) { 3509 for (i = 0; rv == KMF_OK && i < numcerts; i++) { 3510 KMF_RAW_KEY_DATA *key = NULL; 3511 const uchar_t *p = certlist[i].certificate.Data; 3512 long len = certlist[i].certificate.Length; 3513 3514 if (i < numkeys) { 3515 key = (KMF_RAW_KEY_DATA *)keylist[i].keyp; 3516 3517 if (key->keytype == KMF_RSA) { 3518 pkey = ImportRawRSAKey( 3519 &key->rawdata.rsa); 3520 } else if (key->keytype == KMF_DSA) { 3521 pkey = ImportRawDSAKey( 3522 &key->rawdata.dsa); 3523 } else { 3524 rv = KMF_ERR_BAD_PARAMETER; 3525 } 3526 } 3527 3528 xcert = d2i_X509(NULL, &p, len); 3529 if (xcert == NULL) { 3530 SET_ERROR(kmfh, ERR_get_error()); 3531 rv = KMF_ERR_ENCODING; 3532 } 3533 /* Stick the key and the cert into a PKCS#12 file */ 3534 rv = write_pkcs12(kmfh, bio, cred, pkey, xcert); 3535 if (xcert) 3536 X509_free(xcert); 3537 if (pkey) 3538 EVP_PKEY_free(pkey); 3539 } 3540 } 3541 3542cleanup: 3543 3544 if (bio != NULL) 3545 (void) BIO_free_all(bio); 3546 3547 return (rv); 3548} 3549 3550KMF_RETURN 3551OpenSSL_ExportP12(KMF_HANDLE_T handle, 3552 KMF_EXPORTP12_PARAMS *params, 3553 int numcerts, KMF_X509_DER_CERT *certlist, 3554 int numkeys, KMF_KEY_HANDLE *keylist, 3555 char *filename) 3556{ 3557 KMF_RETURN rv; 3558 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3559 KMF_FINDCERT_PARAMS fcargs; 3560 BIO *bio = NULL; 3561 X509 *xcert = NULL; 3562 char *fullpath = NULL; 3563 EVP_PKEY *pkey = NULL; 3564 3565 /* 3566 * First, find the certificate. 3567 */ 3568 if (params == NULL) 3569 return (KMF_ERR_BAD_PARAMETER); 3570 3571 /* 3572 * If the caller already sent the raw keys and certs, 3573 * shortcut the search and just export that 3574 * data. 3575 * 3576 * One *may* export a key OR a cert by itself. 3577 */ 3578 if (certlist != NULL || keylist != NULL) { 3579 rv = ExportPK12FromRawData(handle, 3580 ¶ms->p12cred, 3581 numcerts, certlist, 3582 numkeys, keylist, 3583 filename); 3584 return (rv); 3585 } 3586 3587 if (params->sslparms.certfile != NULL) { 3588 fullpath = get_fullpath(params->sslparms.dirpath, 3589 params->sslparms.certfile); 3590 3591 if (fullpath == NULL) 3592 return (KMF_ERR_BAD_PARAMETER); 3593 3594 if (isdir(fullpath)) { 3595 free(fullpath); 3596 return (KMF_ERR_AMBIGUOUS_PATHNAME); 3597 } 3598 3599 (void *)memset(&fcargs, 0, sizeof (fcargs)); 3600 fcargs.kstype = params->kstype; 3601 fcargs.certLabel = params->certLabel; 3602 fcargs.issuer = params->issuer; 3603 fcargs.subject = params->subject; 3604 fcargs.serial = params->serial; 3605 fcargs.idstr = params->idstr; 3606 fcargs.sslparms.dirpath = NULL; 3607 fcargs.sslparms.certfile = fullpath; 3608 fcargs.sslparms.format = params->sslparms.format; 3609 3610 rv = load_X509cert(kmfh, &fcargs, fullpath, &xcert); 3611 if (rv != KMF_OK) 3612 goto end; 3613 } 3614 3615 /* 3616 * Now find the private key. 3617 */ 3618 if (params->sslparms.keyfile != NULL) { 3619 fullpath = get_fullpath(params->sslparms.dirpath, 3620 params->sslparms.keyfile); 3621 3622 if (fullpath == NULL) 3623 return (KMF_ERR_BAD_PARAMETER); 3624 3625 if (isdir(fullpath)) { 3626 free(fullpath); 3627 return (KMF_ERR_AMBIGUOUS_PATHNAME); 3628 } 3629 3630 pkey = openssl_load_key(handle, fullpath); 3631 if (pkey == NULL) { 3632 rv = KMF_ERR_KEY_NOT_FOUND; 3633 goto end; 3634 } 3635 } 3636 3637 /* 3638 * Open the output file. 3639 */ 3640 if ((bio = BIO_new_file(filename, "wb")) == NULL) { 3641 SET_ERROR(kmfh, ERR_get_error()); 3642 rv = KMF_ERR_OPEN_FILE; 3643 goto end; 3644 } 3645 3646 /* Stick the key and the cert into a PKCS#12 file */ 3647 rv = write_pkcs12(kmfh, bio, ¶ms->p12cred, 3648 pkey, xcert); 3649 3650end: 3651 if (fullpath) 3652 free(fullpath); 3653 if (xcert) 3654 X509_free(xcert); 3655 if (pkey) 3656 EVP_PKEY_free(pkey); 3657 if (bio) 3658 (void) BIO_free(bio); 3659 3660 return (rv); 3661} 3662 3663#define MAX_CHAIN_LENGTH 100 3664/* 3665 * Helper function to extract keys and certificates from 3666 * a single PEM file. Typically the file should contain a 3667 * private key and an associated public key wrapped in an x509 cert. 3668 * However, the file may be just a list of X509 certs with no keys. 3669 */ 3670static KMF_RETURN 3671extract_objects(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, 3672 char *filename, CK_UTF8CHAR *pin, 3673 CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs, 3674 int *numcerts) 3675/* ARGSUSED */ 3676{ 3677 KMF_RETURN rv = KMF_OK; 3678 FILE *fp; 3679 STACK_OF(X509_INFO) *x509_info_stack; 3680 int i, ncerts = 0, matchcerts = 0; 3681 EVP_PKEY *pkey = NULL; 3682 X509_INFO *info; 3683 X509 *x; 3684 X509_INFO *cert_infos[MAX_CHAIN_LENGTH]; 3685 KMF_DATA *certlist = NULL; 3686 3687 if (priv_key) 3688 *priv_key = NULL; 3689 if (certs) 3690 *certs = NULL; 3691 fp = fopen(filename, "r"); 3692 if (fp == NULL) { 3693 return (KMF_ERR_OPEN_FILE); 3694 } 3695 x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin); 3696 if (x509_info_stack == NULL) { 3697 (void) fclose(fp); 3698 return (KMF_ERR_ENCODING); 3699 } 3700 3701 /*LINTED*/ 3702 while ((info = sk_X509_INFO_pop(x509_info_stack)) != NULL && 3703 info->x509 != NULL && ncerts < MAX_CHAIN_LENGTH) { 3704 cert_infos[ncerts] = info; 3705 ncerts++; 3706 } 3707 3708 if (ncerts == 0) { 3709 (void) fclose(fp); 3710 return (KMF_ERR_CERT_NOT_FOUND); 3711 } 3712 3713 if (priv_key != NULL) { 3714 rewind(fp); 3715 pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin); 3716 } 3717 (void) fclose(fp); 3718 3719 x = cert_infos[ncerts - 1]->x509; 3720 /* 3721 * Make sure the private key matchs the last cert in the file. 3722 */ 3723 if (pkey != NULL && !X509_check_private_key(x, pkey)) { 3724 EVP_PKEY_free(pkey); 3725 return (KMF_ERR_KEY_MISMATCH); 3726 } 3727 3728 certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA)); 3729 if (certlist == NULL) { 3730 if (pkey != NULL) 3731 EVP_PKEY_free(pkey); 3732 X509_INFO_free(info); 3733 return (KMF_ERR_MEMORY); 3734 } 3735 3736 /* 3737 * Convert all of the certs to DER format. 3738 */ 3739 matchcerts = 0; 3740 for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) { 3741 boolean_t match = FALSE; 3742 info = cert_infos[ncerts - 1 - i]; 3743 3744 if (params != NULL) { 3745 rv = check_cert(info->x509, params, &match); 3746 if (rv != KMF_OK || match != TRUE) { 3747 X509_INFO_free(info); 3748 rv = KMF_OK; 3749 continue; 3750 } 3751 } 3752 3753 rv = ssl_cert2KMFDATA(kmfh, info->x509, 3754 &certlist[matchcerts++]); 3755 3756 if (rv != KMF_OK) { 3757 free(certlist); 3758 certlist = NULL; 3759 ncerts = matchcerts = 0; 3760 } 3761 3762 X509_INFO_free(info); 3763 } 3764 3765 if (numcerts != NULL) 3766 *numcerts = matchcerts; 3767 if (certs != NULL) 3768 *certs = certlist; 3769 3770 if (priv_key == NULL && pkey != NULL) 3771 EVP_PKEY_free(pkey); 3772 else if (priv_key != NULL && pkey != NULL) 3773 *priv_key = pkey; 3774 3775 return (rv); 3776} 3777 3778/* 3779 * Helper function to decrypt and parse PKCS#12 import file. 3780 */ 3781static KMF_RETURN 3782extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 3783 EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca) 3784/* ARGSUSED */ 3785{ 3786 PKCS12 *pk12, *pk12_tmp; 3787 EVP_PKEY *temp_pkey = NULL; 3788 X509 *temp_cert = NULL; 3789 STACK_OF(X509) *temp_ca = NULL; 3790 3791 if ((pk12 = PKCS12_new()) == NULL) { 3792 return (KMF_ERR_MEMORY); 3793 } 3794 3795 if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) { 3796 /* This is ok; it seems to mean there is no more to read. */ 3797 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 && 3798 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG) 3799 goto end_extract_pkcs12; 3800 3801 PKCS12_free(pk12); 3802 return (KMF_ERR_PKCS12_FORMAT); 3803 } 3804 pk12 = pk12_tmp; 3805 3806 if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert, 3807 &temp_ca) <= 0) { 3808 PKCS12_free(pk12); 3809 return (KMF_ERR_PKCS12_FORMAT); 3810 } 3811 3812end_extract_pkcs12: 3813 3814 *priv_key = temp_pkey; 3815 *cert = temp_cert; 3816 *ca = temp_ca; 3817 3818 PKCS12_free(pk12); 3819 return (KMF_OK); 3820} 3821 3822static KMF_RETURN 3823sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to) 3824{ 3825 KMF_RETURN rv = KMF_OK; 3826 uint32_t sz; 3827 3828 sz = BN_num_bytes(from); 3829 to->val = (uchar_t *)malloc(sz); 3830 if (to->val == NULL) 3831 return (KMF_ERR_MEMORY); 3832 3833 if ((to->len = BN_bn2bin(from, to->val)) != sz) { 3834 free(to->val); 3835 to->val = NULL; 3836 to->len = 0; 3837 rv = KMF_ERR_MEMORY; 3838 } 3839 3840 return (rv); 3841} 3842 3843static KMF_RETURN 3844exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) 3845{ 3846 KMF_RETURN rv; 3847 KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa; 3848 3849 (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY)); 3850 if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK) 3851 goto cleanup; 3852 3853 if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK) 3854 goto cleanup; 3855 3856 if (rsa->d != NULL) 3857 if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK) 3858 goto cleanup; 3859 3860 if (rsa->p != NULL) 3861 if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK) 3862 goto cleanup; 3863 3864 if (rsa->q != NULL) 3865 if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK) 3866 goto cleanup; 3867 3868 if (rsa->dmp1 != NULL) 3869 if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK) 3870 goto cleanup; 3871 3872 if (rsa->dmq1 != NULL) 3873 if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK) 3874 goto cleanup; 3875 3876 if (rsa->iqmp != NULL) 3877 if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK) 3878 goto cleanup; 3879cleanup: 3880 if (rv != KMF_OK) 3881 KMF_FreeRawKey(key); 3882 else 3883 key->keytype = KMF_RSA; 3884 3885 /* 3886 * Free the reference to this key, SSL will not actually free 3887 * the memory until the refcount == 0, so this is safe. 3888 */ 3889 RSA_free(rsa); 3890 3891 return (rv); 3892} 3893 3894static KMF_RETURN 3895exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) 3896{ 3897 KMF_RETURN rv; 3898 KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa; 3899 3900 (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY)); 3901 if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK) 3902 goto cleanup; 3903 3904 if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK) 3905 goto cleanup; 3906 3907 if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK) 3908 goto cleanup; 3909 3910 if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK) 3911 goto cleanup; 3912 3913cleanup: 3914 if (rv != KMF_OK) 3915 KMF_FreeRawKey(key); 3916 else 3917 key->keytype = KMF_DSA; 3918 3919 /* 3920 * Free the reference to this key, SSL will not actually free 3921 * the memory until the refcount == 0, so this is safe. 3922 */ 3923 DSA_free(dsa); 3924 3925 return (rv); 3926} 3927 3928static KMF_RETURN 3929add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert, 3930 KMF_DATA **certlist, int *ncerts) 3931{ 3932 KMF_RETURN rv = KMF_OK; 3933 KMF_DATA *list = (*certlist); 3934 KMF_DATA cert; 3935 int n = (*ncerts); 3936 3937 if (list == NULL) { 3938 list = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 3939 } else { 3940 list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1)); 3941 } 3942 3943 if (list == NULL) 3944 return (KMF_ERR_MEMORY); 3945 3946 rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert); 3947 if (rv == KMF_OK) { 3948 list[n] = cert; 3949 (*ncerts) = n + 1; 3950 3951 *certlist = list; 3952 } else { 3953 free(list); 3954 } 3955 3956 return (rv); 3957} 3958 3959static KMF_RETURN 3960add_key_to_list(KMF_RAW_KEY_DATA **keylist, 3961 KMF_RAW_KEY_DATA *newkey, int *nkeys) 3962{ 3963 KMF_RAW_KEY_DATA *list = (*keylist); 3964 int n = (*nkeys); 3965 3966 if (list == NULL) { 3967 list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA)); 3968 } else { 3969 list = (KMF_RAW_KEY_DATA *)realloc(list, 3970 sizeof (KMF_RAW_KEY_DATA) * (n + 1)); 3971 } 3972 3973 if (list == NULL) 3974 return (KMF_ERR_MEMORY); 3975 3976 list[n] = *newkey; 3977 (*nkeys) = n + 1; 3978 3979 *keylist = list; 3980 3981 return (KMF_OK); 3982} 3983 3984 3985static KMF_RETURN 3986convertPK12Objects( 3987 KMF_HANDLE *kmfh, 3988 EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts, 3989 KMF_RAW_KEY_DATA **keylist, int *nkeys, 3990 KMF_DATA **certlist, int *ncerts) 3991{ 3992 KMF_RETURN rv = KMF_OK; 3993 KMF_RAW_KEY_DATA key; 3994 int i; 3995 3996 if (sslkey != NULL) { 3997 /* Convert SSL key to raw key */ 3998 switch (sslkey->type) { 3999 case EVP_PKEY_RSA: 4000 rv = exportRawRSAKey(EVP_PKEY_get1_RSA(sslkey), 4001 &key); 4002 if (rv != KMF_OK) 4003 return (rv); 4004 4005 break; 4006 case EVP_PKEY_DSA: 4007 rv = exportRawDSAKey(EVP_PKEY_get1_DSA(sslkey), 4008 &key); 4009 if (rv != KMF_OK) 4010 return (rv); 4011 4012 break; 4013 default: 4014 return (KMF_ERR_BAD_PARAMETER); 4015 } 4016 4017 rv = add_key_to_list(keylist, &key, nkeys); 4018 if (rv != KMF_OK) 4019 return (rv); 4020 } 4021 4022 /* Now add the certificate to the certlist */ 4023 if (sslcert != NULL) { 4024 rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts); 4025 if (rv != KMF_OK) 4026 return (rv); 4027 } 4028 4029 /* Also add any included CA certs to the list */ 4030 for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) { 4031 X509 *c; 4032 /* 4033 * sk_X509_value() is macro that embeds a cast to (X509 *). 4034 * Here it translates into ((X509 *)sk_value((ca), (i))). 4035 * Lint is complaining about the embedded casting, and 4036 * to fix it, you need to fix openssl header files. 4037 */ 4038 /* LINTED E_BAD_PTR_CAST_ALIGN */ 4039 c = sk_X509_value(sslcacerts, i); 4040 4041 /* Now add the ca cert to the certlist */ 4042 rv = add_cert_to_list(kmfh, c, certlist, ncerts); 4043 if (rv != KMF_OK) 4044 return (rv); 4045 } 4046 return (rv); 4047} 4048 4049KMF_RETURN 4050openssl_read_pkcs12(KMF_HANDLE *kmfh, 4051 char *filename, KMF_CREDENTIAL *cred, 4052 KMF_DATA **certlist, int *ncerts, 4053 KMF_RAW_KEY_DATA **keylist, int *nkeys) 4054{ 4055 KMF_RETURN rv = KMF_OK; 4056 BIO *bio = NULL; 4057 EVP_PKEY *privkey = NULL; 4058 X509 *cert = NULL; 4059 STACK_OF(X509) *cacerts = NULL; 4060 4061 bio = BIO_new_file(filename, "rb"); 4062 if (bio == NULL) { 4063 SET_ERROR(kmfh, ERR_get_error()); 4064 rv = KMF_ERR_OPEN_FILE; 4065 goto end; 4066 } 4067 4068 *certlist = NULL; 4069 *keylist = NULL; 4070 *ncerts = 0; 4071 *nkeys = 0; 4072 while (rv == KMF_OK) { 4073 rv = extract_pkcs12(bio, 4074 (uchar_t *)cred->cred, 4075 (uint32_t)cred->credlen, 4076 &privkey, &cert, &cacerts); 4077 4078 /* Reached end of import file? */ 4079 if (rv == KMF_OK && privkey == NULL && 4080 cert == NULL && cacerts == NULL) 4081 break; 4082 4083 if (rv == KMF_OK) 4084 /* Convert keys and certs to exportable format */ 4085 rv = convertPK12Objects(kmfh, privkey, cert, cacerts, 4086 keylist, nkeys, certlist, ncerts); 4087 4088 if (privkey) 4089 EVP_PKEY_free(privkey); 4090 4091 if (cert) 4092 X509_free(cert); 4093 4094 if (cacerts) 4095 sk_X509_free(cacerts); 4096 } 4097end: 4098 if (bio != NULL) 4099 (void) BIO_free(bio); 4100 4101 if (privkey) 4102 EVP_PKEY_free(privkey); 4103 4104 if (cert) 4105 X509_free(cert); 4106 4107 if (cacerts) 4108 sk_X509_free(cacerts); 4109 4110 return (rv); 4111} 4112 4113KMF_RETURN 4114openssl_import_keypair(KMF_HANDLE *kmfh, 4115 char *filename, KMF_CREDENTIAL *cred, 4116 KMF_DATA **certlist, int *ncerts, 4117 KMF_RAW_KEY_DATA **keylist, int *nkeys) 4118{ 4119 KMF_RETURN rv = KMF_OK; 4120 EVP_PKEY *privkey = NULL; 4121 KMF_ENCODE_FORMAT format; 4122 4123 /* 4124 * auto-detect the file format, regardless of what 4125 * the 'format' parameters in the params say. 4126 */ 4127 rv = KMF_GetFileFormat(filename, &format); 4128 if (rv != KMF_OK) { 4129 if (rv == KMF_ERR_OPEN_FILE) 4130 rv = KMF_ERR_CERT_NOT_FOUND; 4131 return (rv); 4132 } 4133 4134 /* This function only works on PEM files */ 4135 if (format != KMF_FORMAT_PEM && 4136 format != KMF_FORMAT_PEM_KEYPAIR) 4137 return (KMF_ERR_ENCODING); 4138 4139 *certlist = NULL; 4140 *keylist = NULL; 4141 *ncerts = 0; 4142 *nkeys = 0; 4143 rv = extract_objects(kmfh, NULL, filename, 4144 (uchar_t *)cred->cred, 4145 (uint32_t)cred->credlen, 4146 &privkey, certlist, ncerts); 4147 4148 /* Reached end of import file? */ 4149 if (rv == KMF_OK) 4150 /* Convert keys and certs to exportable format */ 4151 rv = convertPK12Objects(kmfh, privkey, NULL, NULL, 4152 keylist, nkeys, NULL, NULL); 4153 4154end: 4155 if (privkey) 4156 EVP_PKEY_free(privkey); 4157 4158 return (rv); 4159} 4160 4161KMF_RETURN 4162OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, 4163 KMF_RAW_KEY_DATA *key) 4164{ 4165 KMF_RETURN rv = KMF_OK; 4166 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4167 char *fullpath; 4168 EVP_PKEY *pkey = NULL; 4169 BIO *bio = NULL; 4170 4171 if (key != NULL) { 4172 if (key->keytype == KMF_RSA) { 4173 pkey = ImportRawRSAKey(&key->rawdata.rsa); 4174 } else if (key->keytype == KMF_DSA) { 4175 pkey = ImportRawDSAKey(&key->rawdata.dsa); 4176 } else { 4177 rv = KMF_ERR_BAD_PARAMETER; 4178 } 4179 } else { 4180 rv = KMF_ERR_BAD_PARAMETER; 4181 } 4182 if (rv != KMF_OK || pkey == NULL) 4183 return (rv); 4184 4185 fullpath = get_fullpath(params->sslparms.dirpath, 4186 params->sslparms.keyfile); 4187 4188 if (fullpath == NULL) 4189 return (KMF_ERR_BAD_PARAMETER); 4190 4191 /* If the requested file exists, return an error */ 4192 if (access(fullpath, F_OK) == 0) { 4193 free(fullpath); 4194 return (KMF_ERR_DUPLICATE_KEYFILE); 4195 } 4196 4197 bio = BIO_new_file(fullpath, "wb"); 4198 if (bio == NULL) { 4199 SET_ERROR(kmfh, ERR_get_error()); 4200 rv = KMF_ERR_OPEN_FILE; 4201 goto cleanup; 4202 } 4203 4204 rv = ssl_write_private_key(kmfh, 4205 params->sslparms.format, 4206 bio, ¶ms->cred, pkey); 4207 4208cleanup: 4209 if (fullpath) 4210 free(fullpath); 4211 4212 if (pkey) 4213 EVP_PKEY_free(pkey); 4214 4215 if (bio) 4216 (void) BIO_free(bio); 4217 4218 /* Protect the file by making it read-only */ 4219 if (rv == KMF_OK) { 4220 (void) chmod(fullpath, 0400); 4221 } 4222 return (rv); 4223} 4224 4225static KMF_RETURN 4226create_deskey(DES_cblock **deskey) 4227{ 4228 DES_cblock *key; 4229 4230 key = (DES_cblock *) malloc(sizeof (DES_cblock)); 4231 if (key == NULL) { 4232 return (KMF_ERR_MEMORY); 4233 } 4234 4235 if (DES_random_key(key) == 0) { 4236 free(key); 4237 return (KMF_ERR_KEYGEN_FAILED); 4238 } 4239 4240 *deskey = key; 4241 return (KMF_OK); 4242} 4243 4244#define KEYGEN_RETRY 3 4245#define DES3_KEY_SIZE 24 4246 4247static KMF_RETURN 4248create_des3key(unsigned char **des3key) 4249{ 4250 KMF_RETURN ret = KMF_OK; 4251 DES_cblock *deskey1 = NULL; 4252 DES_cblock *deskey2 = NULL; 4253 DES_cblock *deskey3 = NULL; 4254 unsigned char *newkey = NULL; 4255 int retry; 4256 4257 if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) { 4258 return (KMF_ERR_MEMORY); 4259 } 4260 4261 /* create the 1st DES key */ 4262 if ((ret = create_deskey(&deskey1)) != KMF_OK) { 4263 goto out; 4264 } 4265 4266 /* 4267 * Create the 2nd DES key and make sure its value is different 4268 * from the 1st DES key. 4269 */ 4270 retry = 0; 4271 do { 4272 if (deskey2 != NULL) { 4273 free(deskey2); 4274 deskey2 = NULL; 4275 } 4276 4277 if ((ret = create_deskey(&deskey2)) != KMF_OK) { 4278 goto out; 4279 } 4280 4281 if (memcmp((const void *) deskey1, (const void *) deskey2, 8) 4282 == 0) { 4283 ret = KMF_ERR_KEYGEN_FAILED; 4284 retry++; 4285 } 4286 } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 4287 4288 if (ret != KMF_OK) { 4289 goto out; 4290 } 4291 4292 /* 4293 * Create the 3rd DES key and make sure its value is different 4294 * from the 2nd DES key. 4295 */ 4296 retry = 0; 4297 do { 4298 if (deskey3 != NULL) { 4299 free(deskey3); 4300 deskey3 = NULL; 4301 } 4302 4303 if ((ret = create_deskey(&deskey3)) != KMF_OK) { 4304 goto out; 4305 } 4306 4307 if (memcmp((const void *)deskey2, (const void *)deskey3, 8) 4308 == 0) { 4309 ret = KMF_ERR_KEYGEN_FAILED; 4310 retry++; 4311 } 4312 } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 4313 4314 if (ret != KMF_OK) { 4315 goto out; 4316 } 4317 4318 /* Concatenate 3 DES keys into a DES3 key */ 4319 (void) memcpy((void *)newkey, (const void *)deskey1, 8); 4320 (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8); 4321 (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8); 4322 *des3key = newkey; 4323 4324out: 4325 if (deskey1 != NULL) 4326 free(deskey1); 4327 4328 if (deskey2 != NULL) 4329 free(deskey2); 4330 4331 if (deskey3 != NULL) 4332 free(deskey3); 4333 4334 if (ret != KMF_OK && newkey != NULL) 4335 free(newkey); 4336 4337 return (ret); 4338} 4339 4340KMF_RETURN 4341OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, 4342 KMF_KEY_HANDLE *symkey) 4343{ 4344 KMF_RETURN ret = KMF_OK; 4345 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4346 char *fullpath = NULL; 4347 KMF_RAW_SYM_KEY *rkey = NULL; 4348 DES_cblock *deskey = NULL; 4349 unsigned char *des3key = NULL; 4350 unsigned char *random = NULL; 4351 int fd = -1; 4352 4353 if (kmfh == NULL) 4354 return (KMF_ERR_UNINITIALIZED); 4355 4356 if (params == NULL || params->sslparms.keyfile == NULL) { 4357 return (KMF_ERR_BAD_PARAMETER); 4358 } 4359 4360 fullpath = get_fullpath(params->sslparms.dirpath, 4361 params->sslparms.keyfile); 4362 if (fullpath == NULL) 4363 return (KMF_ERR_BAD_PARAMETER); 4364 4365 /* If the requested file exists, return an error */ 4366 if (access(fullpath, F_OK) == 0) { 4367 free(fullpath); 4368 return (KMF_ERR_DUPLICATE_KEYFILE); 4369 } 4370 4371 fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400); 4372 if (fd == -1) { 4373 ret = KMF_ERR_OPEN_FILE; 4374 goto out; 4375 } 4376 4377 rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 4378 if (rkey == NULL) { 4379 ret = KMF_ERR_MEMORY; 4380 goto out; 4381 } 4382 (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 4383 4384 if (params->keytype == KMF_DES) { 4385 if ((ret = create_deskey(&deskey)) != KMF_OK) { 4386 goto out; 4387 } 4388 rkey->keydata.val = (uchar_t *)deskey; 4389 rkey->keydata.len = 8; 4390 4391 symkey->keyalg = KMF_DES; 4392 4393 } else if (params->keytype == KMF_DES3) { 4394 if ((ret = create_des3key(&des3key)) != KMF_OK) { 4395 goto out; 4396 } 4397 rkey->keydata.val = (uchar_t *)des3key; 4398 rkey->keydata.len = DES3_KEY_SIZE; 4399 symkey->keyalg = KMF_DES3; 4400 4401 } else if (params->keytype == KMF_AES || params->keytype == KMF_RC4 || 4402 params->keytype == KMF_GENERIC_SECRET) { 4403 int bytes; 4404 4405 if (params->keylength % 8 != 0) { 4406 ret = KMF_ERR_BAD_KEY_SIZE; 4407 goto out; 4408 } 4409 4410 if (params->keytype == KMF_AES) { 4411 if (params->keylength != 128 && 4412 params->keylength != 192 && 4413 params->keylength != 256) { 4414 ret = KMF_ERR_BAD_KEY_SIZE; 4415 goto out; 4416 } 4417 } 4418 4419 bytes = params->keylength/8; 4420 random = malloc(bytes); 4421 if (random == NULL) { 4422 ret = KMF_ERR_MEMORY; 4423 goto out; 4424 } 4425 if (RAND_bytes(random, bytes) != 1) { 4426 ret = KMF_ERR_KEYGEN_FAILED; 4427 goto out; 4428 } 4429 4430 rkey->keydata.val = (uchar_t *)random; 4431 rkey->keydata.len = bytes; 4432 symkey->keyalg = params->keytype; 4433 4434 } else { 4435 ret = KMF_ERR_BAD_KEY_TYPE; 4436 goto out; 4437 } 4438 4439 (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len); 4440 4441 symkey->kstype = KMF_KEYSTORE_OPENSSL; 4442 symkey->keyclass = KMF_SYMMETRIC; 4443 symkey->keylabel = (char *)fullpath; 4444 symkey->israw = TRUE; 4445 symkey->keyp = rkey; 4446 4447out: 4448 if (fd != -1) 4449 (void) close(fd); 4450 4451 if (ret != KMF_OK && fullpath != NULL) { 4452 free(fullpath); 4453 } 4454 if (ret != KMF_OK) { 4455 KMF_FreeRawSymKey(rkey); 4456 symkey->keyp = NULL; 4457 symkey->keyalg = KMF_KEYALG_NONE; 4458 } 4459 4460 return (ret); 4461} 4462 4463 4464KMF_RETURN 4465OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params) 4466{ 4467 KMF_RETURN ret = KMF_OK; 4468 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4469 BIO *bcrl = NULL; 4470 X509_CRL *xcrl = NULL; 4471 X509 *xcert = NULL; 4472 EVP_PKEY *pkey; 4473 int sslret; 4474 KMF_ENCODE_FORMAT crl_format; 4475 unsigned char *p; 4476 long len; 4477 4478 if (params->crl_name == NULL || params->tacert == NULL) { 4479 return (KMF_ERR_BAD_PARAMETER); 4480 } 4481 4482 ret = KMF_GetFileFormat(params->crl_name, &crl_format); 4483 if (ret != KMF_OK) 4484 return (ret); 4485 4486 bcrl = BIO_new_file(params->crl_name, "rb"); 4487 if (bcrl == NULL) { 4488 SET_ERROR(kmfh, ERR_get_error()); 4489 ret = KMF_ERR_OPEN_FILE; 4490 goto cleanup; 4491 } 4492 4493 if (crl_format == KMF_FORMAT_ASN1) { 4494 xcrl = d2i_X509_CRL_bio(bcrl, NULL); 4495 } else if (crl_format == KMF_FORMAT_PEM) { 4496 xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 4497 } else { 4498 ret = KMF_ERR_BAD_PARAMETER; 4499 goto cleanup; 4500 } 4501 4502 if (xcrl == NULL) { 4503 SET_ERROR(kmfh, ERR_get_error()); 4504 ret = KMF_ERR_BAD_CRLFILE; 4505 goto cleanup; 4506 } 4507 4508 p = params->tacert->Data; 4509 len = params->tacert->Length; 4510 xcert = d2i_X509(NULL, (const uchar_t **)&p, len); 4511 4512 if (xcert == NULL) { 4513 SET_ERROR(kmfh, ERR_get_error()); 4514 ret = KMF_ERR_BAD_CERTFILE; 4515 goto cleanup; 4516 } 4517 4518 /* Get issuer certificate public key */ 4519 pkey = X509_get_pubkey(xcert); 4520 if (!pkey) { 4521 SET_ERROR(kmfh, ERR_get_error()); 4522 ret = KMF_ERR_BAD_CERT_FORMAT; 4523 goto cleanup; 4524 } 4525 4526 /* Verify CRL signature */ 4527 sslret = X509_CRL_verify(xcrl, pkey); 4528 EVP_PKEY_free(pkey); 4529 if (sslret > 0) { 4530 ret = KMF_OK; 4531 } else { 4532 SET_ERROR(kmfh, sslret); 4533 ret = KMF_ERR_BAD_CRLFILE; 4534 } 4535 4536cleanup: 4537 if (bcrl != NULL) 4538 (void) BIO_free(bcrl); 4539 4540 if (xcrl != NULL) 4541 X509_CRL_free(xcrl); 4542 4543 if (xcert != NULL) 4544 X509_free(xcert); 4545 4546 return (ret); 4547 4548} 4549 4550KMF_RETURN 4551OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, 4552 KMF_CHECKCRLDATE_PARAMS *params) 4553{ 4554 4555 KMF_RETURN ret = KMF_OK; 4556 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4557 KMF_ENCODE_FORMAT crl_format; 4558 BIO *bcrl = NULL; 4559 X509_CRL *xcrl = NULL; 4560 int i; 4561 4562 if (params == NULL || params->crl_name == NULL) { 4563 return (KMF_ERR_BAD_PARAMETER); 4564 } 4565 4566 ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format); 4567 if (ret != KMF_OK) 4568 return (ret); 4569 4570 bcrl = BIO_new_file(params->crl_name, "rb"); 4571 if (bcrl == NULL) { 4572 SET_ERROR(kmfh, ERR_get_error()); 4573 ret = KMF_ERR_OPEN_FILE; 4574 goto cleanup; 4575 } 4576 4577 if (crl_format == KMF_FORMAT_ASN1) { 4578 xcrl = d2i_X509_CRL_bio(bcrl, NULL); 4579 } else if (crl_format == KMF_FORMAT_PEM) { 4580 xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 4581 } 4582 4583 if (xcrl == NULL) { 4584 SET_ERROR(kmfh, ERR_get_error()); 4585 ret = KMF_ERR_BAD_CRLFILE; 4586 goto cleanup; 4587 } 4588 4589 i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); 4590 if (i >= 0) { 4591 ret = KMF_ERR_VALIDITY_PERIOD; 4592 goto cleanup; 4593 } 4594 4595 if (X509_CRL_get_nextUpdate(xcrl)) { 4596 i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); 4597 4598 if (i <= 0) { 4599 ret = KMF_ERR_VALIDITY_PERIOD; 4600 goto cleanup; 4601 } 4602 } 4603 4604 ret = KMF_OK; 4605 4606cleanup: 4607 if (bcrl != NULL) 4608 (void) BIO_free(bcrl); 4609 4610 if (xcrl != NULL) 4611 X509_CRL_free(xcrl); 4612 4613 return (ret); 4614} 4615 4616/* 4617 * Check a file to see if it is a CRL file with PEM or DER format. 4618 * If success, return its format in the "pformat" argument. 4619 */ 4620KMF_RETURN 4621OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat) 4622{ 4623 KMF_RETURN ret = KMF_OK; 4624 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4625 BIO *bio = NULL; 4626 X509_CRL *xcrl = NULL; 4627 4628 if (filename == NULL) { 4629 return (KMF_ERR_BAD_PARAMETER); 4630 } 4631 4632 bio = BIO_new_file(filename, "rb"); 4633 if (bio == NULL) { 4634 SET_ERROR(kmfh, ERR_get_error()); 4635 ret = KMF_ERR_OPEN_FILE; 4636 goto out; 4637 } 4638 4639 if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) { 4640 *pformat = KMF_FORMAT_PEM; 4641 goto out; 4642 } 4643 (void) BIO_free(bio); 4644 4645 /* 4646 * Now try to read it as raw DER data. 4647 */ 4648 bio = BIO_new_file(filename, "rb"); 4649 if (bio == NULL) { 4650 SET_ERROR(kmfh, ERR_get_error()); 4651 ret = KMF_ERR_OPEN_FILE; 4652 goto out; 4653 } 4654 4655 if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) { 4656 *pformat = KMF_FORMAT_ASN1; 4657 } else { 4658 ret = KMF_ERR_BAD_CRLFILE; 4659 } 4660 4661out: 4662 if (bio != NULL) 4663 (void) BIO_free(bio); 4664 4665 if (xcrl != NULL) 4666 X509_CRL_free(xcrl); 4667 4668 return (ret); 4669} 4670 4671/* 4672 * Check a file to see if it is a certficate file with PEM or DER format. 4673 * If success, return its format in the pformat argument. 4674 */ 4675KMF_RETURN 4676OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, 4677 KMF_ENCODE_FORMAT *pformat) 4678{ 4679 KMF_RETURN ret = KMF_OK; 4680 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4681 BIO *bio = NULL; 4682 X509 *xcert = NULL; 4683 4684 if (filename == NULL) { 4685 return (KMF_ERR_BAD_PARAMETER); 4686 } 4687 4688 ret = KMF_GetFileFormat(filename, pformat); 4689 if (ret != KMF_OK) 4690 return (ret); 4691 4692 bio = BIO_new_file(filename, "rb"); 4693 if (bio == NULL) { 4694 SET_ERROR(kmfh, ERR_get_error()); 4695 ret = KMF_ERR_OPEN_FILE; 4696 goto out; 4697 } 4698 4699 if ((*pformat) == KMF_FORMAT_PEM) { 4700 if ((xcert = PEM_read_bio_X509(bio, NULL, 4701 NULL, NULL)) == NULL) { 4702 ret = KMF_ERR_BAD_CERTFILE; 4703 } 4704 } else if ((*pformat) == KMF_FORMAT_ASN1) { 4705 if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) { 4706 ret = KMF_ERR_BAD_CERTFILE; 4707 } 4708 } else { 4709 ret = KMF_ERR_BAD_CERTFILE; 4710 } 4711 4712out: 4713 if (bio != NULL) 4714 (void) BIO_free(bio); 4715 4716 if (xcert != NULL) 4717 X509_free(xcert); 4718 4719 return (ret); 4720} 4721 4722KMF_RETURN 4723OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 4724 KMF_RAW_SYM_KEY *rkey) 4725{ 4726 KMF_RETURN rv = KMF_OK; 4727 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4728 KMF_DATA keyvalue; 4729 4730 if (kmfh == NULL) 4731 return (KMF_ERR_UNINITIALIZED); 4732 4733 if (symkey == NULL || rkey == NULL) 4734 return (KMF_ERR_BAD_PARAMETER); 4735 else if (symkey->keyclass != KMF_SYMMETRIC) 4736 return (KMF_ERR_BAD_KEY_CLASS); 4737 4738 if (symkey->israw) { 4739 KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp; 4740 4741 if (rawkey == NULL || 4742 rawkey->keydata.val == NULL || 4743 rawkey->keydata.len == 0) 4744 return (KMF_ERR_BAD_KEYHANDLE); 4745 4746 rkey->keydata.len = rawkey->keydata.len; 4747 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 4748 return (KMF_ERR_MEMORY); 4749 (void) memcpy(rkey->keydata.val, rawkey->keydata.val, 4750 rkey->keydata.len); 4751 } else { 4752 rv = KMF_ReadInputFile(handle, symkey->keylabel, &keyvalue); 4753 if (rv != KMF_OK) 4754 return (rv); 4755 rkey->keydata.len = keyvalue.Length; 4756 rkey->keydata.val = keyvalue.Data; 4757 } 4758 4759 return (rv); 4760} 4761 4762/* 4763 * id-sha1 OBJECT IDENTIFIER ::= { 4764 * iso(1) identified-organization(3) oiw(14) secsig(3) 4765 * algorithms(2) 26 4766 * } 4767 */ 4768#define ASN1_SHA1_OID_PREFIX_LEN 15 4769static uchar_t SHA1_DER_PREFIX[ASN1_SHA1_OID_PREFIX_LEN] = { 4770 0x30, 0x21, 0x30, 0x09, 4771 0x06, 0x05, 0x2b, 0x0e, 4772 0x03, 0x02, 0x1a, 0x05, 4773 0x00, 0x04, 0x14 4774}; 4775 4776/* 4777 * id-md2 OBJECT IDENTIFIER ::= { 4778 * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 4779 * } 4780 */ 4781#define ASN1_MD2_OID_PREFIX_LEN 18 4782static uchar_t MD2_DER_PREFIX[ASN1_MD2_OID_PREFIX_LEN] = { 4783 0x30, 0x20, 0x30, 0x0c, 4784 0x06, 0x08, 0x2a, 0x86, 4785 0x48, 0x86, 0xf7, 0x0d, 4786 0x02, 0x02, 0x05, 0x00, 4787 0x04, 0x10 4788}; 4789 4790/* 4791 * id-md5 OBJECT IDENTIFIER ::= { 4792 * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 4793 * } 4794 */ 4795#define ASN1_MD5_OID_PREFIX_LEN 18 4796static uchar_t MD5_DER_PREFIX[ASN1_MD5_OID_PREFIX_LEN] = { 4797 0x30, 0x20, 0x30, 0x0c, 4798 0x06, 0x08, 0x2a, 0x86, 4799 0x48, 0x86, 0xf7, 0x0d, 4800 0x02, 0x05, 0x05, 0x00, 4801 0x04, 0x10 4802}; 4803 4804KMF_RETURN 4805OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle, 4806 KMF_ALGORITHM_INDEX algid, KMF_DATA *indata, 4807 KMF_DATA *insig, KMF_DATA *cert) 4808{ 4809 KMF_RETURN ret = KMF_OK; 4810 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4811 X509 *xcert = NULL; 4812 EVP_PKEY *pkey = NULL; 4813 uchar_t *p; 4814 uchar_t *rsaout = NULL; 4815 uchar_t *pfx = NULL; 4816 const EVP_MD *md; 4817 int pfxlen = 0, len; 4818 4819 if (handle == NULL || indata == NULL || 4820 indata->Data == NULL || indata->Length == 0 || 4821 insig == NULL|| insig->Data == NULL || insig->Length == 0 || 4822 cert == NULL || cert->Data == NULL || cert->Length == 0) 4823 return (KMF_ERR_BAD_PARAMETER); 4824 4825 p = cert->Data; 4826 xcert = d2i_X509(NULL, (const uchar_t **)&p, cert->Length); 4827 if (xcert == NULL) { 4828 SET_ERROR(kmfh, ERR_get_error()); 4829 ret = KMF_ERR_BAD_CERT_FORMAT; 4830 goto cleanup; 4831 } 4832 4833 pkey = X509_get_pubkey(xcert); 4834 if (!pkey) { 4835 SET_ERROR(kmfh, ERR_get_error()); 4836 ret = KMF_ERR_BAD_CERT_FORMAT; 4837 goto cleanup; 4838 } 4839 4840 if (algid != KMF_ALGID_NONE) { 4841 switch (algid) { 4842 case KMF_ALGID_MD5WithRSA: 4843 md = EVP_md5(); 4844 break; 4845 case KMF_ALGID_MD2WithRSA: 4846 md = EVP_md2(); 4847 break; 4848 case KMF_ALGID_SHA1WithRSA: 4849 md = EVP_sha1(); 4850 break; 4851 case KMF_ALGID_RSA: 4852 md = NULL; 4853 break; 4854 default: 4855 ret = KMF_ERR_BAD_PARAMETER; 4856 goto cleanup; 4857 } 4858 } else { 4859 /* Get the hash type from the cert signature */ 4860 md = EVP_get_digestbyobj(xcert->sig_alg->algorithm); 4861 if (md == NULL) { 4862 SET_ERROR(kmfh, ERR_get_error()); 4863 ret = KMF_ERR_BAD_PARAMETER; 4864 goto cleanup; 4865 } 4866 } 4867 if (md != NULL) { 4868 switch (EVP_MD_type(md)) { 4869 case NID_md2: 4870 case NID_md2WithRSAEncryption: 4871 pfxlen = ASN1_MD2_OID_PREFIX_LEN; 4872 pfx = MD2_DER_PREFIX; 4873 break; 4874 case NID_md5: 4875 case NID_md5WithRSAEncryption: 4876 pfxlen = ASN1_MD5_OID_PREFIX_LEN; 4877 pfx = MD5_DER_PREFIX; 4878 break; 4879 case NID_sha1: 4880 case NID_sha1WithRSAEncryption: 4881 pfxlen = ASN1_SHA1_OID_PREFIX_LEN; 4882 pfx = SHA1_DER_PREFIX; 4883 break; 4884 default: /* Unsupported */ 4885 pfxlen = 0; 4886 pfx = NULL; 4887 break; 4888 } 4889 } 4890 4891 /* RSA with no hash is a special case */ 4892 rsaout = malloc(RSA_size(pkey->pkey.rsa)); 4893 if (rsaout == NULL) 4894 return (KMF_ERR_MEMORY); 4895 4896 /* Decrypt the input signature */ 4897 len = RSA_public_decrypt(insig->Length, 4898 insig->Data, rsaout, pkey->pkey.rsa, RSA_PKCS1_PADDING); 4899 if (len < 1) { 4900 SET_ERROR(kmfh, ERR_get_error()); 4901 ret = KMF_ERR_BAD_PARAMETER; 4902 } else { 4903 size_t hashlen = 0; 4904 uint32_t dlen; 4905 char *digest = NULL; 4906 4907 /* 4908 * If the AlgId requires it, hash the input data before 4909 * comparing it to the decrypted signature. 4910 */ 4911 if (md) { 4912 EVP_MD_CTX ctx; 4913 4914 hashlen = md->md_size; 4915 4916 digest = malloc(hashlen + pfxlen); 4917 if (digest == NULL) 4918 return (KMF_ERR_MEMORY); 4919 /* Add the prefix to the comparison buffer. */ 4920 if (pfx && pfxlen > 0) { 4921 (void) memcpy(digest, pfx, pfxlen); 4922 } 4923 (void) EVP_DigestInit(&ctx, md); 4924 (void) EVP_DigestUpdate(&ctx, indata->Data, 4925 indata->Length); 4926 4927 /* Add the digest AFTER the ASN1 prefix */ 4928 (void) EVP_DigestFinal(&ctx, 4929 (uchar_t *)digest + pfxlen, &dlen); 4930 4931 dlen += pfxlen; 4932 } else { 4933 digest = (char *)indata->Data; 4934 dlen = indata->Length; 4935 } 4936 4937 /* 4938 * The result of the RSA decryption should be ASN1(OID | Hash). 4939 * Compare the output hash to the input data for the final 4940 * result. 4941 */ 4942 if (memcmp(rsaout, digest, dlen)) 4943 ret = KMF_ERR_INTERNAL; 4944 else 4945 ret = KMF_OK; 4946 4947 /* If we had to allocate space for the digest, free it now */ 4948 if (hashlen) 4949 free(digest); 4950 } 4951cleanup: 4952 if (pkey) 4953 EVP_PKEY_free(pkey); 4954 4955 if (xcert) 4956 X509_free(xcert); 4957 4958 if (rsaout) 4959 free(rsaout); 4960 4961 return (ret); 4962} 4963