199ebb4caSwyllys /* 271593db2Swyllys * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 399ebb4caSwyllys * Use is subject to license terms. 499ebb4caSwyllys */ 5*9a767088Shaimay /* 6*9a767088Shaimay * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 7*9a767088Shaimay * project 2000. 8*9a767088Shaimay */ 9*9a767088Shaimay /* 10*9a767088Shaimay * ==================================================================== 11*9a767088Shaimay * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. 12*9a767088Shaimay * 13*9a767088Shaimay * Redistribution and use in source and binary forms, with or without 14*9a767088Shaimay * modification, are permitted provided that the following conditions 15*9a767088Shaimay * are met: 16*9a767088Shaimay * 17*9a767088Shaimay * 1. Redistributions of source code must retain the above copyright 18*9a767088Shaimay * notice, this list of conditions and the following disclaimer. 19*9a767088Shaimay * 20*9a767088Shaimay * 2. Redistributions in binary form must reproduce the above copyright 21*9a767088Shaimay * notice, this list of conditions and the following disclaimer in 22*9a767088Shaimay * the documentation and/or other materials provided with the 23*9a767088Shaimay * distribution. 24*9a767088Shaimay * 25*9a767088Shaimay * 3. All advertising materials mentioning features or use of this 26*9a767088Shaimay * software must display the following acknowledgment: 27*9a767088Shaimay * "This product includes software developed by the OpenSSL Project 28*9a767088Shaimay * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 29*9a767088Shaimay * 30*9a767088Shaimay * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 31*9a767088Shaimay * endorse or promote products derived from this software without 32*9a767088Shaimay * prior written permission. For written permission, please contact 33*9a767088Shaimay * licensing@OpenSSL.org. 34*9a767088Shaimay * 35*9a767088Shaimay * 5. Products derived from this software may not be called "OpenSSL" 36*9a767088Shaimay * nor may "OpenSSL" appear in their names without prior written 37*9a767088Shaimay * permission of the OpenSSL Project. 38*9a767088Shaimay * 39*9a767088Shaimay * 6. Redistributions of any form whatsoever must retain the following 40*9a767088Shaimay * acknowledgment: 41*9a767088Shaimay * "This product includes software developed by the OpenSSL Project 42*9a767088Shaimay * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 43*9a767088Shaimay * 44*9a767088Shaimay * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 45*9a767088Shaimay * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46*9a767088Shaimay * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 47*9a767088Shaimay * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 48*9a767088Shaimay * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49*9a767088Shaimay * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50*9a767088Shaimay * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 51*9a767088Shaimay * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52*9a767088Shaimay * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53*9a767088Shaimay * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54*9a767088Shaimay * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55*9a767088Shaimay * OF THE POSSIBILITY OF SUCH DAMAGE. 56*9a767088Shaimay * ==================================================================== 57*9a767088Shaimay * 58*9a767088Shaimay * This product includes cryptographic software written by Eric Young 59*9a767088Shaimay * (eay@cryptsoft.com). This product includes software written by Tim 60*9a767088Shaimay * Hudson (tjh@cryptsoft.com). 61*9a767088Shaimay * 62*9a767088Shaimay */ 6399ebb4caSwyllys 6499ebb4caSwyllys #pragma ident "%Z%%M% %I% %E% SMI" 6599ebb4caSwyllys 6671593db2Swyllys #include <stdlib.h> 6799ebb4caSwyllys #include <kmfapiP.h> 6899ebb4caSwyllys #include <ber_der.h> 6999ebb4caSwyllys #include <oidsalg.h> 7099ebb4caSwyllys #include <fcntl.h> 7199ebb4caSwyllys #include <sys/stat.h> 7299ebb4caSwyllys #include <dirent.h> 7399ebb4caSwyllys #include <cryptoutil.h> 7499ebb4caSwyllys #include <synch.h> 7599ebb4caSwyllys #include <thread.h> 7699ebb4caSwyllys 7799ebb4caSwyllys /* OPENSSL related headers */ 7899ebb4caSwyllys #include <openssl/bio.h> 7999ebb4caSwyllys #include <openssl/bn.h> 8099ebb4caSwyllys #include <openssl/asn1.h> 8199ebb4caSwyllys #include <openssl/err.h> 8299ebb4caSwyllys #include <openssl/bn.h> 8399ebb4caSwyllys #include <openssl/x509.h> 8499ebb4caSwyllys #include <openssl/rsa.h> 8599ebb4caSwyllys #include <openssl/dsa.h> 8699ebb4caSwyllys #include <openssl/x509v3.h> 8799ebb4caSwyllys #include <openssl/objects.h> 8899ebb4caSwyllys #include <openssl/pem.h> 8999ebb4caSwyllys #include <openssl/pkcs12.h> 9099ebb4caSwyllys #include <openssl/ocsp.h> 9199ebb4caSwyllys #include <openssl/des.h> 9299ebb4caSwyllys #include <openssl/rand.h> 9399ebb4caSwyllys 9499ebb4caSwyllys #define PRINT_ANY_EXTENSION (\ 9599ebb4caSwyllys KMF_X509_EXT_KEY_USAGE |\ 9699ebb4caSwyllys KMF_X509_EXT_CERT_POLICIES |\ 9799ebb4caSwyllys KMF_X509_EXT_SUBJALTNAME |\ 9899ebb4caSwyllys KMF_X509_EXT_BASIC_CONSTRAINTS |\ 9999ebb4caSwyllys KMF_X509_EXT_NAME_CONSTRAINTS |\ 10099ebb4caSwyllys KMF_X509_EXT_POLICY_CONSTRAINTS |\ 10199ebb4caSwyllys KMF_X509_EXT_EXT_KEY_USAGE |\ 10299ebb4caSwyllys KMF_X509_EXT_INHIBIT_ANY_POLICY |\ 10399ebb4caSwyllys KMF_X509_EXT_AUTH_KEY_ID |\ 10499ebb4caSwyllys KMF_X509_EXT_SUBJ_KEY_ID |\ 10599ebb4caSwyllys KMF_X509_EXT_POLICY_MAPPING) 10699ebb4caSwyllys 10799ebb4caSwyllys static BIO *bio_err = NULL; 10899ebb4caSwyllys static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 10999ebb4caSwyllys 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 11099ebb4caSwyllys 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 11199ebb4caSwyllys 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 11299ebb4caSwyllys 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 11399ebb4caSwyllys 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 11499ebb4caSwyllys 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 11599ebb4caSwyllys 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 11699ebb4caSwyllys 0x91 }; 11799ebb4caSwyllys 11899ebb4caSwyllys static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 11999ebb4caSwyllys 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 12099ebb4caSwyllys 0x8e, 0xda, 0xce, 0x91, 0x5f }; 12199ebb4caSwyllys 12299ebb4caSwyllys static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 12399ebb4caSwyllys 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 12499ebb4caSwyllys 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 12599ebb4caSwyllys 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 12699ebb4caSwyllys 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 12799ebb4caSwyllys 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 12899ebb4caSwyllys 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 12999ebb4caSwyllys 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 13099ebb4caSwyllys 0x02 }; 13199ebb4caSwyllys 13299ebb4caSwyllys #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \ 13399ebb4caSwyllys h->lasterr.errcode = c; 13499ebb4caSwyllys 13599ebb4caSwyllys #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c; 13699ebb4caSwyllys 13799ebb4caSwyllys mutex_t init_lock = DEFAULTMUTEX; 13899ebb4caSwyllys static int ssl_initialized = 0; 13999ebb4caSwyllys 14071593db2Swyllys static KMF_RETURN 14171593db2Swyllys extract_objects(KMF_HANDLE *, char *, CK_UTF8CHAR *, CK_ULONG, 14271593db2Swyllys EVP_PKEY **, KMF_DATA **, int *); 14371593db2Swyllys 14471593db2Swyllys static KMF_RETURN 14571593db2Swyllys kmf_load_cert(KMF_HANDLE *, KMF_FINDCERT_PARAMS *, char *, KMF_DATA *); 14671593db2Swyllys 14799ebb4caSwyllys KMF_RETURN 14899ebb4caSwyllys OpenSSL_FindCert(KMF_HANDLE_T, 14999ebb4caSwyllys KMF_FINDCERT_PARAMS *, 15099ebb4caSwyllys KMF_X509_DER_CERT *, 15199ebb4caSwyllys uint32_t *); 15299ebb4caSwyllys 15399ebb4caSwyllys void 15499ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); 15599ebb4caSwyllys 15699ebb4caSwyllys KMF_RETURN 15799ebb4caSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *, KMF_DATA *); 15899ebb4caSwyllys 15999ebb4caSwyllys KMF_RETURN 16099ebb4caSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *); 16199ebb4caSwyllys 16299ebb4caSwyllys KMF_RETURN 16399ebb4caSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, 16499ebb4caSwyllys KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); 16599ebb4caSwyllys 16699ebb4caSwyllys KMF_RETURN 16799ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 16899ebb4caSwyllys 16999ebb4caSwyllys KMF_RETURN 17099ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 17199ebb4caSwyllys KMF_DATA *, KMF_DATA *); 17299ebb4caSwyllys 17399ebb4caSwyllys KMF_RETURN 17499ebb4caSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, 17599ebb4caSwyllys KMF_KEY_HANDLE *, boolean_t); 17699ebb4caSwyllys 17799ebb4caSwyllys KMF_RETURN 17899ebb4caSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *); 17999ebb4caSwyllys 18099ebb4caSwyllys KMF_RETURN 18199ebb4caSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *); 18299ebb4caSwyllys 18399ebb4caSwyllys KMF_RETURN 18499ebb4caSwyllys OpenSSL_ListCRL(KMF_HANDLE_T, KMF_LISTCRL_PARAMS *, char **); 18599ebb4caSwyllys 18699ebb4caSwyllys KMF_RETURN 18799ebb4caSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *); 18899ebb4caSwyllys 18999ebb4caSwyllys KMF_RETURN 19099ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *, 19199ebb4caSwyllys KMF_PRINTABLE_ITEM, char *); 19299ebb4caSwyllys 19399ebb4caSwyllys KMF_RETURN 19499ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T, char **); 19599ebb4caSwyllys 19699ebb4caSwyllys KMF_RETURN 19799ebb4caSwyllys OpenSSL_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, 19899ebb4caSwyllys KMF_KEY_HANDLE *, KMF_KEY_ALG); 19999ebb4caSwyllys 20099ebb4caSwyllys KMF_RETURN 20199ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 20299ebb4caSwyllys KMF_DATA *, KMF_DATA *); 20399ebb4caSwyllys 20499ebb4caSwyllys KMF_RETURN 20599ebb4caSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, KMF_OCSPREQUEST_PARAMS *, 20699ebb4caSwyllys char *reqfile); 20799ebb4caSwyllys 20899ebb4caSwyllys KMF_RETURN 20999ebb4caSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, KMF_OCSPRESPONSE_PARAMS_INPUT *, 21099ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_OUTPUT *); 21199ebb4caSwyllys 21299ebb4caSwyllys KMF_RETURN 21399ebb4caSwyllys OpenSSL_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, 21499ebb4caSwyllys KMF_KEY_HANDLE *, uint32_t *); 21599ebb4caSwyllys 21699ebb4caSwyllys KMF_RETURN 21799ebb4caSwyllys OpenSSL_ExportP12(KMF_HANDLE_T, 21899ebb4caSwyllys KMF_EXPORTP12_PARAMS *, 21999ebb4caSwyllys int, KMF_X509_DER_CERT *, 22099ebb4caSwyllys int, KMF_KEY_HANDLE *, 22199ebb4caSwyllys char *); 22299ebb4caSwyllys 22399ebb4caSwyllys KMF_RETURN 22499ebb4caSwyllys OpenSSL_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, 22599ebb4caSwyllys KMF_RAW_KEY_DATA *); 22699ebb4caSwyllys 22799ebb4caSwyllys KMF_RETURN 22899ebb4caSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, 22999ebb4caSwyllys KMF_KEY_HANDLE *); 23099ebb4caSwyllys 23199ebb4caSwyllys KMF_RETURN 23299ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 23399ebb4caSwyllys 23499ebb4caSwyllys KMF_RETURN 23599ebb4caSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T, KMF_VERIFYCRL_PARAMS *); 23699ebb4caSwyllys 23799ebb4caSwyllys KMF_RETURN 23899ebb4caSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T, KMF_CHECKCRLDATE_PARAMS *); 23999ebb4caSwyllys 24099ebb4caSwyllys static 24199ebb4caSwyllys KMF_PLUGIN_FUNCLIST openssl_plugin_table = 24299ebb4caSwyllys { 24399ebb4caSwyllys 1, /* Version */ 24499ebb4caSwyllys NULL, /* ConfigureKeystore */ 24599ebb4caSwyllys OpenSSL_FindCert, 24699ebb4caSwyllys OpenSSL_FreeKMFCert, 24799ebb4caSwyllys OpenSSL_StoreCert, 24899ebb4caSwyllys NULL, /* ImportCert */ 24999ebb4caSwyllys OpenSSL_ImportCRL, 25099ebb4caSwyllys OpenSSL_DeleteCert, 25199ebb4caSwyllys OpenSSL_DeleteCRL, 25299ebb4caSwyllys OpenSSL_CreateKeypair, 25399ebb4caSwyllys OpenSSL_FindKey, 25499ebb4caSwyllys OpenSSL_EncodePubKeyData, 25599ebb4caSwyllys OpenSSL_SignData, 25699ebb4caSwyllys OpenSSL_DeleteKey, 25799ebb4caSwyllys OpenSSL_ListCRL, 25899ebb4caSwyllys NULL, /* FindCRL */ 25999ebb4caSwyllys OpenSSL_FindCertInCRL, 26099ebb4caSwyllys OpenSSL_GetErrorString, 26199ebb4caSwyllys OpenSSL_GetPrikeyByCert, 26299ebb4caSwyllys OpenSSL_DecryptData, 26399ebb4caSwyllys OpenSSL_ExportP12, 26499ebb4caSwyllys OpenSSL_StorePrivateKey, 26599ebb4caSwyllys OpenSSL_CreateSymKey, 26699ebb4caSwyllys OpenSSL_GetSymKeyValue, 26799ebb4caSwyllys NULL, /* SetTokenPin */ 26899ebb4caSwyllys NULL /* Finalize */ 26999ebb4caSwyllys }; 27099ebb4caSwyllys 27199ebb4caSwyllys static mutex_t *lock_cs; 27299ebb4caSwyllys static long *lock_count; 27399ebb4caSwyllys 27499ebb4caSwyllys static void 27599ebb4caSwyllys /*ARGSUSED*/ 27699ebb4caSwyllys locking_cb(int mode, int type, char *file, int line) 27799ebb4caSwyllys { 27899ebb4caSwyllys if (mode & CRYPTO_LOCK) { 27999ebb4caSwyllys (void) mutex_lock(&(lock_cs[type])); 28099ebb4caSwyllys lock_count[type]++; 28199ebb4caSwyllys } else { 28299ebb4caSwyllys (void) mutex_unlock(&(lock_cs[type])); 28399ebb4caSwyllys } 28499ebb4caSwyllys } 28599ebb4caSwyllys 28699ebb4caSwyllys static unsigned long 28799ebb4caSwyllys thread_id() 28899ebb4caSwyllys { 28999ebb4caSwyllys return ((unsigned long)thr_self()); 29099ebb4caSwyllys } 29199ebb4caSwyllys 29299ebb4caSwyllys KMF_PLUGIN_FUNCLIST * 29399ebb4caSwyllys KMF_Plugin_Initialize() 29499ebb4caSwyllys { 29599ebb4caSwyllys int i; 29699ebb4caSwyllys 29799ebb4caSwyllys (void) mutex_lock(&init_lock); 29899ebb4caSwyllys if (!ssl_initialized) { 29999ebb4caSwyllys OpenSSL_add_all_algorithms(); 30099ebb4caSwyllys 30199ebb4caSwyllys /* Enable error strings for reporting */ 30299ebb4caSwyllys ERR_load_crypto_strings(); 30399ebb4caSwyllys 30499ebb4caSwyllys /* 30599ebb4caSwyllys * Add support for extension OIDs that are not yet in the 30699ebb4caSwyllys * openssl default set. 30799ebb4caSwyllys */ 30899ebb4caSwyllys (void) OBJ_create("2.5.29.30", "nameConstraints", 30999ebb4caSwyllys "X509v3 Name Constraints"); 31099ebb4caSwyllys (void) OBJ_create("2.5.29.33", "policyMappings", 31199ebb4caSwyllys "X509v3 Policy Mappings"); 31299ebb4caSwyllys (void) OBJ_create("2.5.29.36", "policyConstraints", 31399ebb4caSwyllys "X509v3 Policy Constraints"); 31499ebb4caSwyllys (void) OBJ_create("2.5.29.46", "freshestCRL", 31599ebb4caSwyllys "X509v3 Freshest CRL"); 31699ebb4caSwyllys (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy", 31799ebb4caSwyllys "X509v3 Inhibit Any-Policy"); 31899ebb4caSwyllys /* 31999ebb4caSwyllys * Set up for thread-safe operation. 32099ebb4caSwyllys */ 32199ebb4caSwyllys lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t)); 32299ebb4caSwyllys if (lock_cs == NULL) { 32399ebb4caSwyllys (void) mutex_unlock(&init_lock); 32499ebb4caSwyllys return (NULL); 32599ebb4caSwyllys } 32699ebb4caSwyllys 32799ebb4caSwyllys lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long)); 32899ebb4caSwyllys if (lock_count == NULL) { 32999ebb4caSwyllys OPENSSL_free(lock_cs); 33099ebb4caSwyllys (void) mutex_unlock(&init_lock); 33199ebb4caSwyllys return (NULL); 33299ebb4caSwyllys } 33399ebb4caSwyllys 33499ebb4caSwyllys for (i = 0; i < CRYPTO_num_locks(); i++) { 33599ebb4caSwyllys lock_count[i] = 0; 33699ebb4caSwyllys (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL); 33799ebb4caSwyllys } 33899ebb4caSwyllys 33999ebb4caSwyllys CRYPTO_set_id_callback((unsigned long (*)())thread_id); 34099ebb4caSwyllys CRYPTO_set_locking_callback((void (*)())locking_cb); 34199ebb4caSwyllys ssl_initialized = 1; 34299ebb4caSwyllys } 34399ebb4caSwyllys (void) mutex_unlock(&init_lock); 34499ebb4caSwyllys 34599ebb4caSwyllys return (&openssl_plugin_table); 34699ebb4caSwyllys } 34799ebb4caSwyllys /* 34899ebb4caSwyllys * Convert an SSL DN to a KMF DN. 34999ebb4caSwyllys */ 35099ebb4caSwyllys static KMF_RETURN 35199ebb4caSwyllys get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN) 35299ebb4caSwyllys { 35399ebb4caSwyllys KMF_DATA derdata; 35499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 35599ebb4caSwyllys uchar_t *tmp; 35699ebb4caSwyllys 35799ebb4caSwyllys /* Convert to raw DER format */ 35899ebb4caSwyllys derdata.Length = i2d_X509_NAME(sslDN, NULL); 35999ebb4caSwyllys if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length)) 36099ebb4caSwyllys == NULL) { 36199ebb4caSwyllys return (KMF_ERR_MEMORY); 36299ebb4caSwyllys } 36399ebb4caSwyllys (void) i2d_X509_NAME(sslDN, &tmp); 36499ebb4caSwyllys 36599ebb4caSwyllys /* Decode to KMF format */ 36699ebb4caSwyllys rv = DerDecodeName(&derdata, kmfDN); 36799ebb4caSwyllys if (rv != KMF_OK) { 36899ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 36999ebb4caSwyllys } 37099ebb4caSwyllys OPENSSL_free(derdata.Data); 37199ebb4caSwyllys 37299ebb4caSwyllys return (rv); 37399ebb4caSwyllys } 37499ebb4caSwyllys 37599ebb4caSwyllys static int 37699ebb4caSwyllys isdir(char *path) 37799ebb4caSwyllys { 37899ebb4caSwyllys struct stat s; 37999ebb4caSwyllys 38099ebb4caSwyllys if (stat(path, &s) == -1) 38199ebb4caSwyllys return (0); 38299ebb4caSwyllys 38399ebb4caSwyllys return (s.st_mode & S_IFDIR); 38499ebb4caSwyllys } 38599ebb4caSwyllys 38699ebb4caSwyllys static KMF_RETURN 38799ebb4caSwyllys ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert) 38899ebb4caSwyllys { 38999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 39099ebb4caSwyllys unsigned char *buf = NULL, *p; 39199ebb4caSwyllys int len; 39299ebb4caSwyllys 39399ebb4caSwyllys /* 39499ebb4caSwyllys * Convert the X509 internal struct to DER encoded data 39599ebb4caSwyllys */ 39699ebb4caSwyllys if ((len = i2d_X509(x509cert, NULL)) < 0) { 39799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 39899ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 39999ebb4caSwyllys goto cleanup; 40099ebb4caSwyllys } 40199ebb4caSwyllys if ((buf = malloc(len)) == NULL) { 40299ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 40399ebb4caSwyllys rv = KMF_ERR_MEMORY; 40499ebb4caSwyllys goto cleanup; 40599ebb4caSwyllys } 40699ebb4caSwyllys 40799ebb4caSwyllys /* 40899ebb4caSwyllys * i2d_X509 will increment the buf pointer so that we need to 40999ebb4caSwyllys * save it. 41099ebb4caSwyllys */ 41199ebb4caSwyllys p = buf; 41299ebb4caSwyllys if ((len = i2d_X509(x509cert, &p)) < 0) { 41399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 41499ebb4caSwyllys free(buf); 41599ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 41699ebb4caSwyllys goto cleanup; 41799ebb4caSwyllys } 41899ebb4caSwyllys 41999ebb4caSwyllys /* caller's responsibility to free it */ 42099ebb4caSwyllys cert->Data = buf; 42199ebb4caSwyllys cert->Length = len; 42299ebb4caSwyllys 42399ebb4caSwyllys cleanup: 42499ebb4caSwyllys if (rv != KMF_OK) { 42599ebb4caSwyllys if (buf) 42699ebb4caSwyllys free(buf); 42799ebb4caSwyllys cert->Data = NULL; 42899ebb4caSwyllys cert->Length = 0; 42999ebb4caSwyllys } 43099ebb4caSwyllys 43199ebb4caSwyllys return (rv); 43299ebb4caSwyllys } 43399ebb4caSwyllys 43499ebb4caSwyllys static KMF_RETURN 43599ebb4caSwyllys check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) 43699ebb4caSwyllys { 43799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 43899ebb4caSwyllys boolean_t findIssuer = FALSE; 43999ebb4caSwyllys boolean_t findSubject = FALSE; 44099ebb4caSwyllys boolean_t findSerial = FALSE; 44199ebb4caSwyllys KMF_X509_NAME issuerDN, subjectDN; 44299ebb4caSwyllys KMF_X509_NAME certIssuerDN, certSubjectDN; 44399ebb4caSwyllys 44499ebb4caSwyllys *match = FALSE; 44599ebb4caSwyllys if (xcert == NULL) { 44699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 44799ebb4caSwyllys } 44899ebb4caSwyllys 44999ebb4caSwyllys (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME)); 45099ebb4caSwyllys (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME)); 45199ebb4caSwyllys (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME)); 45299ebb4caSwyllys (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME)); 45399ebb4caSwyllys 45499ebb4caSwyllys if (params->issuer != NULL && strlen(params->issuer)) { 45599ebb4caSwyllys rv = KMF_DNParser(params->issuer, &issuerDN); 45699ebb4caSwyllys if (rv != KMF_OK) 45799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 45899ebb4caSwyllys 45999ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); 46099ebb4caSwyllys if (rv != KMF_OK) { 46199ebb4caSwyllys KMF_FreeDN(&issuerDN); 46299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 46399ebb4caSwyllys } 46499ebb4caSwyllys 46599ebb4caSwyllys findIssuer = TRUE; 46699ebb4caSwyllys } 46799ebb4caSwyllys if (params->subject != NULL && strlen(params->subject)) { 46899ebb4caSwyllys rv = KMF_DNParser(params->subject, &subjectDN); 46999ebb4caSwyllys if (rv != KMF_OK) { 47099ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 47199ebb4caSwyllys goto cleanup; 47299ebb4caSwyllys } 47399ebb4caSwyllys 47499ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN); 47599ebb4caSwyllys if (rv != KMF_OK) { 47699ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 47799ebb4caSwyllys goto cleanup; 47899ebb4caSwyllys } 47999ebb4caSwyllys findSubject = TRUE; 48099ebb4caSwyllys } 48199ebb4caSwyllys if (params->serial != NULL && params->serial->val != NULL) 48299ebb4caSwyllys findSerial = TRUE; 48399ebb4caSwyllys 48499ebb4caSwyllys if (findSerial) { 48599ebb4caSwyllys BIGNUM *bn; 48699ebb4caSwyllys 48799ebb4caSwyllys /* Comparing BIGNUMs is a pain! */ 48899ebb4caSwyllys bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL); 48999ebb4caSwyllys if (bn != NULL) { 49099ebb4caSwyllys int bnlen = BN_num_bytes(bn); 49199ebb4caSwyllys 49299ebb4caSwyllys if (bnlen == params->serial->len) { 49399ebb4caSwyllys uchar_t *a = malloc(bnlen); 49499ebb4caSwyllys if (a == NULL) { 49599ebb4caSwyllys rv = KMF_ERR_MEMORY; 49699ebb4caSwyllys BN_free(bn); 49799ebb4caSwyllys goto cleanup; 49899ebb4caSwyllys } 49999ebb4caSwyllys bnlen = BN_bn2bin(bn, a); 50099ebb4caSwyllys *match = !memcmp(a, 50199ebb4caSwyllys params->serial->val, 50299ebb4caSwyllys params->serial->len); 50399ebb4caSwyllys rv = KMF_OK; 50499ebb4caSwyllys free(a); 50599ebb4caSwyllys } 50699ebb4caSwyllys BN_free(bn); 50799ebb4caSwyllys if (!(*match)) 50899ebb4caSwyllys goto cleanup; 50999ebb4caSwyllys } else { 51099ebb4caSwyllys rv = KMF_OK; 51199ebb4caSwyllys goto cleanup; 51299ebb4caSwyllys } 51399ebb4caSwyllys } 51499ebb4caSwyllys if (findIssuer) { 51599ebb4caSwyllys *match = !KMF_CompareRDNs(&issuerDN, &certIssuerDN); 51699ebb4caSwyllys if (!(*match)) { 51799ebb4caSwyllys rv = KMF_OK; 51899ebb4caSwyllys goto cleanup; 51999ebb4caSwyllys } 52099ebb4caSwyllys } 52199ebb4caSwyllys if (findSubject) { 52299ebb4caSwyllys *match = !KMF_CompareRDNs(&subjectDN, &certSubjectDN); 52399ebb4caSwyllys if (!(*match)) { 52499ebb4caSwyllys rv = KMF_OK; 52599ebb4caSwyllys goto cleanup; 52699ebb4caSwyllys } 52799ebb4caSwyllys } 52899ebb4caSwyllys 52999ebb4caSwyllys *match = TRUE; 53099ebb4caSwyllys cleanup: 53199ebb4caSwyllys if (findIssuer) { 53299ebb4caSwyllys KMF_FreeDN(&issuerDN); 53399ebb4caSwyllys KMF_FreeDN(&certIssuerDN); 53499ebb4caSwyllys } 53599ebb4caSwyllys if (findSubject) { 53699ebb4caSwyllys KMF_FreeDN(&subjectDN); 53799ebb4caSwyllys KMF_FreeDN(&certSubjectDN); 53899ebb4caSwyllys } 53999ebb4caSwyllys 54099ebb4caSwyllys return (rv); 54199ebb4caSwyllys } 54299ebb4caSwyllys 54399ebb4caSwyllys static KMF_RETURN 54499ebb4caSwyllys load_X509cert(KMF_HANDLE *kmfh, 54599ebb4caSwyllys KMF_FINDCERT_PARAMS *params, 54699ebb4caSwyllys char *pathname, 54799ebb4caSwyllys X509 **outcert) 54899ebb4caSwyllys { 54999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 55099ebb4caSwyllys X509 *xcert = NULL; 55199ebb4caSwyllys BIO *bcert = NULL; 55299ebb4caSwyllys boolean_t match = FALSE; 55399ebb4caSwyllys KMF_ENCODE_FORMAT format; 55499ebb4caSwyllys 55599ebb4caSwyllys /* 55699ebb4caSwyllys * auto-detect the file format, regardless of what 55799ebb4caSwyllys * the 'format' parameters in the params say. 55899ebb4caSwyllys */ 55999ebb4caSwyllys rv = KMF_GetFileFormat(pathname, &format); 56099ebb4caSwyllys if (rv != KMF_OK) { 56199ebb4caSwyllys if (rv == KMF_ERR_OPEN_FILE) 56299ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 56399ebb4caSwyllys return (rv); 56499ebb4caSwyllys } 56599ebb4caSwyllys 56699ebb4caSwyllys /* Not ASN1(DER) format */ 56799ebb4caSwyllys if ((bcert = BIO_new_file(pathname, "rb")) == NULL) { 56899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 56999ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 57099ebb4caSwyllys goto cleanup; 57199ebb4caSwyllys } 57299ebb4caSwyllys 57399ebb4caSwyllys if (format == KMF_FORMAT_PEM) 57499ebb4caSwyllys xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL); 57599ebb4caSwyllys else if (format == KMF_FORMAT_ASN1) 57699ebb4caSwyllys xcert = d2i_X509_bio(bcert, NULL); 57799ebb4caSwyllys else if (format == KMF_FORMAT_PKCS12) { 57899ebb4caSwyllys PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL); 57999ebb4caSwyllys if (p12 != NULL) { 58099ebb4caSwyllys (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL); 58199ebb4caSwyllys PKCS12_free(p12); 58299ebb4caSwyllys p12 = NULL; 58399ebb4caSwyllys } else { 58499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 58599ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 58699ebb4caSwyllys } 58799ebb4caSwyllys } else { 58899ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 58999ebb4caSwyllys goto cleanup; 59099ebb4caSwyllys } 59199ebb4caSwyllys 59299ebb4caSwyllys if (xcert == NULL) { 59399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 59499ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 59599ebb4caSwyllys goto cleanup; 59699ebb4caSwyllys } 59799ebb4caSwyllys 59899ebb4caSwyllys if (check_cert(xcert, params, &match) != KMF_OK || match == FALSE) { 59999ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 60099ebb4caSwyllys goto cleanup; 60199ebb4caSwyllys } 60299ebb4caSwyllys 60399ebb4caSwyllys if (outcert != NULL) { 60499ebb4caSwyllys *outcert = xcert; 60599ebb4caSwyllys } 60699ebb4caSwyllys 60799ebb4caSwyllys cleanup: 60899ebb4caSwyllys if (bcert != NULL) (void) BIO_free(bcert); 60999ebb4caSwyllys if (rv != KMF_OK && xcert != NULL) 61099ebb4caSwyllys X509_free(xcert); 61199ebb4caSwyllys 61299ebb4caSwyllys return (rv); 61399ebb4caSwyllys } 61499ebb4caSwyllys 61571593db2Swyllys static int 61671593db2Swyllys datacmp(const void *a, const void *b) 61771593db2Swyllys { 61871593db2Swyllys KMF_DATA *adata = (KMF_DATA *)a; 61971593db2Swyllys KMF_DATA *bdata = (KMF_DATA *)b; 62071593db2Swyllys if (adata->Length > bdata->Length) 62171593db2Swyllys return (-1); 62271593db2Swyllys if (adata->Length < bdata->Length) 62371593db2Swyllys return (1); 62471593db2Swyllys return (0); 62571593db2Swyllys } 62671593db2Swyllys 62771593db2Swyllys static KMF_RETURN 62871593db2Swyllys load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, 62971593db2Swyllys KMF_DATA **certlist, uint32_t *numcerts) 63071593db2Swyllys { 63171593db2Swyllys KMF_RETURN rv = KMF_OK; 63271593db2Swyllys int i; 63371593db2Swyllys KMF_DATA *certs = NULL; 63471593db2Swyllys int nc = 0; 63571593db2Swyllys int hits = 0; 63671593db2Swyllys KMF_ENCODE_FORMAT format; 63771593db2Swyllys 63871593db2Swyllys rv = KMF_GetFileFormat(pathname, &format); 63971593db2Swyllys if (rv != KMF_OK) { 64071593db2Swyllys if (rv == KMF_ERR_OPEN_FILE) 64171593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 64271593db2Swyllys return (rv); 64371593db2Swyllys } 64471593db2Swyllys if (format == KMF_FORMAT_ASN1) { 64571593db2Swyllys /* load a single certificate */ 64671593db2Swyllys certs = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 64771593db2Swyllys if (certs == NULL) 64871593db2Swyllys return (KMF_ERR_MEMORY); 64971593db2Swyllys certs->Data = NULL; 65071593db2Swyllys certs->Length = 0; 65171593db2Swyllys rv = kmf_load_cert(kmfh, params, pathname, certs); 65271593db2Swyllys if (rv == KMF_OK) { 65371593db2Swyllys *certlist = certs; 65471593db2Swyllys *numcerts = 1; 65571593db2Swyllys } 65671593db2Swyllys return (rv); 65771593db2Swyllys } else if (format == KMF_FORMAT_PKCS12) { 65871593db2Swyllys /* We need a credential to access a PKCS#12 file */ 65971593db2Swyllys rv = KMF_ERR_BAD_CERT_FORMAT; 66071593db2Swyllys } else if (format == KMF_FORMAT_PEM || 66171593db2Swyllys format != KMF_FORMAT_PEM_KEYPAIR) { 66271593db2Swyllys 66371593db2Swyllys /* This function only works on PEM files */ 66471593db2Swyllys rv = extract_objects(kmfh, pathname, 66571593db2Swyllys (uchar_t *)NULL, 0, NULL, 66671593db2Swyllys &certs, &nc); 66771593db2Swyllys } else { 66871593db2Swyllys return (KMF_ERR_ENCODING); 66971593db2Swyllys } 67071593db2Swyllys 67171593db2Swyllys if (rv != KMF_OK) 67271593db2Swyllys return (rv); 67371593db2Swyllys 67471593db2Swyllys for (i = 0; i < nc; i++) { 67571593db2Swyllys if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) { 67671593db2Swyllys rv = KMF_CheckCertDate(kmfh, &certs[i]); 67771593db2Swyllys } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) { 67871593db2Swyllys rv = KMF_CheckCertDate(kmfh, &certs[i]); 67971593db2Swyllys if (rv == KMF_OK) 68071593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 68171593db2Swyllys if (rv == KMF_ERR_VALIDITY_PERIOD) 68271593db2Swyllys rv = KMF_OK; 68371593db2Swyllys } 68471593db2Swyllys if (rv != KMF_OK) { 68571593db2Swyllys /* Remove this cert from the list by clearing it. */ 68671593db2Swyllys KMF_FreeData(&certs[i]); 68771593db2Swyllys } else { 68871593db2Swyllys hits++; /* count valid certs found */ 68971593db2Swyllys } 69071593db2Swyllys rv = KMF_OK; 69171593db2Swyllys } 69271593db2Swyllys if (rv == KMF_OK && hits == 0) { 69371593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 69471593db2Swyllys } else if (rv == KMF_OK && hits > 0) { 69571593db2Swyllys /* 69671593db2Swyllys * Sort the list of certs by length to put the cleared ones 69771593db2Swyllys * at the end so they don't get accessed by the caller. 69871593db2Swyllys */ 69971593db2Swyllys qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp); 70071593db2Swyllys *certlist = certs; 70171593db2Swyllys 70271593db2Swyllys /* since we sorted the list, just return the number of hits */ 70371593db2Swyllys *numcerts = hits; 70471593db2Swyllys } 70571593db2Swyllys return (rv); 70671593db2Swyllys } 70771593db2Swyllys 70899ebb4caSwyllys static KMF_RETURN 70999ebb4caSwyllys kmf_load_cert(KMF_HANDLE *kmfh, 71099ebb4caSwyllys KMF_FINDCERT_PARAMS *params, 71199ebb4caSwyllys char *pathname, 71299ebb4caSwyllys KMF_DATA *cert) 71399ebb4caSwyllys { 71499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 71599ebb4caSwyllys X509 *x509cert = NULL; 71699ebb4caSwyllys 71799ebb4caSwyllys rv = load_X509cert(kmfh, params, pathname, &x509cert); 71899ebb4caSwyllys if (rv == KMF_OK && x509cert != NULL && cert != NULL) { 71999ebb4caSwyllys rv = ssl_cert2KMFDATA(kmfh, x509cert, cert); 72099ebb4caSwyllys if (rv != KMF_OK) { 72199ebb4caSwyllys goto cleanup; 72299ebb4caSwyllys } 72399ebb4caSwyllys if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) { 72499ebb4caSwyllys rv = KMF_CheckCertDate(kmfh, cert); 72599ebb4caSwyllys } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) { 72699ebb4caSwyllys rv = KMF_CheckCertDate(kmfh, cert); 72799ebb4caSwyllys if (rv == KMF_OK) { 72899ebb4caSwyllys /* 72999ebb4caSwyllys * This is a valid cert so skip it. 73099ebb4caSwyllys */ 73199ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 73299ebb4caSwyllys } 73399ebb4caSwyllys if (rv == KMF_ERR_VALIDITY_PERIOD) { 73499ebb4caSwyllys /* 73599ebb4caSwyllys * We want to return success when we 73699ebb4caSwyllys * find an invalid cert. 73799ebb4caSwyllys */ 73899ebb4caSwyllys rv = KMF_OK; 73999ebb4caSwyllys goto cleanup; 74099ebb4caSwyllys } 74199ebb4caSwyllys } 74299ebb4caSwyllys } 74399ebb4caSwyllys cleanup: 74499ebb4caSwyllys if (x509cert != NULL) 74599ebb4caSwyllys X509_free(x509cert); 74699ebb4caSwyllys 74799ebb4caSwyllys return (rv); 74899ebb4caSwyllys } 74999ebb4caSwyllys 75099ebb4caSwyllys static EVP_PKEY * 75199ebb4caSwyllys openssl_load_key(KMF_HANDLE_T handle, const char *file) 75299ebb4caSwyllys { 75399ebb4caSwyllys BIO *keyfile = NULL; 75499ebb4caSwyllys EVP_PKEY *pkey = NULL; 75599ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 75699ebb4caSwyllys KMF_ENCODE_FORMAT format; 75799ebb4caSwyllys 75899ebb4caSwyllys if (file == NULL) { 75999ebb4caSwyllys return (NULL); 76099ebb4caSwyllys } 76199ebb4caSwyllys 76299ebb4caSwyllys if (KMF_GetFileFormat((char *)file, &format) != KMF_OK) 76399ebb4caSwyllys return (NULL); 76499ebb4caSwyllys 76599ebb4caSwyllys keyfile = BIO_new_file(file, "rb"); 76699ebb4caSwyllys if (keyfile == NULL) { 76799ebb4caSwyllys goto end; 76899ebb4caSwyllys } 76999ebb4caSwyllys 77099ebb4caSwyllys if (format == KMF_FORMAT_ASN1) 77199ebb4caSwyllys pkey = d2i_PrivateKey_bio(keyfile, NULL); 77271593db2Swyllys else if (format == KMF_FORMAT_PEM || 77371593db2Swyllys format == KMF_FORMAT_PEM_KEYPAIR) 77499ebb4caSwyllys pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL); 77599ebb4caSwyllys 77699ebb4caSwyllys end: 77799ebb4caSwyllys if (pkey == NULL) 77899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 77999ebb4caSwyllys 78099ebb4caSwyllys if (keyfile != NULL) 78199ebb4caSwyllys (void) BIO_free(keyfile); 78299ebb4caSwyllys 78399ebb4caSwyllys return (pkey); 78499ebb4caSwyllys } 78599ebb4caSwyllys 78699ebb4caSwyllys KMF_RETURN 78799ebb4caSwyllys OpenSSL_FindCert(KMF_HANDLE_T handle, 78899ebb4caSwyllys KMF_FINDCERT_PARAMS *params, 78999ebb4caSwyllys KMF_X509_DER_CERT *kmf_cert, 79099ebb4caSwyllys uint32_t *num_certs) 79199ebb4caSwyllys { 79299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 79399ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 79499ebb4caSwyllys char *fullpath; 79571593db2Swyllys int i; 79699ebb4caSwyllys 79799ebb4caSwyllys if (num_certs == NULL || params == NULL) 79899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 79999ebb4caSwyllys 80099ebb4caSwyllys *num_certs = 0; 80199ebb4caSwyllys 80299ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 80399ebb4caSwyllys params->sslparms.certfile); 80499ebb4caSwyllys 80599ebb4caSwyllys if (fullpath == NULL) 80699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 80799ebb4caSwyllys 80899ebb4caSwyllys if (isdir(fullpath)) { 80999ebb4caSwyllys DIR *dirp; 81099ebb4caSwyllys struct dirent *dp; 81199ebb4caSwyllys int n = 0; 81299ebb4caSwyllys 81399ebb4caSwyllys /* open all files in the directory and attempt to read them */ 81499ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 81599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 81699ebb4caSwyllys } 81799ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 81899ebb4caSwyllys char *fname; 81971593db2Swyllys KMF_DATA *certlist = NULL; 82071593db2Swyllys uint32_t numcerts = 0; 82171593db2Swyllys 82299ebb4caSwyllys if (strcmp(dp->d_name, ".") == 0 || 82399ebb4caSwyllys strcmp(dp->d_name, "..") == 0) 82499ebb4caSwyllys continue; 82599ebb4caSwyllys 82699ebb4caSwyllys fname = get_fullpath(fullpath, 82799ebb4caSwyllys (char *)&dp->d_name); 82899ebb4caSwyllys 82971593db2Swyllys rv = load_certs(kmfh, params, fname, &certlist, 83071593db2Swyllys &numcerts); 83199ebb4caSwyllys 83299ebb4caSwyllys if (rv != KMF_OK) { 83399ebb4caSwyllys free(fname); 83471593db2Swyllys if (certlist != NULL) { 83571593db2Swyllys for (i = 0; i < numcerts; i++) 83671593db2Swyllys KMF_FreeData(&certlist[i]); 83771593db2Swyllys free(certlist); 83871593db2Swyllys } 83999ebb4caSwyllys continue; 84099ebb4caSwyllys } 84199ebb4caSwyllys 84299ebb4caSwyllys /* If load succeeds, add certdata to the list */ 84399ebb4caSwyllys if (kmf_cert != NULL) { 84471593db2Swyllys for (i = 0; i < numcerts; i++) { 84571593db2Swyllys kmf_cert[n].certificate.Data = 84671593db2Swyllys certlist[i].Data; 84799ebb4caSwyllys kmf_cert[n].certificate.Length = 84871593db2Swyllys certlist[i].Length; 84999ebb4caSwyllys 85099ebb4caSwyllys kmf_cert[n].kmf_private.keystore_type = 85199ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 85299ebb4caSwyllys kmf_cert[n].kmf_private.flags = 85399ebb4caSwyllys KMF_FLAG_CERT_VALID; 85471593db2Swyllys kmf_cert[n].kmf_private.label = 85571593db2Swyllys strdup(fname); 85699ebb4caSwyllys n++; 85799ebb4caSwyllys } 85871593db2Swyllys free(certlist); 85971593db2Swyllys } else { 86071593db2Swyllys for (i = 0; i < numcerts; i++) 86171593db2Swyllys KMF_FreeData(&certlist[i]); 86271593db2Swyllys free(certlist); 86371593db2Swyllys n += numcerts; 86471593db2Swyllys } 86571593db2Swyllys free(fname); 86671593db2Swyllys } 86799ebb4caSwyllys (*num_certs) = n; 86899ebb4caSwyllys if (*num_certs == 0) 86999ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 87099ebb4caSwyllys if (*num_certs > 0) 87199ebb4caSwyllys rv = KMF_OK; 87299ebb4caSwyllys exit: 87399ebb4caSwyllys (void) closedir(dirp); 87499ebb4caSwyllys } else { 87571593db2Swyllys KMF_DATA *certlist = NULL; 87671593db2Swyllys uint32_t numcerts = 0; 87771593db2Swyllys 87871593db2Swyllys rv = load_certs(kmfh, params, fullpath, &certlist, &numcerts); 87999ebb4caSwyllys if (rv != KMF_OK) { 88099ebb4caSwyllys free(fullpath); 88199ebb4caSwyllys return (rv); 88299ebb4caSwyllys } 88399ebb4caSwyllys 88471593db2Swyllys if (kmf_cert != NULL && certlist != NULL) { 88571593db2Swyllys for (i = 0; i < numcerts; i++) { 88671593db2Swyllys kmf_cert[i].certificate.Data = 88771593db2Swyllys certlist[i].Data; 88871593db2Swyllys kmf_cert[i].certificate.Length = 88971593db2Swyllys certlist[i].Length; 89071593db2Swyllys kmf_cert[i].kmf_private.keystore_type = 89199ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 89271593db2Swyllys kmf_cert[i].kmf_private.flags = 89371593db2Swyllys KMF_FLAG_CERT_VALID; 89471593db2Swyllys kmf_cert[i].kmf_private.label = 89571593db2Swyllys strdup(fullpath); 89671593db2Swyllys } 89771593db2Swyllys free(certlist); 89899ebb4caSwyllys } else { 89971593db2Swyllys if (certlist != NULL) { 90071593db2Swyllys for (i = 0; i < numcerts; i++) 90171593db2Swyllys KMF_FreeData(&certlist[i]); 90271593db2Swyllys free(certlist); 90371593db2Swyllys } 90471593db2Swyllys } 90571593db2Swyllys *num_certs = numcerts; 90699ebb4caSwyllys } 90799ebb4caSwyllys 90899ebb4caSwyllys free(fullpath); 90999ebb4caSwyllys 91099ebb4caSwyllys return (rv); 91199ebb4caSwyllys } 91299ebb4caSwyllys 91399ebb4caSwyllys void 91499ebb4caSwyllys /*ARGSUSED*/ 91599ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, 91699ebb4caSwyllys KMF_X509_DER_CERT *kmf_cert) 91799ebb4caSwyllys { 91899ebb4caSwyllys if (kmf_cert != NULL) { 91999ebb4caSwyllys if (kmf_cert->certificate.Data != NULL) { 92099ebb4caSwyllys free(kmf_cert->certificate.Data); 92199ebb4caSwyllys kmf_cert->certificate.Data = NULL; 92299ebb4caSwyllys kmf_cert->certificate.Length = 0; 92399ebb4caSwyllys } 92499ebb4caSwyllys if (kmf_cert->kmf_private.label) 92599ebb4caSwyllys free(kmf_cert->kmf_private.label); 92699ebb4caSwyllys } 92799ebb4caSwyllys } 92899ebb4caSwyllys 92999ebb4caSwyllys KMF_RETURN 93099ebb4caSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, 93199ebb4caSwyllys KMF_DATA * pcert) 93299ebb4caSwyllys { 93399ebb4caSwyllys KMF_RETURN ret = KMF_OK; 93499ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 93599ebb4caSwyllys X509 *xcert = NULL; 93699ebb4caSwyllys FILE *fp; 93799ebb4caSwyllys unsigned char *outbuf; 93899ebb4caSwyllys unsigned char *outbuf_p; 93999ebb4caSwyllys char *fullpath; 94099ebb4caSwyllys int outbuflen; 94199ebb4caSwyllys int len; 94299ebb4caSwyllys KMF_ENCODE_FORMAT format; 94399ebb4caSwyllys 94499ebb4caSwyllys if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) { 94599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 94699ebb4caSwyllys } 94799ebb4caSwyllys 94899ebb4caSwyllys /* 94999ebb4caSwyllys * check if the cert output format is supported by OPENSSL. 95099ebb4caSwyllys * however, since the keystore for OPENSSL is just a file, we have 95199ebb4caSwyllys * no way to store the format along with the file. 95299ebb4caSwyllys */ 95399ebb4caSwyllys format = params->sslparms.format; 95499ebb4caSwyllys if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) 95599ebb4caSwyllys return (KMF_ERR_BAD_CERT_FORMAT); 95699ebb4caSwyllys 95799ebb4caSwyllys 95899ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 95999ebb4caSwyllys params->sslparms.certfile); 96099ebb4caSwyllys if (fullpath == NULL) 96199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 96299ebb4caSwyllys 96399ebb4caSwyllys /* 96499ebb4caSwyllys * When storing a certificate, you must specify a filename. 96599ebb4caSwyllys */ 96699ebb4caSwyllys if (isdir(fullpath)) { 96799ebb4caSwyllys free(fullpath); 96899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 96999ebb4caSwyllys } 97099ebb4caSwyllys 97199ebb4caSwyllys /* copy cert data to outbuf */ 97299ebb4caSwyllys outbuflen = pcert->Length; 97399ebb4caSwyllys outbuf = malloc(outbuflen); 97499ebb4caSwyllys if (outbuf == NULL) { 97599ebb4caSwyllys free(fullpath); 97699ebb4caSwyllys return (KMF_ERR_MEMORY); 97799ebb4caSwyllys } 97899ebb4caSwyllys (void) memcpy(outbuf, pcert->Data, pcert->Length); 97999ebb4caSwyllys 98099ebb4caSwyllys if ((fp = fopen(fullpath, "w")) == 98199ebb4caSwyllys NULL) { 98299ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 98399ebb4caSwyllys ret = KMF_ERR_INTERNAL; 98499ebb4caSwyllys goto out; 98599ebb4caSwyllys } 98699ebb4caSwyllys 98799ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 98899ebb4caSwyllys len = fwrite(outbuf, 1, outbuflen, fp); 98999ebb4caSwyllys if (len != outbuflen) { 99099ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 99199ebb4caSwyllys ret = KMF_ERR_WRITE_FILE; 99299ebb4caSwyllys } else { 99399ebb4caSwyllys ret = KMF_OK; 99499ebb4caSwyllys } 99599ebb4caSwyllys goto out; 99699ebb4caSwyllys } 99799ebb4caSwyllys 99899ebb4caSwyllys /* 99999ebb4caSwyllys * The output format is not KMF_FORMAT_ASN1, so we will 100099ebb4caSwyllys * Convert the cert data to OpenSSL internal X509 first. 100199ebb4caSwyllys */ 100299ebb4caSwyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 100399ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen); 100499ebb4caSwyllys if (xcert == NULL) { 100599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 100699ebb4caSwyllys ret = KMF_ERR_ENCODING; 100799ebb4caSwyllys goto out; 100899ebb4caSwyllys } 100999ebb4caSwyllys 101099ebb4caSwyllys if (format == KMF_FORMAT_PEM) { 101199ebb4caSwyllys /* Convert to the PEM format and write it out */ 101299ebb4caSwyllys if (!PEM_write_X509(fp, xcert)) { 101399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 101499ebb4caSwyllys ret = KMF_ERR_ENCODING; 101599ebb4caSwyllys } else { 101699ebb4caSwyllys ret = KMF_OK; 101799ebb4caSwyllys } 101899ebb4caSwyllys goto out; 101999ebb4caSwyllys } 102099ebb4caSwyllys 102199ebb4caSwyllys out: 102299ebb4caSwyllys if (fullpath != NULL) 102399ebb4caSwyllys free(fullpath); 102499ebb4caSwyllys 102599ebb4caSwyllys if (outbuf != NULL) { 102699ebb4caSwyllys free(outbuf); 102799ebb4caSwyllys } 102899ebb4caSwyllys if (fp != NULL) { 102999ebb4caSwyllys (void) fclose(fp); 103099ebb4caSwyllys } 103199ebb4caSwyllys 103299ebb4caSwyllys if (xcert != NULL) { 103399ebb4caSwyllys X509_free(xcert); 103499ebb4caSwyllys } 103599ebb4caSwyllys 103699ebb4caSwyllys return (ret); 103799ebb4caSwyllys } 103899ebb4caSwyllys 103999ebb4caSwyllys KMF_RETURN 104099ebb4caSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) 104199ebb4caSwyllys { 104299ebb4caSwyllys KMF_RETURN rv; 104399ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 104499ebb4caSwyllys char *fullpath = NULL; 104599ebb4caSwyllys KMF_DATA certdata = {NULL, 0}; 104699ebb4caSwyllys 104799ebb4caSwyllys if (params == NULL) { 104899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 104999ebb4caSwyllys } 105099ebb4caSwyllys 105199ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 105299ebb4caSwyllys params->sslparms.certfile); 105399ebb4caSwyllys 105499ebb4caSwyllys if (fullpath == NULL) 105599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 105699ebb4caSwyllys 105799ebb4caSwyllys if (isdir(fullpath)) { 105899ebb4caSwyllys DIR *dirp; 105999ebb4caSwyllys struct dirent *dp; 106099ebb4caSwyllys 106199ebb4caSwyllys /* open all files in the directory and attempt to read them */ 106299ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 106399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 106499ebb4caSwyllys } 106599ebb4caSwyllys 106699ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 106799ebb4caSwyllys if (strcmp(dp->d_name, ".") != 0 && 106899ebb4caSwyllys strcmp(dp->d_name, "..") != 0) { 106999ebb4caSwyllys char *fname; 107099ebb4caSwyllys 107199ebb4caSwyllys fname = get_fullpath(fullpath, 107299ebb4caSwyllys (char *)&dp->d_name); 107399ebb4caSwyllys 107499ebb4caSwyllys if (fname == NULL) { 107599ebb4caSwyllys rv = KMF_ERR_MEMORY; 107699ebb4caSwyllys break; 107799ebb4caSwyllys } 107899ebb4caSwyllys 107999ebb4caSwyllys rv = kmf_load_cert(kmfh, params, fname, 108099ebb4caSwyllys &certdata); 108199ebb4caSwyllys 108299ebb4caSwyllys if (rv == KMF_ERR_CERT_NOT_FOUND) { 108399ebb4caSwyllys free(fname); 108499ebb4caSwyllys if (certdata.Data) 108599ebb4caSwyllys free(certdata.Data); 108699ebb4caSwyllys rv = KMF_OK; 108799ebb4caSwyllys continue; 108899ebb4caSwyllys } else if (rv != KMF_OK) { 108999ebb4caSwyllys free(fname); 109099ebb4caSwyllys break; 109199ebb4caSwyllys } 109299ebb4caSwyllys 109399ebb4caSwyllys if (unlink(fname) != 0) { 109499ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 109599ebb4caSwyllys rv = KMF_ERR_INTERNAL; 109699ebb4caSwyllys free(fname); 109799ebb4caSwyllys break; 109899ebb4caSwyllys } 109999ebb4caSwyllys free(fname); 110099ebb4caSwyllys if (certdata.Data) 110199ebb4caSwyllys free(certdata.Data); 110299ebb4caSwyllys } 110399ebb4caSwyllys } 110499ebb4caSwyllys (void) closedir(dirp); 110599ebb4caSwyllys } else { 110699ebb4caSwyllys /* Just try to load a single certificate */ 110799ebb4caSwyllys rv = kmf_load_cert(kmfh, params, fullpath, &certdata); 110899ebb4caSwyllys if (rv == KMF_OK) { 110999ebb4caSwyllys if (unlink(fullpath) != 0) { 111099ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 111199ebb4caSwyllys rv = KMF_ERR_INTERNAL; 111299ebb4caSwyllys } 111399ebb4caSwyllys } 111499ebb4caSwyllys } 111599ebb4caSwyllys 111699ebb4caSwyllys out: 111799ebb4caSwyllys if (fullpath != NULL) 111899ebb4caSwyllys free(fullpath); 111999ebb4caSwyllys 112099ebb4caSwyllys if (certdata.Data) 112199ebb4caSwyllys free(certdata.Data); 112299ebb4caSwyllys 112399ebb4caSwyllys return (rv); 112499ebb4caSwyllys } 112599ebb4caSwyllys 112699ebb4caSwyllys KMF_RETURN 112799ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 112899ebb4caSwyllys KMF_DATA *keydata) 112999ebb4caSwyllys { 113099ebb4caSwyllys KMF_RETURN rv = KMF_OK; 113199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 113299ebb4caSwyllys int n; 113399ebb4caSwyllys 113499ebb4caSwyllys if (key == NULL || keydata == NULL || 113599ebb4caSwyllys key->keyp == NULL) 113699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 113799ebb4caSwyllys 113899ebb4caSwyllys if (key->keyalg == KMF_RSA) { 113999ebb4caSwyllys RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp); 114099ebb4caSwyllys 114199ebb4caSwyllys if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) { 114299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 114399ebb4caSwyllys return (KMF_ERR_ENCODING); 114499ebb4caSwyllys } 114599ebb4caSwyllys RSA_free(pubkey); 114699ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 114799ebb4caSwyllys DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp); 114899ebb4caSwyllys 114999ebb4caSwyllys if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) { 115099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 115199ebb4caSwyllys return (KMF_ERR_ENCODING); 115299ebb4caSwyllys } 115399ebb4caSwyllys DSA_free(pubkey); 115499ebb4caSwyllys } else { 115599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 115699ebb4caSwyllys } 115799ebb4caSwyllys keydata->Length = n; 115899ebb4caSwyllys 115999ebb4caSwyllys cleanup: 116099ebb4caSwyllys if (rv != KMF_OK) { 116199ebb4caSwyllys if (keydata->Data) 116299ebb4caSwyllys free(keydata->Data); 116399ebb4caSwyllys keydata->Data = NULL; 116499ebb4caSwyllys keydata->Length = 0; 116599ebb4caSwyllys } 116699ebb4caSwyllys 116799ebb4caSwyllys return (rv); 116899ebb4caSwyllys } 116999ebb4caSwyllys 117099ebb4caSwyllys static KMF_RETURN 117199ebb4caSwyllys ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, 117299ebb4caSwyllys KMF_CREDENTIAL *cred, EVP_PKEY *pkey) 117399ebb4caSwyllys { 117499ebb4caSwyllys int rv = 0; 117599ebb4caSwyllys RSA *rsa; 117699ebb4caSwyllys DSA *dsa; 117799ebb4caSwyllys 117899ebb4caSwyllys switch (format) { 117999ebb4caSwyllys case KMF_FORMAT_ASN1: 118099ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 118199ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 118299ebb4caSwyllys rv = i2d_RSAPrivateKey_bio(out, rsa); 118399ebb4caSwyllys RSA_free(rsa); 118499ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 118599ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 118699ebb4caSwyllys rv = i2d_DSAPrivateKey_bio(out, dsa); 118799ebb4caSwyllys DSA_free(dsa); 118899ebb4caSwyllys } 118999ebb4caSwyllys if (rv == 1) { 119099ebb4caSwyllys rv = KMF_OK; 119199ebb4caSwyllys } else { 119299ebb4caSwyllys SET_ERROR(kmfh, rv); 119399ebb4caSwyllys } 119499ebb4caSwyllys break; 119599ebb4caSwyllys case KMF_FORMAT_PEM: 119699ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 119799ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 119899ebb4caSwyllys rv = PEM_write_bio_RSAPrivateKey(out, 119999ebb4caSwyllys rsa, 120099ebb4caSwyllys NULL /* encryption type */, 120199ebb4caSwyllys NULL, 0, NULL, 120299ebb4caSwyllys cred->cred); 120399ebb4caSwyllys RSA_free(rsa); 120499ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 120599ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 120699ebb4caSwyllys rv = PEM_write_bio_DSAPrivateKey(out, 120799ebb4caSwyllys dsa, 120899ebb4caSwyllys NULL /* encryption type */, 120999ebb4caSwyllys NULL, 0, NULL, 121099ebb4caSwyllys cred->cred); 121199ebb4caSwyllys DSA_free(dsa); 121299ebb4caSwyllys } 121399ebb4caSwyllys 121499ebb4caSwyllys if (rv == 1) { 121599ebb4caSwyllys rv = KMF_OK; 121699ebb4caSwyllys } else { 121799ebb4caSwyllys SET_ERROR(kmfh, rv); 121899ebb4caSwyllys } 121999ebb4caSwyllys break; 122099ebb4caSwyllys 122199ebb4caSwyllys default: 122299ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 122399ebb4caSwyllys } 122499ebb4caSwyllys 122599ebb4caSwyllys return (rv); 122699ebb4caSwyllys } 122799ebb4caSwyllys 122899ebb4caSwyllys KMF_RETURN 122999ebb4caSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, 123099ebb4caSwyllys KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) 123199ebb4caSwyllys { 123299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 123399ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 123499ebb4caSwyllys int format; 123599ebb4caSwyllys uint32_t eValue = 0x010001; 123699ebb4caSwyllys RSA *sslPrivKey = NULL; 123799ebb4caSwyllys DSA *sslDSAKey = NULL; 123899ebb4caSwyllys EVP_PKEY *eprikey = NULL; 123999ebb4caSwyllys EVP_PKEY *epubkey = NULL; 124099ebb4caSwyllys BIO *out = NULL; 124199ebb4caSwyllys char *fullpath = NULL; 124299ebb4caSwyllys 124399ebb4caSwyllys if (params == NULL || params->sslparms.keyfile == NULL) { 124499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 124599ebb4caSwyllys } 124699ebb4caSwyllys 124799ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 124899ebb4caSwyllys params->sslparms.keyfile); 124999ebb4caSwyllys 125099ebb4caSwyllys if (fullpath == NULL) 125199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 125299ebb4caSwyllys 125399ebb4caSwyllys /* If the requested file exists, return an error */ 125499ebb4caSwyllys if (access(fullpath, F_OK) == 0) { 125599ebb4caSwyllys free(fullpath); 125699ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 125799ebb4caSwyllys } 125899ebb4caSwyllys 125999ebb4caSwyllys eprikey = EVP_PKEY_new(); 126099ebb4caSwyllys if (eprikey == NULL) { 126199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 126299ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 126399ebb4caSwyllys goto cleanup; 126499ebb4caSwyllys } 126599ebb4caSwyllys epubkey = EVP_PKEY_new(); 126699ebb4caSwyllys if (epubkey == NULL) { 126799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 126899ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 126999ebb4caSwyllys goto cleanup; 127099ebb4caSwyllys } 127199ebb4caSwyllys if (params->keytype == KMF_RSA) { 127299ebb4caSwyllys if (params->rsa_exponent.len > 0 && 127399ebb4caSwyllys params->rsa_exponent.len <= sizeof (eValue) && 127499ebb4caSwyllys params->rsa_exponent.val != NULL) 127599ebb4caSwyllys /*LINTED*/ 127699ebb4caSwyllys eValue = *(uint32_t *)params->rsa_exponent.val; 127799ebb4caSwyllys 127899ebb4caSwyllys sslPrivKey = RSA_generate_key(params->keylength, eValue, 127999ebb4caSwyllys NULL, NULL); 128099ebb4caSwyllys if (sslPrivKey == NULL) { 128199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 128299ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 128399ebb4caSwyllys } else { 128499ebb4caSwyllys if (privkey != NULL && 128599ebb4caSwyllys EVP_PKEY_set1_RSA(eprikey, sslPrivKey)) { 128699ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 128799ebb4caSwyllys privkey->keyalg = KMF_RSA; 128899ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 128999ebb4caSwyllys privkey->israw = FALSE; 129099ebb4caSwyllys privkey->keylabel = (char *)strdup(fullpath); 129199ebb4caSwyllys privkey->keyp = (void *)eprikey; 129299ebb4caSwyllys } 129399ebb4caSwyllys /* OpenSSL derives the public key from the private */ 129499ebb4caSwyllys if (pubkey != NULL && 129599ebb4caSwyllys EVP_PKEY_set1_RSA(epubkey, sslPrivKey)) { 129699ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 129799ebb4caSwyllys pubkey->keyalg = KMF_RSA; 129899ebb4caSwyllys pubkey->israw = FALSE; 129999ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 130099ebb4caSwyllys pubkey->keylabel = (char *)strdup(fullpath); 130199ebb4caSwyllys pubkey->keyp = (void *)epubkey; 130299ebb4caSwyllys } 130399ebb4caSwyllys } 130499ebb4caSwyllys } else if (params->keytype == KMF_DSA) { 130599ebb4caSwyllys sslDSAKey = DSA_new(); 130699ebb4caSwyllys if (sslDSAKey == NULL) { 130799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 130899ebb4caSwyllys return (KMF_ERR_MEMORY); 130999ebb4caSwyllys } 131099ebb4caSwyllys 131199ebb4caSwyllys if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) == 131299ebb4caSwyllys NULL) { 131399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 131499ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 131599ebb4caSwyllys goto cleanup; 131699ebb4caSwyllys } 131799ebb4caSwyllys if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) == 131899ebb4caSwyllys NULL) { 131999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 132099ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 132199ebb4caSwyllys goto cleanup; 132299ebb4caSwyllys } 132399ebb4caSwyllys if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) == 132499ebb4caSwyllys NULL) { 132599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 132699ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 132799ebb4caSwyllys goto cleanup; 132899ebb4caSwyllys } 132999ebb4caSwyllys 133099ebb4caSwyllys if (!DSA_generate_key(sslDSAKey)) { 133199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 133299ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 133399ebb4caSwyllys goto cleanup; 133499ebb4caSwyllys } 133599ebb4caSwyllys 133699ebb4caSwyllys if (privkey != NULL) { 133799ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 133899ebb4caSwyllys privkey->keyalg = KMF_DSA; 133999ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 134099ebb4caSwyllys privkey->israw = FALSE; 134199ebb4caSwyllys privkey->keylabel = (char *)strdup(fullpath); 134299ebb4caSwyllys if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { 134399ebb4caSwyllys privkey->keyp = (void *)eprikey; 134499ebb4caSwyllys } else { 134599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 134699ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 134799ebb4caSwyllys goto cleanup; 134899ebb4caSwyllys } 134999ebb4caSwyllys } 135099ebb4caSwyllys if (pubkey != NULL) { 135199ebb4caSwyllys DSA *dp = DSA_new(); 135299ebb4caSwyllys /* Make a copy for the public key */ 135399ebb4caSwyllys if (dp != NULL) { 135499ebb4caSwyllys if ((dp->p = BN_new()) == NULL) { 135599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 135699ebb4caSwyllys rv = KMF_ERR_MEMORY; 135799ebb4caSwyllys DSA_free(dp); 135899ebb4caSwyllys goto cleanup; 135999ebb4caSwyllys } 136099ebb4caSwyllys if ((dp->q = BN_new()) == NULL) { 136199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 136299ebb4caSwyllys rv = KMF_ERR_MEMORY; 136399ebb4caSwyllys BN_free(dp->p); 136499ebb4caSwyllys DSA_free(dp); 136599ebb4caSwyllys goto cleanup; 136699ebb4caSwyllys } 136799ebb4caSwyllys if ((dp->g = BN_new()) == NULL) { 136899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 136999ebb4caSwyllys rv = KMF_ERR_MEMORY; 137099ebb4caSwyllys BN_free(dp->q); 137199ebb4caSwyllys BN_free(dp->p); 137299ebb4caSwyllys DSA_free(dp); 137399ebb4caSwyllys goto cleanup; 137499ebb4caSwyllys } 137599ebb4caSwyllys if ((dp->pub_key = BN_new()) == NULL) { 137699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 137799ebb4caSwyllys rv = KMF_ERR_MEMORY; 137899ebb4caSwyllys BN_free(dp->q); 137999ebb4caSwyllys BN_free(dp->p); 138099ebb4caSwyllys BN_free(dp->g); 138199ebb4caSwyllys DSA_free(dp); 138299ebb4caSwyllys goto cleanup; 138399ebb4caSwyllys } 138499ebb4caSwyllys (void) BN_copy(dp->p, sslDSAKey->p); 138599ebb4caSwyllys (void) BN_copy(dp->q, sslDSAKey->q); 138699ebb4caSwyllys (void) BN_copy(dp->g, sslDSAKey->g); 138799ebb4caSwyllys (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); 138899ebb4caSwyllys 138999ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 139099ebb4caSwyllys pubkey->keyalg = KMF_DSA; 139199ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 139299ebb4caSwyllys pubkey->israw = FALSE; 139399ebb4caSwyllys pubkey->keylabel = (char *)strdup(fullpath); 139499ebb4caSwyllys 139599ebb4caSwyllys if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { 139699ebb4caSwyllys pubkey->keyp = (void *)epubkey; 139799ebb4caSwyllys } else { 139899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 139999ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 140099ebb4caSwyllys goto cleanup; 140199ebb4caSwyllys } 140299ebb4caSwyllys } 140399ebb4caSwyllys } 140499ebb4caSwyllys } 140599ebb4caSwyllys 140699ebb4caSwyllys if (rv != KMF_OK) { 140799ebb4caSwyllys goto cleanup; 140899ebb4caSwyllys } 140999ebb4caSwyllys 141099ebb4caSwyllys /* Store the private key to the keyfile */ 141199ebb4caSwyllys format = params->sslparms.format; 141299ebb4caSwyllys out = BIO_new_file(fullpath, "wb"); 141399ebb4caSwyllys if (out == NULL) { 141499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 141599ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 141699ebb4caSwyllys goto cleanup; 141799ebb4caSwyllys } 141899ebb4caSwyllys rv = ssl_write_private_key(kmfh, format, out, ¶ms->cred, eprikey); 141999ebb4caSwyllys 142099ebb4caSwyllys cleanup: 142199ebb4caSwyllys if (rv != KMF_OK) { 142299ebb4caSwyllys if (eprikey != NULL) 142399ebb4caSwyllys EVP_PKEY_free(eprikey); 142499ebb4caSwyllys 142599ebb4caSwyllys if (epubkey != NULL) 142699ebb4caSwyllys EVP_PKEY_free(epubkey); 142799ebb4caSwyllys 142899ebb4caSwyllys if (pubkey->keylabel) { 142999ebb4caSwyllys free(pubkey->keylabel); 143099ebb4caSwyllys pubkey->keylabel = NULL; 143199ebb4caSwyllys } 143299ebb4caSwyllys 143399ebb4caSwyllys if (privkey->keylabel) { 143499ebb4caSwyllys free(privkey->keylabel); 143599ebb4caSwyllys privkey->keylabel = NULL; 143699ebb4caSwyllys } 143799ebb4caSwyllys 143899ebb4caSwyllys pubkey->keyp = NULL; 143999ebb4caSwyllys privkey->keyp = NULL; 144099ebb4caSwyllys } 144199ebb4caSwyllys 144299ebb4caSwyllys if (sslPrivKey) 144399ebb4caSwyllys RSA_free(sslPrivKey); 144499ebb4caSwyllys 144599ebb4caSwyllys if (sslDSAKey) 144699ebb4caSwyllys DSA_free(sslDSAKey); 144799ebb4caSwyllys 144899ebb4caSwyllys 144999ebb4caSwyllys if (out != NULL) 145099ebb4caSwyllys (void) BIO_free(out); 145199ebb4caSwyllys 145299ebb4caSwyllys if (fullpath) 145399ebb4caSwyllys free(fullpath); 145499ebb4caSwyllys 145599ebb4caSwyllys /* Protect the file by making it read-only */ 145699ebb4caSwyllys if (rv == KMF_OK) { 145799ebb4caSwyllys (void) chmod(fullpath, 0400); 145899ebb4caSwyllys } 145999ebb4caSwyllys return (rv); 146099ebb4caSwyllys } 146199ebb4caSwyllys 146299ebb4caSwyllys KMF_RETURN 146399ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 146499ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output) 146599ebb4caSwyllys { 146699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 146799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 146899ebb4caSwyllys KMF_ALGORITHM_INDEX AlgId; 146999ebb4caSwyllys EVP_MD_CTX ctx; 147099ebb4caSwyllys const EVP_MD *md; 147199ebb4caSwyllys if (key == NULL || AlgOID == NULL || 147299ebb4caSwyllys tobesigned == NULL || output == NULL || 147399ebb4caSwyllys tobesigned->Data == NULL || 147499ebb4caSwyllys output->Data == NULL) 147599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 147699ebb4caSwyllys 147799ebb4caSwyllys /* Map the OID to an OpenSSL algorithm */ 147899ebb4caSwyllys AlgId = X509_AlgorithmOidToAlgId(AlgOID); 147999ebb4caSwyllys if (AlgId == KMF_ALGID_NONE) 148099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 148199ebb4caSwyllys 148299ebb4caSwyllys if (key->keyalg == KMF_RSA) { 148399ebb4caSwyllys EVP_PKEY *pkey = (EVP_PKEY *)key->keyp; 148499ebb4caSwyllys uchar_t *p; 148599ebb4caSwyllys uint32_t len; 148699ebb4caSwyllys if (AlgId == KMF_ALGID_MD5WithRSA) 148799ebb4caSwyllys md = EVP_md5(); 148899ebb4caSwyllys else if (AlgId == KMF_ALGID_MD2WithRSA) 148999ebb4caSwyllys md = EVP_md2(); 149099ebb4caSwyllys else if (AlgId == KMF_ALGID_SHA1WithRSA) 149199ebb4caSwyllys md = EVP_sha1(); 149299ebb4caSwyllys else 149399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 149499ebb4caSwyllys 149599ebb4caSwyllys if (md == NULL) { 149699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 149799ebb4caSwyllys return (KMF_ERR_MEMORY); 149899ebb4caSwyllys } 149999ebb4caSwyllys 150099ebb4caSwyllys (void) EVP_MD_CTX_init(&ctx); 150199ebb4caSwyllys (void) EVP_SignInit_ex(&ctx, md, NULL); 150299ebb4caSwyllys (void) EVP_SignUpdate(&ctx, tobesigned->Data, 150399ebb4caSwyllys (uint32_t)tobesigned->Length); 150499ebb4caSwyllys len = (uint32_t)output->Length; 150599ebb4caSwyllys p = output->Data; 150699ebb4caSwyllys if (!EVP_SignFinal(&ctx, p, &len, pkey)) { 150799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 150899ebb4caSwyllys output->Length = 0; 150999ebb4caSwyllys } 151099ebb4caSwyllys output->Length = len; 151199ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 151299ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 151399ebb4caSwyllys DSA *dsa = EVP_PKEY_get1_DSA(key->keyp); 151499ebb4caSwyllys 151599ebb4caSwyllys uchar_t hash[EVP_MAX_MD_SIZE]; 151699ebb4caSwyllys uint32_t hashlen; 151799ebb4caSwyllys DSA_SIG *dsasig; 151899ebb4caSwyllys 151999ebb4caSwyllys /* 152099ebb4caSwyllys * OpenSSL EVP_Sign operation automatically converts to 152199ebb4caSwyllys * ASN.1 output so we do the operations separately so we 152299ebb4caSwyllys * are assured of NOT getting ASN.1 output returned. 152399ebb4caSwyllys * KMF does not want ASN.1 encoded results because 152499ebb4caSwyllys * not all mechanisms return ASN.1 encodings (PKCS#11 152599ebb4caSwyllys * and NSS return raw signature data). 152699ebb4caSwyllys */ 152799ebb4caSwyllys md = EVP_sha1(); 152899ebb4caSwyllys EVP_MD_CTX_init(&ctx); 152999ebb4caSwyllys (void) EVP_DigestInit_ex(&ctx, md, NULL); 153099ebb4caSwyllys (void) EVP_DigestUpdate(&ctx, tobesigned->Data, 153199ebb4caSwyllys tobesigned->Length); 153299ebb4caSwyllys (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen); 153399ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 153499ebb4caSwyllys 153599ebb4caSwyllys dsasig = DSA_do_sign(hash, hashlen, dsa); 153699ebb4caSwyllys if (dsasig != NULL) { 153799ebb4caSwyllys int i; 153899ebb4caSwyllys output->Length = i = BN_bn2bin(dsasig->r, output->Data); 153999ebb4caSwyllys output->Length += BN_bn2bin(dsasig->s, 154099ebb4caSwyllys &output->Data[i]); 154199ebb4caSwyllys DSA_SIG_free(dsasig); 154299ebb4caSwyllys } else { 154399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 154499ebb4caSwyllys } 154599ebb4caSwyllys } else { 154699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 154799ebb4caSwyllys } 154899ebb4caSwyllys cleanup: 154999ebb4caSwyllys return (ret); 155099ebb4caSwyllys } 155199ebb4caSwyllys 155299ebb4caSwyllys KMF_RETURN 155399ebb4caSwyllys /*ARGSUSED*/ 155499ebb4caSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, 155599ebb4caSwyllys KMF_KEY_HANDLE *key, boolean_t destroy) 155699ebb4caSwyllys { 155799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 155899ebb4caSwyllys if (key == NULL || key->keyp == NULL) 155999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 156099ebb4caSwyllys 156199ebb4caSwyllys if (key->keyclass != KMF_ASYM_PUB && 156299ebb4caSwyllys key->keyclass != KMF_ASYM_PRI && 156399ebb4caSwyllys key->keyclass != KMF_SYMMETRIC) 156499ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 156599ebb4caSwyllys 156699ebb4caSwyllys if (key->keyclass == KMF_SYMMETRIC) { 156799ebb4caSwyllys KMF_FreeRawSymKey((KMF_RAW_SYM_KEY *)key->keyp); 156899ebb4caSwyllys key->keyp = NULL; 156999ebb4caSwyllys } else { 157099ebb4caSwyllys if (key->keyp != NULL) { 157199ebb4caSwyllys EVP_PKEY_free(key->keyp); 157299ebb4caSwyllys key->keyp = NULL; 157399ebb4caSwyllys } 157499ebb4caSwyllys } 157599ebb4caSwyllys 157699ebb4caSwyllys if (key->keylabel != NULL) { 157799ebb4caSwyllys EVP_PKEY *pkey = NULL; 157899ebb4caSwyllys /* If the file exists, make sure it is a proper key. */ 157999ebb4caSwyllys pkey = openssl_load_key(handle, key->keylabel); 158099ebb4caSwyllys if (pkey == NULL) { 158199ebb4caSwyllys free(key->keylabel); 158299ebb4caSwyllys key->keylabel = NULL; 158399ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 158499ebb4caSwyllys } 158599ebb4caSwyllys EVP_PKEY_free(pkey); 158699ebb4caSwyllys 158799ebb4caSwyllys if (destroy) { 158899ebb4caSwyllys if (unlink(key->keylabel) != 0) { 158999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 159099ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 159199ebb4caSwyllys rv = KMF_ERR_INTERNAL; 159299ebb4caSwyllys } 159399ebb4caSwyllys } 159499ebb4caSwyllys if (key->keylabel != NULL) { 159599ebb4caSwyllys free(key->keylabel); 159699ebb4caSwyllys key->keylabel = NULL; 159799ebb4caSwyllys } 159899ebb4caSwyllys } 159999ebb4caSwyllys return (rv); 160099ebb4caSwyllys } 160199ebb4caSwyllys 160299ebb4caSwyllys KMF_RETURN 160399ebb4caSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) 160499ebb4caSwyllys { 160599ebb4caSwyllys KMF_RETURN ret = KMF_OK; 160699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 160799ebb4caSwyllys X509_CRL *xcrl = NULL; 160899ebb4caSwyllys X509 *xcert = NULL; 160999ebb4caSwyllys EVP_PKEY *pkey; 161099ebb4caSwyllys KMF_ENCODE_FORMAT format; 161199ebb4caSwyllys BIO *in = NULL, *out = NULL; 161299ebb4caSwyllys int openssl_ret = 0; 161399ebb4caSwyllys char *outcrlfile = NULL; 161499ebb4caSwyllys KMF_ENCODE_FORMAT outformat; 161599ebb4caSwyllys 161699ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL) { 161799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 161899ebb4caSwyllys } 161999ebb4caSwyllys 162099ebb4caSwyllys if (params->sslparms.crl_check == B_TRUE && 162199ebb4caSwyllys params->sslparms.certfile == NULL) { 162299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 162399ebb4caSwyllys } 162499ebb4caSwyllys 162599ebb4caSwyllys outcrlfile = get_fullpath(params->sslparms.dirpath, 162699ebb4caSwyllys params->sslparms.outcrlfile); 162799ebb4caSwyllys 162899ebb4caSwyllys if (outcrlfile == NULL) 162999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 163099ebb4caSwyllys 163199ebb4caSwyllys if (isdir(outcrlfile)) { 163299ebb4caSwyllys free(outcrlfile); 163399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 163499ebb4caSwyllys } 163599ebb4caSwyllys 163699ebb4caSwyllys ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); 163799ebb4caSwyllys if (ret != KMF_OK) { 163899ebb4caSwyllys free(outcrlfile); 163999ebb4caSwyllys return (ret); 164099ebb4caSwyllys } 164199ebb4caSwyllys 164299ebb4caSwyllys in = BIO_new_file(params->sslparms.crlfile, "rb"); 164399ebb4caSwyllys if (in == NULL) { 164499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 164599ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 164699ebb4caSwyllys goto end; 164799ebb4caSwyllys } 164899ebb4caSwyllys 164999ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 165099ebb4caSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 165199ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 165299ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 165399ebb4caSwyllys } 165499ebb4caSwyllys 165599ebb4caSwyllys if (xcrl == NULL) { 165699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 165799ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 165899ebb4caSwyllys goto end; 165999ebb4caSwyllys } 166099ebb4caSwyllys 166199ebb4caSwyllys /* If bypasscheck is specified, no need to verify. */ 166299ebb4caSwyllys if (params->sslparms.crl_check == B_FALSE) { 166399ebb4caSwyllys goto output; 166499ebb4caSwyllys } 166599ebb4caSwyllys 166699ebb4caSwyllys ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); 166799ebb4caSwyllys if (ret != KMF_OK) 166899ebb4caSwyllys goto end; 166999ebb4caSwyllys 167099ebb4caSwyllys /* Read in the CA cert file and convert to X509 */ 167199ebb4caSwyllys if (BIO_read_filename(in, params->sslparms.certfile) <= 0) { 167299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 167399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 167499ebb4caSwyllys goto end; 167599ebb4caSwyllys } 167699ebb4caSwyllys 167799ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 167899ebb4caSwyllys xcert = d2i_X509_bio(in, NULL); 167999ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 168099ebb4caSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 168199ebb4caSwyllys } else { 168299ebb4caSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 168399ebb4caSwyllys goto end; 168499ebb4caSwyllys } 168599ebb4caSwyllys 168699ebb4caSwyllys if (xcert == NULL) { 168799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 168899ebb4caSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 168999ebb4caSwyllys goto end; 169099ebb4caSwyllys } 169199ebb4caSwyllys /* Now get the public key from the CA cert */ 169299ebb4caSwyllys pkey = X509_get_pubkey(xcert); 169399ebb4caSwyllys if (!pkey) { 169499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 169599ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 169699ebb4caSwyllys goto end; 169799ebb4caSwyllys } 169899ebb4caSwyllys 169999ebb4caSwyllys /* Verify the CRL with the CA's public key */ 170099ebb4caSwyllys openssl_ret = X509_CRL_verify(xcrl, pkey); 170199ebb4caSwyllys EVP_PKEY_free(pkey); 170299ebb4caSwyllys if (openssl_ret > 0) { 170399ebb4caSwyllys ret = KMF_OK; /* verify succeed */ 170499ebb4caSwyllys } else { 170599ebb4caSwyllys SET_ERROR(kmfh, openssl_ret); 170699ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 170799ebb4caSwyllys } 170899ebb4caSwyllys 170999ebb4caSwyllys output: 171099ebb4caSwyllys outformat = params->sslparms.format; 171199ebb4caSwyllys 171299ebb4caSwyllys out = BIO_new_file(outcrlfile, "wb"); 171399ebb4caSwyllys if (out == NULL) { 171499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 171599ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 171699ebb4caSwyllys goto end; 171799ebb4caSwyllys } 171899ebb4caSwyllys 171999ebb4caSwyllys if (outformat == KMF_FORMAT_ASN1) { 172099ebb4caSwyllys openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); 172199ebb4caSwyllys } else if (outformat == KMF_FORMAT_PEM) { 172299ebb4caSwyllys openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); 172399ebb4caSwyllys } else { 172499ebb4caSwyllys ret = KMF_ERR_BAD_PARAMETER; 172599ebb4caSwyllys goto end; 172699ebb4caSwyllys } 172799ebb4caSwyllys 172899ebb4caSwyllys if (openssl_ret <= 0) { 172999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 173099ebb4caSwyllys ret = KMF_ERR_WRITE_FILE; 173199ebb4caSwyllys } else { 173299ebb4caSwyllys ret = KMF_OK; 173399ebb4caSwyllys } 173499ebb4caSwyllys 173599ebb4caSwyllys end: 173699ebb4caSwyllys if (xcrl != NULL) 173799ebb4caSwyllys X509_CRL_free(xcrl); 173899ebb4caSwyllys 173999ebb4caSwyllys if (xcert != NULL) 174099ebb4caSwyllys X509_free(xcert); 174199ebb4caSwyllys 174299ebb4caSwyllys if (in != NULL) 174399ebb4caSwyllys (void) BIO_free(in); 174499ebb4caSwyllys 174599ebb4caSwyllys if (out != NULL) 174699ebb4caSwyllys (void) BIO_free(out); 174799ebb4caSwyllys 174899ebb4caSwyllys if (outcrlfile != NULL) 174999ebb4caSwyllys free(outcrlfile); 175099ebb4caSwyllys 175199ebb4caSwyllys return (ret); 175299ebb4caSwyllys } 175399ebb4caSwyllys 175499ebb4caSwyllys KMF_RETURN 175599ebb4caSwyllys OpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, 175699ebb4caSwyllys char **crldata) 175799ebb4caSwyllys { 175899ebb4caSwyllys KMF_RETURN ret = KMF_OK; 175999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 176099ebb4caSwyllys X509_CRL *x = NULL; 176199ebb4caSwyllys KMF_ENCODE_FORMAT format; 176299ebb4caSwyllys char *crlfile = NULL; 176399ebb4caSwyllys BIO *in = NULL; 176499ebb4caSwyllys BIO *mem = NULL; 176599ebb4caSwyllys long len; 176699ebb4caSwyllys char *memptr; 176799ebb4caSwyllys char *data = NULL; 176899ebb4caSwyllys 176999ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL) { 177099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 177199ebb4caSwyllys } 177299ebb4caSwyllys 177399ebb4caSwyllys crlfile = get_fullpath(params->sslparms.dirpath, 177499ebb4caSwyllys params->sslparms.crlfile); 177599ebb4caSwyllys 177699ebb4caSwyllys if (crlfile == NULL) 177799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 177899ebb4caSwyllys 177999ebb4caSwyllys if (isdir(crlfile)) { 178099ebb4caSwyllys free(crlfile); 178199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 178299ebb4caSwyllys } 178399ebb4caSwyllys 178499ebb4caSwyllys ret = KMF_IsCRLFile(handle, crlfile, &format); 178599ebb4caSwyllys if (ret != KMF_OK) { 178699ebb4caSwyllys free(crlfile); 178799ebb4caSwyllys return (ret); 178899ebb4caSwyllys } 178999ebb4caSwyllys 179099ebb4caSwyllys if (bio_err == NULL) 179199ebb4caSwyllys bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 179299ebb4caSwyllys 179399ebb4caSwyllys in = BIO_new_file(crlfile, "rb"); 179499ebb4caSwyllys if (in == NULL) { 179599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 179699ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 179799ebb4caSwyllys goto end; 179899ebb4caSwyllys } 179999ebb4caSwyllys 180099ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 180199ebb4caSwyllys x = d2i_X509_CRL_bio(in, NULL); 180299ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 180399ebb4caSwyllys x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 180499ebb4caSwyllys } 180599ebb4caSwyllys 180699ebb4caSwyllys if (x == NULL) { /* should not happen */ 180799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 180899ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 180999ebb4caSwyllys goto end; 181099ebb4caSwyllys } 181199ebb4caSwyllys 181299ebb4caSwyllys mem = BIO_new(BIO_s_mem()); 181399ebb4caSwyllys if (mem == NULL) { 181499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 181599ebb4caSwyllys ret = KMF_ERR_MEMORY; 181699ebb4caSwyllys goto end; 181799ebb4caSwyllys } 181899ebb4caSwyllys 181999ebb4caSwyllys (void) X509_CRL_print(mem, x); 182099ebb4caSwyllys len = BIO_get_mem_data(mem, &memptr); 182199ebb4caSwyllys if (len <= 0) { 182299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 182399ebb4caSwyllys ret = KMF_ERR_MEMORY; 182499ebb4caSwyllys goto end; 182599ebb4caSwyllys } 182699ebb4caSwyllys 182799ebb4caSwyllys data = malloc(len + 1); 182899ebb4caSwyllys if (data == NULL) { 182999ebb4caSwyllys ret = KMF_ERR_MEMORY; 183099ebb4caSwyllys goto end; 183199ebb4caSwyllys } 183299ebb4caSwyllys 183399ebb4caSwyllys (void) memcpy(data, memptr, len); 183499ebb4caSwyllys data[len] = '\0'; 183599ebb4caSwyllys *crldata = data; 183699ebb4caSwyllys 183799ebb4caSwyllys end: 183899ebb4caSwyllys if (x != NULL) 183999ebb4caSwyllys X509_CRL_free(x); 184099ebb4caSwyllys 184199ebb4caSwyllys if (crlfile != NULL) 184299ebb4caSwyllys free(crlfile); 184399ebb4caSwyllys 184499ebb4caSwyllys if (in != NULL) 184599ebb4caSwyllys (void) BIO_free(in); 184699ebb4caSwyllys 184799ebb4caSwyllys if (mem != NULL) 184899ebb4caSwyllys (void) BIO_free(mem); 184999ebb4caSwyllys 185099ebb4caSwyllys return (ret); 185199ebb4caSwyllys } 185299ebb4caSwyllys 185399ebb4caSwyllys KMF_RETURN 185499ebb4caSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) 185599ebb4caSwyllys { 185699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 185799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 185899ebb4caSwyllys KMF_ENCODE_FORMAT format; 185999ebb4caSwyllys char *crlfile = NULL; 186099ebb4caSwyllys BIO *in = NULL; 186199ebb4caSwyllys 186299ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL) { 186399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 186499ebb4caSwyllys } 186599ebb4caSwyllys 186699ebb4caSwyllys crlfile = get_fullpath(params->sslparms.dirpath, 186799ebb4caSwyllys params->sslparms.crlfile); 186899ebb4caSwyllys 186999ebb4caSwyllys if (crlfile == NULL) 187099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 187199ebb4caSwyllys 187299ebb4caSwyllys if (isdir(crlfile)) { 187399ebb4caSwyllys ret = KMF_ERR_BAD_PARAMETER; 187499ebb4caSwyllys goto end; 187599ebb4caSwyllys } 187699ebb4caSwyllys 187799ebb4caSwyllys ret = KMF_IsCRLFile(handle, crlfile, &format); 187899ebb4caSwyllys if (ret != KMF_OK) 187999ebb4caSwyllys goto end; 188099ebb4caSwyllys 188199ebb4caSwyllys if (unlink(crlfile) != 0) { 188299ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 188399ebb4caSwyllys ret = KMF_ERR_INTERNAL; 188499ebb4caSwyllys goto end; 188599ebb4caSwyllys } 188699ebb4caSwyllys 188799ebb4caSwyllys end: 188899ebb4caSwyllys if (in != NULL) 188999ebb4caSwyllys (void) BIO_free(in); 189099ebb4caSwyllys if (crlfile != NULL) 189199ebb4caSwyllys free(crlfile); 189299ebb4caSwyllys 189399ebb4caSwyllys return (ret); 189499ebb4caSwyllys } 189599ebb4caSwyllys 189699ebb4caSwyllys 189799ebb4caSwyllys KMF_RETURN 189899ebb4caSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) 189999ebb4caSwyllys { 190099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 190199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 190299ebb4caSwyllys KMF_ENCODE_FORMAT format; 190399ebb4caSwyllys BIO *in = NULL; 190499ebb4caSwyllys X509 *xcert = NULL; 190599ebb4caSwyllys X509_CRL *xcrl = NULL; 190699ebb4caSwyllys STACK_OF(X509_REVOKED) *revoke_stack = NULL; 190799ebb4caSwyllys X509_REVOKED *revoke; 190899ebb4caSwyllys int i; 190999ebb4caSwyllys 191099ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL || 191199ebb4caSwyllys params->sslparms.certfile == NULL) { 191299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 191399ebb4caSwyllys } 191499ebb4caSwyllys 191599ebb4caSwyllys ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); 191699ebb4caSwyllys if (ret != KMF_OK) 191799ebb4caSwyllys return (ret); 191899ebb4caSwyllys 191999ebb4caSwyllys /* Read the CRL file and load it into a X509_CRL structure */ 192099ebb4caSwyllys in = BIO_new_file(params->sslparms.crlfile, "rb"); 192199ebb4caSwyllys if (in == NULL) { 192299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 192399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 192499ebb4caSwyllys goto end; 192599ebb4caSwyllys } 192699ebb4caSwyllys 192799ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 192899ebb4caSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 192999ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 193099ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 193199ebb4caSwyllys } 193299ebb4caSwyllys 193399ebb4caSwyllys if (xcrl == NULL) { 193499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 193599ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 193699ebb4caSwyllys goto end; 193799ebb4caSwyllys } 193899ebb4caSwyllys (void) BIO_free(in); 193999ebb4caSwyllys 194099ebb4caSwyllys /* Read the Certificate file and load it into a X509 structure */ 194199ebb4caSwyllys ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); 194299ebb4caSwyllys if (ret != KMF_OK) 194399ebb4caSwyllys goto end; 194499ebb4caSwyllys 194599ebb4caSwyllys in = BIO_new_file(params->sslparms.certfile, "rb"); 194699ebb4caSwyllys if (in == NULL) { 194799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 194899ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 194999ebb4caSwyllys goto end; 195099ebb4caSwyllys } 195199ebb4caSwyllys 195299ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 195399ebb4caSwyllys xcert = d2i_X509_bio(in, NULL); 195499ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 195599ebb4caSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 195699ebb4caSwyllys } 195799ebb4caSwyllys 195899ebb4caSwyllys if (xcert == NULL) { 195999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 196099ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 196199ebb4caSwyllys goto end; 196299ebb4caSwyllys } 196399ebb4caSwyllys 196499ebb4caSwyllys /* Check if the certificate and the CRL have same issuer */ 196599ebb4caSwyllys if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { 196699ebb4caSwyllys ret = KMF_ERR_ISSUER; 196799ebb4caSwyllys goto end; 196899ebb4caSwyllys } 196999ebb4caSwyllys 197099ebb4caSwyllys /* Check to see if the certificate serial number is revoked */ 197199ebb4caSwyllys revoke_stack = X509_CRL_get_REVOKED(xcrl); 197299ebb4caSwyllys if (sk_X509_REVOKED_num(revoke_stack) <= 0) { 197399ebb4caSwyllys /* No revoked certificates in the CRL file */ 197499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 197599ebb4caSwyllys ret = KMF_ERR_EMPTY_CRL; 197699ebb4caSwyllys goto end; 197799ebb4caSwyllys } 197899ebb4caSwyllys 197999ebb4caSwyllys for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { 198099ebb4caSwyllys /*LINTED*/ 198199ebb4caSwyllys revoke = sk_X509_REVOKED_value(revoke_stack, i); 198299ebb4caSwyllys if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, 198399ebb4caSwyllys revoke->serialNumber) == 0) { 198499ebb4caSwyllys break; 198599ebb4caSwyllys } 198699ebb4caSwyllys } 198799ebb4caSwyllys 198899ebb4caSwyllys if (i < sk_X509_REVOKED_num(revoke_stack)) { 198999ebb4caSwyllys ret = KMF_OK; 199099ebb4caSwyllys } else { 199199ebb4caSwyllys ret = KMF_ERR_NOT_REVOKED; 199299ebb4caSwyllys } 199399ebb4caSwyllys 199499ebb4caSwyllys end: 199599ebb4caSwyllys if (in != NULL) 199699ebb4caSwyllys (void) BIO_free(in); 199799ebb4caSwyllys if (xcrl != NULL) 199899ebb4caSwyllys X509_CRL_free(xcrl); 199999ebb4caSwyllys if (xcert != NULL) 200099ebb4caSwyllys X509_free(xcert); 200199ebb4caSwyllys 200299ebb4caSwyllys return (ret); 200399ebb4caSwyllys } 200499ebb4caSwyllys 200599ebb4caSwyllys KMF_RETURN 200699ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 200799ebb4caSwyllys { 200899ebb4caSwyllys KMF_RETURN ret = KMF_OK; 200999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 201099ebb4caSwyllys char str[256]; /* OpenSSL needs at least 120 byte buffer */ 201199ebb4caSwyllys 201299ebb4caSwyllys ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str)); 201399ebb4caSwyllys if (strlen(str)) { 201499ebb4caSwyllys *msgstr = (char *)strdup(str); 201599ebb4caSwyllys if ((*msgstr) == NULL) 201699ebb4caSwyllys ret = KMF_ERR_MEMORY; 201799ebb4caSwyllys } else { 201899ebb4caSwyllys *msgstr = NULL; 201999ebb4caSwyllys } 202099ebb4caSwyllys 202199ebb4caSwyllys return (ret); 202299ebb4caSwyllys } 202399ebb4caSwyllys 202499ebb4caSwyllys static int 202599ebb4caSwyllys ext2NID(int kmfext) 202699ebb4caSwyllys { 202799ebb4caSwyllys switch (kmfext) { 202899ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 202999ebb4caSwyllys return (NID_key_usage); 203099ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 203199ebb4caSwyllys return (NID_private_key_usage_period); 203299ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 203399ebb4caSwyllys return (NID_certificate_policies); 203499ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 203599ebb4caSwyllys return (NID_subject_alt_name); 203699ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 203799ebb4caSwyllys return (NID_issuer_alt_name); 203899ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 203999ebb4caSwyllys return (NID_basic_constraints); 204099ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 204199ebb4caSwyllys return (NID_ext_key_usage); 204299ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 204399ebb4caSwyllys return (NID_authority_key_identifier); 204499ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 204599ebb4caSwyllys return (NID_crl_distribution_points); 204699ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 204799ebb4caSwyllys return (NID_subject_key_identifier); 204899ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 204999ebb4caSwyllys return (OBJ_sn2nid("policyMappings")); 205099ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 205199ebb4caSwyllys return (OBJ_sn2nid("nameConstraints")); 205299ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 205399ebb4caSwyllys return (OBJ_sn2nid("policyConstraints")); 205499ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 205599ebb4caSwyllys return (OBJ_sn2nid("inhibitAnyPolicy")); 205699ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 205799ebb4caSwyllys return (OBJ_sn2nid("freshestCRL")); 205899ebb4caSwyllys default: 205999ebb4caSwyllys return (NID_undef); 206099ebb4caSwyllys } 206199ebb4caSwyllys } 206299ebb4caSwyllys 206399ebb4caSwyllys KMF_RETURN 206499ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, 206599ebb4caSwyllys KMF_PRINTABLE_ITEM flag, char *resultStr) 206699ebb4caSwyllys { 206799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 206899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 206999ebb4caSwyllys X509 *xcert = NULL; 207099ebb4caSwyllys unsigned char *outbuf = NULL; 207199ebb4caSwyllys unsigned char *outbuf_p; 207299ebb4caSwyllys char *tmpstr = NULL; 207399ebb4caSwyllys int j; 207499ebb4caSwyllys int ext_index, nid, len; 207599ebb4caSwyllys BIO *mem = NULL; 207699ebb4caSwyllys STACK *emlst = NULL; 207799ebb4caSwyllys X509_EXTENSION *ex; 207899ebb4caSwyllys X509_CINF *ci; 207999ebb4caSwyllys 208099ebb4caSwyllys if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) { 208199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 208299ebb4caSwyllys } 208399ebb4caSwyllys 208499ebb4caSwyllys /* copy cert data to outbuf */ 208599ebb4caSwyllys outbuf = malloc(pcert->Length); 208699ebb4caSwyllys if (outbuf == NULL) { 208799ebb4caSwyllys return (KMF_ERR_MEMORY); 208899ebb4caSwyllys } 208999ebb4caSwyllys (void) memcpy(outbuf, pcert->Data, pcert->Length); 209099ebb4caSwyllys 209199ebb4caSwyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 209299ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length); 209399ebb4caSwyllys if (xcert == NULL) { 209499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 209599ebb4caSwyllys ret = KMF_ERR_ENCODING; 209699ebb4caSwyllys goto out; 209799ebb4caSwyllys } 209899ebb4caSwyllys 209999ebb4caSwyllys mem = BIO_new(BIO_s_mem()); 210099ebb4caSwyllys if (mem == NULL) { 210199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 210299ebb4caSwyllys ret = KMF_ERR_MEMORY; 210399ebb4caSwyllys goto out; 210499ebb4caSwyllys } 210599ebb4caSwyllys 210699ebb4caSwyllys switch (flag) { 210799ebb4caSwyllys case KMF_CERT_ISSUER: 210899ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0, 210999ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 211099ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 211199ebb4caSwyllys break; 211299ebb4caSwyllys 211399ebb4caSwyllys case KMF_CERT_SUBJECT: 211499ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0, 211599ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 211699ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 211799ebb4caSwyllys break; 211899ebb4caSwyllys 211999ebb4caSwyllys case KMF_CERT_VERSION: 212099ebb4caSwyllys tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version); 212199ebb4caSwyllys (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN); 212299ebb4caSwyllys OPENSSL_free(tmpstr); 212399ebb4caSwyllys len = strlen(resultStr); 212499ebb4caSwyllys break; 212599ebb4caSwyllys 212699ebb4caSwyllys case KMF_CERT_SERIALNUM: 212799ebb4caSwyllys if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) { 212899ebb4caSwyllys (void) strcpy(resultStr, "0x"); 212999ebb4caSwyllys len = BIO_gets(mem, &resultStr[2], 213099ebb4caSwyllys KMF_CERT_PRINTABLE_LEN - 2); 213199ebb4caSwyllys } 213299ebb4caSwyllys break; 213399ebb4caSwyllys 213499ebb4caSwyllys case KMF_CERT_NOTBEFORE: 213599ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert)); 213699ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 213799ebb4caSwyllys break; 213899ebb4caSwyllys 213999ebb4caSwyllys case KMF_CERT_NOTAFTER: 214099ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert)); 214199ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 214299ebb4caSwyllys break; 214399ebb4caSwyllys 214499ebb4caSwyllys case KMF_CERT_PUBKEY_DATA: 214599ebb4caSwyllys { 214699ebb4caSwyllys EVP_PKEY *pkey = X509_get_pubkey(xcert); 214799ebb4caSwyllys if (pkey == NULL) { 214899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 214999ebb4caSwyllys ret = KMF_ERR_ENCODING; 215099ebb4caSwyllys goto out; 215199ebb4caSwyllys } 215299ebb4caSwyllys 215399ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 215499ebb4caSwyllys (void) BIO_printf(mem, 215599ebb4caSwyllys "RSA Public Key: (%d bit)\n", 215699ebb4caSwyllys BN_num_bits(pkey->pkey.rsa->n)); 215799ebb4caSwyllys (void) RSA_print(mem, pkey->pkey.rsa, 0); 215899ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 215999ebb4caSwyllys (void) BIO_printf(mem, 216099ebb4caSwyllys "%12sDSA Public Key:\n", ""); 216199ebb4caSwyllys (void) DSA_print(mem, pkey->pkey.dsa, 0); 216299ebb4caSwyllys } else { 216399ebb4caSwyllys (void) BIO_printf(mem, 216499ebb4caSwyllys "%12sUnknown Public Key:\n", ""); 216599ebb4caSwyllys } 216699ebb4caSwyllys (void) BIO_printf(mem, "\n"); 216799ebb4caSwyllys EVP_PKEY_free(pkey); 216899ebb4caSwyllys } 216999ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 217099ebb4caSwyllys break; 217199ebb4caSwyllys case KMF_CERT_SIGNATURE_ALG: 217299ebb4caSwyllys case KMF_CERT_PUBKEY_ALG: 217399ebb4caSwyllys if (flag == KMF_CERT_SIGNATURE_ALG) { 217499ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 217599ebb4caSwyllys xcert->sig_alg->algorithm); 217699ebb4caSwyllys } else { 217799ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 217899ebb4caSwyllys xcert->cert_info->key->algor->algorithm); 217999ebb4caSwyllys } 218099ebb4caSwyllys 218199ebb4caSwyllys if (len > 0) { 218299ebb4caSwyllys len = BIO_read(mem, resultStr, 218399ebb4caSwyllys KMF_CERT_PRINTABLE_LEN); 218499ebb4caSwyllys } 218599ebb4caSwyllys break; 218699ebb4caSwyllys 218799ebb4caSwyllys case KMF_CERT_EMAIL: 218899ebb4caSwyllys emlst = X509_get1_email(xcert); 218999ebb4caSwyllys for (j = 0; j < sk_num(emlst); j++) 219099ebb4caSwyllys (void) BIO_printf(mem, "%s\n", sk_value(emlst, j)); 219199ebb4caSwyllys 219299ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 219399ebb4caSwyllys X509_email_free(emlst); 219499ebb4caSwyllys break; 219599ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 219699ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 219799ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 219899ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 219999ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 220099ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 220199ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 220299ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 220399ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 220499ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 220599ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 220699ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 220799ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 220899ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 220999ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 221099ebb4caSwyllys nid = ext2NID(flag); 221199ebb4caSwyllys if (nid == NID_undef) { 221299ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 221399ebb4caSwyllys goto out; 221499ebb4caSwyllys } 221599ebb4caSwyllys ci = xcert->cert_info; 221699ebb4caSwyllys 221799ebb4caSwyllys ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1); 221899ebb4caSwyllys if (ext_index == -1) { 221999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 222099ebb4caSwyllys 222199ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 222299ebb4caSwyllys goto out; 222399ebb4caSwyllys } 222499ebb4caSwyllys ex = X509v3_get_ext(ci->extensions, ext_index); 222599ebb4caSwyllys 222699ebb4caSwyllys (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); 222799ebb4caSwyllys 222899ebb4caSwyllys if (BIO_printf(mem, ": %s\n", 222999ebb4caSwyllys X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 223099ebb4caSwyllys 0) { 223199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 223299ebb4caSwyllys ret = KMF_ERR_ENCODING; 223399ebb4caSwyllys goto out; 223499ebb4caSwyllys } 223599ebb4caSwyllys if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) { 223699ebb4caSwyllys (void) BIO_printf(mem, "%*s", 4, ""); 223799ebb4caSwyllys (void) M_ASN1_OCTET_STRING_print(mem, ex->value); 223899ebb4caSwyllys } 223999ebb4caSwyllys if (BIO_write(mem, "\n", 1) <= 0) { 224099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 224199ebb4caSwyllys ret = KMF_ERR_ENCODING; 224299ebb4caSwyllys goto out; 224399ebb4caSwyllys } 224499ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 224599ebb4caSwyllys } 224699ebb4caSwyllys if (len <= 0) { 224799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 224899ebb4caSwyllys ret = KMF_ERR_ENCODING; 224999ebb4caSwyllys } 225099ebb4caSwyllys 225199ebb4caSwyllys out: 225299ebb4caSwyllys if (outbuf != NULL) { 225399ebb4caSwyllys free(outbuf); 225499ebb4caSwyllys } 225599ebb4caSwyllys 225699ebb4caSwyllys if (xcert != NULL) { 225799ebb4caSwyllys X509_free(xcert); 225899ebb4caSwyllys } 225999ebb4caSwyllys 226099ebb4caSwyllys if (mem != NULL) { 226199ebb4caSwyllys (void) BIO_free(mem); 226299ebb4caSwyllys } 226399ebb4caSwyllys 226499ebb4caSwyllys return (ret); 226599ebb4caSwyllys } 226699ebb4caSwyllys KMF_RETURN 226799ebb4caSwyllys /*ARGSUSED*/ 226899ebb4caSwyllys OpenSSL_GetPrikeyByCert(KMF_HANDLE_T handle, 226999ebb4caSwyllys KMF_CRYPTOWITHCERT_PARAMS *params, 227099ebb4caSwyllys KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, 227199ebb4caSwyllys KMF_KEY_ALG keytype) 227299ebb4caSwyllys { 227399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 227499ebb4caSwyllys KMF_FINDKEY_PARAMS fkparms; 227599ebb4caSwyllys uint32_t numkeys = 0; 227699ebb4caSwyllys 227799ebb4caSwyllys if (params == NULL && params->sslparms.keyfile == NULL) 227899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 227999ebb4caSwyllys 228099ebb4caSwyllys /* 228199ebb4caSwyllys * This is really just a FindKey operation, reuse the 228299ebb4caSwyllys * FindKey function. 228399ebb4caSwyllys */ 228499ebb4caSwyllys (void *)memset(&fkparms, 0, sizeof (fkparms)); 228599ebb4caSwyllys fkparms.kstype = KMF_KEYSTORE_OPENSSL; 228699ebb4caSwyllys fkparms.keyclass = KMF_ASYM_PRI; 228799ebb4caSwyllys fkparms.keytype = keytype; 228899ebb4caSwyllys fkparms.format = params->format; 228999ebb4caSwyllys fkparms.sslparms = params->sslparms; 229099ebb4caSwyllys 229199ebb4caSwyllys rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys); 229299ebb4caSwyllys 229399ebb4caSwyllys return (rv); 229499ebb4caSwyllys } 229599ebb4caSwyllys 229699ebb4caSwyllys KMF_RETURN 229799ebb4caSwyllys /*ARGSUSED*/ 229899ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 229999ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *ciphertext, 230099ebb4caSwyllys KMF_DATA *output) 230199ebb4caSwyllys { 230299ebb4caSwyllys KMF_RETURN ret = KMF_OK; 230399ebb4caSwyllys RSA *rsa = NULL; 230499ebb4caSwyllys unsigned int in_len = 0, out_len = 0; 230599ebb4caSwyllys unsigned int total_decrypted = 0, modulus_len = 0; 230699ebb4caSwyllys uint8_t *in_data, *out_data; 230799ebb4caSwyllys int i, blocks; 230899ebb4caSwyllys 230999ebb4caSwyllys if (key == NULL || AlgOID == NULL || 231099ebb4caSwyllys ciphertext == NULL || output == NULL || 231199ebb4caSwyllys ciphertext->Data == NULL || 231299ebb4caSwyllys output->Data == NULL) 231399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 231499ebb4caSwyllys 231599ebb4caSwyllys if (key->keyalg == KMF_RSA) { 231699ebb4caSwyllys rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp); 231799ebb4caSwyllys modulus_len = RSA_size(rsa); 231899ebb4caSwyllys } else { 231999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 232099ebb4caSwyllys } 232199ebb4caSwyllys 232299ebb4caSwyllys blocks = ciphertext->Length/modulus_len; 232399ebb4caSwyllys out_data = output->Data; 232499ebb4caSwyllys in_data = ciphertext->Data; 232599ebb4caSwyllys out_len = modulus_len - 11; 232699ebb4caSwyllys in_len = modulus_len; 232799ebb4caSwyllys 232899ebb4caSwyllys for (i = 0; i < blocks; i++) { 232999ebb4caSwyllys out_len = RSA_private_decrypt(in_len, 233099ebb4caSwyllys in_data, out_data, rsa, RSA_PKCS1_PADDING); 233199ebb4caSwyllys 233299ebb4caSwyllys if (out_len == 0) { 233399ebb4caSwyllys ret = KMF_ERR_INTERNAL; 233499ebb4caSwyllys goto cleanup; 233599ebb4caSwyllys } 233699ebb4caSwyllys 233799ebb4caSwyllys out_data += out_len; 233899ebb4caSwyllys total_decrypted += out_len; 233999ebb4caSwyllys in_data += in_len; 234099ebb4caSwyllys } 234199ebb4caSwyllys 234299ebb4caSwyllys output->Length = total_decrypted; 234399ebb4caSwyllys 234499ebb4caSwyllys cleanup: 234599ebb4caSwyllys RSA_free(rsa); 234699ebb4caSwyllys if (ret != KMF_OK) 234799ebb4caSwyllys output->Length = 0; 234899ebb4caSwyllys 234999ebb4caSwyllys return (ret); 235099ebb4caSwyllys 235199ebb4caSwyllys } 235299ebb4caSwyllys 235399ebb4caSwyllys /* 235499ebb4caSwyllys * This function will create a certid from issuer_cert and user_cert. 235599ebb4caSwyllys * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate 235699ebb4caSwyllys * certid memory after use. 235799ebb4caSwyllys */ 235899ebb4caSwyllys static KMF_RETURN 235999ebb4caSwyllys create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert, 236099ebb4caSwyllys const KMF_DATA *user_cert, OCSP_CERTID **certid) 236199ebb4caSwyllys { 236299ebb4caSwyllys KMF_RETURN ret = KMF_OK; 236399ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 236499ebb4caSwyllys X509 *issuer = NULL; 236599ebb4caSwyllys X509 *cert = NULL; 236699ebb4caSwyllys unsigned char *ptmp; 236799ebb4caSwyllys 236899ebb4caSwyllys if (issuer_cert == NULL || user_cert == NULL) { 236999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 237099ebb4caSwyllys } 237199ebb4caSwyllys 237299ebb4caSwyllys /* convert the DER-encoded issuer cert to an internal X509 */ 237399ebb4caSwyllys ptmp = issuer_cert->Data; 237499ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 237599ebb4caSwyllys issuer_cert->Length); 237699ebb4caSwyllys if (issuer == NULL) { 237799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 237899ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 237999ebb4caSwyllys goto end; 238099ebb4caSwyllys } 238199ebb4caSwyllys 238299ebb4caSwyllys /* convert the DER-encoded user cert to an internal X509 */ 238399ebb4caSwyllys ptmp = user_cert->Data; 238499ebb4caSwyllys cert = d2i_X509(NULL, (const uchar_t **)&ptmp, 238599ebb4caSwyllys user_cert->Length); 238699ebb4caSwyllys if (cert == NULL) { 238799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 238899ebb4caSwyllys 238999ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_CERT; 239099ebb4caSwyllys goto end; 239199ebb4caSwyllys } 239299ebb4caSwyllys 239399ebb4caSwyllys /* create a CERTID */ 239499ebb4caSwyllys *certid = OCSP_cert_to_id(NULL, cert, issuer); 239599ebb4caSwyllys if (*certid == NULL) { 239699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 239799ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 239899ebb4caSwyllys goto end; 239999ebb4caSwyllys } 240099ebb4caSwyllys 240199ebb4caSwyllys end: 240299ebb4caSwyllys if (issuer != NULL) { 240399ebb4caSwyllys X509_free(issuer); 240499ebb4caSwyllys } 240599ebb4caSwyllys 240699ebb4caSwyllys if (cert != NULL) { 240799ebb4caSwyllys X509_free(cert); 240899ebb4caSwyllys } 240999ebb4caSwyllys 241099ebb4caSwyllys return (ret); 241199ebb4caSwyllys } 241299ebb4caSwyllys 241399ebb4caSwyllys KMF_RETURN 241499ebb4caSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, 241599ebb4caSwyllys char *reqfile) 241699ebb4caSwyllys { 241799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 241899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 241999ebb4caSwyllys OCSP_CERTID *id = NULL; 242099ebb4caSwyllys OCSP_REQUEST *req = NULL; 242199ebb4caSwyllys BIO *derbio = NULL; 242299ebb4caSwyllys 242399ebb4caSwyllys if (params->user_cert == NULL || params->issuer_cert == NULL || 242499ebb4caSwyllys reqfile == NULL) { 242599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 242699ebb4caSwyllys } 242799ebb4caSwyllys 242899ebb4caSwyllys ret = create_certid(handle, params->issuer_cert, params->user_cert, 242999ebb4caSwyllys &id); 243099ebb4caSwyllys if (ret != KMF_OK) { 243199ebb4caSwyllys return (ret); 243299ebb4caSwyllys } 243399ebb4caSwyllys 243499ebb4caSwyllys /* Create an OCSP request */ 243599ebb4caSwyllys req = OCSP_REQUEST_new(); 243699ebb4caSwyllys if (req == NULL) { 243799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 243899ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 243999ebb4caSwyllys goto end; 244099ebb4caSwyllys } 244199ebb4caSwyllys 244299ebb4caSwyllys if (!OCSP_request_add0_id(req, id)) { 244399ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 244499ebb4caSwyllys goto end; 244599ebb4caSwyllys } 244699ebb4caSwyllys 244799ebb4caSwyllys /* Write the request to the output file with DER encoding */ 244899ebb4caSwyllys derbio = BIO_new_file(reqfile, "wb"); 244999ebb4caSwyllys if (!derbio) { 245099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 245199ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 245299ebb4caSwyllys goto end; 245399ebb4caSwyllys } 245499ebb4caSwyllys if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) { 245599ebb4caSwyllys ret = KMF_ERR_ENCODING; 245699ebb4caSwyllys } 245799ebb4caSwyllys 245899ebb4caSwyllys end: 245999ebb4caSwyllys /* 246099ebb4caSwyllys * We don't need to free "id" explicitely, because OCSP_REQUEST_free() 246199ebb4caSwyllys * will deallocate certid's space also. 246299ebb4caSwyllys */ 246399ebb4caSwyllys if (req != NULL) { 246499ebb4caSwyllys OCSP_REQUEST_free(req); 246599ebb4caSwyllys } 246699ebb4caSwyllys 246799ebb4caSwyllys if (derbio != NULL) { 246899ebb4caSwyllys (void) BIO_free(derbio); 246999ebb4caSwyllys } 247099ebb4caSwyllys 247199ebb4caSwyllys return (ret); 247299ebb4caSwyllys } 247399ebb4caSwyllys 247499ebb4caSwyllys /* ocsp_find_signer_sk() is copied from openssl source */ 247599ebb4caSwyllys static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 247699ebb4caSwyllys { 247799ebb4caSwyllys int i; 247899ebb4caSwyllys unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 247999ebb4caSwyllys 248099ebb4caSwyllys /* Easy if lookup by name */ 248199ebb4caSwyllys if (id->type == V_OCSP_RESPID_NAME) 248299ebb4caSwyllys return (X509_find_by_subject(certs, id->value.byName)); 248399ebb4caSwyllys 248499ebb4caSwyllys /* Lookup by key hash */ 248599ebb4caSwyllys 248699ebb4caSwyllys /* If key hash isn't SHA1 length then forget it */ 248799ebb4caSwyllys if (id->value.byKey->length != SHA_DIGEST_LENGTH) 248899ebb4caSwyllys return (NULL); 248999ebb4caSwyllys 249099ebb4caSwyllys keyhash = id->value.byKey->data; 249199ebb4caSwyllys /* Calculate hash of each key and compare */ 249299ebb4caSwyllys for (i = 0; i < sk_X509_num(certs); i++) { 249399ebb4caSwyllys /*LINTED*/ 249499ebb4caSwyllys X509 *x = sk_X509_value(certs, i); 249599ebb4caSwyllys (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 249699ebb4caSwyllys if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 249799ebb4caSwyllys return (x); 249899ebb4caSwyllys } 249999ebb4caSwyllys return (NULL); 250099ebb4caSwyllys } 250199ebb4caSwyllys 250299ebb4caSwyllys /* ocsp_find_signer() is copied from openssl source */ 250399ebb4caSwyllys /*ARGSUSED*/ 250499ebb4caSwyllys static int 250599ebb4caSwyllys ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, 250699ebb4caSwyllys X509_STORE *st, unsigned long flags) 250799ebb4caSwyllys { 250899ebb4caSwyllys X509 *signer; 250999ebb4caSwyllys OCSP_RESPID *rid = bs->tbsResponseData->responderId; 251099ebb4caSwyllys if ((signer = ocsp_find_signer_sk(certs, rid))) { 251199ebb4caSwyllys *psigner = signer; 251299ebb4caSwyllys return (2); 251399ebb4caSwyllys } 251499ebb4caSwyllys if (!(flags & OCSP_NOINTERN) && 251599ebb4caSwyllys (signer = ocsp_find_signer_sk(bs->certs, rid))) { 251699ebb4caSwyllys *psigner = signer; 251799ebb4caSwyllys return (1); 251899ebb4caSwyllys } 251999ebb4caSwyllys /* Maybe lookup from store if by subject name */ 252099ebb4caSwyllys 252199ebb4caSwyllys *psigner = NULL; 252299ebb4caSwyllys return (0); 252399ebb4caSwyllys } 252499ebb4caSwyllys 252599ebb4caSwyllys /* 252699ebb4caSwyllys * This function will verify the signature of a basic response, using 252799ebb4caSwyllys * the public key from the OCSP responder certificate. 252899ebb4caSwyllys */ 252999ebb4caSwyllys static KMF_RETURN 253099ebb4caSwyllys check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, 253199ebb4caSwyllys KMF_DATA *signer_cert, KMF_DATA *issuer_cert) 253299ebb4caSwyllys { 253399ebb4caSwyllys KMF_RETURN ret = KMF_OK; 253499ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 253599ebb4caSwyllys STACK_OF(X509) *cert_stack = NULL; 253699ebb4caSwyllys X509 *signer = NULL; 253799ebb4caSwyllys X509 *issuer = NULL; 253899ebb4caSwyllys EVP_PKEY *skey = NULL; 253999ebb4caSwyllys unsigned char *ptmp; 254099ebb4caSwyllys 254199ebb4caSwyllys 254299ebb4caSwyllys if (bs == NULL || issuer_cert == NULL) 254399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 254499ebb4caSwyllys 254599ebb4caSwyllys /* 254699ebb4caSwyllys * Find the certificate that signed the basic response. 254799ebb4caSwyllys * 254899ebb4caSwyllys * If signer_cert is not NULL, we will use that as the signer cert. 254999ebb4caSwyllys * Otherwise, we will check if the issuer cert is actually the signer. 255099ebb4caSwyllys * If we still do not find a signer, we will look for it from the 255199ebb4caSwyllys * certificate list came with the response file. 255299ebb4caSwyllys */ 255399ebb4caSwyllys if (signer_cert != NULL) { 255499ebb4caSwyllys ptmp = signer_cert->Data; 255599ebb4caSwyllys signer = d2i_X509(NULL, (const uchar_t **)&ptmp, 255699ebb4caSwyllys signer_cert->Length); 255799ebb4caSwyllys if (signer == NULL) { 255899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 255999ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 256099ebb4caSwyllys goto end; 256199ebb4caSwyllys } 256299ebb4caSwyllys } else { 256399ebb4caSwyllys /* 256499ebb4caSwyllys * Convert the issuer cert into X509 and push it into a 256599ebb4caSwyllys * stack to be used by ocsp_find_signer(). 256699ebb4caSwyllys */ 256799ebb4caSwyllys ptmp = issuer_cert->Data; 256899ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 256999ebb4caSwyllys issuer_cert->Length); 257099ebb4caSwyllys if (issuer == NULL) { 257199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 257299ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 257399ebb4caSwyllys goto end; 257499ebb4caSwyllys } 257599ebb4caSwyllys 257699ebb4caSwyllys if ((cert_stack = sk_X509_new_null()) == NULL) { 257799ebb4caSwyllys ret = KMF_ERR_INTERNAL; 257899ebb4caSwyllys goto end; 257999ebb4caSwyllys } 258099ebb4caSwyllys 258199ebb4caSwyllys if (sk_X509_push(cert_stack, issuer) == NULL) { 258299ebb4caSwyllys ret = KMF_ERR_INTERNAL; 258399ebb4caSwyllys goto end; 258499ebb4caSwyllys } 258599ebb4caSwyllys 258699ebb4caSwyllys ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0); 258799ebb4caSwyllys if (!ret) { 258899ebb4caSwyllys /* can not find the signer */ 258999ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 259099ebb4caSwyllys goto end; 259199ebb4caSwyllys } 259299ebb4caSwyllys } 259399ebb4caSwyllys 259499ebb4caSwyllys /* Verify the signature of the response */ 259599ebb4caSwyllys skey = X509_get_pubkey(signer); 259699ebb4caSwyllys if (skey == NULL) { 259799ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 259899ebb4caSwyllys goto end; 259999ebb4caSwyllys } 260099ebb4caSwyllys 260199ebb4caSwyllys ret = OCSP_BASICRESP_verify(bs, skey, 0); 260299ebb4caSwyllys if (ret == 0) { 260399ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE; 260499ebb4caSwyllys goto end; 260599ebb4caSwyllys } 260699ebb4caSwyllys 260799ebb4caSwyllys end: 260899ebb4caSwyllys if (issuer != NULL) { 260999ebb4caSwyllys X509_free(issuer); 261099ebb4caSwyllys } 261199ebb4caSwyllys 261299ebb4caSwyllys if (signer != NULL) { 261399ebb4caSwyllys X509_free(signer); 261499ebb4caSwyllys } 261599ebb4caSwyllys 261699ebb4caSwyllys if (skey != NULL) { 261799ebb4caSwyllys EVP_PKEY_free(skey); 261899ebb4caSwyllys } 261999ebb4caSwyllys 262099ebb4caSwyllys if (cert_stack != NULL) { 262199ebb4caSwyllys sk_X509_free(cert_stack); 262299ebb4caSwyllys } 262399ebb4caSwyllys 262499ebb4caSwyllys return (ret); 262599ebb4caSwyllys } 262699ebb4caSwyllys 262799ebb4caSwyllys 262899ebb4caSwyllys 262999ebb4caSwyllys KMF_RETURN 263099ebb4caSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, 263199ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 263299ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) 263399ebb4caSwyllys { 263499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 263599ebb4caSwyllys BIO *derbio = NULL; 263699ebb4caSwyllys OCSP_RESPONSE *resp = NULL; 263799ebb4caSwyllys OCSP_BASICRESP *bs = NULL; 263899ebb4caSwyllys OCSP_CERTID *id = NULL; 263999ebb4caSwyllys OCSP_SINGLERESP *single = NULL; 264099ebb4caSwyllys ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 264199ebb4caSwyllys int index, status, reason; 264299ebb4caSwyllys 264399ebb4caSwyllys if (params_in == NULL || params_in->issuer_cert == NULL || 264499ebb4caSwyllys params_in->user_cert == NULL || params_in->response == NULL) { 264599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 264699ebb4caSwyllys } 264799ebb4caSwyllys 264899ebb4caSwyllys if (params_out == NULL) { 264999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 265099ebb4caSwyllys } 265199ebb4caSwyllys 265299ebb4caSwyllys /* Read in the response */ 265399ebb4caSwyllys derbio = BIO_new_mem_buf(params_in->response->Data, 265499ebb4caSwyllys params_in->response->Length); 265599ebb4caSwyllys if (!derbio) { 265699ebb4caSwyllys ret = KMF_ERR_MEMORY; 265799ebb4caSwyllys return (ret); 265899ebb4caSwyllys } 265999ebb4caSwyllys 266099ebb4caSwyllys resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 266199ebb4caSwyllys if (resp == NULL) { 266299ebb4caSwyllys ret = KMF_ERR_OCSP_MALFORMED_RESPONSE; 266399ebb4caSwyllys goto end; 266499ebb4caSwyllys } 266599ebb4caSwyllys 266699ebb4caSwyllys /* Check the response status */ 266799ebb4caSwyllys status = OCSP_response_status(resp); 266899ebb4caSwyllys params_out->response_status = status; 266999ebb4caSwyllys if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 267099ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_STATUS; 267199ebb4caSwyllys goto end; 267299ebb4caSwyllys } 267399ebb4caSwyllys 267499ebb4caSwyllys #ifdef DEBUG 267599ebb4caSwyllys printf("Successfully checked the response file status.\n"); 267699ebb4caSwyllys #endif /* DEBUG */ 267799ebb4caSwyllys 267899ebb4caSwyllys /* Extract basic response */ 267999ebb4caSwyllys bs = OCSP_response_get1_basic(resp); 268099ebb4caSwyllys if (bs == NULL) { 268199ebb4caSwyllys ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE; 268299ebb4caSwyllys goto end; 268399ebb4caSwyllys } 268499ebb4caSwyllys 268599ebb4caSwyllys #ifdef DEBUG 268699ebb4caSwyllys printf("Successfully retrieved the basic response.\n"); 268799ebb4caSwyllys #endif /* DEBUG */ 268899ebb4caSwyllys 268999ebb4caSwyllys /* Check the basic response signature if required */ 269099ebb4caSwyllys if (params_in->ignore_response_sign == B_FALSE) { 269199ebb4caSwyllys ret = check_response_signature(handle, bs, 269299ebb4caSwyllys params_in->signer_cert, params_in->issuer_cert); 269399ebb4caSwyllys if (ret != KMF_OK) 269499ebb4caSwyllys goto end; 269599ebb4caSwyllys } 269699ebb4caSwyllys 269799ebb4caSwyllys #ifdef DEBUG 269899ebb4caSwyllys printf("Successfully verified the response signature.\n"); 269999ebb4caSwyllys #endif /* DEBUG */ 270099ebb4caSwyllys 270199ebb4caSwyllys /* Create a certid for the certificate in question */ 270299ebb4caSwyllys ret = create_certid(handle, params_in->issuer_cert, 270399ebb4caSwyllys params_in->user_cert, &id); 270499ebb4caSwyllys if (ret != KMF_OK) { 270599ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 270699ebb4caSwyllys goto end; 270799ebb4caSwyllys } 270899ebb4caSwyllys 270999ebb4caSwyllys #ifdef DEBUG 271099ebb4caSwyllys printf("successfully created a certid for the cert.\n"); 271199ebb4caSwyllys #endif /* DEBUG */ 271299ebb4caSwyllys 271399ebb4caSwyllys /* Find the index of the single response for the certid */ 271499ebb4caSwyllys index = OCSP_resp_find(bs, id, -1); 271599ebb4caSwyllys if (index < 0) { 271699ebb4caSwyllys /* cound not find this certificate in the response */ 271799ebb4caSwyllys ret = KMF_ERR_OCSP_UNKNOWN_CERT; 271899ebb4caSwyllys goto end; 271999ebb4caSwyllys } 272099ebb4caSwyllys 272199ebb4caSwyllys #ifdef DEBUG 272299ebb4caSwyllys printf("Successfully found the single response index for the cert.\n"); 272399ebb4caSwyllys #endif /* DEBUG */ 272499ebb4caSwyllys 272599ebb4caSwyllys /* Retrieve the single response and get the cert status */ 272699ebb4caSwyllys single = OCSP_resp_get0(bs, index); 272799ebb4caSwyllys status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, 272899ebb4caSwyllys &nextupd); 272999ebb4caSwyllys if (status == V_OCSP_CERTSTATUS_GOOD) { 273099ebb4caSwyllys params_out->cert_status = OCSP_GOOD; 273199ebb4caSwyllys } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { 273299ebb4caSwyllys params_out->cert_status = OCSP_UNKNOWN; 273399ebb4caSwyllys } else { /* revoked */ 273499ebb4caSwyllys params_out->cert_status = OCSP_REVOKED; 273599ebb4caSwyllys params_out->reason = reason; 273699ebb4caSwyllys } 273799ebb4caSwyllys ret = KMF_OK; 273899ebb4caSwyllys 273999ebb4caSwyllys /* Verify the time */ 274099ebb4caSwyllys if (!OCSP_check_validity(thisupd, nextupd, 300, 274199ebb4caSwyllys params_in->response_lifetime)) { 274299ebb4caSwyllys ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; 274399ebb4caSwyllys goto end; 274499ebb4caSwyllys } 274599ebb4caSwyllys 274699ebb4caSwyllys #ifdef DEBUG 274799ebb4caSwyllys printf("Successfully verify the time.\n"); 274899ebb4caSwyllys #endif /* DEBUG */ 274999ebb4caSwyllys 275099ebb4caSwyllys end: 275199ebb4caSwyllys if (derbio != NULL) 275299ebb4caSwyllys (void) BIO_free(derbio); 275399ebb4caSwyllys 275499ebb4caSwyllys if (resp != NULL) 275599ebb4caSwyllys OCSP_RESPONSE_free(resp); 275699ebb4caSwyllys 275799ebb4caSwyllys if (bs != NULL) 275899ebb4caSwyllys OCSP_BASICRESP_free(bs); 275999ebb4caSwyllys 276099ebb4caSwyllys if (id != NULL) 276199ebb4caSwyllys OCSP_CERTID_free(id); 276299ebb4caSwyllys 276399ebb4caSwyllys return (ret); 276499ebb4caSwyllys } 276599ebb4caSwyllys 276699ebb4caSwyllys static KMF_RETURN 276799ebb4caSwyllys fetch_key(KMF_HANDLE_T handle, char *path, 276899ebb4caSwyllys KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) 276999ebb4caSwyllys { 277099ebb4caSwyllys KMF_RETURN rv = KMF_OK; 277199ebb4caSwyllys EVP_PKEY *pkey; 277299ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 277399ebb4caSwyllys 277499ebb4caSwyllys /* Make sure the requested file actually exists. */ 277599ebb4caSwyllys if (access(path, F_OK) != 0) { 277699ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 277799ebb4caSwyllys } 277899ebb4caSwyllys 277999ebb4caSwyllys if (keyclass == KMF_ASYM_PRI || 278099ebb4caSwyllys keyclass == KMF_ASYM_PUB) { 278199ebb4caSwyllys pkey = openssl_load_key(handle, path); 278299ebb4caSwyllys if (pkey == NULL) { 278399ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 278499ebb4caSwyllys } 278599ebb4caSwyllys if (key != NULL) { 278699ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) 278799ebb4caSwyllys key->keyalg = KMF_RSA; 278899ebb4caSwyllys else if (pkey->type == EVP_PKEY_DSA) 278999ebb4caSwyllys key->keyalg = KMF_DSA; 279099ebb4caSwyllys 279199ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 279299ebb4caSwyllys key->keyclass = keyclass; 279399ebb4caSwyllys key->keyp = (void *)pkey; 279499ebb4caSwyllys key->israw = FALSE; 279599ebb4caSwyllys key->keylabel = path; 279699ebb4caSwyllys } else { 279799ebb4caSwyllys EVP_PKEY_free(pkey); 279899ebb4caSwyllys pkey = NULL; 279999ebb4caSwyllys } 280099ebb4caSwyllys } else if (keyclass == KMF_SYMMETRIC) { 280199ebb4caSwyllys KMF_ENCODE_FORMAT fmt; 280299ebb4caSwyllys /* 280399ebb4caSwyllys * If the file is a recognized format, 280499ebb4caSwyllys * then it is NOT a symmetric key. 280599ebb4caSwyllys */ 280699ebb4caSwyllys rv = KMF_GetFileFormat(path, &fmt); 280799ebb4caSwyllys if (rv == KMF_OK || fmt != 0) { 280899ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 280999ebb4caSwyllys } else if (rv == KMF_ERR_ENCODING) { 281099ebb4caSwyllys /* 281199ebb4caSwyllys * If we don't know the encoding, 281299ebb4caSwyllys * it is probably a symmetric key. 281399ebb4caSwyllys */ 281499ebb4caSwyllys rv = KMF_OK; 281599ebb4caSwyllys } 281699ebb4caSwyllys 281799ebb4caSwyllys if (key != NULL) { 281899ebb4caSwyllys KMF_DATA keyvalue; 281999ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 282099ebb4caSwyllys if (rkey == NULL) { 282199ebb4caSwyllys rv = KMF_ERR_MEMORY; 282299ebb4caSwyllys goto out; 282399ebb4caSwyllys } 282499ebb4caSwyllys 282599ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 282699ebb4caSwyllys rv = KMF_ReadInputFile(handle, path, &keyvalue); 282799ebb4caSwyllys if (rv != KMF_OK) 282899ebb4caSwyllys goto out; 282999ebb4caSwyllys 283099ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 283199ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 283299ebb4caSwyllys 283399ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 283499ebb4caSwyllys key->keyclass = keyclass; 283599ebb4caSwyllys key->israw = TRUE; 283699ebb4caSwyllys key->keylabel = path; 283799ebb4caSwyllys key->keyp = (void *)rkey; 283899ebb4caSwyllys } 283999ebb4caSwyllys } 284099ebb4caSwyllys out: 284199ebb4caSwyllys if (rv != KMF_OK) { 284299ebb4caSwyllys if (rkey != NULL) { 284399ebb4caSwyllys KMF_FreeRawSymKey(rkey); 284499ebb4caSwyllys } 284599ebb4caSwyllys if (pkey != NULL) 284699ebb4caSwyllys EVP_PKEY_free(pkey); 284799ebb4caSwyllys 284899ebb4caSwyllys if (key != NULL) { 284999ebb4caSwyllys key->keyalg = KMF_KEYALG_NONE; 285099ebb4caSwyllys key->keyclass = KMF_KEYCLASS_NONE; 285199ebb4caSwyllys key->keyp = NULL; 285299ebb4caSwyllys } 285399ebb4caSwyllys } 285499ebb4caSwyllys 285599ebb4caSwyllys return (rv); 285699ebb4caSwyllys } 285799ebb4caSwyllys 285899ebb4caSwyllys KMF_RETURN 285999ebb4caSwyllys OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, 286099ebb4caSwyllys KMF_KEY_HANDLE *key, uint32_t *numkeys) 286199ebb4caSwyllys { 286299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 286399ebb4caSwyllys char *fullpath = NULL; 286499ebb4caSwyllys 286599ebb4caSwyllys if (handle == NULL || params == NULL || numkeys == NULL) 286699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 286799ebb4caSwyllys 286899ebb4caSwyllys if (params->keyclass != KMF_ASYM_PUB && 286999ebb4caSwyllys params->keyclass != KMF_ASYM_PRI && 287099ebb4caSwyllys params->keyclass != KMF_SYMMETRIC) 287199ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 287299ebb4caSwyllys 287399ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 287499ebb4caSwyllys params->sslparms.keyfile); 287599ebb4caSwyllys 287699ebb4caSwyllys if (fullpath == NULL) 287799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 287899ebb4caSwyllys 287999ebb4caSwyllys *numkeys = 0; 288099ebb4caSwyllys 288199ebb4caSwyllys if (isdir(fullpath)) { 288299ebb4caSwyllys DIR *dirp; 288399ebb4caSwyllys struct dirent *dp; 288499ebb4caSwyllys int n = 0; 288599ebb4caSwyllys 288699ebb4caSwyllys /* open all files in the directory and attempt to read them */ 288799ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 288899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 288999ebb4caSwyllys } 289099ebb4caSwyllys rewinddir(dirp); 289199ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 289299ebb4caSwyllys if (strcmp(dp->d_name, ".") && 289399ebb4caSwyllys strcmp(dp->d_name, "..")) { 289499ebb4caSwyllys char *fname; 289599ebb4caSwyllys 289699ebb4caSwyllys fname = get_fullpath(fullpath, 289799ebb4caSwyllys (char *)&dp->d_name); 289899ebb4caSwyllys 289999ebb4caSwyllys rv = fetch_key(handle, fname, 290099ebb4caSwyllys params->keyclass, 290199ebb4caSwyllys key ? &key[n] : NULL); 290299ebb4caSwyllys 290399ebb4caSwyllys if (rv == KMF_OK) 290499ebb4caSwyllys n++; 290599ebb4caSwyllys 290699ebb4caSwyllys if (rv != KMF_OK || key == NULL) 290799ebb4caSwyllys free(fname); 290899ebb4caSwyllys } 290999ebb4caSwyllys } 291099ebb4caSwyllys (void) closedir(dirp); 291199ebb4caSwyllys free(fullpath); 291299ebb4caSwyllys (*numkeys) = n; 291399ebb4caSwyllys } else { 291499ebb4caSwyllys rv = fetch_key(handle, fullpath, params->keyclass, key); 291599ebb4caSwyllys if (rv == KMF_OK) 291699ebb4caSwyllys (*numkeys) = 1; 291799ebb4caSwyllys 291899ebb4caSwyllys if (rv != KMF_OK || key == NULL) 291999ebb4caSwyllys free(fullpath); 292099ebb4caSwyllys } 292199ebb4caSwyllys 292299ebb4caSwyllys if ((*numkeys) == 0) 292399ebb4caSwyllys rv = KMF_ERR_KEY_NOT_FOUND; 292499ebb4caSwyllys 292599ebb4caSwyllys return (rv); 292699ebb4caSwyllys } 292799ebb4caSwyllys 292899ebb4caSwyllys #define HANDLE_PK12_ERROR { \ 292999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); \ 293099ebb4caSwyllys rv = KMF_ERR_ENCODING; \ 293199ebb4caSwyllys goto out; \ 293299ebb4caSwyllys } 293399ebb4caSwyllys 293499ebb4caSwyllys static KMF_RETURN 293599ebb4caSwyllys write_pkcs12(KMF_HANDLE *kmfh, 293699ebb4caSwyllys BIO *bio, 293799ebb4caSwyllys KMF_CREDENTIAL *cred, 293899ebb4caSwyllys EVP_PKEY *pkey, 293999ebb4caSwyllys X509 *sslcert) 294099ebb4caSwyllys { 294199ebb4caSwyllys KMF_RETURN rv = KMF_OK; 294299ebb4caSwyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 294399ebb4caSwyllys PKCS12_SAFEBAG *bag = NULL; 294499ebb4caSwyllys PKCS7 *cert_authsafe = NULL; 294599ebb4caSwyllys PKCS8_PRIV_KEY_INFO *p8 = NULL; 294699ebb4caSwyllys PKCS7 *key_authsafe = NULL; 294799ebb4caSwyllys STACK_OF(PKCS7) *authsafe_stack = NULL; 294899ebb4caSwyllys PKCS12 *p12_elem = NULL; 294999ebb4caSwyllys char *lab = NULL; 295099ebb4caSwyllys int lab_len = 0; 295199ebb4caSwyllys unsigned char keyid[EVP_MAX_MD_SIZE]; 295299ebb4caSwyllys unsigned int keyidlen = 0; 295399ebb4caSwyllys 295499ebb4caSwyllys /* Must have at least a cert OR a key */ 295599ebb4caSwyllys if (sslcert == NULL && pkey == NULL) 295699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 295799ebb4caSwyllys 295899ebb4caSwyllys (void) memset(keyid, 0, sizeof (keyid)); 295999ebb4caSwyllys /* 296099ebb4caSwyllys * Section 1: 296199ebb4caSwyllys * 296299ebb4caSwyllys * The first PKCS#12 container (safebag) will hold the certificates 296399ebb4caSwyllys * associated with this key. The result of this section is a 296499ebb4caSwyllys * PIN-encrypted PKCS#7 container (authsafe). If there are no 296599ebb4caSwyllys * certificates, there is no point in creating the "safebag" or the 296699ebb4caSwyllys * "authsafe" so we go to the next section. 296799ebb4caSwyllys */ 296899ebb4caSwyllys if (sslcert != NULL && pkey != NULL) { 296999ebb4caSwyllys if (X509_check_private_key(sslcert, pkey)) { 297099ebb4caSwyllys (void) X509_digest(sslcert, EVP_sha1(), keyid, 297199ebb4caSwyllys &keyidlen); 297299ebb4caSwyllys } else { 297399ebb4caSwyllys /* The key doesn't match the cert */ 297499ebb4caSwyllys HANDLE_PK12_ERROR 297599ebb4caSwyllys } 297699ebb4caSwyllys } 297799ebb4caSwyllys 297899ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 297999ebb4caSwyllys if (bag_stack == NULL) 298099ebb4caSwyllys return (KMF_ERR_MEMORY); 298199ebb4caSwyllys 298299ebb4caSwyllys if (sslcert != NULL) { 298399ebb4caSwyllys /* Convert cert from X509 struct to PKCS#12 bag */ 298499ebb4caSwyllys bag = PKCS12_x5092certbag(sslcert); 298599ebb4caSwyllys if (bag == NULL) { 298699ebb4caSwyllys HANDLE_PK12_ERROR 298799ebb4caSwyllys } 298899ebb4caSwyllys 298999ebb4caSwyllys /* Add the key id to the certificate bag. */ 299099ebb4caSwyllys if (keyidlen > 0 && 299199ebb4caSwyllys !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 299299ebb4caSwyllys HANDLE_PK12_ERROR 299399ebb4caSwyllys } 299499ebb4caSwyllys 299599ebb4caSwyllys /* Pile it on the bag_stack. */ 299699ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 299799ebb4caSwyllys HANDLE_PK12_ERROR 299899ebb4caSwyllys } 299999ebb4caSwyllys #if 0 300099ebb4caSwyllys /* No support for CA certs yet */ 300199ebb4caSwyllys if (cacerts != NULL && ncacerts > 0) { 300299ebb4caSwyllys int i; 300399ebb4caSwyllys for (i = 0; i < ncacerts; i++) { 300499ebb4caSwyllys KMF_X509_DER_CERT *c = &cacerts[i]; 300599ebb4caSwyllys X509 *ca = NULL; 300699ebb4caSwyllys 300799ebb4caSwyllys uchar_t *p = (uchar_t *)c->certificate.Data; 300899ebb4caSwyllys ca = d2i_X509(NULL, &p, 300999ebb4caSwyllys c->certificate.Length); 301099ebb4caSwyllys if (ca == NULL) { 301199ebb4caSwyllys HANDLE_PK12_ERROR 301299ebb4caSwyllys } 301399ebb4caSwyllys /* Convert CA cert to PKCS#12 bag. */ 301499ebb4caSwyllys bag = PKCS12_x5092certbag(ca); 301599ebb4caSwyllys if (bag == NULL) { 301699ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, 301799ebb4caSwyllys PKCS12_SAFEBAG_free); 301899ebb4caSwyllys HANDLE_PK12_ERROR 301999ebb4caSwyllys } 302099ebb4caSwyllys /* Pile it onto the bag_stack. */ 302199ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 302299ebb4caSwyllys HANDLE_PK12_ERROR 302399ebb4caSwyllys } 302499ebb4caSwyllys } 302599ebb4caSwyllys } 302699ebb4caSwyllys #endif 302799ebb4caSwyllys /* Turn bag_stack of certs into encrypted authsafe. */ 302899ebb4caSwyllys cert_authsafe = PKCS12_pack_p7encdata( 302999ebb4caSwyllys NID_pbe_WithSHA1And40BitRC2_CBC, 303099ebb4caSwyllys cred->cred, 303199ebb4caSwyllys cred->credlen, NULL, 0, 303299ebb4caSwyllys PKCS12_DEFAULT_ITER, 303399ebb4caSwyllys bag_stack); 303499ebb4caSwyllys 303599ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 303699ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 303799ebb4caSwyllys bag_stack = NULL; 303899ebb4caSwyllys 303999ebb4caSwyllys if (cert_authsafe == NULL) { 304099ebb4caSwyllys HANDLE_PK12_ERROR 304199ebb4caSwyllys } 304299ebb4caSwyllys } 304399ebb4caSwyllys /* 304499ebb4caSwyllys * Section 2: 304599ebb4caSwyllys * 304699ebb4caSwyllys * The second PKCS#12 container (safebag) will hold the private key 304799ebb4caSwyllys * that goes with the certificates above. The results of this section 304899ebb4caSwyllys * is an unencrypted PKCS#7 container (authsafe). If there is no 304999ebb4caSwyllys * private key, there is no point in creating the "safebag" or the 305099ebb4caSwyllys * "authsafe" so we go to the next section. 305199ebb4caSwyllys */ 305299ebb4caSwyllys if (pkey != NULL) { 305399ebb4caSwyllys p8 = EVP_PKEY2PKCS8(pkey); 305499ebb4caSwyllys if (p8 == NULL) { 305599ebb4caSwyllys HANDLE_PK12_ERROR 305699ebb4caSwyllys } 305799ebb4caSwyllys /* Put the shrouded key into a PKCS#12 bag. */ 305899ebb4caSwyllys bag = PKCS12_MAKE_SHKEYBAG( 305999ebb4caSwyllys NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 306099ebb4caSwyllys cred->cred, cred->credlen, 306199ebb4caSwyllys NULL, 0, PKCS12_DEFAULT_ITER, p8); 306299ebb4caSwyllys 306399ebb4caSwyllys /* Clean up the PKCS#8 shrouded key, don't need it now. */ 306499ebb4caSwyllys PKCS8_PRIV_KEY_INFO_free(p8); 306599ebb4caSwyllys p8 = NULL; 306699ebb4caSwyllys 306799ebb4caSwyllys if (bag == NULL) { 306899ebb4caSwyllys HANDLE_PK12_ERROR 306999ebb4caSwyllys } 307099ebb4caSwyllys if (keyidlen && 307199ebb4caSwyllys !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 307299ebb4caSwyllys HANDLE_PK12_ERROR 307399ebb4caSwyllys } 307499ebb4caSwyllys if (lab != NULL) { 307599ebb4caSwyllys if (!PKCS12_add_friendlyname(bag, 307699ebb4caSwyllys (char *)lab, lab_len)) { 307799ebb4caSwyllys HANDLE_PK12_ERROR 307899ebb4caSwyllys } 307999ebb4caSwyllys } 308099ebb4caSwyllys /* Start a PKCS#12 safebag container for the private key. */ 308199ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 308299ebb4caSwyllys if (bag_stack == NULL) { 308399ebb4caSwyllys HANDLE_PK12_ERROR 308499ebb4caSwyllys } 308599ebb4caSwyllys 308699ebb4caSwyllys /* Pile on the private key on the bag_stack. */ 308799ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 308899ebb4caSwyllys HANDLE_PK12_ERROR 308999ebb4caSwyllys } 309099ebb4caSwyllys key_authsafe = PKCS12_pack_p7data(bag_stack); 309199ebb4caSwyllys 309299ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 309399ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 309499ebb4caSwyllys bag_stack = NULL; 309599ebb4caSwyllys 309699ebb4caSwyllys if (key_authsafe == NULL) { 309799ebb4caSwyllys HANDLE_PK12_ERROR 309899ebb4caSwyllys } 309999ebb4caSwyllys } 310099ebb4caSwyllys /* 310199ebb4caSwyllys * Section 3: 310299ebb4caSwyllys * 310399ebb4caSwyllys * This is where the two PKCS#7 containers, one for the certificates 310499ebb4caSwyllys * and one for the private key, are put together into a PKCS#12 310599ebb4caSwyllys * element. This final PKCS#12 element is written to the export file. 310699ebb4caSwyllys */ 310799ebb4caSwyllys 310899ebb4caSwyllys /* Start a PKCS#7 stack. */ 310999ebb4caSwyllys authsafe_stack = sk_PKCS7_new_null(); 311099ebb4caSwyllys if (authsafe_stack == NULL) { 311199ebb4caSwyllys HANDLE_PK12_ERROR 311299ebb4caSwyllys } 311399ebb4caSwyllys if (key_authsafe != NULL) { 311499ebb4caSwyllys if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) { 311599ebb4caSwyllys HANDLE_PK12_ERROR 311699ebb4caSwyllys } 311799ebb4caSwyllys } 311899ebb4caSwyllys if (cert_authsafe != NULL) { 311999ebb4caSwyllys if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) { 312099ebb4caSwyllys HANDLE_PK12_ERROR 312199ebb4caSwyllys } 312299ebb4caSwyllys } 312399ebb4caSwyllys p12_elem = PKCS12_init(NID_pkcs7_data); 312499ebb4caSwyllys if (p12_elem == NULL) { 312599ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 312699ebb4caSwyllys HANDLE_PK12_ERROR 312799ebb4caSwyllys } 312899ebb4caSwyllys 312999ebb4caSwyllys /* Put the PKCS#7 stack into the PKCS#12 element. */ 313099ebb4caSwyllys if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) { 313199ebb4caSwyllys HANDLE_PK12_ERROR 313299ebb4caSwyllys } 313399ebb4caSwyllys /* Clear away the PKCS#7 stack, we're done with it. */ 313499ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 313599ebb4caSwyllys authsafe_stack = NULL; 313699ebb4caSwyllys 313799ebb4caSwyllys /* Set the integrity MAC on the PKCS#12 element. */ 313899ebb4caSwyllys if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen, 313999ebb4caSwyllys NULL, 0, PKCS12_DEFAULT_ITER, NULL)) { 314099ebb4caSwyllys HANDLE_PK12_ERROR 314199ebb4caSwyllys } 314299ebb4caSwyllys 314399ebb4caSwyllys /* Write the PKCS#12 element to the export file. */ 314499ebb4caSwyllys if (!i2d_PKCS12_bio(bio, p12_elem)) { 314599ebb4caSwyllys HANDLE_PK12_ERROR 314699ebb4caSwyllys } 314799ebb4caSwyllys 314899ebb4caSwyllys PKCS12_free(p12_elem); 314999ebb4caSwyllys out: 315099ebb4caSwyllys if (rv != KMF_OK) { 315199ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 315299ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 315399ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 315499ebb4caSwyllys } 315599ebb4caSwyllys return (rv); 315699ebb4caSwyllys } 315799ebb4caSwyllys 315899ebb4caSwyllys static EVP_PKEY * 315999ebb4caSwyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *key) 316099ebb4caSwyllys { 316199ebb4caSwyllys RSA *rsa = NULL; 316299ebb4caSwyllys EVP_PKEY *newkey = NULL; 316399ebb4caSwyllys 316499ebb4caSwyllys if ((rsa = RSA_new()) == NULL) 316599ebb4caSwyllys return (NULL); 316699ebb4caSwyllys 316799ebb4caSwyllys if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL) 316899ebb4caSwyllys return (NULL); 316999ebb4caSwyllys 317099ebb4caSwyllys if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) == 317199ebb4caSwyllys NULL) 317299ebb4caSwyllys return (NULL); 317399ebb4caSwyllys 317499ebb4caSwyllys if (key->priexp.val != NULL) 317599ebb4caSwyllys if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len, 317699ebb4caSwyllys rsa->d)) == NULL) 317799ebb4caSwyllys return (NULL); 317899ebb4caSwyllys 317999ebb4caSwyllys if (key->prime1.val != NULL) 318099ebb4caSwyllys if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len, 318199ebb4caSwyllys rsa->p)) == NULL) 318299ebb4caSwyllys return (NULL); 318399ebb4caSwyllys 318499ebb4caSwyllys if (key->prime2.val != NULL) 318599ebb4caSwyllys if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len, 318699ebb4caSwyllys rsa->q)) == NULL) 318799ebb4caSwyllys return (NULL); 318899ebb4caSwyllys 318999ebb4caSwyllys if (key->exp1.val != NULL) 319099ebb4caSwyllys if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, 319199ebb4caSwyllys rsa->dmp1)) == NULL) 319299ebb4caSwyllys return (NULL); 319399ebb4caSwyllys 319499ebb4caSwyllys if (key->exp2.val != NULL) 319599ebb4caSwyllys if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, 319699ebb4caSwyllys rsa->dmq1)) == NULL) 319799ebb4caSwyllys return (NULL); 319899ebb4caSwyllys 319999ebb4caSwyllys if (key->coef.val != NULL) 320099ebb4caSwyllys if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len, 320199ebb4caSwyllys rsa->iqmp)) == NULL) 320299ebb4caSwyllys return (NULL); 320399ebb4caSwyllys 320499ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 320599ebb4caSwyllys return (NULL); 320699ebb4caSwyllys 320799ebb4caSwyllys (void) EVP_PKEY_set1_RSA(newkey, rsa); 320899ebb4caSwyllys 320999ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 321099ebb4caSwyllys RSA_free(rsa); 321199ebb4caSwyllys 321299ebb4caSwyllys return (newkey); 321399ebb4caSwyllys } 321499ebb4caSwyllys 321599ebb4caSwyllys static EVP_PKEY * 321699ebb4caSwyllys ImportRawDSAKey(KMF_RAW_DSA_KEY *key) 321799ebb4caSwyllys { 321899ebb4caSwyllys DSA *dsa = NULL; 321999ebb4caSwyllys EVP_PKEY *newkey = NULL; 322099ebb4caSwyllys 322199ebb4caSwyllys if ((dsa = DSA_new()) == NULL) 322299ebb4caSwyllys return (NULL); 322399ebb4caSwyllys 322499ebb4caSwyllys if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len, 322599ebb4caSwyllys dsa->p)) == NULL) 322699ebb4caSwyllys return (NULL); 322799ebb4caSwyllys 322899ebb4caSwyllys if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len, 322999ebb4caSwyllys dsa->q)) == NULL) 323099ebb4caSwyllys return (NULL); 323199ebb4caSwyllys 323299ebb4caSwyllys if ((dsa->g = BN_bin2bn(key->base.val, key->base.len, 323399ebb4caSwyllys dsa->g)) == NULL) 323499ebb4caSwyllys return (NULL); 323599ebb4caSwyllys 323699ebb4caSwyllys if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len, 323799ebb4caSwyllys dsa->priv_key)) == NULL) 323899ebb4caSwyllys return (NULL); 323999ebb4caSwyllys 324099ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 324199ebb4caSwyllys return (NULL); 324299ebb4caSwyllys 324399ebb4caSwyllys (void) EVP_PKEY_set1_DSA(newkey, dsa); 324499ebb4caSwyllys 324599ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 324699ebb4caSwyllys DSA_free(dsa); 324799ebb4caSwyllys return (newkey); 324899ebb4caSwyllys } 324999ebb4caSwyllys 325099ebb4caSwyllys static KMF_RETURN 325199ebb4caSwyllys ExportPK12FromRawData(KMF_HANDLE_T handle, 325299ebb4caSwyllys KMF_CREDENTIAL *cred, 325399ebb4caSwyllys int numcerts, KMF_X509_DER_CERT *certlist, 325499ebb4caSwyllys int numkeys, KMF_KEY_HANDLE *keylist, 325599ebb4caSwyllys char *filename) 325699ebb4caSwyllys { 325799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 325899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 325999ebb4caSwyllys BIO *bio = NULL; 326099ebb4caSwyllys X509 *xcert = NULL; 326199ebb4caSwyllys EVP_PKEY *pkey = NULL; 326299ebb4caSwyllys int i; 326399ebb4caSwyllys 326499ebb4caSwyllys /* 326599ebb4caSwyllys * Open the output file. 326699ebb4caSwyllys */ 326799ebb4caSwyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) { 326899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 326999ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 327099ebb4caSwyllys goto cleanup; 327199ebb4caSwyllys } 327299ebb4caSwyllys 327399ebb4caSwyllys if (numcerts > 0 && numkeys > 0) { 327499ebb4caSwyllys for (i = 0; rv == KMF_OK && i < numcerts; i++) { 327599ebb4caSwyllys KMF_RAW_KEY_DATA *key = NULL; 327699ebb4caSwyllys const uchar_t *p = certlist[i].certificate.Data; 327799ebb4caSwyllys long len = certlist[i].certificate.Length; 327899ebb4caSwyllys 327999ebb4caSwyllys if (i < numkeys) { 328099ebb4caSwyllys key = (KMF_RAW_KEY_DATA *)keylist[i].keyp; 328199ebb4caSwyllys 328299ebb4caSwyllys if (key->keytype == KMF_RSA) { 328399ebb4caSwyllys pkey = ImportRawRSAKey( 328499ebb4caSwyllys &key->rawdata.rsa); 328599ebb4caSwyllys } else if (key->keytype == KMF_DSA) { 328699ebb4caSwyllys pkey = ImportRawDSAKey( 328799ebb4caSwyllys &key->rawdata.dsa); 328899ebb4caSwyllys } else { 328999ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 329099ebb4caSwyllys } 329199ebb4caSwyllys } 329299ebb4caSwyllys 329399ebb4caSwyllys xcert = d2i_X509(NULL, &p, len); 329499ebb4caSwyllys if (xcert == NULL) { 329599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 329699ebb4caSwyllys rv = KMF_ERR_ENCODING; 329799ebb4caSwyllys } 329899ebb4caSwyllys /* Stick the key and the cert into a PKCS#12 file */ 329999ebb4caSwyllys rv = write_pkcs12(kmfh, bio, cred, pkey, xcert); 330099ebb4caSwyllys if (xcert) 330199ebb4caSwyllys X509_free(xcert); 330299ebb4caSwyllys if (pkey) 330399ebb4caSwyllys EVP_PKEY_free(pkey); 330499ebb4caSwyllys } 330599ebb4caSwyllys } 330699ebb4caSwyllys 330799ebb4caSwyllys cleanup: 330899ebb4caSwyllys 330999ebb4caSwyllys if (bio != NULL) 331099ebb4caSwyllys (void) BIO_free_all(bio); 331199ebb4caSwyllys 331299ebb4caSwyllys return (rv); 331399ebb4caSwyllys } 331499ebb4caSwyllys 331599ebb4caSwyllys KMF_RETURN 331699ebb4caSwyllys OpenSSL_ExportP12(KMF_HANDLE_T handle, 331799ebb4caSwyllys KMF_EXPORTP12_PARAMS *params, 331899ebb4caSwyllys int numcerts, KMF_X509_DER_CERT *certlist, 331999ebb4caSwyllys int numkeys, KMF_KEY_HANDLE *keylist, 332099ebb4caSwyllys char *filename) 332199ebb4caSwyllys { 332299ebb4caSwyllys KMF_RETURN rv; 332399ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 332499ebb4caSwyllys KMF_FINDCERT_PARAMS fcargs; 332599ebb4caSwyllys BIO *bio = NULL; 332699ebb4caSwyllys X509 *xcert = NULL; 332799ebb4caSwyllys char *fullpath = NULL; 332899ebb4caSwyllys EVP_PKEY *pkey = NULL; 332999ebb4caSwyllys 333099ebb4caSwyllys /* 333199ebb4caSwyllys * First, find the certificate. 333299ebb4caSwyllys */ 333399ebb4caSwyllys if (params == NULL) 333499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 333599ebb4caSwyllys 333699ebb4caSwyllys /* 333799ebb4caSwyllys * If the caller already sent the raw keys and certs, 333899ebb4caSwyllys * shortcut the search and just export that 333999ebb4caSwyllys * data. 334099ebb4caSwyllys * 334199ebb4caSwyllys * One *may* export a key OR a cert by itself. 334299ebb4caSwyllys */ 334399ebb4caSwyllys if (certlist != NULL || keylist != NULL) { 334499ebb4caSwyllys rv = ExportPK12FromRawData(handle, 334599ebb4caSwyllys ¶ms->p12cred, 334699ebb4caSwyllys numcerts, certlist, 334799ebb4caSwyllys numkeys, keylist, 334899ebb4caSwyllys filename); 334999ebb4caSwyllys return (rv); 335099ebb4caSwyllys } 335199ebb4caSwyllys 335299ebb4caSwyllys if (params->sslparms.certfile != NULL) { 335399ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 335499ebb4caSwyllys params->sslparms.certfile); 335599ebb4caSwyllys 335699ebb4caSwyllys if (fullpath == NULL) 335799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 335899ebb4caSwyllys 335999ebb4caSwyllys if (isdir(fullpath)) { 336099ebb4caSwyllys free(fullpath); 336199ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 336299ebb4caSwyllys } 336399ebb4caSwyllys 336499ebb4caSwyllys (void *)memset(&fcargs, 0, sizeof (fcargs)); 336599ebb4caSwyllys fcargs.kstype = params->kstype; 336699ebb4caSwyllys fcargs.certLabel = params->certLabel; 336799ebb4caSwyllys fcargs.issuer = params->issuer; 336899ebb4caSwyllys fcargs.subject = params->subject; 336999ebb4caSwyllys fcargs.serial = params->serial; 337099ebb4caSwyllys fcargs.idstr = params->idstr; 337199ebb4caSwyllys fcargs.sslparms.dirpath = NULL; 337299ebb4caSwyllys fcargs.sslparms.certfile = fullpath; 337399ebb4caSwyllys fcargs.sslparms.format = params->sslparms.format; 337499ebb4caSwyllys 337599ebb4caSwyllys rv = load_X509cert(kmfh, &fcargs, fullpath, &xcert); 337699ebb4caSwyllys if (rv != KMF_OK) 337799ebb4caSwyllys goto end; 337899ebb4caSwyllys } 337999ebb4caSwyllys 338099ebb4caSwyllys /* 338199ebb4caSwyllys * Now find the private key. 338299ebb4caSwyllys */ 338399ebb4caSwyllys if (params->sslparms.keyfile != NULL) { 338499ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 338599ebb4caSwyllys params->sslparms.keyfile); 338699ebb4caSwyllys 338799ebb4caSwyllys if (fullpath == NULL) 338899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 338999ebb4caSwyllys 339099ebb4caSwyllys if (isdir(fullpath)) { 339199ebb4caSwyllys free(fullpath); 339299ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 339399ebb4caSwyllys } 339499ebb4caSwyllys 339599ebb4caSwyllys pkey = openssl_load_key(handle, fullpath); 339699ebb4caSwyllys if (pkey == NULL) { 339799ebb4caSwyllys rv = KMF_ERR_KEY_NOT_FOUND; 339899ebb4caSwyllys goto end; 339999ebb4caSwyllys } 340099ebb4caSwyllys } 340199ebb4caSwyllys 340299ebb4caSwyllys /* 340399ebb4caSwyllys * Open the output file. 340499ebb4caSwyllys */ 340599ebb4caSwyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) { 340699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 340799ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 340899ebb4caSwyllys goto end; 340999ebb4caSwyllys } 341099ebb4caSwyllys 341199ebb4caSwyllys /* Stick the key and the cert into a PKCS#12 file */ 341299ebb4caSwyllys rv = write_pkcs12(kmfh, bio, ¶ms->p12cred, 341399ebb4caSwyllys pkey, xcert); 341499ebb4caSwyllys 341599ebb4caSwyllys end: 341699ebb4caSwyllys if (fullpath) 341799ebb4caSwyllys free(fullpath); 341899ebb4caSwyllys if (xcert) 341999ebb4caSwyllys X509_free(xcert); 342099ebb4caSwyllys if (pkey) 342199ebb4caSwyllys EVP_PKEY_free(pkey); 342299ebb4caSwyllys if (bio) 342399ebb4caSwyllys (void) BIO_free(bio); 342499ebb4caSwyllys 342599ebb4caSwyllys return (rv); 342699ebb4caSwyllys } 342799ebb4caSwyllys 342871593db2Swyllys #define MAX_CHAIN_LENGTH 100 342971593db2Swyllys /* 343071593db2Swyllys * Helper function to extract keys and certificates from 343171593db2Swyllys * a single PEM file. Typically the file should contain a 343271593db2Swyllys * private key and an associated public key wrapped in an x509 cert. 343371593db2Swyllys * However, the file may be just a list of X509 certs with no keys. 343471593db2Swyllys */ 343571593db2Swyllys static KMF_RETURN 343671593db2Swyllys extract_objects(KMF_HANDLE *kmfh, char *filename, CK_UTF8CHAR *pin, 343771593db2Swyllys CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs, 343871593db2Swyllys int *numcerts) 343971593db2Swyllys /* ARGSUSED */ 344071593db2Swyllys { 344171593db2Swyllys KMF_RETURN rv = KMF_OK; 344271593db2Swyllys FILE *fp; 344371593db2Swyllys STACK_OF(X509_INFO) *x509_info_stack; 344471593db2Swyllys int i, ncerts = 0; 344571593db2Swyllys EVP_PKEY *pkey = NULL; 344671593db2Swyllys X509_INFO *info; 344771593db2Swyllys X509 *x; 344871593db2Swyllys X509_INFO *cert_infos[MAX_CHAIN_LENGTH]; 344971593db2Swyllys KMF_DATA *certlist = NULL; 345071593db2Swyllys 345171593db2Swyllys if (priv_key) 345271593db2Swyllys *priv_key = NULL; 345371593db2Swyllys if (certs) 345471593db2Swyllys *certs = NULL; 345571593db2Swyllys fp = fopen(filename, "r"); 345671593db2Swyllys if (fp == NULL) { 345771593db2Swyllys return (KMF_ERR_OPEN_FILE); 345871593db2Swyllys } 345971593db2Swyllys x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin); 346071593db2Swyllys if (x509_info_stack == NULL) { 346171593db2Swyllys (void) fclose(fp); 346271593db2Swyllys return (KMF_ERR_ENCODING); 346371593db2Swyllys } 346471593db2Swyllys 346571593db2Swyllys /*LINTED*/ 346671593db2Swyllys while ((info = sk_X509_INFO_pop(x509_info_stack)) != NULL && 346771593db2Swyllys ncerts < MAX_CHAIN_LENGTH) { 346871593db2Swyllys cert_infos[ncerts] = info; 346971593db2Swyllys ncerts++; 347071593db2Swyllys } 347171593db2Swyllys 347271593db2Swyllys if (ncerts == 0) { 347371593db2Swyllys (void) fclose(fp); 347471593db2Swyllys return (KMF_ERR_CERT_NOT_FOUND); 347571593db2Swyllys } 347671593db2Swyllys 347771593db2Swyllys if (priv_key != NULL) { 347871593db2Swyllys rewind(fp); 347971593db2Swyllys pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin); 348071593db2Swyllys } 348171593db2Swyllys (void) fclose(fp); 348271593db2Swyllys 348371593db2Swyllys x = cert_infos[ncerts - 1]->x509; 348471593db2Swyllys /* 348571593db2Swyllys * Make sure the private key matchs the last cert in the file. 348671593db2Swyllys */ 348771593db2Swyllys if (pkey != NULL && !X509_check_private_key(x, pkey)) { 348871593db2Swyllys EVP_PKEY_free(pkey); 348971593db2Swyllys return (KMF_ERR_KEY_MISMATCH); 349071593db2Swyllys } 349171593db2Swyllys 349271593db2Swyllys certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA)); 349371593db2Swyllys if (certlist == NULL) { 349471593db2Swyllys if (pkey != NULL) 349571593db2Swyllys EVP_PKEY_free(pkey); 349671593db2Swyllys X509_INFO_free(info); 349771593db2Swyllys return (KMF_ERR_MEMORY); 349871593db2Swyllys } 349971593db2Swyllys 350071593db2Swyllys /* 350171593db2Swyllys * Convert all of the certs to DER format. 350271593db2Swyllys */ 350371593db2Swyllys for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) { 350471593db2Swyllys info = cert_infos[ncerts - 1 - i]; 350571593db2Swyllys 350671593db2Swyllys rv = ssl_cert2KMFDATA(kmfh, info->x509, &certlist[i]); 350771593db2Swyllys 350871593db2Swyllys if (rv != KMF_OK) { 350971593db2Swyllys free(certlist); 351071593db2Swyllys certlist = NULL; 351171593db2Swyllys ncerts = 0; 351271593db2Swyllys } 351371593db2Swyllys X509_INFO_free(info); 351471593db2Swyllys } 351571593db2Swyllys 351671593db2Swyllys if (numcerts != NULL) 351771593db2Swyllys *numcerts = ncerts; 351871593db2Swyllys if (certs != NULL) 351971593db2Swyllys *certs = certlist; 352071593db2Swyllys 352171593db2Swyllys if (priv_key == NULL && pkey != NULL) 352271593db2Swyllys EVP_PKEY_free(pkey); 352371593db2Swyllys else if (priv_key != NULL && pkey != NULL) 352471593db2Swyllys *priv_key = pkey; 352571593db2Swyllys 352671593db2Swyllys return (rv); 352771593db2Swyllys } 352871593db2Swyllys 352999ebb4caSwyllys /* 353099ebb4caSwyllys * Helper function to decrypt and parse PKCS#12 import file. 353199ebb4caSwyllys */ 353299ebb4caSwyllys static KMF_RETURN 353399ebb4caSwyllys extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 353499ebb4caSwyllys EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca) 353599ebb4caSwyllys /* ARGSUSED */ 353699ebb4caSwyllys { 353799ebb4caSwyllys PKCS12 *pk12, *pk12_tmp; 353899ebb4caSwyllys EVP_PKEY *temp_pkey = NULL; 353999ebb4caSwyllys X509 *temp_cert = NULL; 354099ebb4caSwyllys STACK_OF(X509) *temp_ca = NULL; 354199ebb4caSwyllys 354299ebb4caSwyllys if ((pk12 = PKCS12_new()) == NULL) { 354399ebb4caSwyllys return (KMF_ERR_MEMORY); 354499ebb4caSwyllys } 354599ebb4caSwyllys 354699ebb4caSwyllys if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) { 354799ebb4caSwyllys /* This is ok; it seems to mean there is no more to read. */ 354899ebb4caSwyllys if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 && 354999ebb4caSwyllys ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG) 355099ebb4caSwyllys goto end_extract_pkcs12; 355199ebb4caSwyllys 355299ebb4caSwyllys PKCS12_free(pk12); 355399ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 355499ebb4caSwyllys } 355599ebb4caSwyllys pk12 = pk12_tmp; 355699ebb4caSwyllys 355799ebb4caSwyllys if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert, 355899ebb4caSwyllys &temp_ca) <= 0) { 355999ebb4caSwyllys PKCS12_free(pk12); 356099ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 356199ebb4caSwyllys } 356299ebb4caSwyllys 356399ebb4caSwyllys end_extract_pkcs12: 356499ebb4caSwyllys 356599ebb4caSwyllys *priv_key = temp_pkey; 356699ebb4caSwyllys *cert = temp_cert; 356799ebb4caSwyllys *ca = temp_ca; 356899ebb4caSwyllys 356999ebb4caSwyllys PKCS12_free(pk12); 357099ebb4caSwyllys return (KMF_OK); 357199ebb4caSwyllys } 357299ebb4caSwyllys 357399ebb4caSwyllys static KMF_RETURN 357499ebb4caSwyllys sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to) 357599ebb4caSwyllys { 357699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 357799ebb4caSwyllys uint32_t sz; 357899ebb4caSwyllys 357999ebb4caSwyllys sz = BN_num_bytes(from); 358099ebb4caSwyllys to->val = (uchar_t *)malloc(sz); 358199ebb4caSwyllys if (to->val == NULL) 358299ebb4caSwyllys return (KMF_ERR_MEMORY); 358399ebb4caSwyllys 358499ebb4caSwyllys if ((to->len = BN_bn2bin(from, to->val)) != sz) { 358599ebb4caSwyllys free(to->val); 358699ebb4caSwyllys to->val = NULL; 358799ebb4caSwyllys to->len = 0; 358899ebb4caSwyllys rv = KMF_ERR_MEMORY; 358999ebb4caSwyllys } 359099ebb4caSwyllys 359199ebb4caSwyllys return (rv); 359299ebb4caSwyllys } 359399ebb4caSwyllys 359499ebb4caSwyllys static KMF_RETURN 359599ebb4caSwyllys exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) 359699ebb4caSwyllys { 359799ebb4caSwyllys KMF_RETURN rv; 359899ebb4caSwyllys KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa; 359999ebb4caSwyllys 360099ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY)); 360199ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK) 360299ebb4caSwyllys goto cleanup; 360399ebb4caSwyllys 360499ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK) 360599ebb4caSwyllys goto cleanup; 360699ebb4caSwyllys 360799ebb4caSwyllys if (rsa->d != NULL) 360899ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK) 360999ebb4caSwyllys goto cleanup; 361099ebb4caSwyllys 361199ebb4caSwyllys if (rsa->p != NULL) 361299ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK) 361399ebb4caSwyllys goto cleanup; 361499ebb4caSwyllys 361599ebb4caSwyllys if (rsa->q != NULL) 361699ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK) 361799ebb4caSwyllys goto cleanup; 361899ebb4caSwyllys 361999ebb4caSwyllys if (rsa->dmp1 != NULL) 362099ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK) 362199ebb4caSwyllys goto cleanup; 362299ebb4caSwyllys 362399ebb4caSwyllys if (rsa->dmq1 != NULL) 362499ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK) 362599ebb4caSwyllys goto cleanup; 362699ebb4caSwyllys 362799ebb4caSwyllys if (rsa->iqmp != NULL) 362899ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK) 362999ebb4caSwyllys goto cleanup; 363099ebb4caSwyllys cleanup: 363199ebb4caSwyllys if (rv != KMF_OK) 363299ebb4caSwyllys KMF_FreeRawKey(key); 363399ebb4caSwyllys else 363499ebb4caSwyllys key->keytype = KMF_RSA; 363599ebb4caSwyllys 363699ebb4caSwyllys /* 363799ebb4caSwyllys * Free the reference to this key, SSL will not actually free 363899ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 363999ebb4caSwyllys */ 364099ebb4caSwyllys RSA_free(rsa); 364199ebb4caSwyllys 364299ebb4caSwyllys return (rv); 364399ebb4caSwyllys } 364499ebb4caSwyllys 364599ebb4caSwyllys static KMF_RETURN 364699ebb4caSwyllys exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) 364799ebb4caSwyllys { 364899ebb4caSwyllys KMF_RETURN rv; 364999ebb4caSwyllys KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa; 365099ebb4caSwyllys 365199ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY)); 365299ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK) 365399ebb4caSwyllys goto cleanup; 365499ebb4caSwyllys 365599ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK) 365699ebb4caSwyllys goto cleanup; 365799ebb4caSwyllys 365899ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK) 365999ebb4caSwyllys goto cleanup; 366099ebb4caSwyllys 366199ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK) 366299ebb4caSwyllys goto cleanup; 366399ebb4caSwyllys 366499ebb4caSwyllys cleanup: 366599ebb4caSwyllys if (rv != KMF_OK) 366699ebb4caSwyllys KMF_FreeRawKey(key); 366799ebb4caSwyllys else 366899ebb4caSwyllys key->keytype = KMF_DSA; 366999ebb4caSwyllys 367099ebb4caSwyllys /* 367199ebb4caSwyllys * Free the reference to this key, SSL will not actually free 367299ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 367399ebb4caSwyllys */ 367499ebb4caSwyllys DSA_free(dsa); 367599ebb4caSwyllys 367699ebb4caSwyllys return (rv); 367799ebb4caSwyllys } 367899ebb4caSwyllys 367999ebb4caSwyllys static KMF_RETURN 368099ebb4caSwyllys add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert, 368199ebb4caSwyllys KMF_DATA **certlist, int *ncerts) 368299ebb4caSwyllys { 368399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 368499ebb4caSwyllys KMF_DATA *list = (*certlist); 368599ebb4caSwyllys KMF_DATA cert; 368699ebb4caSwyllys int n = (*ncerts); 368799ebb4caSwyllys 368899ebb4caSwyllys if (list == NULL) { 368999ebb4caSwyllys list = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 369099ebb4caSwyllys } else { 369199ebb4caSwyllys list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1)); 369299ebb4caSwyllys } 369399ebb4caSwyllys 369499ebb4caSwyllys if (list == NULL) 369599ebb4caSwyllys return (KMF_ERR_MEMORY); 369699ebb4caSwyllys 369799ebb4caSwyllys rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert); 369899ebb4caSwyllys if (rv == KMF_OK) { 369999ebb4caSwyllys list[n] = cert; 370099ebb4caSwyllys (*ncerts) = n + 1; 370199ebb4caSwyllys 370299ebb4caSwyllys *certlist = list; 370399ebb4caSwyllys } else { 370499ebb4caSwyllys free(list); 370599ebb4caSwyllys } 370699ebb4caSwyllys 370799ebb4caSwyllys return (rv); 370899ebb4caSwyllys } 370999ebb4caSwyllys 371099ebb4caSwyllys static KMF_RETURN 371199ebb4caSwyllys add_key_to_list(KMF_RAW_KEY_DATA **keylist, 371299ebb4caSwyllys KMF_RAW_KEY_DATA *newkey, int *nkeys) 371399ebb4caSwyllys { 371499ebb4caSwyllys KMF_RAW_KEY_DATA *list = (*keylist); 371599ebb4caSwyllys int n = (*nkeys); 371699ebb4caSwyllys 371799ebb4caSwyllys if (list == NULL) { 371899ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA)); 371999ebb4caSwyllys } else { 372099ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)realloc(list, 372199ebb4caSwyllys sizeof (KMF_RAW_KEY_DATA) * (n + 1)); 372299ebb4caSwyllys } 372399ebb4caSwyllys 372499ebb4caSwyllys if (list == NULL) 372599ebb4caSwyllys return (KMF_ERR_MEMORY); 372699ebb4caSwyllys 372799ebb4caSwyllys list[n] = *newkey; 372899ebb4caSwyllys (*nkeys) = n + 1; 372999ebb4caSwyllys 373099ebb4caSwyllys *keylist = list; 373199ebb4caSwyllys 373299ebb4caSwyllys return (KMF_OK); 373399ebb4caSwyllys } 373499ebb4caSwyllys 373599ebb4caSwyllys 373699ebb4caSwyllys static KMF_RETURN 373799ebb4caSwyllys convertPK12Objects( 373899ebb4caSwyllys KMF_HANDLE *kmfh, 373999ebb4caSwyllys EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts, 374099ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys, 374199ebb4caSwyllys KMF_DATA **certlist, int *ncerts) 374299ebb4caSwyllys { 374399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 374499ebb4caSwyllys KMF_RAW_KEY_DATA key; 374599ebb4caSwyllys int i; 374699ebb4caSwyllys 374799ebb4caSwyllys if (sslkey != NULL) { 374899ebb4caSwyllys /* Convert SSL key to raw key */ 374999ebb4caSwyllys switch (sslkey->type) { 375099ebb4caSwyllys case EVP_PKEY_RSA: 375199ebb4caSwyllys rv = exportRawRSAKey(EVP_PKEY_get1_RSA(sslkey), 375299ebb4caSwyllys &key); 375399ebb4caSwyllys if (rv != KMF_OK) 375499ebb4caSwyllys return (rv); 375599ebb4caSwyllys 375699ebb4caSwyllys break; 375799ebb4caSwyllys case EVP_PKEY_DSA: 375899ebb4caSwyllys rv = exportRawDSAKey(EVP_PKEY_get1_DSA(sslkey), 375999ebb4caSwyllys &key); 376099ebb4caSwyllys if (rv != KMF_OK) 376199ebb4caSwyllys return (rv); 376299ebb4caSwyllys 376399ebb4caSwyllys break; 376499ebb4caSwyllys default: 376599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 376699ebb4caSwyllys } 376799ebb4caSwyllys 376899ebb4caSwyllys rv = add_key_to_list(keylist, &key, nkeys); 376999ebb4caSwyllys if (rv != KMF_OK) 377099ebb4caSwyllys return (rv); 377199ebb4caSwyllys } 377299ebb4caSwyllys 377399ebb4caSwyllys /* Now add the certificate to the certlist */ 377499ebb4caSwyllys if (sslcert != NULL) { 377599ebb4caSwyllys rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts); 377699ebb4caSwyllys if (rv != KMF_OK) 377799ebb4caSwyllys return (rv); 377899ebb4caSwyllys } 377999ebb4caSwyllys 378099ebb4caSwyllys /* Also add any included CA certs to the list */ 378171593db2Swyllys for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) { 378299ebb4caSwyllys X509 *c; 378399ebb4caSwyllys /* 378499ebb4caSwyllys * sk_X509_value() is macro that embeds a cast to (X509 *). 378599ebb4caSwyllys * Here it translates into ((X509 *)sk_value((ca), (i))). 378699ebb4caSwyllys * Lint is complaining about the embedded casting, and 378799ebb4caSwyllys * to fix it, you need to fix openssl header files. 378899ebb4caSwyllys */ 378999ebb4caSwyllys /* LINTED E_BAD_PTR_CAST_ALIGN */ 379099ebb4caSwyllys c = sk_X509_value(sslcacerts, i); 379199ebb4caSwyllys 379299ebb4caSwyllys /* Now add the ca cert to the certlist */ 379399ebb4caSwyllys rv = add_cert_to_list(kmfh, c, certlist, ncerts); 379499ebb4caSwyllys if (rv != KMF_OK) 379599ebb4caSwyllys return (rv); 379699ebb4caSwyllys } 379799ebb4caSwyllys return (rv); 379899ebb4caSwyllys } 379999ebb4caSwyllys 380099ebb4caSwyllys KMF_RETURN 380199ebb4caSwyllys openssl_read_pkcs12(KMF_HANDLE *kmfh, 380299ebb4caSwyllys char *filename, KMF_CREDENTIAL *cred, 380399ebb4caSwyllys KMF_DATA **certlist, int *ncerts, 380499ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys) 380599ebb4caSwyllys { 380699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 380799ebb4caSwyllys BIO *bio = NULL; 380899ebb4caSwyllys EVP_PKEY *privkey = NULL; 380999ebb4caSwyllys X509 *cert = NULL; 381099ebb4caSwyllys STACK_OF(X509) *cacerts = NULL; 381199ebb4caSwyllys 381299ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 381399ebb4caSwyllys if (bio == NULL) { 381499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 381599ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 381699ebb4caSwyllys goto end; 381799ebb4caSwyllys } 381899ebb4caSwyllys 381999ebb4caSwyllys *certlist = NULL; 382099ebb4caSwyllys *keylist = NULL; 382199ebb4caSwyllys *ncerts = 0; 382299ebb4caSwyllys *nkeys = 0; 382399ebb4caSwyllys while (rv == KMF_OK) { 382499ebb4caSwyllys rv = extract_pkcs12(bio, 382599ebb4caSwyllys (uchar_t *)cred->cred, 382699ebb4caSwyllys (uint32_t)cred->credlen, 382799ebb4caSwyllys &privkey, &cert, &cacerts); 382899ebb4caSwyllys 382999ebb4caSwyllys /* Reached end of import file? */ 383099ebb4caSwyllys if (rv == KMF_OK && privkey == NULL && 383199ebb4caSwyllys cert == NULL && cacerts == NULL) 383299ebb4caSwyllys break; 383399ebb4caSwyllys 383499ebb4caSwyllys if (rv == KMF_OK) 383599ebb4caSwyllys /* Convert keys and certs to exportable format */ 383699ebb4caSwyllys rv = convertPK12Objects(kmfh, privkey, cert, cacerts, 383799ebb4caSwyllys keylist, nkeys, certlist, ncerts); 383899ebb4caSwyllys 383999ebb4caSwyllys if (privkey) 384099ebb4caSwyllys EVP_PKEY_free(privkey); 384199ebb4caSwyllys 384299ebb4caSwyllys if (cert) 384399ebb4caSwyllys X509_free(cert); 384499ebb4caSwyllys 384599ebb4caSwyllys if (cacerts) 384699ebb4caSwyllys sk_X509_free(cacerts); 384799ebb4caSwyllys } 384899ebb4caSwyllys end: 384999ebb4caSwyllys if (bio != NULL) 385099ebb4caSwyllys (void) BIO_free(bio); 385199ebb4caSwyllys 385299ebb4caSwyllys if (privkey) 385399ebb4caSwyllys EVP_PKEY_free(privkey); 385499ebb4caSwyllys 385599ebb4caSwyllys if (cert) 385699ebb4caSwyllys X509_free(cert); 385799ebb4caSwyllys 385899ebb4caSwyllys if (cacerts) 385999ebb4caSwyllys sk_X509_free(cacerts); 386099ebb4caSwyllys 386199ebb4caSwyllys return (rv); 386299ebb4caSwyllys } 386399ebb4caSwyllys 386499ebb4caSwyllys KMF_RETURN 386571593db2Swyllys openssl_import_keypair(KMF_HANDLE *kmfh, 386671593db2Swyllys char *filename, KMF_CREDENTIAL *cred, 386771593db2Swyllys KMF_DATA **certlist, int *ncerts, 386871593db2Swyllys KMF_RAW_KEY_DATA **keylist, int *nkeys) 386971593db2Swyllys { 387071593db2Swyllys KMF_RETURN rv = KMF_OK; 387171593db2Swyllys EVP_PKEY *privkey = NULL; 387271593db2Swyllys KMF_ENCODE_FORMAT format; 387371593db2Swyllys 387471593db2Swyllys /* 387571593db2Swyllys * auto-detect the file format, regardless of what 387671593db2Swyllys * the 'format' parameters in the params say. 387771593db2Swyllys */ 387871593db2Swyllys rv = KMF_GetFileFormat(filename, &format); 387971593db2Swyllys if (rv != KMF_OK) { 388071593db2Swyllys if (rv == KMF_ERR_OPEN_FILE) 388171593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 388271593db2Swyllys return (rv); 388371593db2Swyllys } 388471593db2Swyllys 388571593db2Swyllys /* This function only works on PEM files */ 388671593db2Swyllys if (format != KMF_FORMAT_PEM && 388771593db2Swyllys format != KMF_FORMAT_PEM_KEYPAIR) 388871593db2Swyllys return (KMF_ERR_ENCODING); 388971593db2Swyllys 389071593db2Swyllys *certlist = NULL; 389171593db2Swyllys *keylist = NULL; 389271593db2Swyllys *ncerts = 0; 389371593db2Swyllys *nkeys = 0; 389471593db2Swyllys rv = extract_objects(kmfh, filename, 389571593db2Swyllys (uchar_t *)cred->cred, 389671593db2Swyllys (uint32_t)cred->credlen, 389771593db2Swyllys &privkey, certlist, ncerts); 389871593db2Swyllys 389971593db2Swyllys /* Reached end of import file? */ 390071593db2Swyllys if (rv == KMF_OK) 390171593db2Swyllys /* Convert keys and certs to exportable format */ 390271593db2Swyllys rv = convertPK12Objects(kmfh, privkey, NULL, NULL, 390371593db2Swyllys keylist, nkeys, NULL, NULL); 390471593db2Swyllys 390571593db2Swyllys end: 390671593db2Swyllys if (privkey) 390771593db2Swyllys EVP_PKEY_free(privkey); 390871593db2Swyllys 390971593db2Swyllys return (rv); 391071593db2Swyllys } 391171593db2Swyllys 391271593db2Swyllys KMF_RETURN 391399ebb4caSwyllys OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, 391499ebb4caSwyllys KMF_RAW_KEY_DATA *key) 391599ebb4caSwyllys { 391699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 391799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 391899ebb4caSwyllys char *fullpath; 391999ebb4caSwyllys EVP_PKEY *pkey = NULL; 392099ebb4caSwyllys BIO *bio = NULL; 392199ebb4caSwyllys 392299ebb4caSwyllys if (key != NULL) { 392399ebb4caSwyllys if (key->keytype == KMF_RSA) { 392499ebb4caSwyllys pkey = ImportRawRSAKey(&key->rawdata.rsa); 392599ebb4caSwyllys } else if (key->keytype == KMF_DSA) { 392699ebb4caSwyllys pkey = ImportRawDSAKey(&key->rawdata.dsa); 392799ebb4caSwyllys } else { 392899ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 392999ebb4caSwyllys } 393099ebb4caSwyllys } else { 393199ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 393299ebb4caSwyllys } 393399ebb4caSwyllys if (rv != KMF_OK || pkey == NULL) 393499ebb4caSwyllys return (rv); 393599ebb4caSwyllys 393699ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 393799ebb4caSwyllys params->sslparms.keyfile); 393899ebb4caSwyllys 393999ebb4caSwyllys if (fullpath == NULL) 394099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 394199ebb4caSwyllys 394299ebb4caSwyllys /* If the requested file exists, return an error */ 394399ebb4caSwyllys if (access(fullpath, F_OK) == 0) { 394499ebb4caSwyllys free(fullpath); 394599ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 394699ebb4caSwyllys } 394799ebb4caSwyllys 394899ebb4caSwyllys bio = BIO_new_file(fullpath, "wb"); 394999ebb4caSwyllys if (bio == NULL) { 395099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 395199ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 395299ebb4caSwyllys goto cleanup; 395399ebb4caSwyllys } 395499ebb4caSwyllys 395599ebb4caSwyllys rv = ssl_write_private_key(kmfh, 395699ebb4caSwyllys params->sslparms.format, 395799ebb4caSwyllys bio, ¶ms->cred, pkey); 395899ebb4caSwyllys 395999ebb4caSwyllys cleanup: 396099ebb4caSwyllys if (fullpath) 396199ebb4caSwyllys free(fullpath); 396299ebb4caSwyllys 396399ebb4caSwyllys if (pkey) 396499ebb4caSwyllys EVP_PKEY_free(pkey); 396599ebb4caSwyllys 396699ebb4caSwyllys if (bio) 396799ebb4caSwyllys (void) BIO_free(bio); 396899ebb4caSwyllys 396999ebb4caSwyllys /* Protect the file by making it read-only */ 397099ebb4caSwyllys if (rv == KMF_OK) { 397199ebb4caSwyllys (void) chmod(fullpath, 0400); 397299ebb4caSwyllys } 397399ebb4caSwyllys return (rv); 397499ebb4caSwyllys } 397599ebb4caSwyllys 397699ebb4caSwyllys static KMF_RETURN 397799ebb4caSwyllys create_deskey(DES_cblock **deskey) 397899ebb4caSwyllys { 397999ebb4caSwyllys DES_cblock *key; 398099ebb4caSwyllys 398199ebb4caSwyllys key = (DES_cblock *) malloc(sizeof (DES_cblock)); 398299ebb4caSwyllys if (key == NULL) { 398399ebb4caSwyllys return (KMF_ERR_MEMORY); 398499ebb4caSwyllys } 398599ebb4caSwyllys 398699ebb4caSwyllys if (DES_random_key(key) == 0) { 398799ebb4caSwyllys free(key); 398899ebb4caSwyllys return (KMF_ERR_KEYGEN_FAILED); 398999ebb4caSwyllys } 399099ebb4caSwyllys 399199ebb4caSwyllys *deskey = key; 399299ebb4caSwyllys return (KMF_OK); 399399ebb4caSwyllys } 399499ebb4caSwyllys 399599ebb4caSwyllys #define KEYGEN_RETRY 3 399699ebb4caSwyllys #define DES3_KEY_SIZE 24 399799ebb4caSwyllys 399899ebb4caSwyllys static KMF_RETURN 399999ebb4caSwyllys create_des3key(unsigned char **des3key) 400099ebb4caSwyllys { 400199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 400299ebb4caSwyllys DES_cblock *deskey1 = NULL; 400399ebb4caSwyllys DES_cblock *deskey2 = NULL; 400499ebb4caSwyllys DES_cblock *deskey3 = NULL; 400599ebb4caSwyllys unsigned char *newkey = NULL; 400699ebb4caSwyllys int retry; 400799ebb4caSwyllys 400899ebb4caSwyllys if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) { 400999ebb4caSwyllys return (KMF_ERR_MEMORY); 401099ebb4caSwyllys } 401199ebb4caSwyllys 401299ebb4caSwyllys /* create the 1st DES key */ 401399ebb4caSwyllys if ((ret = create_deskey(&deskey1)) != KMF_OK) { 401499ebb4caSwyllys goto out; 401599ebb4caSwyllys } 401699ebb4caSwyllys 401799ebb4caSwyllys /* 401899ebb4caSwyllys * Create the 2nd DES key and make sure its value is different 401999ebb4caSwyllys * from the 1st DES key. 402099ebb4caSwyllys */ 402199ebb4caSwyllys retry = 0; 402299ebb4caSwyllys do { 402399ebb4caSwyllys if (deskey2 != NULL) { 402499ebb4caSwyllys free(deskey2); 402599ebb4caSwyllys deskey2 = NULL; 402699ebb4caSwyllys } 402799ebb4caSwyllys 402899ebb4caSwyllys if ((ret = create_deskey(&deskey2)) != KMF_OK) { 402999ebb4caSwyllys goto out; 403099ebb4caSwyllys } 403199ebb4caSwyllys 403299ebb4caSwyllys if (memcmp((const void *) deskey1, (const void *) deskey2, 8) 403399ebb4caSwyllys == 0) { 403499ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 403599ebb4caSwyllys retry++; 403699ebb4caSwyllys } 403799ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 403899ebb4caSwyllys 403999ebb4caSwyllys if (ret != KMF_OK) { 404099ebb4caSwyllys goto out; 404199ebb4caSwyllys } 404299ebb4caSwyllys 404399ebb4caSwyllys /* 404499ebb4caSwyllys * Create the 3rd DES key and make sure its value is different 404599ebb4caSwyllys * from the 2nd DES key. 404699ebb4caSwyllys */ 404799ebb4caSwyllys retry = 0; 404899ebb4caSwyllys do { 404999ebb4caSwyllys if (deskey3 != NULL) { 405099ebb4caSwyllys free(deskey3); 405199ebb4caSwyllys deskey3 = NULL; 405299ebb4caSwyllys } 405399ebb4caSwyllys 405499ebb4caSwyllys if ((ret = create_deskey(&deskey3)) != KMF_OK) { 405599ebb4caSwyllys goto out; 405699ebb4caSwyllys } 405799ebb4caSwyllys 405899ebb4caSwyllys if (memcmp((const void *)deskey2, (const void *)deskey3, 8) 405999ebb4caSwyllys == 0) { 406099ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 406199ebb4caSwyllys retry++; 406299ebb4caSwyllys } 406399ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 406499ebb4caSwyllys 406599ebb4caSwyllys if (ret != KMF_OK) { 406699ebb4caSwyllys goto out; 406799ebb4caSwyllys } 406899ebb4caSwyllys 406999ebb4caSwyllys /* Concatenate 3 DES keys into a DES3 key */ 407099ebb4caSwyllys (void) memcpy((void *)newkey, (const void *)deskey1, 8); 407199ebb4caSwyllys (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8); 407299ebb4caSwyllys (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8); 407399ebb4caSwyllys *des3key = newkey; 407499ebb4caSwyllys 407599ebb4caSwyllys out: 407699ebb4caSwyllys if (deskey1 != NULL) 407799ebb4caSwyllys free(deskey1); 407899ebb4caSwyllys 407999ebb4caSwyllys if (deskey2 != NULL) 408099ebb4caSwyllys free(deskey2); 408199ebb4caSwyllys 408299ebb4caSwyllys if (deskey3 != NULL) 408399ebb4caSwyllys free(deskey3); 408499ebb4caSwyllys 408599ebb4caSwyllys if (ret != KMF_OK && newkey != NULL) 408699ebb4caSwyllys free(newkey); 408799ebb4caSwyllys 408899ebb4caSwyllys return (ret); 408999ebb4caSwyllys } 409099ebb4caSwyllys 409199ebb4caSwyllys KMF_RETURN 409299ebb4caSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, 409399ebb4caSwyllys KMF_KEY_HANDLE *symkey) 409499ebb4caSwyllys { 409599ebb4caSwyllys KMF_RETURN ret = KMF_OK; 409699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 409799ebb4caSwyllys char *fullpath = NULL; 409899ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 409999ebb4caSwyllys DES_cblock *deskey = NULL; 410099ebb4caSwyllys unsigned char *des3key = NULL; 410199ebb4caSwyllys unsigned char *random = NULL; 410299ebb4caSwyllys int fd = -1; 410399ebb4caSwyllys 410499ebb4caSwyllys if (kmfh == NULL) 410599ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 410699ebb4caSwyllys 410799ebb4caSwyllys if (params == NULL || params->sslparms.keyfile == NULL) { 410899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 410999ebb4caSwyllys } 411099ebb4caSwyllys 411199ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 411299ebb4caSwyllys params->sslparms.keyfile); 411399ebb4caSwyllys if (fullpath == NULL) 411499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 411599ebb4caSwyllys 411699ebb4caSwyllys /* If the requested file exists, return an error */ 411799ebb4caSwyllys if (access(fullpath, F_OK) == 0) { 411899ebb4caSwyllys free(fullpath); 411999ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 412099ebb4caSwyllys } 412199ebb4caSwyllys 412299ebb4caSwyllys fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400); 412399ebb4caSwyllys if (fd == -1) { 412499ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 412599ebb4caSwyllys goto out; 412699ebb4caSwyllys } 412799ebb4caSwyllys 412899ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 412999ebb4caSwyllys if (rkey == NULL) { 413099ebb4caSwyllys ret = KMF_ERR_MEMORY; 413199ebb4caSwyllys goto out; 413299ebb4caSwyllys } 413399ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 413499ebb4caSwyllys 413599ebb4caSwyllys if (params->keytype == KMF_DES) { 413699ebb4caSwyllys if ((ret = create_deskey(&deskey)) != KMF_OK) { 413799ebb4caSwyllys goto out; 413899ebb4caSwyllys } 413999ebb4caSwyllys rkey->keydata.val = (uchar_t *)deskey; 414099ebb4caSwyllys rkey->keydata.len = 8; 414199ebb4caSwyllys 414299ebb4caSwyllys symkey->keyalg = KMF_DES; 414399ebb4caSwyllys 414499ebb4caSwyllys } else if (params->keytype == KMF_DES3) { 414599ebb4caSwyllys if ((ret = create_des3key(&des3key)) != KMF_OK) { 414699ebb4caSwyllys goto out; 414799ebb4caSwyllys } 414899ebb4caSwyllys rkey->keydata.val = (uchar_t *)des3key; 414999ebb4caSwyllys rkey->keydata.len = DES3_KEY_SIZE; 415099ebb4caSwyllys symkey->keyalg = KMF_DES3; 415199ebb4caSwyllys 415299ebb4caSwyllys } else if (params->keytype == KMF_AES || params->keytype == KMF_RC4) { 415399ebb4caSwyllys int bytes; 415499ebb4caSwyllys 415599ebb4caSwyllys if (params->keylength % 8 != 0) { 415699ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 415799ebb4caSwyllys goto out; 415899ebb4caSwyllys } 415999ebb4caSwyllys 416099ebb4caSwyllys if (params->keytype == KMF_AES) { 416199ebb4caSwyllys if (params->keylength != 128 && 416299ebb4caSwyllys params->keylength != 192 && 416399ebb4caSwyllys params->keylength != 256) { 416499ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 416599ebb4caSwyllys goto out; 416699ebb4caSwyllys } 416799ebb4caSwyllys } 416899ebb4caSwyllys 416999ebb4caSwyllys bytes = params->keylength/8; 417099ebb4caSwyllys random = malloc(bytes); 417199ebb4caSwyllys if (random == NULL) { 417299ebb4caSwyllys ret = KMF_ERR_MEMORY; 417399ebb4caSwyllys goto out; 417499ebb4caSwyllys } 417599ebb4caSwyllys if (RAND_bytes(random, bytes) != 1) { 417699ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 417799ebb4caSwyllys goto out; 417899ebb4caSwyllys } 417999ebb4caSwyllys 418099ebb4caSwyllys rkey->keydata.val = (uchar_t *)random; 418199ebb4caSwyllys rkey->keydata.len = bytes; 418299ebb4caSwyllys symkey->keyalg = params->keytype; 418399ebb4caSwyllys 418499ebb4caSwyllys } else { 418599ebb4caSwyllys ret = KMF_ERR_BAD_KEY_TYPE; 418699ebb4caSwyllys goto out; 418799ebb4caSwyllys } 418899ebb4caSwyllys 418999ebb4caSwyllys (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len); 419099ebb4caSwyllys 419199ebb4caSwyllys symkey->kstype = KMF_KEYSTORE_OPENSSL; 419299ebb4caSwyllys symkey->keyclass = KMF_SYMMETRIC; 419399ebb4caSwyllys symkey->keylabel = (char *)fullpath; 419499ebb4caSwyllys symkey->israw = TRUE; 419599ebb4caSwyllys symkey->keyp = rkey; 419699ebb4caSwyllys 419799ebb4caSwyllys out: 419899ebb4caSwyllys if (fd != -1) 419999ebb4caSwyllys (void) close(fd); 420099ebb4caSwyllys 420199ebb4caSwyllys if (ret != KMF_OK && fullpath != NULL) { 420299ebb4caSwyllys free(fullpath); 420399ebb4caSwyllys } 420499ebb4caSwyllys if (ret != KMF_OK) { 420599ebb4caSwyllys KMF_FreeRawSymKey(rkey); 420699ebb4caSwyllys symkey->keyp = NULL; 420799ebb4caSwyllys symkey->keyalg = KMF_KEYALG_NONE; 420899ebb4caSwyllys } 420999ebb4caSwyllys 421099ebb4caSwyllys return (ret); 421199ebb4caSwyllys } 421299ebb4caSwyllys 421399ebb4caSwyllys 421499ebb4caSwyllys KMF_RETURN 421599ebb4caSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params) 421699ebb4caSwyllys { 421799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 421899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 421999ebb4caSwyllys BIO *bcrl = NULL; 422099ebb4caSwyllys X509_CRL *xcrl = NULL; 422199ebb4caSwyllys X509 *xcert = NULL; 422299ebb4caSwyllys EVP_PKEY *pkey; 422399ebb4caSwyllys int sslret; 422499ebb4caSwyllys KMF_ENCODE_FORMAT crl_format; 422599ebb4caSwyllys unsigned char *p; 422699ebb4caSwyllys long len; 422799ebb4caSwyllys 422899ebb4caSwyllys if (params->crl_name == NULL || params->tacert == NULL) { 422999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 423099ebb4caSwyllys } 423199ebb4caSwyllys 423299ebb4caSwyllys ret = KMF_GetFileFormat(params->crl_name, &crl_format); 423399ebb4caSwyllys if (ret != KMF_OK) 423499ebb4caSwyllys return (ret); 423599ebb4caSwyllys 423699ebb4caSwyllys bcrl = BIO_new_file(params->crl_name, "rb"); 423799ebb4caSwyllys if (bcrl == NULL) { 423899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 423999ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 424099ebb4caSwyllys goto cleanup; 424199ebb4caSwyllys } 424299ebb4caSwyllys 424399ebb4caSwyllys if (crl_format == KMF_FORMAT_ASN1) { 424499ebb4caSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 424599ebb4caSwyllys } else if (crl_format == KMF_FORMAT_PEM) { 424699ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 424799ebb4caSwyllys } else { 424899ebb4caSwyllys ret = KMF_ERR_BAD_PARAMETER; 424999ebb4caSwyllys goto cleanup; 425099ebb4caSwyllys } 425199ebb4caSwyllys 425299ebb4caSwyllys if (xcrl == NULL) { 425399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 425499ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 425599ebb4caSwyllys goto cleanup; 425699ebb4caSwyllys } 425799ebb4caSwyllys 425899ebb4caSwyllys p = params->tacert->Data; 425999ebb4caSwyllys len = params->tacert->Length; 426099ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, len); 426199ebb4caSwyllys 426299ebb4caSwyllys if (xcert == NULL) { 426399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 426499ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 426599ebb4caSwyllys goto cleanup; 426699ebb4caSwyllys } 426799ebb4caSwyllys 426899ebb4caSwyllys /* Get issuer certificate public key */ 426999ebb4caSwyllys pkey = X509_get_pubkey(xcert); 427099ebb4caSwyllys if (!pkey) { 427199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 427299ebb4caSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 427399ebb4caSwyllys goto cleanup; 427499ebb4caSwyllys } 427599ebb4caSwyllys 427699ebb4caSwyllys /* Verify CRL signature */ 427799ebb4caSwyllys sslret = X509_CRL_verify(xcrl, pkey); 427899ebb4caSwyllys EVP_PKEY_free(pkey); 427999ebb4caSwyllys if (sslret > 0) { 428099ebb4caSwyllys ret = KMF_OK; 428199ebb4caSwyllys } else { 428299ebb4caSwyllys SET_ERROR(kmfh, sslret); 428399ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 428499ebb4caSwyllys } 428599ebb4caSwyllys 428699ebb4caSwyllys cleanup: 428799ebb4caSwyllys if (bcrl != NULL) 428899ebb4caSwyllys (void) BIO_free(bcrl); 428999ebb4caSwyllys 429099ebb4caSwyllys if (xcrl != NULL) 429199ebb4caSwyllys X509_CRL_free(xcrl); 429299ebb4caSwyllys 429399ebb4caSwyllys if (xcert != NULL) 429499ebb4caSwyllys X509_free(xcert); 429599ebb4caSwyllys 429699ebb4caSwyllys return (ret); 429799ebb4caSwyllys 429899ebb4caSwyllys } 429999ebb4caSwyllys 430099ebb4caSwyllys KMF_RETURN 430199ebb4caSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, 430299ebb4caSwyllys KMF_CHECKCRLDATE_PARAMS *params) 430399ebb4caSwyllys { 430499ebb4caSwyllys 430599ebb4caSwyllys KMF_RETURN ret = KMF_OK; 430699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 430799ebb4caSwyllys KMF_ENCODE_FORMAT crl_format; 430899ebb4caSwyllys BIO *bcrl = NULL; 430999ebb4caSwyllys X509_CRL *xcrl = NULL; 431099ebb4caSwyllys int i; 431199ebb4caSwyllys 431299ebb4caSwyllys if (params == NULL || params->crl_name == NULL) { 431399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 431499ebb4caSwyllys } 431599ebb4caSwyllys 431699ebb4caSwyllys ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format); 431799ebb4caSwyllys if (ret != KMF_OK) 431899ebb4caSwyllys return (ret); 431999ebb4caSwyllys 432099ebb4caSwyllys bcrl = BIO_new_file(params->crl_name, "rb"); 432199ebb4caSwyllys if (bcrl == NULL) { 432299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 432399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 432499ebb4caSwyllys goto cleanup; 432599ebb4caSwyllys } 432699ebb4caSwyllys 432799ebb4caSwyllys if (crl_format == KMF_FORMAT_ASN1) { 432899ebb4caSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 432999ebb4caSwyllys } else if (crl_format == KMF_FORMAT_PEM) { 433099ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 433199ebb4caSwyllys } 433299ebb4caSwyllys 433399ebb4caSwyllys if (xcrl == NULL) { 433499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 433599ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 433699ebb4caSwyllys goto cleanup; 433799ebb4caSwyllys } 433899ebb4caSwyllys 433999ebb4caSwyllys i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); 434099ebb4caSwyllys if (i >= 0) { 434199ebb4caSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 434299ebb4caSwyllys goto cleanup; 434399ebb4caSwyllys } 434499ebb4caSwyllys 434599ebb4caSwyllys if (X509_CRL_get_nextUpdate(xcrl)) { 434699ebb4caSwyllys i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); 434799ebb4caSwyllys 434899ebb4caSwyllys if (i <= 0) { 434999ebb4caSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 435099ebb4caSwyllys goto cleanup; 435199ebb4caSwyllys } 435299ebb4caSwyllys } 435399ebb4caSwyllys 435499ebb4caSwyllys ret = KMF_OK; 435599ebb4caSwyllys 435699ebb4caSwyllys cleanup: 435799ebb4caSwyllys if (bcrl != NULL) 435899ebb4caSwyllys (void) BIO_free(bcrl); 435999ebb4caSwyllys 436099ebb4caSwyllys if (xcrl != NULL) 436199ebb4caSwyllys X509_CRL_free(xcrl); 436299ebb4caSwyllys 436399ebb4caSwyllys return (ret); 436499ebb4caSwyllys } 436599ebb4caSwyllys 436699ebb4caSwyllys /* 436799ebb4caSwyllys * Check a file to see if it is a CRL file with PEM or DER format. 436899ebb4caSwyllys * If success, return its format in the "pformat" argument. 436999ebb4caSwyllys */ 437099ebb4caSwyllys KMF_RETURN 437199ebb4caSwyllys OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat) 437299ebb4caSwyllys { 437399ebb4caSwyllys KMF_RETURN ret = KMF_OK; 437499ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 437599ebb4caSwyllys BIO *bio = NULL; 437699ebb4caSwyllys X509_CRL *xcrl = NULL; 437799ebb4caSwyllys 437899ebb4caSwyllys if (filename == NULL) { 437999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 438099ebb4caSwyllys } 438199ebb4caSwyllys 438299ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 438399ebb4caSwyllys if (bio == NULL) { 438499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 438599ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 438699ebb4caSwyllys goto out; 438799ebb4caSwyllys } 438899ebb4caSwyllys 438999ebb4caSwyllys if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) { 439099ebb4caSwyllys *pformat = KMF_FORMAT_PEM; 439199ebb4caSwyllys goto out; 439299ebb4caSwyllys } 439399ebb4caSwyllys (void) BIO_free(bio); 439499ebb4caSwyllys 439599ebb4caSwyllys /* 439699ebb4caSwyllys * Now try to read it as raw DER data. 439799ebb4caSwyllys */ 439899ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 439999ebb4caSwyllys if (bio == NULL) { 440099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 440199ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 440299ebb4caSwyllys goto out; 440399ebb4caSwyllys } 440499ebb4caSwyllys 440599ebb4caSwyllys if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) { 440699ebb4caSwyllys *pformat = KMF_FORMAT_ASN1; 440799ebb4caSwyllys } else { 440899ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 440999ebb4caSwyllys } 441099ebb4caSwyllys 441199ebb4caSwyllys out: 441299ebb4caSwyllys if (bio != NULL) 441399ebb4caSwyllys (void) BIO_free(bio); 441499ebb4caSwyllys 441599ebb4caSwyllys if (xcrl != NULL) 441699ebb4caSwyllys X509_CRL_free(xcrl); 441799ebb4caSwyllys 441899ebb4caSwyllys return (ret); 441999ebb4caSwyllys } 442099ebb4caSwyllys 442199ebb4caSwyllys /* 442299ebb4caSwyllys * Check a file to see if it is a certficate file with PEM or DER format. 442399ebb4caSwyllys * If success, return its format in the pformat argument. 442499ebb4caSwyllys */ 442599ebb4caSwyllys KMF_RETURN 442699ebb4caSwyllys OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, 442799ebb4caSwyllys KMF_ENCODE_FORMAT *pformat) 442899ebb4caSwyllys { 442999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 443099ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 443199ebb4caSwyllys BIO *bio = NULL; 443299ebb4caSwyllys X509 *xcert = NULL; 443399ebb4caSwyllys 443499ebb4caSwyllys if (filename == NULL) { 443599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 443699ebb4caSwyllys } 443799ebb4caSwyllys 443899ebb4caSwyllys ret = KMF_GetFileFormat(filename, pformat); 443999ebb4caSwyllys if (ret != KMF_OK) 444099ebb4caSwyllys return (ret); 444199ebb4caSwyllys 444299ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 444399ebb4caSwyllys if (bio == NULL) { 444499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 444599ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 444699ebb4caSwyllys goto out; 444799ebb4caSwyllys } 444899ebb4caSwyllys 444999ebb4caSwyllys if ((*pformat) == KMF_FORMAT_PEM) { 445099ebb4caSwyllys if ((xcert = PEM_read_bio_X509(bio, NULL, 445199ebb4caSwyllys NULL, NULL)) == NULL) { 445299ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 445399ebb4caSwyllys } 445499ebb4caSwyllys } else if ((*pformat) == KMF_FORMAT_ASN1) { 445599ebb4caSwyllys if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) { 445699ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 445799ebb4caSwyllys } 445899ebb4caSwyllys } else { 445999ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 446099ebb4caSwyllys } 446199ebb4caSwyllys 446299ebb4caSwyllys out: 446399ebb4caSwyllys if (bio != NULL) 446499ebb4caSwyllys (void) BIO_free(bio); 446599ebb4caSwyllys 446699ebb4caSwyllys if (xcert != NULL) 446799ebb4caSwyllys X509_free(xcert); 446899ebb4caSwyllys 446999ebb4caSwyllys return (ret); 447099ebb4caSwyllys } 447199ebb4caSwyllys 447299ebb4caSwyllys KMF_RETURN 447399ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 447499ebb4caSwyllys KMF_RAW_SYM_KEY *rkey) 447599ebb4caSwyllys { 447699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 447799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 447899ebb4caSwyllys KMF_DATA keyvalue; 447999ebb4caSwyllys 448099ebb4caSwyllys if (kmfh == NULL) 448199ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 448299ebb4caSwyllys 448399ebb4caSwyllys if (symkey == NULL || rkey == NULL) 448499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 448599ebb4caSwyllys else if (symkey->keyclass != KMF_SYMMETRIC) 448699ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 448799ebb4caSwyllys 448899ebb4caSwyllys if (symkey->israw) { 448999ebb4caSwyllys KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp; 449099ebb4caSwyllys 449199ebb4caSwyllys if (rawkey == NULL || 449299ebb4caSwyllys rawkey->keydata.val == NULL || 449399ebb4caSwyllys rawkey->keydata.len == 0) 449499ebb4caSwyllys return (KMF_ERR_BAD_KEYHANDLE); 449599ebb4caSwyllys 449699ebb4caSwyllys rkey->keydata.len = rawkey->keydata.len; 449799ebb4caSwyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 449899ebb4caSwyllys return (KMF_ERR_MEMORY); 449999ebb4caSwyllys (void) memcpy(rkey->keydata.val, rawkey->keydata.val, 450099ebb4caSwyllys rkey->keydata.len); 450199ebb4caSwyllys } else { 450299ebb4caSwyllys rv = KMF_ReadInputFile(handle, symkey->keylabel, &keyvalue); 450399ebb4caSwyllys if (rv != KMF_OK) 450499ebb4caSwyllys return (rv); 450599ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 450699ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 450799ebb4caSwyllys } 450899ebb4caSwyllys 450999ebb4caSwyllys return (rv); 451099ebb4caSwyllys } 4511