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