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