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