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