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