199ebb4caSwyllys /* 271593db2Swyllys * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 399ebb4caSwyllys * Use is subject to license terms. 499ebb4caSwyllys */ 59a767088Shaimay /* 69a767088Shaimay * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 79a767088Shaimay * project 2000. 89a767088Shaimay */ 99a767088Shaimay /* 109a767088Shaimay * ==================================================================== 119a767088Shaimay * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. 129a767088Shaimay * 139a767088Shaimay * Redistribution and use in source and binary forms, with or without 149a767088Shaimay * modification, are permitted provided that the following conditions 159a767088Shaimay * are met: 169a767088Shaimay * 179a767088Shaimay * 1. Redistributions of source code must retain the above copyright 189a767088Shaimay * notice, this list of conditions and the following disclaimer. 199a767088Shaimay * 209a767088Shaimay * 2. Redistributions in binary form must reproduce the above copyright 219a767088Shaimay * notice, this list of conditions and the following disclaimer in 229a767088Shaimay * the documentation and/or other materials provided with the 239a767088Shaimay * distribution. 249a767088Shaimay * 259a767088Shaimay * 3. All advertising materials mentioning features or use of this 269a767088Shaimay * software must display the following acknowledgment: 279a767088Shaimay * "This product includes software developed by the OpenSSL Project 289a767088Shaimay * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 299a767088Shaimay * 309a767088Shaimay * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 319a767088Shaimay * endorse or promote products derived from this software without 329a767088Shaimay * prior written permission. For written permission, please contact 339a767088Shaimay * licensing@OpenSSL.org. 349a767088Shaimay * 359a767088Shaimay * 5. Products derived from this software may not be called "OpenSSL" 369a767088Shaimay * nor may "OpenSSL" appear in their names without prior written 379a767088Shaimay * permission of the OpenSSL Project. 389a767088Shaimay * 399a767088Shaimay * 6. Redistributions of any form whatsoever must retain the following 409a767088Shaimay * acknowledgment: 419a767088Shaimay * "This product includes software developed by the OpenSSL Project 429a767088Shaimay * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 439a767088Shaimay * 449a767088Shaimay * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 459a767088Shaimay * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 469a767088Shaimay * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 479a767088Shaimay * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 489a767088Shaimay * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 499a767088Shaimay * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 509a767088Shaimay * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 519a767088Shaimay * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 529a767088Shaimay * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 539a767088Shaimay * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 549a767088Shaimay * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 559a767088Shaimay * OF THE POSSIBILITY OF SUCH DAMAGE. 569a767088Shaimay * ==================================================================== 579a767088Shaimay * 589a767088Shaimay * This product includes cryptographic software written by Eric Young 599a767088Shaimay * (eay@cryptsoft.com). This product includes software written by Tim 609a767088Shaimay * Hudson (tjh@cryptsoft.com). 619a767088Shaimay * 629a767088Shaimay */ 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 <fcntl.h> 7099ebb4caSwyllys #include <sys/stat.h> 7199ebb4caSwyllys #include <dirent.h> 7299ebb4caSwyllys #include <cryptoutil.h> 7399ebb4caSwyllys #include <synch.h> 7499ebb4caSwyllys #include <thread.h> 7599ebb4caSwyllys 7699ebb4caSwyllys /* OPENSSL related headers */ 7799ebb4caSwyllys #include <openssl/bio.h> 7899ebb4caSwyllys #include <openssl/bn.h> 7999ebb4caSwyllys #include <openssl/asn1.h> 8099ebb4caSwyllys #include <openssl/err.h> 8199ebb4caSwyllys #include <openssl/bn.h> 8299ebb4caSwyllys #include <openssl/x509.h> 8399ebb4caSwyllys #include <openssl/rsa.h> 8499ebb4caSwyllys #include <openssl/dsa.h> 8599ebb4caSwyllys #include <openssl/x509v3.h> 8699ebb4caSwyllys #include <openssl/objects.h> 8799ebb4caSwyllys #include <openssl/pem.h> 8899ebb4caSwyllys #include <openssl/pkcs12.h> 8999ebb4caSwyllys #include <openssl/ocsp.h> 9099ebb4caSwyllys #include <openssl/des.h> 9199ebb4caSwyllys #include <openssl/rand.h> 9299ebb4caSwyllys 9399ebb4caSwyllys #define PRINT_ANY_EXTENSION (\ 9499ebb4caSwyllys KMF_X509_EXT_KEY_USAGE |\ 9599ebb4caSwyllys KMF_X509_EXT_CERT_POLICIES |\ 9699ebb4caSwyllys KMF_X509_EXT_SUBJALTNAME |\ 9799ebb4caSwyllys KMF_X509_EXT_BASIC_CONSTRAINTS |\ 9899ebb4caSwyllys KMF_X509_EXT_NAME_CONSTRAINTS |\ 9999ebb4caSwyllys KMF_X509_EXT_POLICY_CONSTRAINTS |\ 10099ebb4caSwyllys KMF_X509_EXT_EXT_KEY_USAGE |\ 10199ebb4caSwyllys KMF_X509_EXT_INHIBIT_ANY_POLICY |\ 10299ebb4caSwyllys KMF_X509_EXT_AUTH_KEY_ID |\ 10399ebb4caSwyllys KMF_X509_EXT_SUBJ_KEY_ID |\ 10499ebb4caSwyllys KMF_X509_EXT_POLICY_MAPPING) 10599ebb4caSwyllys 10699ebb4caSwyllys static BIO *bio_err = NULL; 10799ebb4caSwyllys static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 10899ebb4caSwyllys 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 10999ebb4caSwyllys 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 11099ebb4caSwyllys 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 11199ebb4caSwyllys 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 11299ebb4caSwyllys 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 11399ebb4caSwyllys 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 11499ebb4caSwyllys 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 11599ebb4caSwyllys 0x91 }; 11699ebb4caSwyllys 11799ebb4caSwyllys static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 11899ebb4caSwyllys 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 11999ebb4caSwyllys 0x8e, 0xda, 0xce, 0x91, 0x5f }; 12099ebb4caSwyllys 12199ebb4caSwyllys static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 12299ebb4caSwyllys 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 12399ebb4caSwyllys 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 12499ebb4caSwyllys 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 12599ebb4caSwyllys 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 12699ebb4caSwyllys 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 12799ebb4caSwyllys 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 12899ebb4caSwyllys 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 12999ebb4caSwyllys 0x02 }; 13099ebb4caSwyllys 13199ebb4caSwyllys #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \ 13299ebb4caSwyllys h->lasterr.errcode = c; 13399ebb4caSwyllys 13499ebb4caSwyllys #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c; 13599ebb4caSwyllys 13699ebb4caSwyllys mutex_t init_lock = DEFAULTMUTEX; 13799ebb4caSwyllys static int ssl_initialized = 0; 13899ebb4caSwyllys 13971593db2Swyllys static KMF_RETURN 14002744e81Swyllys extract_objects(KMF_HANDLE *, KMF_FINDCERT_PARAMS *, char *, 14102744e81Swyllys CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *); 14271593db2Swyllys 14371593db2Swyllys static KMF_RETURN 14471593db2Swyllys kmf_load_cert(KMF_HANDLE *, KMF_FINDCERT_PARAMS *, char *, KMF_DATA *); 14571593db2Swyllys 14602744e81Swyllys static KMF_RETURN 14702744e81Swyllys sslBN2KMFBN(BIGNUM *, KMF_BIGINT *); 14802744e81Swyllys 14902744e81Swyllys static EVP_PKEY * 15002744e81Swyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *); 15102744e81Swyllys 15299ebb4caSwyllys KMF_RETURN 15399ebb4caSwyllys OpenSSL_FindCert(KMF_HANDLE_T, 15499ebb4caSwyllys KMF_FINDCERT_PARAMS *, 15599ebb4caSwyllys KMF_X509_DER_CERT *, 15699ebb4caSwyllys uint32_t *); 15799ebb4caSwyllys 15899ebb4caSwyllys void 15999ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); 16099ebb4caSwyllys 16199ebb4caSwyllys KMF_RETURN 16299ebb4caSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *, KMF_DATA *); 16399ebb4caSwyllys 16499ebb4caSwyllys KMF_RETURN 16599ebb4caSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *); 16699ebb4caSwyllys 16799ebb4caSwyllys KMF_RETURN 16899ebb4caSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, 16999ebb4caSwyllys KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); 17099ebb4caSwyllys 17199ebb4caSwyllys KMF_RETURN 17299ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 17399ebb4caSwyllys 17499ebb4caSwyllys KMF_RETURN 17599ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 17699ebb4caSwyllys KMF_DATA *, KMF_DATA *); 17799ebb4caSwyllys 17899ebb4caSwyllys KMF_RETURN 17999ebb4caSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, 18099ebb4caSwyllys KMF_KEY_HANDLE *, boolean_t); 18199ebb4caSwyllys 18299ebb4caSwyllys KMF_RETURN 18399ebb4caSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *); 18499ebb4caSwyllys 18599ebb4caSwyllys KMF_RETURN 18699ebb4caSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *); 18799ebb4caSwyllys 18899ebb4caSwyllys KMF_RETURN 18999ebb4caSwyllys OpenSSL_ListCRL(KMF_HANDLE_T, KMF_LISTCRL_PARAMS *, char **); 19099ebb4caSwyllys 19199ebb4caSwyllys KMF_RETURN 19299ebb4caSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *); 19399ebb4caSwyllys 19499ebb4caSwyllys KMF_RETURN 19599ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *, 19699ebb4caSwyllys KMF_PRINTABLE_ITEM, char *); 19799ebb4caSwyllys 19899ebb4caSwyllys KMF_RETURN 19999ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T, char **); 20099ebb4caSwyllys 20199ebb4caSwyllys KMF_RETURN 20299ebb4caSwyllys OpenSSL_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, 20399ebb4caSwyllys KMF_KEY_HANDLE *, KMF_KEY_ALG); 20499ebb4caSwyllys 20599ebb4caSwyllys KMF_RETURN 20699ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 20799ebb4caSwyllys KMF_DATA *, KMF_DATA *); 20899ebb4caSwyllys 20999ebb4caSwyllys KMF_RETURN 21099ebb4caSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, KMF_OCSPREQUEST_PARAMS *, 21199ebb4caSwyllys char *reqfile); 21299ebb4caSwyllys 21399ebb4caSwyllys KMF_RETURN 21499ebb4caSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, KMF_OCSPRESPONSE_PARAMS_INPUT *, 21599ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_OUTPUT *); 21699ebb4caSwyllys 21799ebb4caSwyllys KMF_RETURN 21899ebb4caSwyllys OpenSSL_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, 21999ebb4caSwyllys KMF_KEY_HANDLE *, uint32_t *); 22099ebb4caSwyllys 22199ebb4caSwyllys KMF_RETURN 22299ebb4caSwyllys OpenSSL_ExportP12(KMF_HANDLE_T, 22399ebb4caSwyllys KMF_EXPORTP12_PARAMS *, 22499ebb4caSwyllys int, KMF_X509_DER_CERT *, 22599ebb4caSwyllys int, KMF_KEY_HANDLE *, 22699ebb4caSwyllys char *); 22799ebb4caSwyllys 22899ebb4caSwyllys KMF_RETURN 22999ebb4caSwyllys OpenSSL_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, 23099ebb4caSwyllys KMF_RAW_KEY_DATA *); 23199ebb4caSwyllys 23299ebb4caSwyllys KMF_RETURN 23399ebb4caSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, 23499ebb4caSwyllys KMF_KEY_HANDLE *); 23599ebb4caSwyllys 23699ebb4caSwyllys KMF_RETURN 23799ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 23899ebb4caSwyllys 23999ebb4caSwyllys KMF_RETURN 24099ebb4caSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T, KMF_VERIFYCRL_PARAMS *); 24199ebb4caSwyllys 24299ebb4caSwyllys KMF_RETURN 24399ebb4caSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T, KMF_CHECKCRLDATE_PARAMS *); 24499ebb4caSwyllys 24502744e81Swyllys KMF_RETURN 24602744e81Swyllys OpenSSL_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, 24702744e81Swyllys KMF_DATA *, KMF_DATA *, KMF_DATA *); 24802744e81Swyllys 24999ebb4caSwyllys static 25099ebb4caSwyllys KMF_PLUGIN_FUNCLIST openssl_plugin_table = 25199ebb4caSwyllys { 25299ebb4caSwyllys 1, /* Version */ 25399ebb4caSwyllys NULL, /* ConfigureKeystore */ 25499ebb4caSwyllys OpenSSL_FindCert, 25599ebb4caSwyllys OpenSSL_FreeKMFCert, 25699ebb4caSwyllys OpenSSL_StoreCert, 25799ebb4caSwyllys NULL, /* ImportCert */ 25899ebb4caSwyllys OpenSSL_ImportCRL, 25999ebb4caSwyllys OpenSSL_DeleteCert, 26099ebb4caSwyllys OpenSSL_DeleteCRL, 26199ebb4caSwyllys OpenSSL_CreateKeypair, 26299ebb4caSwyllys OpenSSL_FindKey, 26399ebb4caSwyllys OpenSSL_EncodePubKeyData, 26499ebb4caSwyllys OpenSSL_SignData, 26599ebb4caSwyllys OpenSSL_DeleteKey, 26699ebb4caSwyllys OpenSSL_ListCRL, 26799ebb4caSwyllys NULL, /* FindCRL */ 26899ebb4caSwyllys OpenSSL_FindCertInCRL, 26999ebb4caSwyllys OpenSSL_GetErrorString, 27099ebb4caSwyllys OpenSSL_GetPrikeyByCert, 27199ebb4caSwyllys OpenSSL_DecryptData, 27299ebb4caSwyllys OpenSSL_ExportP12, 27399ebb4caSwyllys OpenSSL_StorePrivateKey, 27499ebb4caSwyllys OpenSSL_CreateSymKey, 27599ebb4caSwyllys OpenSSL_GetSymKeyValue, 27699ebb4caSwyllys NULL, /* SetTokenPin */ 27702744e81Swyllys OpenSSL_VerifyDataWithCert, 27899ebb4caSwyllys NULL /* Finalize */ 27999ebb4caSwyllys }; 28099ebb4caSwyllys 28199ebb4caSwyllys static mutex_t *lock_cs; 28299ebb4caSwyllys static long *lock_count; 28399ebb4caSwyllys 28499ebb4caSwyllys static void 28599ebb4caSwyllys /*ARGSUSED*/ 28699ebb4caSwyllys locking_cb(int mode, int type, char *file, int line) 28799ebb4caSwyllys { 28899ebb4caSwyllys if (mode & CRYPTO_LOCK) { 28999ebb4caSwyllys (void) mutex_lock(&(lock_cs[type])); 29099ebb4caSwyllys lock_count[type]++; 29199ebb4caSwyllys } else { 29299ebb4caSwyllys (void) mutex_unlock(&(lock_cs[type])); 29399ebb4caSwyllys } 29499ebb4caSwyllys } 29599ebb4caSwyllys 29699ebb4caSwyllys static unsigned long 29799ebb4caSwyllys thread_id() 29899ebb4caSwyllys { 29999ebb4caSwyllys return ((unsigned long)thr_self()); 30099ebb4caSwyllys } 30199ebb4caSwyllys 30299ebb4caSwyllys KMF_PLUGIN_FUNCLIST * 30399ebb4caSwyllys KMF_Plugin_Initialize() 30499ebb4caSwyllys { 30599ebb4caSwyllys int i; 30699ebb4caSwyllys 30799ebb4caSwyllys (void) mutex_lock(&init_lock); 30899ebb4caSwyllys if (!ssl_initialized) { 30999ebb4caSwyllys OpenSSL_add_all_algorithms(); 31099ebb4caSwyllys 31199ebb4caSwyllys /* Enable error strings for reporting */ 31299ebb4caSwyllys ERR_load_crypto_strings(); 31399ebb4caSwyllys 31499ebb4caSwyllys /* 31599ebb4caSwyllys * Add support for extension OIDs that are not yet in the 31699ebb4caSwyllys * openssl default set. 31799ebb4caSwyllys */ 31899ebb4caSwyllys (void) OBJ_create("2.5.29.30", "nameConstraints", 31999ebb4caSwyllys "X509v3 Name Constraints"); 32099ebb4caSwyllys (void) OBJ_create("2.5.29.33", "policyMappings", 32199ebb4caSwyllys "X509v3 Policy Mappings"); 32299ebb4caSwyllys (void) OBJ_create("2.5.29.36", "policyConstraints", 32399ebb4caSwyllys "X509v3 Policy Constraints"); 32499ebb4caSwyllys (void) OBJ_create("2.5.29.46", "freshestCRL", 32599ebb4caSwyllys "X509v3 Freshest CRL"); 32699ebb4caSwyllys (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy", 32799ebb4caSwyllys "X509v3 Inhibit Any-Policy"); 32899ebb4caSwyllys /* 32999ebb4caSwyllys * Set up for thread-safe operation. 33099ebb4caSwyllys */ 33199ebb4caSwyllys lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t)); 33299ebb4caSwyllys if (lock_cs == NULL) { 33399ebb4caSwyllys (void) mutex_unlock(&init_lock); 33499ebb4caSwyllys return (NULL); 33599ebb4caSwyllys } 33699ebb4caSwyllys 33799ebb4caSwyllys lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long)); 33899ebb4caSwyllys if (lock_count == NULL) { 33999ebb4caSwyllys OPENSSL_free(lock_cs); 34099ebb4caSwyllys (void) mutex_unlock(&init_lock); 34199ebb4caSwyllys return (NULL); 34299ebb4caSwyllys } 34399ebb4caSwyllys 34499ebb4caSwyllys for (i = 0; i < CRYPTO_num_locks(); i++) { 34599ebb4caSwyllys lock_count[i] = 0; 34699ebb4caSwyllys (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL); 34799ebb4caSwyllys } 34899ebb4caSwyllys 34999ebb4caSwyllys CRYPTO_set_id_callback((unsigned long (*)())thread_id); 35099ebb4caSwyllys CRYPTO_set_locking_callback((void (*)())locking_cb); 35199ebb4caSwyllys ssl_initialized = 1; 35299ebb4caSwyllys } 35399ebb4caSwyllys (void) mutex_unlock(&init_lock); 35499ebb4caSwyllys 35599ebb4caSwyllys return (&openssl_plugin_table); 35699ebb4caSwyllys } 35799ebb4caSwyllys /* 35899ebb4caSwyllys * Convert an SSL DN to a KMF DN. 35999ebb4caSwyllys */ 36099ebb4caSwyllys static KMF_RETURN 36199ebb4caSwyllys get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN) 36299ebb4caSwyllys { 36399ebb4caSwyllys KMF_DATA derdata; 36499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 36599ebb4caSwyllys uchar_t *tmp; 36699ebb4caSwyllys 36799ebb4caSwyllys /* Convert to raw DER format */ 36899ebb4caSwyllys derdata.Length = i2d_X509_NAME(sslDN, NULL); 36999ebb4caSwyllys if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length)) 37099ebb4caSwyllys == NULL) { 37199ebb4caSwyllys return (KMF_ERR_MEMORY); 37299ebb4caSwyllys } 37399ebb4caSwyllys (void) i2d_X509_NAME(sslDN, &tmp); 37499ebb4caSwyllys 37599ebb4caSwyllys /* Decode to KMF format */ 37699ebb4caSwyllys rv = DerDecodeName(&derdata, kmfDN); 37799ebb4caSwyllys if (rv != KMF_OK) { 37899ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 37999ebb4caSwyllys } 38099ebb4caSwyllys OPENSSL_free(derdata.Data); 38199ebb4caSwyllys 38299ebb4caSwyllys return (rv); 38399ebb4caSwyllys } 38499ebb4caSwyllys 38599ebb4caSwyllys static int 38699ebb4caSwyllys isdir(char *path) 38799ebb4caSwyllys { 38899ebb4caSwyllys struct stat s; 38999ebb4caSwyllys 39099ebb4caSwyllys if (stat(path, &s) == -1) 39199ebb4caSwyllys return (0); 39299ebb4caSwyllys 39399ebb4caSwyllys return (s.st_mode & S_IFDIR); 39499ebb4caSwyllys } 39599ebb4caSwyllys 39699ebb4caSwyllys static KMF_RETURN 39799ebb4caSwyllys ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert) 39899ebb4caSwyllys { 39999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 40099ebb4caSwyllys unsigned char *buf = NULL, *p; 40199ebb4caSwyllys int len; 40299ebb4caSwyllys 40399ebb4caSwyllys /* 40499ebb4caSwyllys * Convert the X509 internal struct to DER encoded data 40599ebb4caSwyllys */ 40699ebb4caSwyllys if ((len = i2d_X509(x509cert, NULL)) < 0) { 40799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 40899ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 40999ebb4caSwyllys goto cleanup; 41099ebb4caSwyllys } 41199ebb4caSwyllys if ((buf = malloc(len)) == NULL) { 41299ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 41399ebb4caSwyllys rv = KMF_ERR_MEMORY; 41499ebb4caSwyllys goto cleanup; 41599ebb4caSwyllys } 41699ebb4caSwyllys 41799ebb4caSwyllys /* 41899ebb4caSwyllys * i2d_X509 will increment the buf pointer so that we need to 41999ebb4caSwyllys * save it. 42099ebb4caSwyllys */ 42199ebb4caSwyllys p = buf; 42299ebb4caSwyllys if ((len = i2d_X509(x509cert, &p)) < 0) { 42399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 42499ebb4caSwyllys free(buf); 42599ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 42699ebb4caSwyllys goto cleanup; 42799ebb4caSwyllys } 42899ebb4caSwyllys 42999ebb4caSwyllys /* caller's responsibility to free it */ 43099ebb4caSwyllys cert->Data = buf; 43199ebb4caSwyllys cert->Length = len; 43299ebb4caSwyllys 43399ebb4caSwyllys cleanup: 43499ebb4caSwyllys if (rv != KMF_OK) { 43599ebb4caSwyllys if (buf) 43699ebb4caSwyllys free(buf); 43799ebb4caSwyllys cert->Data = NULL; 43899ebb4caSwyllys cert->Length = 0; 43999ebb4caSwyllys } 44099ebb4caSwyllys 44199ebb4caSwyllys return (rv); 44299ebb4caSwyllys } 44399ebb4caSwyllys 44499ebb4caSwyllys static KMF_RETURN 44599ebb4caSwyllys check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) 44699ebb4caSwyllys { 44799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 44899ebb4caSwyllys boolean_t findIssuer = FALSE; 44999ebb4caSwyllys boolean_t findSubject = FALSE; 45099ebb4caSwyllys boolean_t findSerial = FALSE; 45199ebb4caSwyllys KMF_X509_NAME issuerDN, subjectDN; 45299ebb4caSwyllys KMF_X509_NAME certIssuerDN, certSubjectDN; 45399ebb4caSwyllys 45499ebb4caSwyllys *match = FALSE; 45599ebb4caSwyllys if (xcert == NULL) { 45699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 45799ebb4caSwyllys } 45899ebb4caSwyllys 45999ebb4caSwyllys (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME)); 46099ebb4caSwyllys (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME)); 46199ebb4caSwyllys (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME)); 46299ebb4caSwyllys (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME)); 46399ebb4caSwyllys 46499ebb4caSwyllys if (params->issuer != NULL && strlen(params->issuer)) { 46599ebb4caSwyllys rv = KMF_DNParser(params->issuer, &issuerDN); 46699ebb4caSwyllys if (rv != KMF_OK) 46799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 46899ebb4caSwyllys 46999ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); 47099ebb4caSwyllys if (rv != KMF_OK) { 47199ebb4caSwyllys KMF_FreeDN(&issuerDN); 47299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 47399ebb4caSwyllys } 47499ebb4caSwyllys 47599ebb4caSwyllys findIssuer = TRUE; 47699ebb4caSwyllys } 47799ebb4caSwyllys if (params->subject != NULL && strlen(params->subject)) { 47899ebb4caSwyllys rv = KMF_DNParser(params->subject, &subjectDN); 47999ebb4caSwyllys if (rv != KMF_OK) { 48099ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 48199ebb4caSwyllys goto cleanup; 48299ebb4caSwyllys } 48399ebb4caSwyllys 48499ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN); 48599ebb4caSwyllys if (rv != KMF_OK) { 48699ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 48799ebb4caSwyllys goto cleanup; 48899ebb4caSwyllys } 48999ebb4caSwyllys findSubject = TRUE; 49099ebb4caSwyllys } 49199ebb4caSwyllys if (params->serial != NULL && params->serial->val != NULL) 49299ebb4caSwyllys findSerial = TRUE; 49399ebb4caSwyllys 49499ebb4caSwyllys if (findSerial) { 49599ebb4caSwyllys BIGNUM *bn; 49699ebb4caSwyllys 49799ebb4caSwyllys /* Comparing BIGNUMs is a pain! */ 49899ebb4caSwyllys bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL); 49999ebb4caSwyllys if (bn != NULL) { 50099ebb4caSwyllys int bnlen = BN_num_bytes(bn); 50199ebb4caSwyllys 50299ebb4caSwyllys if (bnlen == params->serial->len) { 50399ebb4caSwyllys uchar_t *a = malloc(bnlen); 50499ebb4caSwyllys if (a == NULL) { 50599ebb4caSwyllys rv = KMF_ERR_MEMORY; 50699ebb4caSwyllys BN_free(bn); 50799ebb4caSwyllys goto cleanup; 50899ebb4caSwyllys } 50999ebb4caSwyllys bnlen = BN_bn2bin(bn, a); 51099ebb4caSwyllys *match = !memcmp(a, 51199ebb4caSwyllys params->serial->val, 51299ebb4caSwyllys params->serial->len); 51399ebb4caSwyllys rv = KMF_OK; 51499ebb4caSwyllys free(a); 51599ebb4caSwyllys } 51699ebb4caSwyllys BN_free(bn); 51799ebb4caSwyllys if (!(*match)) 51899ebb4caSwyllys goto cleanup; 51999ebb4caSwyllys } else { 52099ebb4caSwyllys rv = KMF_OK; 52199ebb4caSwyllys goto cleanup; 52299ebb4caSwyllys } 52399ebb4caSwyllys } 52499ebb4caSwyllys if (findIssuer) { 52599ebb4caSwyllys *match = !KMF_CompareRDNs(&issuerDN, &certIssuerDN); 52699ebb4caSwyllys if (!(*match)) { 52799ebb4caSwyllys rv = KMF_OK; 52899ebb4caSwyllys goto cleanup; 52999ebb4caSwyllys } 53099ebb4caSwyllys } 53199ebb4caSwyllys if (findSubject) { 53299ebb4caSwyllys *match = !KMF_CompareRDNs(&subjectDN, &certSubjectDN); 53399ebb4caSwyllys if (!(*match)) { 53499ebb4caSwyllys rv = KMF_OK; 53599ebb4caSwyllys goto cleanup; 53699ebb4caSwyllys } 53799ebb4caSwyllys } 53899ebb4caSwyllys 53999ebb4caSwyllys *match = TRUE; 54099ebb4caSwyllys cleanup: 54199ebb4caSwyllys if (findIssuer) { 54299ebb4caSwyllys KMF_FreeDN(&issuerDN); 54399ebb4caSwyllys KMF_FreeDN(&certIssuerDN); 54499ebb4caSwyllys } 54599ebb4caSwyllys if (findSubject) { 54699ebb4caSwyllys KMF_FreeDN(&subjectDN); 54799ebb4caSwyllys KMF_FreeDN(&certSubjectDN); 54899ebb4caSwyllys } 54999ebb4caSwyllys 55099ebb4caSwyllys return (rv); 55199ebb4caSwyllys } 55299ebb4caSwyllys 55399ebb4caSwyllys static KMF_RETURN 55499ebb4caSwyllys load_X509cert(KMF_HANDLE *kmfh, 55599ebb4caSwyllys KMF_FINDCERT_PARAMS *params, 55699ebb4caSwyllys char *pathname, 55799ebb4caSwyllys X509 **outcert) 55899ebb4caSwyllys { 55999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 56099ebb4caSwyllys X509 *xcert = NULL; 56199ebb4caSwyllys BIO *bcert = NULL; 56299ebb4caSwyllys boolean_t match = FALSE; 56399ebb4caSwyllys KMF_ENCODE_FORMAT format; 56499ebb4caSwyllys 56599ebb4caSwyllys /* 56699ebb4caSwyllys * auto-detect the file format, regardless of what 56799ebb4caSwyllys * the 'format' parameters in the params say. 56899ebb4caSwyllys */ 56999ebb4caSwyllys rv = KMF_GetFileFormat(pathname, &format); 57099ebb4caSwyllys if (rv != KMF_OK) { 57199ebb4caSwyllys if (rv == KMF_ERR_OPEN_FILE) 57299ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 57399ebb4caSwyllys return (rv); 57499ebb4caSwyllys } 57599ebb4caSwyllys 57699ebb4caSwyllys /* Not ASN1(DER) format */ 57799ebb4caSwyllys if ((bcert = BIO_new_file(pathname, "rb")) == NULL) { 57899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 57999ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 58099ebb4caSwyllys goto cleanup; 58199ebb4caSwyllys } 58299ebb4caSwyllys 58399ebb4caSwyllys if (format == KMF_FORMAT_PEM) 58499ebb4caSwyllys xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL); 58599ebb4caSwyllys else if (format == KMF_FORMAT_ASN1) 58699ebb4caSwyllys xcert = d2i_X509_bio(bcert, NULL); 58799ebb4caSwyllys else if (format == KMF_FORMAT_PKCS12) { 58899ebb4caSwyllys PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL); 58999ebb4caSwyllys if (p12 != NULL) { 59099ebb4caSwyllys (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL); 59199ebb4caSwyllys PKCS12_free(p12); 59299ebb4caSwyllys p12 = NULL; 59399ebb4caSwyllys } else { 59499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 59599ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 59699ebb4caSwyllys } 59799ebb4caSwyllys } else { 59899ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 59999ebb4caSwyllys goto cleanup; 60099ebb4caSwyllys } 60199ebb4caSwyllys 60299ebb4caSwyllys if (xcert == NULL) { 60399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 60499ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 60599ebb4caSwyllys goto cleanup; 60699ebb4caSwyllys } 60799ebb4caSwyllys 60899ebb4caSwyllys if (check_cert(xcert, params, &match) != KMF_OK || match == FALSE) { 60999ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 61099ebb4caSwyllys goto cleanup; 61199ebb4caSwyllys } 61299ebb4caSwyllys 61399ebb4caSwyllys if (outcert != NULL) { 61499ebb4caSwyllys *outcert = xcert; 61599ebb4caSwyllys } 61699ebb4caSwyllys 61799ebb4caSwyllys cleanup: 61899ebb4caSwyllys if (bcert != NULL) (void) BIO_free(bcert); 61999ebb4caSwyllys if (rv != KMF_OK && xcert != NULL) 62099ebb4caSwyllys X509_free(xcert); 62199ebb4caSwyllys 62299ebb4caSwyllys return (rv); 62399ebb4caSwyllys } 62499ebb4caSwyllys 62571593db2Swyllys static int 62671593db2Swyllys datacmp(const void *a, const void *b) 62771593db2Swyllys { 62871593db2Swyllys KMF_DATA *adata = (KMF_DATA *)a; 62971593db2Swyllys KMF_DATA *bdata = (KMF_DATA *)b; 63071593db2Swyllys if (adata->Length > bdata->Length) 63171593db2Swyllys return (-1); 63271593db2Swyllys if (adata->Length < bdata->Length) 63371593db2Swyllys return (1); 63471593db2Swyllys return (0); 63571593db2Swyllys } 63671593db2Swyllys 63771593db2Swyllys static KMF_RETURN 63871593db2Swyllys load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname, 63971593db2Swyllys KMF_DATA **certlist, uint32_t *numcerts) 64071593db2Swyllys { 64171593db2Swyllys KMF_RETURN rv = KMF_OK; 64271593db2Swyllys int i; 64371593db2Swyllys KMF_DATA *certs = NULL; 64471593db2Swyllys int nc = 0; 64571593db2Swyllys int hits = 0; 64671593db2Swyllys KMF_ENCODE_FORMAT format; 64771593db2Swyllys 64871593db2Swyllys rv = KMF_GetFileFormat(pathname, &format); 64971593db2Swyllys if (rv != KMF_OK) { 65071593db2Swyllys if (rv == KMF_ERR_OPEN_FILE) 65171593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 65271593db2Swyllys return (rv); 65371593db2Swyllys } 65471593db2Swyllys if (format == KMF_FORMAT_ASN1) { 65571593db2Swyllys /* load a single certificate */ 65671593db2Swyllys certs = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 65771593db2Swyllys if (certs == NULL) 65871593db2Swyllys return (KMF_ERR_MEMORY); 65971593db2Swyllys certs->Data = NULL; 66071593db2Swyllys certs->Length = 0; 66171593db2Swyllys rv = kmf_load_cert(kmfh, params, pathname, certs); 66271593db2Swyllys if (rv == KMF_OK) { 66371593db2Swyllys *certlist = certs; 66471593db2Swyllys *numcerts = 1; 66571593db2Swyllys } 66671593db2Swyllys return (rv); 66771593db2Swyllys } else if (format == KMF_FORMAT_PKCS12) { 66871593db2Swyllys /* We need a credential to access a PKCS#12 file */ 66971593db2Swyllys rv = KMF_ERR_BAD_CERT_FORMAT; 67071593db2Swyllys } else if (format == KMF_FORMAT_PEM || 67171593db2Swyllys format != KMF_FORMAT_PEM_KEYPAIR) { 67271593db2Swyllys 67371593db2Swyllys /* This function only works on PEM files */ 67402744e81Swyllys rv = extract_objects(kmfh, params, pathname, 67571593db2Swyllys (uchar_t *)NULL, 0, NULL, 67671593db2Swyllys &certs, &nc); 67771593db2Swyllys } else { 67871593db2Swyllys return (KMF_ERR_ENCODING); 67971593db2Swyllys } 68071593db2Swyllys 68171593db2Swyllys if (rv != KMF_OK) 68271593db2Swyllys return (rv); 68371593db2Swyllys 68471593db2Swyllys for (i = 0; i < nc; i++) { 68571593db2Swyllys if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) { 68671593db2Swyllys rv = KMF_CheckCertDate(kmfh, &certs[i]); 68771593db2Swyllys } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) { 68871593db2Swyllys rv = KMF_CheckCertDate(kmfh, &certs[i]); 68971593db2Swyllys if (rv == KMF_OK) 69071593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 69171593db2Swyllys if (rv == KMF_ERR_VALIDITY_PERIOD) 69271593db2Swyllys rv = KMF_OK; 69371593db2Swyllys } 69471593db2Swyllys if (rv != KMF_OK) { 69571593db2Swyllys /* Remove this cert from the list by clearing it. */ 69671593db2Swyllys KMF_FreeData(&certs[i]); 69771593db2Swyllys } else { 69871593db2Swyllys hits++; /* count valid certs found */ 69971593db2Swyllys } 70071593db2Swyllys rv = KMF_OK; 70171593db2Swyllys } 70271593db2Swyllys if (rv == KMF_OK && hits == 0) { 70371593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 70471593db2Swyllys } else if (rv == KMF_OK && hits > 0) { 70571593db2Swyllys /* 70671593db2Swyllys * Sort the list of certs by length to put the cleared ones 70771593db2Swyllys * at the end so they don't get accessed by the caller. 70871593db2Swyllys */ 70971593db2Swyllys qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp); 71071593db2Swyllys *certlist = certs; 71171593db2Swyllys 71271593db2Swyllys /* since we sorted the list, just return the number of hits */ 71371593db2Swyllys *numcerts = hits; 71471593db2Swyllys } 71571593db2Swyllys return (rv); 71671593db2Swyllys } 71771593db2Swyllys 71899ebb4caSwyllys static KMF_RETURN 71999ebb4caSwyllys kmf_load_cert(KMF_HANDLE *kmfh, 72099ebb4caSwyllys KMF_FINDCERT_PARAMS *params, 72199ebb4caSwyllys char *pathname, 72299ebb4caSwyllys KMF_DATA *cert) 72399ebb4caSwyllys { 72499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 72599ebb4caSwyllys X509 *x509cert = NULL; 72699ebb4caSwyllys 72799ebb4caSwyllys rv = load_X509cert(kmfh, params, pathname, &x509cert); 72899ebb4caSwyllys if (rv == KMF_OK && x509cert != NULL && cert != NULL) { 72999ebb4caSwyllys rv = ssl_cert2KMFDATA(kmfh, x509cert, cert); 73099ebb4caSwyllys if (rv != KMF_OK) { 73199ebb4caSwyllys goto cleanup; 73299ebb4caSwyllys } 73399ebb4caSwyllys if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) { 73499ebb4caSwyllys rv = KMF_CheckCertDate(kmfh, cert); 73599ebb4caSwyllys } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) { 73699ebb4caSwyllys rv = KMF_CheckCertDate(kmfh, cert); 73799ebb4caSwyllys if (rv == KMF_OK) { 73899ebb4caSwyllys /* 73999ebb4caSwyllys * This is a valid cert so skip it. 74099ebb4caSwyllys */ 74199ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 74299ebb4caSwyllys } 74399ebb4caSwyllys if (rv == KMF_ERR_VALIDITY_PERIOD) { 74499ebb4caSwyllys /* 74599ebb4caSwyllys * We want to return success when we 74699ebb4caSwyllys * find an invalid cert. 74799ebb4caSwyllys */ 74899ebb4caSwyllys rv = KMF_OK; 74999ebb4caSwyllys goto cleanup; 75099ebb4caSwyllys } 75199ebb4caSwyllys } 75299ebb4caSwyllys } 75399ebb4caSwyllys cleanup: 75499ebb4caSwyllys if (x509cert != NULL) 75599ebb4caSwyllys X509_free(x509cert); 75699ebb4caSwyllys 75799ebb4caSwyllys return (rv); 75899ebb4caSwyllys } 75999ebb4caSwyllys 76002744e81Swyllys static KMF_RETURN 76102744e81Swyllys readAltFormatPrivateKey(KMF_DATA *filedata, EVP_PKEY **pkey) 76202744e81Swyllys { 76302744e81Swyllys KMF_RETURN ret = KMF_OK; 76402744e81Swyllys KMF_RAW_RSA_KEY rsa; 76502744e81Swyllys BerElement *asn1 = NULL; 76602744e81Swyllys BerValue filebuf; 76702744e81Swyllys BerValue OID = { NULL, 0 }; 76802744e81Swyllys BerValue *Mod = NULL, *PubExp = NULL; 76902744e81Swyllys BerValue *PriExp = NULL, *Prime1 = NULL, *Prime2 = NULL; 77002744e81Swyllys BerValue *Coef = NULL; 77102744e81Swyllys BIGNUM *D = NULL, *P = NULL, *Q = NULL, *COEF = NULL; 77202744e81Swyllys BIGNUM *Exp1 = NULL, *Exp2 = NULL, *pminus1 = NULL; 77302744e81Swyllys BIGNUM *qminus1 = NULL; 77402744e81Swyllys BN_CTX *ctx = NULL; 77502744e81Swyllys 77602744e81Swyllys *pkey = NULL; 77702744e81Swyllys 77802744e81Swyllys filebuf.bv_val = (char *)filedata->Data; 77902744e81Swyllys filebuf.bv_len = filedata->Length; 78002744e81Swyllys 78102744e81Swyllys asn1 = kmfder_init(&filebuf); 78202744e81Swyllys if (asn1 == NULL) { 78302744e81Swyllys ret = KMF_ERR_MEMORY; 78402744e81Swyllys goto out; 78502744e81Swyllys } 78602744e81Swyllys 78702744e81Swyllys if (kmfber_scanf(asn1, "{{Dn{IIIIII}}}", 78802744e81Swyllys &OID, &Mod, &PubExp, &PriExp, &Prime1, 78902744e81Swyllys &Prime2, &Coef) == -1) { 79002744e81Swyllys ret = KMF_ERR_ENCODING; 79102744e81Swyllys goto out; 79202744e81Swyllys } 79302744e81Swyllys 79402744e81Swyllys /* 79502744e81Swyllys * We have to derive the 2 Exponents using Bignumber math. 79602744e81Swyllys * Exp1 = PriExp mod (Prime1 - 1) 79702744e81Swyllys * Exp2 = PriExp mod (Prime2 - 1) 79802744e81Swyllys */ 79902744e81Swyllys 80002744e81Swyllys /* D = PrivateExponent */ 80102744e81Swyllys D = BN_bin2bn((const uchar_t *)PriExp->bv_val, PriExp->bv_len, D); 80202744e81Swyllys if (D == NULL) { 80302744e81Swyllys ret = KMF_ERR_MEMORY; 80402744e81Swyllys goto out; 80502744e81Swyllys } 80602744e81Swyllys 80702744e81Swyllys /* P = Prime1 (first prime factor of Modulus) */ 80802744e81Swyllys P = BN_bin2bn((const uchar_t *)Prime1->bv_val, Prime1->bv_len, P); 80902744e81Swyllys if (D == NULL) { 81002744e81Swyllys ret = KMF_ERR_MEMORY; 81102744e81Swyllys goto out; 81202744e81Swyllys } 81302744e81Swyllys 81402744e81Swyllys /* Q = Prime2 (second prime factor of Modulus) */ 81502744e81Swyllys Q = BN_bin2bn((const uchar_t *)Prime2->bv_val, Prime2->bv_len, Q); 81602744e81Swyllys 81702744e81Swyllys if ((ctx = BN_CTX_new()) == NULL) { 81802744e81Swyllys ret = KMF_ERR_MEMORY; 81902744e81Swyllys goto out; 82002744e81Swyllys } 82102744e81Swyllys 82202744e81Swyllys /* Compute (P - 1) */ 82302744e81Swyllys pminus1 = BN_new(); 82402744e81Swyllys (void) BN_sub(pminus1, P, BN_value_one()); 82502744e81Swyllys 82602744e81Swyllys /* Exponent1 = D mod (P - 1) */ 82702744e81Swyllys Exp1 = BN_new(); 82802744e81Swyllys (void) BN_mod(Exp1, D, pminus1, ctx); 82902744e81Swyllys 83002744e81Swyllys /* Compute (Q - 1) */ 83102744e81Swyllys qminus1 = BN_new(); 83202744e81Swyllys (void) BN_sub(qminus1, Q, BN_value_one()); 83302744e81Swyllys 83402744e81Swyllys /* Exponent2 = D mod (Q - 1) */ 83502744e81Swyllys Exp2 = BN_new(); 83602744e81Swyllys (void) BN_mod(Exp2, D, qminus1, ctx); 83702744e81Swyllys 83802744e81Swyllys /* Coef = (Inverse Q) mod P */ 83902744e81Swyllys COEF = BN_new(); 84002744e81Swyllys (void) BN_mod_inverse(COEF, Q, P, ctx); 84102744e81Swyllys 84202744e81Swyllys /* Convert back to KMF format */ 84302744e81Swyllys (void) memset(&rsa, 0, sizeof (rsa)); 84402744e81Swyllys 84502744e81Swyllys if ((ret = sslBN2KMFBN(Exp1, &rsa.exp1)) != KMF_OK) 84602744e81Swyllys goto out; 84702744e81Swyllys if ((ret = sslBN2KMFBN(Exp2, &rsa.exp2)) != KMF_OK) 84802744e81Swyllys goto out; 84902744e81Swyllys if ((ret = sslBN2KMFBN(COEF, &rsa.coef)) != KMF_OK) 85002744e81Swyllys goto out; 85102744e81Swyllys 85202744e81Swyllys rsa.mod.val = (uchar_t *)Mod->bv_val; 85302744e81Swyllys rsa.mod.len = Mod->bv_len; 85402744e81Swyllys 85502744e81Swyllys rsa.pubexp.val = (uchar_t *)PubExp->bv_val; 85602744e81Swyllys rsa.pubexp.len = PubExp->bv_len; 85702744e81Swyllys 85802744e81Swyllys rsa.priexp.val = (uchar_t *)PriExp->bv_val; 85902744e81Swyllys rsa.priexp.len = PriExp->bv_len; 86002744e81Swyllys 86102744e81Swyllys rsa.prime1.val = (uchar_t *)Prime1->bv_val; 86202744e81Swyllys rsa.prime1.len = Prime1->bv_len; 86302744e81Swyllys 86402744e81Swyllys rsa.prime2.val = (uchar_t *)Prime2->bv_val; 86502744e81Swyllys rsa.prime2.len = Prime2->bv_len; 86602744e81Swyllys 86702744e81Swyllys *pkey = ImportRawRSAKey(&rsa); 86802744e81Swyllys out: 86902744e81Swyllys if (asn1 != NULL) 87002744e81Swyllys kmfber_free(asn1, 1); 87102744e81Swyllys 87202744e81Swyllys if (OID.bv_val) { 87302744e81Swyllys free(OID.bv_val); 87402744e81Swyllys } 87502744e81Swyllys if (PriExp) 87602744e81Swyllys free(PriExp); 87702744e81Swyllys 87802744e81Swyllys if (Mod) 87902744e81Swyllys free(Mod); 88002744e81Swyllys 88102744e81Swyllys if (PubExp) 88202744e81Swyllys free(PubExp); 88302744e81Swyllys 88402744e81Swyllys if (Coef) { 88502744e81Swyllys (void) memset(Coef->bv_val, 0, Coef->bv_len); 88602744e81Swyllys free(Coef->bv_val); 88702744e81Swyllys free(Coef); 88802744e81Swyllys } 88902744e81Swyllys if (Prime1) 89002744e81Swyllys free(Prime1); 89102744e81Swyllys if (Prime2) 89202744e81Swyllys free(Prime2); 89302744e81Swyllys 89402744e81Swyllys if (ctx != NULL) 89502744e81Swyllys BN_CTX_free(ctx); 89602744e81Swyllys 89702744e81Swyllys if (D) 89802744e81Swyllys BN_clear_free(D); 89902744e81Swyllys if (P) 90002744e81Swyllys BN_clear_free(P); 90102744e81Swyllys if (Q) 90202744e81Swyllys BN_clear_free(Q); 90302744e81Swyllys if (pminus1) 90402744e81Swyllys BN_clear_free(pminus1); 90502744e81Swyllys if (qminus1) 90602744e81Swyllys BN_clear_free(qminus1); 90702744e81Swyllys if (Exp1) 90802744e81Swyllys BN_clear_free(Exp1); 90902744e81Swyllys if (Exp2) 91002744e81Swyllys BN_clear_free(Exp2); 91102744e81Swyllys 91202744e81Swyllys return (ret); 91302744e81Swyllys 91402744e81Swyllys } 91502744e81Swyllys 91699ebb4caSwyllys static EVP_PKEY * 91799ebb4caSwyllys openssl_load_key(KMF_HANDLE_T handle, const char *file) 91899ebb4caSwyllys { 91999ebb4caSwyllys BIO *keyfile = NULL; 92099ebb4caSwyllys EVP_PKEY *pkey = NULL; 92199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 92299ebb4caSwyllys KMF_ENCODE_FORMAT format; 92302744e81Swyllys KMF_RETURN rv; 92402744e81Swyllys KMF_DATA filedata; 92599ebb4caSwyllys 92699ebb4caSwyllys if (file == NULL) { 92799ebb4caSwyllys return (NULL); 92899ebb4caSwyllys } 92999ebb4caSwyllys 93099ebb4caSwyllys if (KMF_GetFileFormat((char *)file, &format) != KMF_OK) 93199ebb4caSwyllys return (NULL); 93299ebb4caSwyllys 93399ebb4caSwyllys keyfile = BIO_new_file(file, "rb"); 93499ebb4caSwyllys if (keyfile == NULL) { 93599ebb4caSwyllys goto end; 93699ebb4caSwyllys } 93799ebb4caSwyllys 93802744e81Swyllys if (format == KMF_FORMAT_ASN1) { 93999ebb4caSwyllys pkey = d2i_PrivateKey_bio(keyfile, NULL); 94002744e81Swyllys if (pkey == NULL) { 94102744e81Swyllys 94202744e81Swyllys (void) BIO_free(keyfile); 94302744e81Swyllys keyfile = NULL; 94402744e81Swyllys /* Try odd ASN.1 variations */ 94502744e81Swyllys rv = KMF_ReadInputFile(kmfh, (char *)file, 94602744e81Swyllys &filedata); 94702744e81Swyllys if (rv == KMF_OK) { 94802744e81Swyllys (void) readAltFormatPrivateKey(&filedata, 94902744e81Swyllys &pkey); 95002744e81Swyllys KMF_FreeData(&filedata); 95102744e81Swyllys } 95202744e81Swyllys } 95302744e81Swyllys } else if (format == KMF_FORMAT_PEM || 95402744e81Swyllys format == KMF_FORMAT_PEM_KEYPAIR) { 95599ebb4caSwyllys pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL); 95602744e81Swyllys if (pkey == NULL) { 95702744e81Swyllys KMF_DATA derdata; 95802744e81Swyllys /* 95902744e81Swyllys * Check if this is the alt. format 96002744e81Swyllys * RSA private key file. 96102744e81Swyllys */ 96202744e81Swyllys rv = KMF_ReadInputFile(kmfh, (char *)file, 96302744e81Swyllys &filedata); 96402744e81Swyllys if (rv == KMF_OK) { 96502744e81Swyllys uchar_t *d = NULL; 96602744e81Swyllys int len; 96702744e81Swyllys rv = KMF_Pem2Der(filedata.Data, 96802744e81Swyllys filedata.Length, &d, &len); 96902744e81Swyllys if (rv == KMF_OK && d != NULL) { 97002744e81Swyllys derdata.Data = d; 97102744e81Swyllys derdata.Length = (size_t)len; 97202744e81Swyllys (void) readAltFormatPrivateKey( 97302744e81Swyllys &derdata, &pkey); 97402744e81Swyllys free(d); 97502744e81Swyllys } 97602744e81Swyllys KMF_FreeData(&filedata); 97702744e81Swyllys } 97802744e81Swyllys } 97902744e81Swyllys } 98099ebb4caSwyllys 98199ebb4caSwyllys end: 98299ebb4caSwyllys if (pkey == NULL) 98399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 98499ebb4caSwyllys 98599ebb4caSwyllys if (keyfile != NULL) 98699ebb4caSwyllys (void) BIO_free(keyfile); 98799ebb4caSwyllys 98899ebb4caSwyllys return (pkey); 98999ebb4caSwyllys } 99099ebb4caSwyllys 99199ebb4caSwyllys KMF_RETURN 99299ebb4caSwyllys OpenSSL_FindCert(KMF_HANDLE_T handle, 99399ebb4caSwyllys KMF_FINDCERT_PARAMS *params, 99499ebb4caSwyllys KMF_X509_DER_CERT *kmf_cert, 99599ebb4caSwyllys uint32_t *num_certs) 99699ebb4caSwyllys { 99799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 99899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 99999ebb4caSwyllys char *fullpath; 1000*f482c776Swyllys int i, n; 1001*f482c776Swyllys uint32_t maxcerts = 0; 100299ebb4caSwyllys 100399ebb4caSwyllys if (num_certs == NULL || params == NULL) 100499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 100599ebb4caSwyllys 1006*f482c776Swyllys maxcerts = *num_certs; 1007*f482c776Swyllys if (maxcerts == 0) 1008*f482c776Swyllys maxcerts = 0xFFFFFFFF; 100999ebb4caSwyllys *num_certs = 0; 101099ebb4caSwyllys 101199ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 101299ebb4caSwyllys params->sslparms.certfile); 101399ebb4caSwyllys 101499ebb4caSwyllys if (fullpath == NULL) 101599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 101699ebb4caSwyllys 101799ebb4caSwyllys if (isdir(fullpath)) { 101899ebb4caSwyllys DIR *dirp; 101999ebb4caSwyllys struct dirent *dp; 102099ebb4caSwyllys 1021*f482c776Swyllys n = 0; 102299ebb4caSwyllys /* open all files in the directory and attempt to read them */ 102399ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 102499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 102599ebb4caSwyllys } 102699ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 102799ebb4caSwyllys char *fname; 102871593db2Swyllys KMF_DATA *certlist = NULL; 1029*f482c776Swyllys uint32_t loaded_certs = 0; 103071593db2Swyllys 103199ebb4caSwyllys if (strcmp(dp->d_name, ".") == 0 || 103299ebb4caSwyllys strcmp(dp->d_name, "..") == 0) 103399ebb4caSwyllys continue; 103499ebb4caSwyllys 103599ebb4caSwyllys fname = get_fullpath(fullpath, 103699ebb4caSwyllys (char *)&dp->d_name); 103799ebb4caSwyllys 103871593db2Swyllys rv = load_certs(kmfh, params, fname, &certlist, 1039*f482c776Swyllys &loaded_certs); 104099ebb4caSwyllys 104199ebb4caSwyllys if (rv != KMF_OK) { 104299ebb4caSwyllys free(fname); 104371593db2Swyllys if (certlist != NULL) { 1044*f482c776Swyllys for (i = 0; i < loaded_certs; i++) 104571593db2Swyllys KMF_FreeData(&certlist[i]); 104671593db2Swyllys free(certlist); 104771593db2Swyllys } 104899ebb4caSwyllys continue; 104999ebb4caSwyllys } 105099ebb4caSwyllys 105199ebb4caSwyllys /* If load succeeds, add certdata to the list */ 105299ebb4caSwyllys if (kmf_cert != NULL) { 1053*f482c776Swyllys for (i = 0; i < loaded_certs && 1054*f482c776Swyllys i < maxcerts; i++) { 105571593db2Swyllys kmf_cert[n].certificate.Data = 105671593db2Swyllys certlist[i].Data; 105799ebb4caSwyllys kmf_cert[n].certificate.Length = 105871593db2Swyllys certlist[i].Length; 105999ebb4caSwyllys 106099ebb4caSwyllys kmf_cert[n].kmf_private.keystore_type = 106199ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 106299ebb4caSwyllys kmf_cert[n].kmf_private.flags = 106399ebb4caSwyllys KMF_FLAG_CERT_VALID; 106471593db2Swyllys kmf_cert[n].kmf_private.label = 106571593db2Swyllys strdup(fname); 106699ebb4caSwyllys n++; 106799ebb4caSwyllys } 1068*f482c776Swyllys /* If maxcerts < loaded_certs, clean up */ 1069*f482c776Swyllys for (; i < loaded_certs; i++) 107071593db2Swyllys KMF_FreeData(&certlist[i]); 1071*f482c776Swyllys } else { 1072*f482c776Swyllys for (i = 0; i < loaded_certs; i++) 1073*f482c776Swyllys KMF_FreeData(&certlist[i]); 1074*f482c776Swyllys n += loaded_certs; 107571593db2Swyllys } 1076*f482c776Swyllys free(certlist); 107771593db2Swyllys free(fname); 107871593db2Swyllys } 107999ebb4caSwyllys (*num_certs) = n; 108099ebb4caSwyllys if (*num_certs == 0) 108199ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 1082*f482c776Swyllys else 108399ebb4caSwyllys rv = KMF_OK; 108499ebb4caSwyllys exit: 108599ebb4caSwyllys (void) closedir(dirp); 108699ebb4caSwyllys } else { 108771593db2Swyllys KMF_DATA *certlist = NULL; 1088*f482c776Swyllys uint32_t loaded_certs = 0; 108971593db2Swyllys 1090*f482c776Swyllys rv = load_certs(kmfh, params, fullpath, 1091*f482c776Swyllys &certlist, &loaded_certs); 109299ebb4caSwyllys if (rv != KMF_OK) { 109399ebb4caSwyllys free(fullpath); 109499ebb4caSwyllys return (rv); 109599ebb4caSwyllys } 109699ebb4caSwyllys 1097*f482c776Swyllys n = 0; 109871593db2Swyllys if (kmf_cert != NULL && certlist != NULL) { 1099*f482c776Swyllys for (i = 0; i < loaded_certs && i < maxcerts; i++) { 1100*f482c776Swyllys kmf_cert[n].certificate.Data = 110171593db2Swyllys certlist[i].Data; 1102*f482c776Swyllys kmf_cert[n].certificate.Length = 110371593db2Swyllys certlist[i].Length; 1104*f482c776Swyllys kmf_cert[n].kmf_private.keystore_type = 110599ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 1106*f482c776Swyllys kmf_cert[n].kmf_private.flags = 110771593db2Swyllys KMF_FLAG_CERT_VALID; 1108*f482c776Swyllys kmf_cert[n].kmf_private.label = 110971593db2Swyllys strdup(fullpath); 1110*f482c776Swyllys n++; 111171593db2Swyllys } 1112*f482c776Swyllys /* If maxcerts < loaded_certs, clean up */ 1113*f482c776Swyllys for (; i < loaded_certs; i++) 111471593db2Swyllys KMF_FreeData(&certlist[i]); 1115*f482c776Swyllys } else if (certlist != NULL) { 1116*f482c776Swyllys for (i = 0; i < loaded_certs; i++) 1117*f482c776Swyllys KMF_FreeData(&certlist[i]); 1118*f482c776Swyllys n = loaded_certs; 1119*f482c776Swyllys } 1120*f482c776Swyllys if (certlist) 112171593db2Swyllys free(certlist); 1122*f482c776Swyllys 1123*f482c776Swyllys *num_certs = n; 112499ebb4caSwyllys } 112599ebb4caSwyllys 112699ebb4caSwyllys free(fullpath); 112799ebb4caSwyllys 112899ebb4caSwyllys return (rv); 112999ebb4caSwyllys } 113099ebb4caSwyllys 113199ebb4caSwyllys void 113299ebb4caSwyllys /*ARGSUSED*/ 113399ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, 113499ebb4caSwyllys KMF_X509_DER_CERT *kmf_cert) 113599ebb4caSwyllys { 113699ebb4caSwyllys if (kmf_cert != NULL) { 113799ebb4caSwyllys if (kmf_cert->certificate.Data != NULL) { 113899ebb4caSwyllys free(kmf_cert->certificate.Data); 113999ebb4caSwyllys kmf_cert->certificate.Data = NULL; 114099ebb4caSwyllys kmf_cert->certificate.Length = 0; 114199ebb4caSwyllys } 114299ebb4caSwyllys if (kmf_cert->kmf_private.label) 114399ebb4caSwyllys free(kmf_cert->kmf_private.label); 114499ebb4caSwyllys } 114599ebb4caSwyllys } 114699ebb4caSwyllys 114799ebb4caSwyllys KMF_RETURN 114899ebb4caSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, 114999ebb4caSwyllys KMF_DATA * pcert) 115099ebb4caSwyllys { 115199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 115299ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 115399ebb4caSwyllys X509 *xcert = NULL; 115499ebb4caSwyllys FILE *fp; 115599ebb4caSwyllys unsigned char *outbuf; 115699ebb4caSwyllys unsigned char *outbuf_p; 115799ebb4caSwyllys char *fullpath; 115899ebb4caSwyllys int outbuflen; 115999ebb4caSwyllys int len; 116099ebb4caSwyllys KMF_ENCODE_FORMAT format; 116199ebb4caSwyllys 116299ebb4caSwyllys if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) { 116399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 116499ebb4caSwyllys } 116599ebb4caSwyllys 116699ebb4caSwyllys /* 116799ebb4caSwyllys * check if the cert output format is supported by OPENSSL. 116899ebb4caSwyllys * however, since the keystore for OPENSSL is just a file, we have 116999ebb4caSwyllys * no way to store the format along with the file. 117099ebb4caSwyllys */ 117199ebb4caSwyllys format = params->sslparms.format; 117299ebb4caSwyllys if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) 117399ebb4caSwyllys return (KMF_ERR_BAD_CERT_FORMAT); 117499ebb4caSwyllys 117599ebb4caSwyllys 117699ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 117799ebb4caSwyllys params->sslparms.certfile); 117899ebb4caSwyllys if (fullpath == NULL) 117999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 118099ebb4caSwyllys 118199ebb4caSwyllys /* 118299ebb4caSwyllys * When storing a certificate, you must specify a filename. 118399ebb4caSwyllys */ 118499ebb4caSwyllys if (isdir(fullpath)) { 118599ebb4caSwyllys free(fullpath); 118699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 118799ebb4caSwyllys } 118899ebb4caSwyllys 118999ebb4caSwyllys /* copy cert data to outbuf */ 119099ebb4caSwyllys outbuflen = pcert->Length; 119199ebb4caSwyllys outbuf = malloc(outbuflen); 119299ebb4caSwyllys if (outbuf == NULL) { 119399ebb4caSwyllys free(fullpath); 119499ebb4caSwyllys return (KMF_ERR_MEMORY); 119599ebb4caSwyllys } 119699ebb4caSwyllys (void) memcpy(outbuf, pcert->Data, pcert->Length); 119799ebb4caSwyllys 119899ebb4caSwyllys if ((fp = fopen(fullpath, "w")) == 119999ebb4caSwyllys NULL) { 120099ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 120199ebb4caSwyllys ret = KMF_ERR_INTERNAL; 120299ebb4caSwyllys goto out; 120399ebb4caSwyllys } 120499ebb4caSwyllys 120599ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 120699ebb4caSwyllys len = fwrite(outbuf, 1, outbuflen, fp); 120799ebb4caSwyllys if (len != outbuflen) { 120899ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 120999ebb4caSwyllys ret = KMF_ERR_WRITE_FILE; 121099ebb4caSwyllys } else { 121199ebb4caSwyllys ret = KMF_OK; 121299ebb4caSwyllys } 121399ebb4caSwyllys goto out; 121499ebb4caSwyllys } 121599ebb4caSwyllys 121699ebb4caSwyllys /* 121799ebb4caSwyllys * The output format is not KMF_FORMAT_ASN1, so we will 121899ebb4caSwyllys * Convert the cert data to OpenSSL internal X509 first. 121999ebb4caSwyllys */ 122099ebb4caSwyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 122199ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen); 122299ebb4caSwyllys if (xcert == NULL) { 122399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 122499ebb4caSwyllys ret = KMF_ERR_ENCODING; 122599ebb4caSwyllys goto out; 122699ebb4caSwyllys } 122799ebb4caSwyllys 122899ebb4caSwyllys if (format == KMF_FORMAT_PEM) { 122999ebb4caSwyllys /* Convert to the PEM format and write it out */ 123099ebb4caSwyllys if (!PEM_write_X509(fp, xcert)) { 123199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 123299ebb4caSwyllys ret = KMF_ERR_ENCODING; 123399ebb4caSwyllys } else { 123499ebb4caSwyllys ret = KMF_OK; 123599ebb4caSwyllys } 123699ebb4caSwyllys goto out; 123799ebb4caSwyllys } 123899ebb4caSwyllys 123999ebb4caSwyllys out: 124099ebb4caSwyllys if (fullpath != NULL) 124199ebb4caSwyllys free(fullpath); 124299ebb4caSwyllys 124399ebb4caSwyllys if (outbuf != NULL) { 124499ebb4caSwyllys free(outbuf); 124599ebb4caSwyllys } 124699ebb4caSwyllys if (fp != NULL) { 124799ebb4caSwyllys (void) fclose(fp); 124899ebb4caSwyllys } 124999ebb4caSwyllys 125099ebb4caSwyllys if (xcert != NULL) { 125199ebb4caSwyllys X509_free(xcert); 125299ebb4caSwyllys } 125399ebb4caSwyllys 125499ebb4caSwyllys return (ret); 125599ebb4caSwyllys } 125699ebb4caSwyllys 125799ebb4caSwyllys KMF_RETURN 125899ebb4caSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) 125999ebb4caSwyllys { 126099ebb4caSwyllys KMF_RETURN rv; 126199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 126299ebb4caSwyllys char *fullpath = NULL; 126399ebb4caSwyllys KMF_DATA certdata = {NULL, 0}; 126499ebb4caSwyllys 126599ebb4caSwyllys if (params == NULL) { 126699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 126799ebb4caSwyllys } 126899ebb4caSwyllys 126999ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 127099ebb4caSwyllys params->sslparms.certfile); 127199ebb4caSwyllys 127299ebb4caSwyllys if (fullpath == NULL) 127399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 127499ebb4caSwyllys 127599ebb4caSwyllys if (isdir(fullpath)) { 127699ebb4caSwyllys DIR *dirp; 127799ebb4caSwyllys struct dirent *dp; 127899ebb4caSwyllys 127999ebb4caSwyllys /* open all files in the directory and attempt to read them */ 128099ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 128199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 128299ebb4caSwyllys } 128399ebb4caSwyllys 128499ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 128599ebb4caSwyllys if (strcmp(dp->d_name, ".") != 0 && 128699ebb4caSwyllys strcmp(dp->d_name, "..") != 0) { 128799ebb4caSwyllys char *fname; 128899ebb4caSwyllys 128999ebb4caSwyllys fname = get_fullpath(fullpath, 129099ebb4caSwyllys (char *)&dp->d_name); 129199ebb4caSwyllys 129299ebb4caSwyllys if (fname == NULL) { 129399ebb4caSwyllys rv = KMF_ERR_MEMORY; 129499ebb4caSwyllys break; 129599ebb4caSwyllys } 129699ebb4caSwyllys 129799ebb4caSwyllys rv = kmf_load_cert(kmfh, params, fname, 129899ebb4caSwyllys &certdata); 129999ebb4caSwyllys 130099ebb4caSwyllys if (rv == KMF_ERR_CERT_NOT_FOUND) { 130199ebb4caSwyllys free(fname); 130299ebb4caSwyllys if (certdata.Data) 130399ebb4caSwyllys free(certdata.Data); 130499ebb4caSwyllys rv = KMF_OK; 130599ebb4caSwyllys continue; 130699ebb4caSwyllys } else if (rv != KMF_OK) { 130799ebb4caSwyllys free(fname); 130899ebb4caSwyllys break; 130999ebb4caSwyllys } 131099ebb4caSwyllys 131199ebb4caSwyllys if (unlink(fname) != 0) { 131299ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 131399ebb4caSwyllys rv = KMF_ERR_INTERNAL; 131499ebb4caSwyllys free(fname); 131599ebb4caSwyllys break; 131699ebb4caSwyllys } 131799ebb4caSwyllys free(fname); 131899ebb4caSwyllys if (certdata.Data) 131999ebb4caSwyllys free(certdata.Data); 132099ebb4caSwyllys } 132199ebb4caSwyllys } 132299ebb4caSwyllys (void) closedir(dirp); 132399ebb4caSwyllys } else { 132499ebb4caSwyllys /* Just try to load a single certificate */ 132599ebb4caSwyllys rv = kmf_load_cert(kmfh, params, fullpath, &certdata); 132699ebb4caSwyllys if (rv == KMF_OK) { 132799ebb4caSwyllys if (unlink(fullpath) != 0) { 132899ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 132999ebb4caSwyllys rv = KMF_ERR_INTERNAL; 133099ebb4caSwyllys } 133199ebb4caSwyllys } 133299ebb4caSwyllys } 133399ebb4caSwyllys 133499ebb4caSwyllys out: 133599ebb4caSwyllys if (fullpath != NULL) 133699ebb4caSwyllys free(fullpath); 133799ebb4caSwyllys 133899ebb4caSwyllys if (certdata.Data) 133999ebb4caSwyllys free(certdata.Data); 134099ebb4caSwyllys 134199ebb4caSwyllys return (rv); 134299ebb4caSwyllys } 134399ebb4caSwyllys 134499ebb4caSwyllys KMF_RETURN 134599ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 134699ebb4caSwyllys KMF_DATA *keydata) 134799ebb4caSwyllys { 134899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 134999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 135099ebb4caSwyllys int n; 135199ebb4caSwyllys 135299ebb4caSwyllys if (key == NULL || keydata == NULL || 135399ebb4caSwyllys key->keyp == NULL) 135499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 135599ebb4caSwyllys 135699ebb4caSwyllys if (key->keyalg == KMF_RSA) { 135799ebb4caSwyllys RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp); 135899ebb4caSwyllys 135999ebb4caSwyllys if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) { 136099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 136199ebb4caSwyllys return (KMF_ERR_ENCODING); 136299ebb4caSwyllys } 136399ebb4caSwyllys RSA_free(pubkey); 136499ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 136599ebb4caSwyllys DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp); 136699ebb4caSwyllys 136799ebb4caSwyllys if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) { 136899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 136999ebb4caSwyllys return (KMF_ERR_ENCODING); 137099ebb4caSwyllys } 137199ebb4caSwyllys DSA_free(pubkey); 137299ebb4caSwyllys } else { 137399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 137499ebb4caSwyllys } 137599ebb4caSwyllys keydata->Length = n; 137699ebb4caSwyllys 137799ebb4caSwyllys cleanup: 137899ebb4caSwyllys if (rv != KMF_OK) { 137999ebb4caSwyllys if (keydata->Data) 138099ebb4caSwyllys free(keydata->Data); 138199ebb4caSwyllys keydata->Data = NULL; 138299ebb4caSwyllys keydata->Length = 0; 138399ebb4caSwyllys } 138499ebb4caSwyllys 138599ebb4caSwyllys return (rv); 138699ebb4caSwyllys } 138799ebb4caSwyllys 138899ebb4caSwyllys static KMF_RETURN 138999ebb4caSwyllys ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, 139099ebb4caSwyllys KMF_CREDENTIAL *cred, EVP_PKEY *pkey) 139199ebb4caSwyllys { 139299ebb4caSwyllys int rv = 0; 139399ebb4caSwyllys RSA *rsa; 139499ebb4caSwyllys DSA *dsa; 139599ebb4caSwyllys 139699ebb4caSwyllys switch (format) { 139799ebb4caSwyllys case KMF_FORMAT_ASN1: 139899ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 139999ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 140099ebb4caSwyllys rv = i2d_RSAPrivateKey_bio(out, rsa); 140199ebb4caSwyllys RSA_free(rsa); 140299ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 140399ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 140499ebb4caSwyllys rv = i2d_DSAPrivateKey_bio(out, dsa); 140599ebb4caSwyllys DSA_free(dsa); 140699ebb4caSwyllys } 140799ebb4caSwyllys if (rv == 1) { 140899ebb4caSwyllys rv = KMF_OK; 140999ebb4caSwyllys } else { 141099ebb4caSwyllys SET_ERROR(kmfh, rv); 141199ebb4caSwyllys } 141299ebb4caSwyllys break; 141399ebb4caSwyllys case KMF_FORMAT_PEM: 141499ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 141599ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 141699ebb4caSwyllys rv = PEM_write_bio_RSAPrivateKey(out, 141799ebb4caSwyllys rsa, 141899ebb4caSwyllys NULL /* encryption type */, 141999ebb4caSwyllys NULL, 0, NULL, 142099ebb4caSwyllys cred->cred); 142199ebb4caSwyllys RSA_free(rsa); 142299ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 142399ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 142499ebb4caSwyllys rv = PEM_write_bio_DSAPrivateKey(out, 142599ebb4caSwyllys dsa, 142699ebb4caSwyllys NULL /* encryption type */, 142799ebb4caSwyllys NULL, 0, NULL, 142899ebb4caSwyllys cred->cred); 142999ebb4caSwyllys DSA_free(dsa); 143099ebb4caSwyllys } 143199ebb4caSwyllys 143299ebb4caSwyllys if (rv == 1) { 143399ebb4caSwyllys rv = KMF_OK; 143499ebb4caSwyllys } else { 143599ebb4caSwyllys SET_ERROR(kmfh, rv); 143699ebb4caSwyllys } 143799ebb4caSwyllys break; 143899ebb4caSwyllys 143999ebb4caSwyllys default: 144099ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 144199ebb4caSwyllys } 144299ebb4caSwyllys 144399ebb4caSwyllys return (rv); 144499ebb4caSwyllys } 144599ebb4caSwyllys 144699ebb4caSwyllys KMF_RETURN 144799ebb4caSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, 144899ebb4caSwyllys KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) 144999ebb4caSwyllys { 145099ebb4caSwyllys KMF_RETURN rv = KMF_OK; 145199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 145299ebb4caSwyllys int format; 145399ebb4caSwyllys uint32_t eValue = 0x010001; 145499ebb4caSwyllys RSA *sslPrivKey = NULL; 145599ebb4caSwyllys DSA *sslDSAKey = NULL; 145699ebb4caSwyllys EVP_PKEY *eprikey = NULL; 145799ebb4caSwyllys EVP_PKEY *epubkey = NULL; 145899ebb4caSwyllys BIO *out = NULL; 145999ebb4caSwyllys char *fullpath = NULL; 146099ebb4caSwyllys 146199ebb4caSwyllys if (params == NULL || params->sslparms.keyfile == NULL) { 146299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 146399ebb4caSwyllys } 146499ebb4caSwyllys 146599ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 146699ebb4caSwyllys params->sslparms.keyfile); 146799ebb4caSwyllys 146899ebb4caSwyllys if (fullpath == NULL) 146999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 147099ebb4caSwyllys 147199ebb4caSwyllys /* If the requested file exists, return an error */ 147299ebb4caSwyllys if (access(fullpath, F_OK) == 0) { 147399ebb4caSwyllys free(fullpath); 147499ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 147599ebb4caSwyllys } 147699ebb4caSwyllys 147799ebb4caSwyllys eprikey = EVP_PKEY_new(); 147899ebb4caSwyllys if (eprikey == NULL) { 147999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 148099ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 148199ebb4caSwyllys goto cleanup; 148299ebb4caSwyllys } 148399ebb4caSwyllys epubkey = EVP_PKEY_new(); 148499ebb4caSwyllys if (epubkey == NULL) { 148599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 148699ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 148799ebb4caSwyllys goto cleanup; 148899ebb4caSwyllys } 148999ebb4caSwyllys if (params->keytype == KMF_RSA) { 149099ebb4caSwyllys if (params->rsa_exponent.len > 0 && 149199ebb4caSwyllys params->rsa_exponent.len <= sizeof (eValue) && 149299ebb4caSwyllys params->rsa_exponent.val != NULL) 149399ebb4caSwyllys /*LINTED*/ 149499ebb4caSwyllys eValue = *(uint32_t *)params->rsa_exponent.val; 149599ebb4caSwyllys 149699ebb4caSwyllys sslPrivKey = RSA_generate_key(params->keylength, eValue, 149799ebb4caSwyllys NULL, NULL); 149899ebb4caSwyllys if (sslPrivKey == NULL) { 149999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 150099ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 150199ebb4caSwyllys } else { 150299ebb4caSwyllys if (privkey != NULL && 150399ebb4caSwyllys EVP_PKEY_set1_RSA(eprikey, sslPrivKey)) { 150499ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 150599ebb4caSwyllys privkey->keyalg = KMF_RSA; 150699ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 150799ebb4caSwyllys privkey->israw = FALSE; 150899ebb4caSwyllys privkey->keylabel = (char *)strdup(fullpath); 150999ebb4caSwyllys privkey->keyp = (void *)eprikey; 151099ebb4caSwyllys } 151199ebb4caSwyllys /* OpenSSL derives the public key from the private */ 151299ebb4caSwyllys if (pubkey != NULL && 151399ebb4caSwyllys EVP_PKEY_set1_RSA(epubkey, sslPrivKey)) { 151499ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 151599ebb4caSwyllys pubkey->keyalg = KMF_RSA; 151699ebb4caSwyllys pubkey->israw = FALSE; 151799ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 151899ebb4caSwyllys pubkey->keylabel = (char *)strdup(fullpath); 151999ebb4caSwyllys pubkey->keyp = (void *)epubkey; 152099ebb4caSwyllys } 152199ebb4caSwyllys } 152299ebb4caSwyllys } else if (params->keytype == KMF_DSA) { 152399ebb4caSwyllys sslDSAKey = DSA_new(); 152499ebb4caSwyllys if (sslDSAKey == NULL) { 152599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 152699ebb4caSwyllys return (KMF_ERR_MEMORY); 152799ebb4caSwyllys } 152899ebb4caSwyllys 152999ebb4caSwyllys if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) == 153099ebb4caSwyllys NULL) { 153199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 153299ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 153399ebb4caSwyllys goto cleanup; 153499ebb4caSwyllys } 153599ebb4caSwyllys if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) == 153699ebb4caSwyllys NULL) { 153799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 153899ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 153999ebb4caSwyllys goto cleanup; 154099ebb4caSwyllys } 154199ebb4caSwyllys if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) == 154299ebb4caSwyllys NULL) { 154399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 154499ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 154599ebb4caSwyllys goto cleanup; 154699ebb4caSwyllys } 154799ebb4caSwyllys 154899ebb4caSwyllys if (!DSA_generate_key(sslDSAKey)) { 154999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 155099ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 155199ebb4caSwyllys goto cleanup; 155299ebb4caSwyllys } 155399ebb4caSwyllys 155499ebb4caSwyllys if (privkey != NULL) { 155599ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 155699ebb4caSwyllys privkey->keyalg = KMF_DSA; 155799ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 155899ebb4caSwyllys privkey->israw = FALSE; 155999ebb4caSwyllys privkey->keylabel = (char *)strdup(fullpath); 156099ebb4caSwyllys if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { 156199ebb4caSwyllys privkey->keyp = (void *)eprikey; 156299ebb4caSwyllys } else { 156399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 156499ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 156599ebb4caSwyllys goto cleanup; 156699ebb4caSwyllys } 156799ebb4caSwyllys } 156899ebb4caSwyllys if (pubkey != NULL) { 156999ebb4caSwyllys DSA *dp = DSA_new(); 157099ebb4caSwyllys /* Make a copy for the public key */ 157199ebb4caSwyllys if (dp != NULL) { 157299ebb4caSwyllys if ((dp->p = BN_new()) == NULL) { 157399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 157499ebb4caSwyllys rv = KMF_ERR_MEMORY; 157599ebb4caSwyllys DSA_free(dp); 157699ebb4caSwyllys goto cleanup; 157799ebb4caSwyllys } 157899ebb4caSwyllys if ((dp->q = BN_new()) == NULL) { 157999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 158099ebb4caSwyllys rv = KMF_ERR_MEMORY; 158199ebb4caSwyllys BN_free(dp->p); 158299ebb4caSwyllys DSA_free(dp); 158399ebb4caSwyllys goto cleanup; 158499ebb4caSwyllys } 158599ebb4caSwyllys if ((dp->g = BN_new()) == NULL) { 158699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 158799ebb4caSwyllys rv = KMF_ERR_MEMORY; 158899ebb4caSwyllys BN_free(dp->q); 158999ebb4caSwyllys BN_free(dp->p); 159099ebb4caSwyllys DSA_free(dp); 159199ebb4caSwyllys goto cleanup; 159299ebb4caSwyllys } 159399ebb4caSwyllys if ((dp->pub_key = BN_new()) == NULL) { 159499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 159599ebb4caSwyllys rv = KMF_ERR_MEMORY; 159699ebb4caSwyllys BN_free(dp->q); 159799ebb4caSwyllys BN_free(dp->p); 159899ebb4caSwyllys BN_free(dp->g); 159999ebb4caSwyllys DSA_free(dp); 160099ebb4caSwyllys goto cleanup; 160199ebb4caSwyllys } 160299ebb4caSwyllys (void) BN_copy(dp->p, sslDSAKey->p); 160399ebb4caSwyllys (void) BN_copy(dp->q, sslDSAKey->q); 160499ebb4caSwyllys (void) BN_copy(dp->g, sslDSAKey->g); 160599ebb4caSwyllys (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); 160699ebb4caSwyllys 160799ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 160899ebb4caSwyllys pubkey->keyalg = KMF_DSA; 160999ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 161099ebb4caSwyllys pubkey->israw = FALSE; 161199ebb4caSwyllys pubkey->keylabel = (char *)strdup(fullpath); 161299ebb4caSwyllys 161399ebb4caSwyllys if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { 161499ebb4caSwyllys pubkey->keyp = (void *)epubkey; 161599ebb4caSwyllys } else { 161699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 161799ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 161899ebb4caSwyllys goto cleanup; 161999ebb4caSwyllys } 162099ebb4caSwyllys } 162199ebb4caSwyllys } 162299ebb4caSwyllys } 162399ebb4caSwyllys 162499ebb4caSwyllys if (rv != KMF_OK) { 162599ebb4caSwyllys goto cleanup; 162699ebb4caSwyllys } 162799ebb4caSwyllys 162899ebb4caSwyllys /* Store the private key to the keyfile */ 162999ebb4caSwyllys format = params->sslparms.format; 163099ebb4caSwyllys out = BIO_new_file(fullpath, "wb"); 163199ebb4caSwyllys if (out == NULL) { 163299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 163399ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 163499ebb4caSwyllys goto cleanup; 163599ebb4caSwyllys } 163699ebb4caSwyllys rv = ssl_write_private_key(kmfh, format, out, ¶ms->cred, eprikey); 163799ebb4caSwyllys 163899ebb4caSwyllys cleanup: 163999ebb4caSwyllys if (rv != KMF_OK) { 164099ebb4caSwyllys if (eprikey != NULL) 164199ebb4caSwyllys EVP_PKEY_free(eprikey); 164299ebb4caSwyllys 164399ebb4caSwyllys if (epubkey != NULL) 164499ebb4caSwyllys EVP_PKEY_free(epubkey); 164599ebb4caSwyllys 164699ebb4caSwyllys if (pubkey->keylabel) { 164799ebb4caSwyllys free(pubkey->keylabel); 164899ebb4caSwyllys pubkey->keylabel = NULL; 164999ebb4caSwyllys } 165099ebb4caSwyllys 165199ebb4caSwyllys if (privkey->keylabel) { 165299ebb4caSwyllys free(privkey->keylabel); 165399ebb4caSwyllys privkey->keylabel = NULL; 165499ebb4caSwyllys } 165599ebb4caSwyllys 165699ebb4caSwyllys pubkey->keyp = NULL; 165799ebb4caSwyllys privkey->keyp = NULL; 165899ebb4caSwyllys } 165999ebb4caSwyllys 166099ebb4caSwyllys if (sslPrivKey) 166199ebb4caSwyllys RSA_free(sslPrivKey); 166299ebb4caSwyllys 166399ebb4caSwyllys if (sslDSAKey) 166499ebb4caSwyllys DSA_free(sslDSAKey); 166599ebb4caSwyllys 166699ebb4caSwyllys 166799ebb4caSwyllys if (out != NULL) 166899ebb4caSwyllys (void) BIO_free(out); 166999ebb4caSwyllys 167099ebb4caSwyllys if (fullpath) 167199ebb4caSwyllys free(fullpath); 167299ebb4caSwyllys 167399ebb4caSwyllys /* Protect the file by making it read-only */ 167499ebb4caSwyllys if (rv == KMF_OK) { 167599ebb4caSwyllys (void) chmod(fullpath, 0400); 167699ebb4caSwyllys } 167799ebb4caSwyllys return (rv); 167899ebb4caSwyllys } 167999ebb4caSwyllys 168099ebb4caSwyllys KMF_RETURN 168199ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 168299ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output) 168399ebb4caSwyllys { 168499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 168599ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 168699ebb4caSwyllys KMF_ALGORITHM_INDEX AlgId; 168799ebb4caSwyllys EVP_MD_CTX ctx; 168899ebb4caSwyllys const EVP_MD *md; 168902744e81Swyllys 169099ebb4caSwyllys if (key == NULL || AlgOID == NULL || 169199ebb4caSwyllys tobesigned == NULL || output == NULL || 169299ebb4caSwyllys tobesigned->Data == NULL || 169399ebb4caSwyllys output->Data == NULL) 169499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 169599ebb4caSwyllys 169699ebb4caSwyllys /* Map the OID to an OpenSSL algorithm */ 169799ebb4caSwyllys AlgId = X509_AlgorithmOidToAlgId(AlgOID); 169899ebb4caSwyllys if (AlgId == KMF_ALGID_NONE) 169999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 170099ebb4caSwyllys 170199ebb4caSwyllys if (key->keyalg == KMF_RSA) { 170299ebb4caSwyllys EVP_PKEY *pkey = (EVP_PKEY *)key->keyp; 170399ebb4caSwyllys uchar_t *p; 170402744e81Swyllys int len; 170599ebb4caSwyllys if (AlgId == KMF_ALGID_MD5WithRSA) 170699ebb4caSwyllys md = EVP_md5(); 170799ebb4caSwyllys else if (AlgId == KMF_ALGID_MD2WithRSA) 170899ebb4caSwyllys md = EVP_md2(); 170999ebb4caSwyllys else if (AlgId == KMF_ALGID_SHA1WithRSA) 171099ebb4caSwyllys md = EVP_sha1(); 171102744e81Swyllys else if (AlgId == KMF_ALGID_RSA) 171202744e81Swyllys md = NULL; 171399ebb4caSwyllys else 171499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 171599ebb4caSwyllys 171602744e81Swyllys if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) { 171702744e81Swyllys RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey); 171899ebb4caSwyllys 171902744e81Swyllys p = output->Data; 172002744e81Swyllys if ((len = RSA_private_encrypt(tobesigned->Length, 172102744e81Swyllys tobesigned->Data, p, rsa, 172202744e81Swyllys RSA_PKCS1_PADDING)) <= 0) { 172302744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 172402744e81Swyllys ret = KMF_ERR_INTERNAL; 172502744e81Swyllys } 172602744e81Swyllys output->Length = len; 172702744e81Swyllys } else { 172899ebb4caSwyllys (void) EVP_MD_CTX_init(&ctx); 172999ebb4caSwyllys (void) EVP_SignInit_ex(&ctx, md, NULL); 173099ebb4caSwyllys (void) EVP_SignUpdate(&ctx, tobesigned->Data, 173199ebb4caSwyllys (uint32_t)tobesigned->Length); 173299ebb4caSwyllys len = (uint32_t)output->Length; 173399ebb4caSwyllys p = output->Data; 173402744e81Swyllys if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) { 173599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 173602744e81Swyllys len = 0; 173702744e81Swyllys ret = KMF_ERR_INTERNAL; 173899ebb4caSwyllys } 173999ebb4caSwyllys output->Length = len; 174099ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 174102744e81Swyllys } 174299ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 174399ebb4caSwyllys DSA *dsa = EVP_PKEY_get1_DSA(key->keyp); 174499ebb4caSwyllys 174599ebb4caSwyllys uchar_t hash[EVP_MAX_MD_SIZE]; 174699ebb4caSwyllys uint32_t hashlen; 174799ebb4caSwyllys DSA_SIG *dsasig; 174899ebb4caSwyllys 174999ebb4caSwyllys /* 175099ebb4caSwyllys * OpenSSL EVP_Sign operation automatically converts to 175199ebb4caSwyllys * ASN.1 output so we do the operations separately so we 175299ebb4caSwyllys * are assured of NOT getting ASN.1 output returned. 175399ebb4caSwyllys * KMF does not want ASN.1 encoded results because 175499ebb4caSwyllys * not all mechanisms return ASN.1 encodings (PKCS#11 175599ebb4caSwyllys * and NSS return raw signature data). 175699ebb4caSwyllys */ 175799ebb4caSwyllys md = EVP_sha1(); 175899ebb4caSwyllys EVP_MD_CTX_init(&ctx); 175999ebb4caSwyllys (void) EVP_DigestInit_ex(&ctx, md, NULL); 176099ebb4caSwyllys (void) EVP_DigestUpdate(&ctx, tobesigned->Data, 176199ebb4caSwyllys tobesigned->Length); 176299ebb4caSwyllys (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen); 176399ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 176499ebb4caSwyllys 176599ebb4caSwyllys dsasig = DSA_do_sign(hash, hashlen, dsa); 176699ebb4caSwyllys if (dsasig != NULL) { 176799ebb4caSwyllys int i; 176899ebb4caSwyllys output->Length = i = BN_bn2bin(dsasig->r, output->Data); 176999ebb4caSwyllys output->Length += BN_bn2bin(dsasig->s, 177099ebb4caSwyllys &output->Data[i]); 177199ebb4caSwyllys DSA_SIG_free(dsasig); 177299ebb4caSwyllys } else { 177399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 177499ebb4caSwyllys } 177599ebb4caSwyllys } else { 177699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 177799ebb4caSwyllys } 177899ebb4caSwyllys cleanup: 177999ebb4caSwyllys return (ret); 178099ebb4caSwyllys } 178199ebb4caSwyllys 178299ebb4caSwyllys KMF_RETURN 178399ebb4caSwyllys /*ARGSUSED*/ 178499ebb4caSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, 178599ebb4caSwyllys KMF_KEY_HANDLE *key, boolean_t destroy) 178699ebb4caSwyllys { 178799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 178899ebb4caSwyllys if (key == NULL || key->keyp == NULL) 178999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 179099ebb4caSwyllys 179199ebb4caSwyllys if (key->keyclass != KMF_ASYM_PUB && 179299ebb4caSwyllys key->keyclass != KMF_ASYM_PRI && 179399ebb4caSwyllys key->keyclass != KMF_SYMMETRIC) 179499ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 179599ebb4caSwyllys 179699ebb4caSwyllys if (key->keyclass == KMF_SYMMETRIC) { 179799ebb4caSwyllys KMF_FreeRawSymKey((KMF_RAW_SYM_KEY *)key->keyp); 179899ebb4caSwyllys key->keyp = NULL; 179999ebb4caSwyllys } else { 180099ebb4caSwyllys if (key->keyp != NULL) { 180199ebb4caSwyllys EVP_PKEY_free(key->keyp); 180299ebb4caSwyllys key->keyp = NULL; 180399ebb4caSwyllys } 180499ebb4caSwyllys } 180599ebb4caSwyllys 180699ebb4caSwyllys if (key->keylabel != NULL) { 180799ebb4caSwyllys EVP_PKEY *pkey = NULL; 180899ebb4caSwyllys /* If the file exists, make sure it is a proper key. */ 180999ebb4caSwyllys pkey = openssl_load_key(handle, key->keylabel); 181099ebb4caSwyllys if (pkey == NULL) { 181199ebb4caSwyllys free(key->keylabel); 181299ebb4caSwyllys key->keylabel = NULL; 181399ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 181499ebb4caSwyllys } 181599ebb4caSwyllys EVP_PKEY_free(pkey); 181699ebb4caSwyllys 181799ebb4caSwyllys if (destroy) { 181899ebb4caSwyllys if (unlink(key->keylabel) != 0) { 181999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 182099ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 182199ebb4caSwyllys rv = KMF_ERR_INTERNAL; 182299ebb4caSwyllys } 182399ebb4caSwyllys } 182499ebb4caSwyllys if (key->keylabel != NULL) { 182599ebb4caSwyllys free(key->keylabel); 182699ebb4caSwyllys key->keylabel = NULL; 182799ebb4caSwyllys } 182899ebb4caSwyllys } 182999ebb4caSwyllys return (rv); 183099ebb4caSwyllys } 183199ebb4caSwyllys 183299ebb4caSwyllys KMF_RETURN 183399ebb4caSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) 183499ebb4caSwyllys { 183599ebb4caSwyllys KMF_RETURN ret = KMF_OK; 183699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 183799ebb4caSwyllys X509_CRL *xcrl = NULL; 183899ebb4caSwyllys X509 *xcert = NULL; 183999ebb4caSwyllys EVP_PKEY *pkey; 184099ebb4caSwyllys KMF_ENCODE_FORMAT format; 184199ebb4caSwyllys BIO *in = NULL, *out = NULL; 184299ebb4caSwyllys int openssl_ret = 0; 184399ebb4caSwyllys char *outcrlfile = NULL; 184499ebb4caSwyllys KMF_ENCODE_FORMAT outformat; 184599ebb4caSwyllys 184699ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL) { 184799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 184899ebb4caSwyllys } 184999ebb4caSwyllys 185099ebb4caSwyllys if (params->sslparms.crl_check == B_TRUE && 185199ebb4caSwyllys params->sslparms.certfile == NULL) { 185299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 185399ebb4caSwyllys } 185499ebb4caSwyllys 185599ebb4caSwyllys outcrlfile = get_fullpath(params->sslparms.dirpath, 185699ebb4caSwyllys params->sslparms.outcrlfile); 185799ebb4caSwyllys 185899ebb4caSwyllys if (outcrlfile == NULL) 185999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 186099ebb4caSwyllys 186199ebb4caSwyllys if (isdir(outcrlfile)) { 186299ebb4caSwyllys free(outcrlfile); 186399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 186499ebb4caSwyllys } 186599ebb4caSwyllys 186699ebb4caSwyllys ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); 186799ebb4caSwyllys if (ret != KMF_OK) { 186899ebb4caSwyllys free(outcrlfile); 186999ebb4caSwyllys return (ret); 187099ebb4caSwyllys } 187199ebb4caSwyllys 187299ebb4caSwyllys in = BIO_new_file(params->sslparms.crlfile, "rb"); 187399ebb4caSwyllys if (in == NULL) { 187499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 187599ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 187699ebb4caSwyllys goto end; 187799ebb4caSwyllys } 187899ebb4caSwyllys 187999ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 188099ebb4caSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 188199ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 188299ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 188399ebb4caSwyllys } 188499ebb4caSwyllys 188599ebb4caSwyllys if (xcrl == NULL) { 188699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 188799ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 188899ebb4caSwyllys goto end; 188999ebb4caSwyllys } 189099ebb4caSwyllys 189199ebb4caSwyllys /* If bypasscheck is specified, no need to verify. */ 189299ebb4caSwyllys if (params->sslparms.crl_check == B_FALSE) { 189399ebb4caSwyllys goto output; 189499ebb4caSwyllys } 189599ebb4caSwyllys 189699ebb4caSwyllys ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); 189799ebb4caSwyllys if (ret != KMF_OK) 189899ebb4caSwyllys goto end; 189999ebb4caSwyllys 190099ebb4caSwyllys /* Read in the CA cert file and convert to X509 */ 190199ebb4caSwyllys if (BIO_read_filename(in, params->sslparms.certfile) <= 0) { 190299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 190399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 190499ebb4caSwyllys goto end; 190599ebb4caSwyllys } 190699ebb4caSwyllys 190799ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 190899ebb4caSwyllys xcert = d2i_X509_bio(in, NULL); 190999ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 191099ebb4caSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 191199ebb4caSwyllys } else { 191299ebb4caSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 191399ebb4caSwyllys goto end; 191499ebb4caSwyllys } 191599ebb4caSwyllys 191699ebb4caSwyllys if (xcert == NULL) { 191799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 191899ebb4caSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 191999ebb4caSwyllys goto end; 192099ebb4caSwyllys } 192199ebb4caSwyllys /* Now get the public key from the CA cert */ 192299ebb4caSwyllys pkey = X509_get_pubkey(xcert); 192399ebb4caSwyllys if (!pkey) { 192499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 192599ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 192699ebb4caSwyllys goto end; 192799ebb4caSwyllys } 192899ebb4caSwyllys 192999ebb4caSwyllys /* Verify the CRL with the CA's public key */ 193099ebb4caSwyllys openssl_ret = X509_CRL_verify(xcrl, pkey); 193199ebb4caSwyllys EVP_PKEY_free(pkey); 193299ebb4caSwyllys if (openssl_ret > 0) { 193399ebb4caSwyllys ret = KMF_OK; /* verify succeed */ 193499ebb4caSwyllys } else { 193599ebb4caSwyllys SET_ERROR(kmfh, openssl_ret); 193699ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 193799ebb4caSwyllys } 193899ebb4caSwyllys 193999ebb4caSwyllys output: 194099ebb4caSwyllys outformat = params->sslparms.format; 194199ebb4caSwyllys 194299ebb4caSwyllys out = BIO_new_file(outcrlfile, "wb"); 194399ebb4caSwyllys if (out == NULL) { 194499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 194599ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 194699ebb4caSwyllys goto end; 194799ebb4caSwyllys } 194899ebb4caSwyllys 194999ebb4caSwyllys if (outformat == KMF_FORMAT_ASN1) { 195099ebb4caSwyllys openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); 195199ebb4caSwyllys } else if (outformat == KMF_FORMAT_PEM) { 195299ebb4caSwyllys openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); 195399ebb4caSwyllys } else { 195499ebb4caSwyllys ret = KMF_ERR_BAD_PARAMETER; 195599ebb4caSwyllys goto end; 195699ebb4caSwyllys } 195799ebb4caSwyllys 195899ebb4caSwyllys if (openssl_ret <= 0) { 195999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 196099ebb4caSwyllys ret = KMF_ERR_WRITE_FILE; 196199ebb4caSwyllys } else { 196299ebb4caSwyllys ret = KMF_OK; 196399ebb4caSwyllys } 196499ebb4caSwyllys 196599ebb4caSwyllys end: 196699ebb4caSwyllys if (xcrl != NULL) 196799ebb4caSwyllys X509_CRL_free(xcrl); 196899ebb4caSwyllys 196999ebb4caSwyllys if (xcert != NULL) 197099ebb4caSwyllys X509_free(xcert); 197199ebb4caSwyllys 197299ebb4caSwyllys if (in != NULL) 197399ebb4caSwyllys (void) BIO_free(in); 197499ebb4caSwyllys 197599ebb4caSwyllys if (out != NULL) 197699ebb4caSwyllys (void) BIO_free(out); 197799ebb4caSwyllys 197899ebb4caSwyllys if (outcrlfile != NULL) 197999ebb4caSwyllys free(outcrlfile); 198099ebb4caSwyllys 198199ebb4caSwyllys return (ret); 198299ebb4caSwyllys } 198399ebb4caSwyllys 198499ebb4caSwyllys KMF_RETURN 198599ebb4caSwyllys OpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, 198699ebb4caSwyllys char **crldata) 198799ebb4caSwyllys { 198899ebb4caSwyllys KMF_RETURN ret = KMF_OK; 198999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 199099ebb4caSwyllys X509_CRL *x = NULL; 199199ebb4caSwyllys KMF_ENCODE_FORMAT format; 199299ebb4caSwyllys char *crlfile = NULL; 199399ebb4caSwyllys BIO *in = NULL; 199499ebb4caSwyllys BIO *mem = NULL; 199599ebb4caSwyllys long len; 199699ebb4caSwyllys char *memptr; 199799ebb4caSwyllys char *data = NULL; 199899ebb4caSwyllys 199999ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL) { 200099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 200199ebb4caSwyllys } 200299ebb4caSwyllys 200399ebb4caSwyllys crlfile = get_fullpath(params->sslparms.dirpath, 200499ebb4caSwyllys params->sslparms.crlfile); 200599ebb4caSwyllys 200699ebb4caSwyllys if (crlfile == NULL) 200799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 200899ebb4caSwyllys 200999ebb4caSwyllys if (isdir(crlfile)) { 201099ebb4caSwyllys free(crlfile); 201199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 201299ebb4caSwyllys } 201399ebb4caSwyllys 201499ebb4caSwyllys ret = KMF_IsCRLFile(handle, crlfile, &format); 201599ebb4caSwyllys if (ret != KMF_OK) { 201699ebb4caSwyllys free(crlfile); 201799ebb4caSwyllys return (ret); 201899ebb4caSwyllys } 201999ebb4caSwyllys 202099ebb4caSwyllys if (bio_err == NULL) 202199ebb4caSwyllys bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 202299ebb4caSwyllys 202399ebb4caSwyllys in = BIO_new_file(crlfile, "rb"); 202499ebb4caSwyllys if (in == NULL) { 202599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 202699ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 202799ebb4caSwyllys goto end; 202899ebb4caSwyllys } 202999ebb4caSwyllys 203099ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 203199ebb4caSwyllys x = d2i_X509_CRL_bio(in, NULL); 203299ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 203399ebb4caSwyllys x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 203499ebb4caSwyllys } 203599ebb4caSwyllys 203699ebb4caSwyllys if (x == NULL) { /* should not happen */ 203799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 203899ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 203999ebb4caSwyllys goto end; 204099ebb4caSwyllys } 204199ebb4caSwyllys 204299ebb4caSwyllys mem = BIO_new(BIO_s_mem()); 204399ebb4caSwyllys if (mem == NULL) { 204499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 204599ebb4caSwyllys ret = KMF_ERR_MEMORY; 204699ebb4caSwyllys goto end; 204799ebb4caSwyllys } 204899ebb4caSwyllys 204999ebb4caSwyllys (void) X509_CRL_print(mem, x); 205099ebb4caSwyllys len = BIO_get_mem_data(mem, &memptr); 205199ebb4caSwyllys if (len <= 0) { 205299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 205399ebb4caSwyllys ret = KMF_ERR_MEMORY; 205499ebb4caSwyllys goto end; 205599ebb4caSwyllys } 205699ebb4caSwyllys 205799ebb4caSwyllys data = malloc(len + 1); 205899ebb4caSwyllys if (data == NULL) { 205999ebb4caSwyllys ret = KMF_ERR_MEMORY; 206099ebb4caSwyllys goto end; 206199ebb4caSwyllys } 206299ebb4caSwyllys 206399ebb4caSwyllys (void) memcpy(data, memptr, len); 206499ebb4caSwyllys data[len] = '\0'; 206599ebb4caSwyllys *crldata = data; 206699ebb4caSwyllys 206799ebb4caSwyllys end: 206899ebb4caSwyllys if (x != NULL) 206999ebb4caSwyllys X509_CRL_free(x); 207099ebb4caSwyllys 207199ebb4caSwyllys if (crlfile != NULL) 207299ebb4caSwyllys free(crlfile); 207399ebb4caSwyllys 207499ebb4caSwyllys if (in != NULL) 207599ebb4caSwyllys (void) BIO_free(in); 207699ebb4caSwyllys 207799ebb4caSwyllys if (mem != NULL) 207899ebb4caSwyllys (void) BIO_free(mem); 207999ebb4caSwyllys 208099ebb4caSwyllys return (ret); 208199ebb4caSwyllys } 208299ebb4caSwyllys 208399ebb4caSwyllys KMF_RETURN 208499ebb4caSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) 208599ebb4caSwyllys { 208699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 208799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 208899ebb4caSwyllys KMF_ENCODE_FORMAT format; 208999ebb4caSwyllys char *crlfile = NULL; 209099ebb4caSwyllys BIO *in = NULL; 209199ebb4caSwyllys 209299ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL) { 209399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 209499ebb4caSwyllys } 209599ebb4caSwyllys 209699ebb4caSwyllys crlfile = get_fullpath(params->sslparms.dirpath, 209799ebb4caSwyllys params->sslparms.crlfile); 209899ebb4caSwyllys 209999ebb4caSwyllys if (crlfile == NULL) 210099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 210199ebb4caSwyllys 210299ebb4caSwyllys if (isdir(crlfile)) { 210399ebb4caSwyllys ret = KMF_ERR_BAD_PARAMETER; 210499ebb4caSwyllys goto end; 210599ebb4caSwyllys } 210699ebb4caSwyllys 210799ebb4caSwyllys ret = KMF_IsCRLFile(handle, crlfile, &format); 210899ebb4caSwyllys if (ret != KMF_OK) 210999ebb4caSwyllys goto end; 211099ebb4caSwyllys 211199ebb4caSwyllys if (unlink(crlfile) != 0) { 211299ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 211399ebb4caSwyllys ret = KMF_ERR_INTERNAL; 211499ebb4caSwyllys goto end; 211599ebb4caSwyllys } 211699ebb4caSwyllys 211799ebb4caSwyllys end: 211899ebb4caSwyllys if (in != NULL) 211999ebb4caSwyllys (void) BIO_free(in); 212099ebb4caSwyllys if (crlfile != NULL) 212199ebb4caSwyllys free(crlfile); 212299ebb4caSwyllys 212399ebb4caSwyllys return (ret); 212499ebb4caSwyllys } 212599ebb4caSwyllys 212699ebb4caSwyllys 212799ebb4caSwyllys KMF_RETURN 212899ebb4caSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) 212999ebb4caSwyllys { 213099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 213199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 213299ebb4caSwyllys KMF_ENCODE_FORMAT format; 213399ebb4caSwyllys BIO *in = NULL; 213499ebb4caSwyllys X509 *xcert = NULL; 213599ebb4caSwyllys X509_CRL *xcrl = NULL; 213699ebb4caSwyllys STACK_OF(X509_REVOKED) *revoke_stack = NULL; 213799ebb4caSwyllys X509_REVOKED *revoke; 213899ebb4caSwyllys int i; 213999ebb4caSwyllys 214099ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL || 214199ebb4caSwyllys params->sslparms.certfile == NULL) { 214299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 214399ebb4caSwyllys } 214499ebb4caSwyllys 214599ebb4caSwyllys ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); 214699ebb4caSwyllys if (ret != KMF_OK) 214799ebb4caSwyllys return (ret); 214899ebb4caSwyllys 214999ebb4caSwyllys /* Read the CRL file and load it into a X509_CRL structure */ 215099ebb4caSwyllys in = BIO_new_file(params->sslparms.crlfile, "rb"); 215199ebb4caSwyllys if (in == NULL) { 215299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 215399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 215499ebb4caSwyllys goto end; 215599ebb4caSwyllys } 215699ebb4caSwyllys 215799ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 215899ebb4caSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 215999ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 216099ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 216199ebb4caSwyllys } 216299ebb4caSwyllys 216399ebb4caSwyllys if (xcrl == NULL) { 216499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 216599ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 216699ebb4caSwyllys goto end; 216799ebb4caSwyllys } 216899ebb4caSwyllys (void) BIO_free(in); 216999ebb4caSwyllys 217099ebb4caSwyllys /* Read the Certificate file and load it into a X509 structure */ 217199ebb4caSwyllys ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); 217299ebb4caSwyllys if (ret != KMF_OK) 217399ebb4caSwyllys goto end; 217499ebb4caSwyllys 217599ebb4caSwyllys in = BIO_new_file(params->sslparms.certfile, "rb"); 217699ebb4caSwyllys if (in == NULL) { 217799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 217899ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 217999ebb4caSwyllys goto end; 218099ebb4caSwyllys } 218199ebb4caSwyllys 218299ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 218399ebb4caSwyllys xcert = d2i_X509_bio(in, NULL); 218499ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 218599ebb4caSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 218699ebb4caSwyllys } 218799ebb4caSwyllys 218899ebb4caSwyllys if (xcert == NULL) { 218999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 219099ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 219199ebb4caSwyllys goto end; 219299ebb4caSwyllys } 219399ebb4caSwyllys 219499ebb4caSwyllys /* Check if the certificate and the CRL have same issuer */ 219599ebb4caSwyllys if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { 219699ebb4caSwyllys ret = KMF_ERR_ISSUER; 219799ebb4caSwyllys goto end; 219899ebb4caSwyllys } 219999ebb4caSwyllys 220099ebb4caSwyllys /* Check to see if the certificate serial number is revoked */ 220199ebb4caSwyllys revoke_stack = X509_CRL_get_REVOKED(xcrl); 220299ebb4caSwyllys if (sk_X509_REVOKED_num(revoke_stack) <= 0) { 220399ebb4caSwyllys /* No revoked certificates in the CRL file */ 220499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 220599ebb4caSwyllys ret = KMF_ERR_EMPTY_CRL; 220699ebb4caSwyllys goto end; 220799ebb4caSwyllys } 220899ebb4caSwyllys 220999ebb4caSwyllys for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { 221099ebb4caSwyllys /*LINTED*/ 221199ebb4caSwyllys revoke = sk_X509_REVOKED_value(revoke_stack, i); 221299ebb4caSwyllys if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, 221399ebb4caSwyllys revoke->serialNumber) == 0) { 221499ebb4caSwyllys break; 221599ebb4caSwyllys } 221699ebb4caSwyllys } 221799ebb4caSwyllys 221899ebb4caSwyllys if (i < sk_X509_REVOKED_num(revoke_stack)) { 221999ebb4caSwyllys ret = KMF_OK; 222099ebb4caSwyllys } else { 222199ebb4caSwyllys ret = KMF_ERR_NOT_REVOKED; 222299ebb4caSwyllys } 222399ebb4caSwyllys 222499ebb4caSwyllys end: 222599ebb4caSwyllys if (in != NULL) 222699ebb4caSwyllys (void) BIO_free(in); 222799ebb4caSwyllys if (xcrl != NULL) 222899ebb4caSwyllys X509_CRL_free(xcrl); 222999ebb4caSwyllys if (xcert != NULL) 223099ebb4caSwyllys X509_free(xcert); 223199ebb4caSwyllys 223299ebb4caSwyllys return (ret); 223399ebb4caSwyllys } 223499ebb4caSwyllys 223599ebb4caSwyllys KMF_RETURN 223699ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 223799ebb4caSwyllys { 223899ebb4caSwyllys KMF_RETURN ret = KMF_OK; 223999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 224099ebb4caSwyllys char str[256]; /* OpenSSL needs at least 120 byte buffer */ 224199ebb4caSwyllys 224299ebb4caSwyllys ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str)); 224399ebb4caSwyllys if (strlen(str)) { 224499ebb4caSwyllys *msgstr = (char *)strdup(str); 224599ebb4caSwyllys if ((*msgstr) == NULL) 224699ebb4caSwyllys ret = KMF_ERR_MEMORY; 224799ebb4caSwyllys } else { 224899ebb4caSwyllys *msgstr = NULL; 224999ebb4caSwyllys } 225099ebb4caSwyllys 225199ebb4caSwyllys return (ret); 225299ebb4caSwyllys } 225399ebb4caSwyllys 225499ebb4caSwyllys static int 225599ebb4caSwyllys ext2NID(int kmfext) 225699ebb4caSwyllys { 225799ebb4caSwyllys switch (kmfext) { 225899ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 225999ebb4caSwyllys return (NID_key_usage); 226099ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 226199ebb4caSwyllys return (NID_private_key_usage_period); 226299ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 226399ebb4caSwyllys return (NID_certificate_policies); 226499ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 226599ebb4caSwyllys return (NID_subject_alt_name); 226699ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 226799ebb4caSwyllys return (NID_issuer_alt_name); 226899ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 226999ebb4caSwyllys return (NID_basic_constraints); 227099ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 227199ebb4caSwyllys return (NID_ext_key_usage); 227299ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 227399ebb4caSwyllys return (NID_authority_key_identifier); 227499ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 227599ebb4caSwyllys return (NID_crl_distribution_points); 227699ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 227799ebb4caSwyllys return (NID_subject_key_identifier); 227899ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 227999ebb4caSwyllys return (OBJ_sn2nid("policyMappings")); 228099ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 228199ebb4caSwyllys return (OBJ_sn2nid("nameConstraints")); 228299ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 228399ebb4caSwyllys return (OBJ_sn2nid("policyConstraints")); 228499ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 228599ebb4caSwyllys return (OBJ_sn2nid("inhibitAnyPolicy")); 228699ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 228799ebb4caSwyllys return (OBJ_sn2nid("freshestCRL")); 228899ebb4caSwyllys default: 228999ebb4caSwyllys return (NID_undef); 229099ebb4caSwyllys } 229199ebb4caSwyllys } 229299ebb4caSwyllys 229399ebb4caSwyllys KMF_RETURN 229499ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, 229599ebb4caSwyllys KMF_PRINTABLE_ITEM flag, char *resultStr) 229699ebb4caSwyllys { 229799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 229899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 229999ebb4caSwyllys X509 *xcert = NULL; 230099ebb4caSwyllys unsigned char *outbuf = NULL; 230199ebb4caSwyllys unsigned char *outbuf_p; 230299ebb4caSwyllys char *tmpstr = NULL; 230399ebb4caSwyllys int j; 230499ebb4caSwyllys int ext_index, nid, len; 230599ebb4caSwyllys BIO *mem = NULL; 230699ebb4caSwyllys STACK *emlst = NULL; 230799ebb4caSwyllys X509_EXTENSION *ex; 230899ebb4caSwyllys X509_CINF *ci; 230999ebb4caSwyllys 231099ebb4caSwyllys if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) { 231199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 231299ebb4caSwyllys } 231399ebb4caSwyllys 231499ebb4caSwyllys /* copy cert data to outbuf */ 231599ebb4caSwyllys outbuf = malloc(pcert->Length); 231699ebb4caSwyllys if (outbuf == NULL) { 231799ebb4caSwyllys return (KMF_ERR_MEMORY); 231899ebb4caSwyllys } 231999ebb4caSwyllys (void) memcpy(outbuf, pcert->Data, pcert->Length); 232099ebb4caSwyllys 232199ebb4caSwyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 232299ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length); 232399ebb4caSwyllys if (xcert == NULL) { 232499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 232599ebb4caSwyllys ret = KMF_ERR_ENCODING; 232699ebb4caSwyllys goto out; 232799ebb4caSwyllys } 232899ebb4caSwyllys 232999ebb4caSwyllys mem = BIO_new(BIO_s_mem()); 233099ebb4caSwyllys if (mem == NULL) { 233199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 233299ebb4caSwyllys ret = KMF_ERR_MEMORY; 233399ebb4caSwyllys goto out; 233499ebb4caSwyllys } 233599ebb4caSwyllys 233699ebb4caSwyllys switch (flag) { 233799ebb4caSwyllys case KMF_CERT_ISSUER: 233899ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0, 233999ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 234099ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 234199ebb4caSwyllys break; 234299ebb4caSwyllys 234399ebb4caSwyllys case KMF_CERT_SUBJECT: 234499ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0, 234599ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 234699ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 234799ebb4caSwyllys break; 234899ebb4caSwyllys 234999ebb4caSwyllys case KMF_CERT_VERSION: 235099ebb4caSwyllys tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version); 235199ebb4caSwyllys (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN); 235299ebb4caSwyllys OPENSSL_free(tmpstr); 235399ebb4caSwyllys len = strlen(resultStr); 235499ebb4caSwyllys break; 235599ebb4caSwyllys 235699ebb4caSwyllys case KMF_CERT_SERIALNUM: 235799ebb4caSwyllys if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) { 235899ebb4caSwyllys (void) strcpy(resultStr, "0x"); 235999ebb4caSwyllys len = BIO_gets(mem, &resultStr[2], 236099ebb4caSwyllys KMF_CERT_PRINTABLE_LEN - 2); 236199ebb4caSwyllys } 236299ebb4caSwyllys break; 236399ebb4caSwyllys 236499ebb4caSwyllys case KMF_CERT_NOTBEFORE: 236599ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert)); 236699ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 236799ebb4caSwyllys break; 236899ebb4caSwyllys 236999ebb4caSwyllys case KMF_CERT_NOTAFTER: 237099ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert)); 237199ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 237299ebb4caSwyllys break; 237399ebb4caSwyllys 237499ebb4caSwyllys case KMF_CERT_PUBKEY_DATA: 237599ebb4caSwyllys { 237699ebb4caSwyllys EVP_PKEY *pkey = X509_get_pubkey(xcert); 237799ebb4caSwyllys if (pkey == NULL) { 237899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 237999ebb4caSwyllys ret = KMF_ERR_ENCODING; 238099ebb4caSwyllys goto out; 238199ebb4caSwyllys } 238299ebb4caSwyllys 238399ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 238499ebb4caSwyllys (void) BIO_printf(mem, 238599ebb4caSwyllys "RSA Public Key: (%d bit)\n", 238699ebb4caSwyllys BN_num_bits(pkey->pkey.rsa->n)); 238799ebb4caSwyllys (void) RSA_print(mem, pkey->pkey.rsa, 0); 238899ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 238999ebb4caSwyllys (void) BIO_printf(mem, 239099ebb4caSwyllys "%12sDSA Public Key:\n", ""); 239199ebb4caSwyllys (void) DSA_print(mem, pkey->pkey.dsa, 0); 239299ebb4caSwyllys } else { 239399ebb4caSwyllys (void) BIO_printf(mem, 239499ebb4caSwyllys "%12sUnknown Public Key:\n", ""); 239599ebb4caSwyllys } 239699ebb4caSwyllys (void) BIO_printf(mem, "\n"); 239799ebb4caSwyllys EVP_PKEY_free(pkey); 239899ebb4caSwyllys } 239999ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 240099ebb4caSwyllys break; 240199ebb4caSwyllys case KMF_CERT_SIGNATURE_ALG: 240299ebb4caSwyllys case KMF_CERT_PUBKEY_ALG: 240399ebb4caSwyllys if (flag == KMF_CERT_SIGNATURE_ALG) { 240499ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 240599ebb4caSwyllys xcert->sig_alg->algorithm); 240699ebb4caSwyllys } else { 240799ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 240899ebb4caSwyllys xcert->cert_info->key->algor->algorithm); 240999ebb4caSwyllys } 241099ebb4caSwyllys 241199ebb4caSwyllys if (len > 0) { 241299ebb4caSwyllys len = BIO_read(mem, resultStr, 241399ebb4caSwyllys KMF_CERT_PRINTABLE_LEN); 241499ebb4caSwyllys } 241599ebb4caSwyllys break; 241699ebb4caSwyllys 241799ebb4caSwyllys case KMF_CERT_EMAIL: 241899ebb4caSwyllys emlst = X509_get1_email(xcert); 241999ebb4caSwyllys for (j = 0; j < sk_num(emlst); j++) 242099ebb4caSwyllys (void) BIO_printf(mem, "%s\n", sk_value(emlst, j)); 242199ebb4caSwyllys 242299ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 242399ebb4caSwyllys X509_email_free(emlst); 242499ebb4caSwyllys break; 242599ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 242699ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 242799ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 242899ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 242999ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 243099ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 243199ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 243299ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 243399ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 243499ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 243599ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 243699ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 243799ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 243899ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 243999ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 244099ebb4caSwyllys nid = ext2NID(flag); 244199ebb4caSwyllys if (nid == NID_undef) { 244299ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 244399ebb4caSwyllys goto out; 244499ebb4caSwyllys } 244599ebb4caSwyllys ci = xcert->cert_info; 244699ebb4caSwyllys 244799ebb4caSwyllys ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1); 244899ebb4caSwyllys if (ext_index == -1) { 244999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 245099ebb4caSwyllys 245199ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 245299ebb4caSwyllys goto out; 245399ebb4caSwyllys } 245499ebb4caSwyllys ex = X509v3_get_ext(ci->extensions, ext_index); 245599ebb4caSwyllys 245699ebb4caSwyllys (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); 245799ebb4caSwyllys 245899ebb4caSwyllys if (BIO_printf(mem, ": %s\n", 245999ebb4caSwyllys X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 246099ebb4caSwyllys 0) { 246199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 246299ebb4caSwyllys ret = KMF_ERR_ENCODING; 246399ebb4caSwyllys goto out; 246499ebb4caSwyllys } 246599ebb4caSwyllys if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) { 246699ebb4caSwyllys (void) BIO_printf(mem, "%*s", 4, ""); 246799ebb4caSwyllys (void) M_ASN1_OCTET_STRING_print(mem, ex->value); 246899ebb4caSwyllys } 246999ebb4caSwyllys if (BIO_write(mem, "\n", 1) <= 0) { 247099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 247199ebb4caSwyllys ret = KMF_ERR_ENCODING; 247299ebb4caSwyllys goto out; 247399ebb4caSwyllys } 247499ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 247599ebb4caSwyllys } 247699ebb4caSwyllys if (len <= 0) { 247799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 247899ebb4caSwyllys ret = KMF_ERR_ENCODING; 247999ebb4caSwyllys } 248099ebb4caSwyllys 248199ebb4caSwyllys out: 248299ebb4caSwyllys if (outbuf != NULL) { 248399ebb4caSwyllys free(outbuf); 248499ebb4caSwyllys } 248599ebb4caSwyllys 248699ebb4caSwyllys if (xcert != NULL) { 248799ebb4caSwyllys X509_free(xcert); 248899ebb4caSwyllys } 248999ebb4caSwyllys 249099ebb4caSwyllys if (mem != NULL) { 249199ebb4caSwyllys (void) BIO_free(mem); 249299ebb4caSwyllys } 249399ebb4caSwyllys 249499ebb4caSwyllys return (ret); 249599ebb4caSwyllys } 249699ebb4caSwyllys KMF_RETURN 249799ebb4caSwyllys /*ARGSUSED*/ 249899ebb4caSwyllys OpenSSL_GetPrikeyByCert(KMF_HANDLE_T handle, 249999ebb4caSwyllys KMF_CRYPTOWITHCERT_PARAMS *params, 250099ebb4caSwyllys KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, 250199ebb4caSwyllys KMF_KEY_ALG keytype) 250299ebb4caSwyllys { 250399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 250499ebb4caSwyllys KMF_FINDKEY_PARAMS fkparms; 250599ebb4caSwyllys uint32_t numkeys = 0; 250699ebb4caSwyllys 250702744e81Swyllys if (params == NULL || params->sslparms.keyfile == NULL) 250899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 250999ebb4caSwyllys 251099ebb4caSwyllys /* 251199ebb4caSwyllys * This is really just a FindKey operation, reuse the 251299ebb4caSwyllys * FindKey function. 251399ebb4caSwyllys */ 251499ebb4caSwyllys (void *)memset(&fkparms, 0, sizeof (fkparms)); 251599ebb4caSwyllys fkparms.kstype = KMF_KEYSTORE_OPENSSL; 251699ebb4caSwyllys fkparms.keyclass = KMF_ASYM_PRI; 251799ebb4caSwyllys fkparms.keytype = keytype; 251899ebb4caSwyllys fkparms.format = params->format; 251999ebb4caSwyllys fkparms.sslparms = params->sslparms; 252099ebb4caSwyllys 252199ebb4caSwyllys rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys); 252299ebb4caSwyllys 252399ebb4caSwyllys return (rv); 252499ebb4caSwyllys } 252599ebb4caSwyllys 252699ebb4caSwyllys KMF_RETURN 252799ebb4caSwyllys /*ARGSUSED*/ 252899ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 252999ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *ciphertext, 253099ebb4caSwyllys KMF_DATA *output) 253199ebb4caSwyllys { 253299ebb4caSwyllys KMF_RETURN ret = KMF_OK; 253399ebb4caSwyllys RSA *rsa = NULL; 253499ebb4caSwyllys unsigned int in_len = 0, out_len = 0; 253599ebb4caSwyllys unsigned int total_decrypted = 0, modulus_len = 0; 253699ebb4caSwyllys uint8_t *in_data, *out_data; 253799ebb4caSwyllys int i, blocks; 253899ebb4caSwyllys 253999ebb4caSwyllys if (key == NULL || AlgOID == NULL || 254099ebb4caSwyllys ciphertext == NULL || output == NULL || 254199ebb4caSwyllys ciphertext->Data == NULL || 254299ebb4caSwyllys output->Data == NULL) 254399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 254499ebb4caSwyllys 254599ebb4caSwyllys if (key->keyalg == KMF_RSA) { 254699ebb4caSwyllys rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp); 254799ebb4caSwyllys modulus_len = RSA_size(rsa); 254899ebb4caSwyllys } else { 254999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 255099ebb4caSwyllys } 255199ebb4caSwyllys 255299ebb4caSwyllys blocks = ciphertext->Length/modulus_len; 255399ebb4caSwyllys out_data = output->Data; 255499ebb4caSwyllys in_data = ciphertext->Data; 255599ebb4caSwyllys out_len = modulus_len - 11; 255699ebb4caSwyllys in_len = modulus_len; 255799ebb4caSwyllys 255899ebb4caSwyllys for (i = 0; i < blocks; i++) { 255999ebb4caSwyllys out_len = RSA_private_decrypt(in_len, 256099ebb4caSwyllys in_data, out_data, rsa, RSA_PKCS1_PADDING); 256199ebb4caSwyllys 256299ebb4caSwyllys if (out_len == 0) { 256399ebb4caSwyllys ret = KMF_ERR_INTERNAL; 256499ebb4caSwyllys goto cleanup; 256599ebb4caSwyllys } 256699ebb4caSwyllys 256799ebb4caSwyllys out_data += out_len; 256899ebb4caSwyllys total_decrypted += out_len; 256999ebb4caSwyllys in_data += in_len; 257099ebb4caSwyllys } 257199ebb4caSwyllys 257299ebb4caSwyllys output->Length = total_decrypted; 257399ebb4caSwyllys 257499ebb4caSwyllys cleanup: 257599ebb4caSwyllys RSA_free(rsa); 257699ebb4caSwyllys if (ret != KMF_OK) 257799ebb4caSwyllys output->Length = 0; 257899ebb4caSwyllys 257999ebb4caSwyllys return (ret); 258099ebb4caSwyllys 258199ebb4caSwyllys } 258299ebb4caSwyllys 258399ebb4caSwyllys /* 258499ebb4caSwyllys * This function will create a certid from issuer_cert and user_cert. 258599ebb4caSwyllys * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate 258699ebb4caSwyllys * certid memory after use. 258799ebb4caSwyllys */ 258899ebb4caSwyllys static KMF_RETURN 258999ebb4caSwyllys create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert, 259099ebb4caSwyllys const KMF_DATA *user_cert, OCSP_CERTID **certid) 259199ebb4caSwyllys { 259299ebb4caSwyllys KMF_RETURN ret = KMF_OK; 259399ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 259499ebb4caSwyllys X509 *issuer = NULL; 259599ebb4caSwyllys X509 *cert = NULL; 259699ebb4caSwyllys unsigned char *ptmp; 259799ebb4caSwyllys 259899ebb4caSwyllys if (issuer_cert == NULL || user_cert == NULL) { 259999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 260099ebb4caSwyllys } 260199ebb4caSwyllys 260299ebb4caSwyllys /* convert the DER-encoded issuer cert to an internal X509 */ 260399ebb4caSwyllys ptmp = issuer_cert->Data; 260499ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 260599ebb4caSwyllys issuer_cert->Length); 260699ebb4caSwyllys if (issuer == NULL) { 260799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 260899ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 260999ebb4caSwyllys goto end; 261099ebb4caSwyllys } 261199ebb4caSwyllys 261299ebb4caSwyllys /* convert the DER-encoded user cert to an internal X509 */ 261399ebb4caSwyllys ptmp = user_cert->Data; 261499ebb4caSwyllys cert = d2i_X509(NULL, (const uchar_t **)&ptmp, 261599ebb4caSwyllys user_cert->Length); 261699ebb4caSwyllys if (cert == NULL) { 261799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 261899ebb4caSwyllys 261999ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_CERT; 262099ebb4caSwyllys goto end; 262199ebb4caSwyllys } 262299ebb4caSwyllys 262399ebb4caSwyllys /* create a CERTID */ 262499ebb4caSwyllys *certid = OCSP_cert_to_id(NULL, cert, issuer); 262599ebb4caSwyllys if (*certid == NULL) { 262699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 262799ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 262899ebb4caSwyllys goto end; 262999ebb4caSwyllys } 263099ebb4caSwyllys 263199ebb4caSwyllys end: 263299ebb4caSwyllys if (issuer != NULL) { 263399ebb4caSwyllys X509_free(issuer); 263499ebb4caSwyllys } 263599ebb4caSwyllys 263699ebb4caSwyllys if (cert != NULL) { 263799ebb4caSwyllys X509_free(cert); 263899ebb4caSwyllys } 263999ebb4caSwyllys 264099ebb4caSwyllys return (ret); 264199ebb4caSwyllys } 264299ebb4caSwyllys 264399ebb4caSwyllys KMF_RETURN 264499ebb4caSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, 264599ebb4caSwyllys char *reqfile) 264699ebb4caSwyllys { 264799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 264899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 264999ebb4caSwyllys OCSP_CERTID *id = NULL; 265099ebb4caSwyllys OCSP_REQUEST *req = NULL; 265199ebb4caSwyllys BIO *derbio = NULL; 265299ebb4caSwyllys 265399ebb4caSwyllys if (params->user_cert == NULL || params->issuer_cert == NULL || 265499ebb4caSwyllys reqfile == NULL) { 265599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 265699ebb4caSwyllys } 265799ebb4caSwyllys 265899ebb4caSwyllys ret = create_certid(handle, params->issuer_cert, params->user_cert, 265999ebb4caSwyllys &id); 266099ebb4caSwyllys if (ret != KMF_OK) { 266199ebb4caSwyllys return (ret); 266299ebb4caSwyllys } 266399ebb4caSwyllys 266499ebb4caSwyllys /* Create an OCSP request */ 266599ebb4caSwyllys req = OCSP_REQUEST_new(); 266699ebb4caSwyllys if (req == NULL) { 266799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 266899ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 266999ebb4caSwyllys goto end; 267099ebb4caSwyllys } 267199ebb4caSwyllys 267299ebb4caSwyllys if (!OCSP_request_add0_id(req, id)) { 267399ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 267499ebb4caSwyllys goto end; 267599ebb4caSwyllys } 267699ebb4caSwyllys 267799ebb4caSwyllys /* Write the request to the output file with DER encoding */ 267899ebb4caSwyllys derbio = BIO_new_file(reqfile, "wb"); 267999ebb4caSwyllys if (!derbio) { 268099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 268199ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 268299ebb4caSwyllys goto end; 268399ebb4caSwyllys } 268499ebb4caSwyllys if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) { 268599ebb4caSwyllys ret = KMF_ERR_ENCODING; 268699ebb4caSwyllys } 268799ebb4caSwyllys 268899ebb4caSwyllys end: 268999ebb4caSwyllys /* 269099ebb4caSwyllys * We don't need to free "id" explicitely, because OCSP_REQUEST_free() 269199ebb4caSwyllys * will deallocate certid's space also. 269299ebb4caSwyllys */ 269399ebb4caSwyllys if (req != NULL) { 269499ebb4caSwyllys OCSP_REQUEST_free(req); 269599ebb4caSwyllys } 269699ebb4caSwyllys 269799ebb4caSwyllys if (derbio != NULL) { 269899ebb4caSwyllys (void) BIO_free(derbio); 269999ebb4caSwyllys } 270099ebb4caSwyllys 270199ebb4caSwyllys return (ret); 270299ebb4caSwyllys } 270399ebb4caSwyllys 270499ebb4caSwyllys /* ocsp_find_signer_sk() is copied from openssl source */ 270599ebb4caSwyllys static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 270699ebb4caSwyllys { 270799ebb4caSwyllys int i; 270899ebb4caSwyllys unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 270999ebb4caSwyllys 271099ebb4caSwyllys /* Easy if lookup by name */ 271199ebb4caSwyllys if (id->type == V_OCSP_RESPID_NAME) 271299ebb4caSwyllys return (X509_find_by_subject(certs, id->value.byName)); 271399ebb4caSwyllys 271499ebb4caSwyllys /* Lookup by key hash */ 271599ebb4caSwyllys 271699ebb4caSwyllys /* If key hash isn't SHA1 length then forget it */ 271799ebb4caSwyllys if (id->value.byKey->length != SHA_DIGEST_LENGTH) 271899ebb4caSwyllys return (NULL); 271999ebb4caSwyllys 272099ebb4caSwyllys keyhash = id->value.byKey->data; 272199ebb4caSwyllys /* Calculate hash of each key and compare */ 272299ebb4caSwyllys for (i = 0; i < sk_X509_num(certs); i++) { 272399ebb4caSwyllys /*LINTED*/ 272499ebb4caSwyllys X509 *x = sk_X509_value(certs, i); 272599ebb4caSwyllys (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 272699ebb4caSwyllys if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 272799ebb4caSwyllys return (x); 272899ebb4caSwyllys } 272999ebb4caSwyllys return (NULL); 273099ebb4caSwyllys } 273199ebb4caSwyllys 273299ebb4caSwyllys /* ocsp_find_signer() is copied from openssl source */ 273399ebb4caSwyllys /*ARGSUSED*/ 273499ebb4caSwyllys static int 273599ebb4caSwyllys ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, 273699ebb4caSwyllys X509_STORE *st, unsigned long flags) 273799ebb4caSwyllys { 273899ebb4caSwyllys X509 *signer; 273999ebb4caSwyllys OCSP_RESPID *rid = bs->tbsResponseData->responderId; 274099ebb4caSwyllys if ((signer = ocsp_find_signer_sk(certs, rid))) { 274199ebb4caSwyllys *psigner = signer; 274299ebb4caSwyllys return (2); 274399ebb4caSwyllys } 274499ebb4caSwyllys if (!(flags & OCSP_NOINTERN) && 274599ebb4caSwyllys (signer = ocsp_find_signer_sk(bs->certs, rid))) { 274699ebb4caSwyllys *psigner = signer; 274799ebb4caSwyllys return (1); 274899ebb4caSwyllys } 274999ebb4caSwyllys /* Maybe lookup from store if by subject name */ 275099ebb4caSwyllys 275199ebb4caSwyllys *psigner = NULL; 275299ebb4caSwyllys return (0); 275399ebb4caSwyllys } 275499ebb4caSwyllys 275599ebb4caSwyllys /* 275699ebb4caSwyllys * This function will verify the signature of a basic response, using 275799ebb4caSwyllys * the public key from the OCSP responder certificate. 275899ebb4caSwyllys */ 275999ebb4caSwyllys static KMF_RETURN 276099ebb4caSwyllys check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, 276199ebb4caSwyllys KMF_DATA *signer_cert, KMF_DATA *issuer_cert) 276299ebb4caSwyllys { 276399ebb4caSwyllys KMF_RETURN ret = KMF_OK; 276499ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 276599ebb4caSwyllys STACK_OF(X509) *cert_stack = NULL; 276699ebb4caSwyllys X509 *signer = NULL; 276799ebb4caSwyllys X509 *issuer = NULL; 276899ebb4caSwyllys EVP_PKEY *skey = NULL; 276999ebb4caSwyllys unsigned char *ptmp; 277099ebb4caSwyllys 277199ebb4caSwyllys 277299ebb4caSwyllys if (bs == NULL || issuer_cert == NULL) 277399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 277499ebb4caSwyllys 277599ebb4caSwyllys /* 277699ebb4caSwyllys * Find the certificate that signed the basic response. 277799ebb4caSwyllys * 277899ebb4caSwyllys * If signer_cert is not NULL, we will use that as the signer cert. 277999ebb4caSwyllys * Otherwise, we will check if the issuer cert is actually the signer. 278099ebb4caSwyllys * If we still do not find a signer, we will look for it from the 278199ebb4caSwyllys * certificate list came with the response file. 278299ebb4caSwyllys */ 278399ebb4caSwyllys if (signer_cert != NULL) { 278499ebb4caSwyllys ptmp = signer_cert->Data; 278599ebb4caSwyllys signer = d2i_X509(NULL, (const uchar_t **)&ptmp, 278699ebb4caSwyllys signer_cert->Length); 278799ebb4caSwyllys if (signer == NULL) { 278899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 278999ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 279099ebb4caSwyllys goto end; 279199ebb4caSwyllys } 279299ebb4caSwyllys } else { 279399ebb4caSwyllys /* 279499ebb4caSwyllys * Convert the issuer cert into X509 and push it into a 279599ebb4caSwyllys * stack to be used by ocsp_find_signer(). 279699ebb4caSwyllys */ 279799ebb4caSwyllys ptmp = issuer_cert->Data; 279899ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 279999ebb4caSwyllys issuer_cert->Length); 280099ebb4caSwyllys if (issuer == NULL) { 280199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 280299ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 280399ebb4caSwyllys goto end; 280499ebb4caSwyllys } 280599ebb4caSwyllys 280699ebb4caSwyllys if ((cert_stack = sk_X509_new_null()) == NULL) { 280799ebb4caSwyllys ret = KMF_ERR_INTERNAL; 280899ebb4caSwyllys goto end; 280999ebb4caSwyllys } 281099ebb4caSwyllys 281199ebb4caSwyllys if (sk_X509_push(cert_stack, issuer) == NULL) { 281299ebb4caSwyllys ret = KMF_ERR_INTERNAL; 281399ebb4caSwyllys goto end; 281499ebb4caSwyllys } 281599ebb4caSwyllys 281699ebb4caSwyllys ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0); 281799ebb4caSwyllys if (!ret) { 281899ebb4caSwyllys /* can not find the signer */ 281999ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 282099ebb4caSwyllys goto end; 282199ebb4caSwyllys } 282299ebb4caSwyllys } 282399ebb4caSwyllys 282499ebb4caSwyllys /* Verify the signature of the response */ 282599ebb4caSwyllys skey = X509_get_pubkey(signer); 282699ebb4caSwyllys if (skey == NULL) { 282799ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 282899ebb4caSwyllys goto end; 282999ebb4caSwyllys } 283099ebb4caSwyllys 283199ebb4caSwyllys ret = OCSP_BASICRESP_verify(bs, skey, 0); 283299ebb4caSwyllys if (ret == 0) { 283399ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE; 283499ebb4caSwyllys goto end; 283599ebb4caSwyllys } 283699ebb4caSwyllys 283799ebb4caSwyllys end: 283899ebb4caSwyllys if (issuer != NULL) { 283999ebb4caSwyllys X509_free(issuer); 284099ebb4caSwyllys } 284199ebb4caSwyllys 284299ebb4caSwyllys if (signer != NULL) { 284399ebb4caSwyllys X509_free(signer); 284499ebb4caSwyllys } 284599ebb4caSwyllys 284699ebb4caSwyllys if (skey != NULL) { 284799ebb4caSwyllys EVP_PKEY_free(skey); 284899ebb4caSwyllys } 284999ebb4caSwyllys 285099ebb4caSwyllys if (cert_stack != NULL) { 285199ebb4caSwyllys sk_X509_free(cert_stack); 285299ebb4caSwyllys } 285399ebb4caSwyllys 285499ebb4caSwyllys return (ret); 285599ebb4caSwyllys } 285699ebb4caSwyllys 285799ebb4caSwyllys 285899ebb4caSwyllys 285999ebb4caSwyllys KMF_RETURN 286099ebb4caSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, 286199ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 286299ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) 286399ebb4caSwyllys { 286499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 286599ebb4caSwyllys BIO *derbio = NULL; 286699ebb4caSwyllys OCSP_RESPONSE *resp = NULL; 286799ebb4caSwyllys OCSP_BASICRESP *bs = NULL; 286899ebb4caSwyllys OCSP_CERTID *id = NULL; 286999ebb4caSwyllys OCSP_SINGLERESP *single = NULL; 287099ebb4caSwyllys ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 287199ebb4caSwyllys int index, status, reason; 287299ebb4caSwyllys 287399ebb4caSwyllys if (params_in == NULL || params_in->issuer_cert == NULL || 287499ebb4caSwyllys params_in->user_cert == NULL || params_in->response == NULL) { 287599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 287699ebb4caSwyllys } 287799ebb4caSwyllys 287899ebb4caSwyllys if (params_out == NULL) { 287999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 288099ebb4caSwyllys } 288199ebb4caSwyllys 288299ebb4caSwyllys /* Read in the response */ 288399ebb4caSwyllys derbio = BIO_new_mem_buf(params_in->response->Data, 288499ebb4caSwyllys params_in->response->Length); 288599ebb4caSwyllys if (!derbio) { 288699ebb4caSwyllys ret = KMF_ERR_MEMORY; 288799ebb4caSwyllys return (ret); 288899ebb4caSwyllys } 288999ebb4caSwyllys 289099ebb4caSwyllys resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 289199ebb4caSwyllys if (resp == NULL) { 289299ebb4caSwyllys ret = KMF_ERR_OCSP_MALFORMED_RESPONSE; 289399ebb4caSwyllys goto end; 289499ebb4caSwyllys } 289599ebb4caSwyllys 289699ebb4caSwyllys /* Check the response status */ 289799ebb4caSwyllys status = OCSP_response_status(resp); 289899ebb4caSwyllys params_out->response_status = status; 289999ebb4caSwyllys if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 290099ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_STATUS; 290199ebb4caSwyllys goto end; 290299ebb4caSwyllys } 290399ebb4caSwyllys 290499ebb4caSwyllys #ifdef DEBUG 290599ebb4caSwyllys printf("Successfully checked the response file status.\n"); 290699ebb4caSwyllys #endif /* DEBUG */ 290799ebb4caSwyllys 290899ebb4caSwyllys /* Extract basic response */ 290999ebb4caSwyllys bs = OCSP_response_get1_basic(resp); 291099ebb4caSwyllys if (bs == NULL) { 291199ebb4caSwyllys ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE; 291299ebb4caSwyllys goto end; 291399ebb4caSwyllys } 291499ebb4caSwyllys 291599ebb4caSwyllys #ifdef DEBUG 291699ebb4caSwyllys printf("Successfully retrieved the basic response.\n"); 291799ebb4caSwyllys #endif /* DEBUG */ 291899ebb4caSwyllys 291999ebb4caSwyllys /* Check the basic response signature if required */ 292099ebb4caSwyllys if (params_in->ignore_response_sign == B_FALSE) { 292199ebb4caSwyllys ret = check_response_signature(handle, bs, 292299ebb4caSwyllys params_in->signer_cert, params_in->issuer_cert); 292399ebb4caSwyllys if (ret != KMF_OK) 292499ebb4caSwyllys goto end; 292599ebb4caSwyllys } 292699ebb4caSwyllys 292799ebb4caSwyllys #ifdef DEBUG 292899ebb4caSwyllys printf("Successfully verified the response signature.\n"); 292999ebb4caSwyllys #endif /* DEBUG */ 293099ebb4caSwyllys 293199ebb4caSwyllys /* Create a certid for the certificate in question */ 293299ebb4caSwyllys ret = create_certid(handle, params_in->issuer_cert, 293399ebb4caSwyllys params_in->user_cert, &id); 293499ebb4caSwyllys if (ret != KMF_OK) { 293599ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 293699ebb4caSwyllys goto end; 293799ebb4caSwyllys } 293899ebb4caSwyllys 293999ebb4caSwyllys #ifdef DEBUG 294099ebb4caSwyllys printf("successfully created a certid for the cert.\n"); 294199ebb4caSwyllys #endif /* DEBUG */ 294299ebb4caSwyllys 294399ebb4caSwyllys /* Find the index of the single response for the certid */ 294499ebb4caSwyllys index = OCSP_resp_find(bs, id, -1); 294599ebb4caSwyllys if (index < 0) { 294699ebb4caSwyllys /* cound not find this certificate in the response */ 294799ebb4caSwyllys ret = KMF_ERR_OCSP_UNKNOWN_CERT; 294899ebb4caSwyllys goto end; 294999ebb4caSwyllys } 295099ebb4caSwyllys 295199ebb4caSwyllys #ifdef DEBUG 295299ebb4caSwyllys printf("Successfully found the single response index for the cert.\n"); 295399ebb4caSwyllys #endif /* DEBUG */ 295499ebb4caSwyllys 295599ebb4caSwyllys /* Retrieve the single response and get the cert status */ 295699ebb4caSwyllys single = OCSP_resp_get0(bs, index); 295799ebb4caSwyllys status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, 295899ebb4caSwyllys &nextupd); 295999ebb4caSwyllys if (status == V_OCSP_CERTSTATUS_GOOD) { 296099ebb4caSwyllys params_out->cert_status = OCSP_GOOD; 296199ebb4caSwyllys } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { 296299ebb4caSwyllys params_out->cert_status = OCSP_UNKNOWN; 296399ebb4caSwyllys } else { /* revoked */ 296499ebb4caSwyllys params_out->cert_status = OCSP_REVOKED; 296599ebb4caSwyllys params_out->reason = reason; 296699ebb4caSwyllys } 296799ebb4caSwyllys ret = KMF_OK; 296899ebb4caSwyllys 296999ebb4caSwyllys /* Verify the time */ 297099ebb4caSwyllys if (!OCSP_check_validity(thisupd, nextupd, 300, 297199ebb4caSwyllys params_in->response_lifetime)) { 297299ebb4caSwyllys ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; 297399ebb4caSwyllys goto end; 297499ebb4caSwyllys } 297599ebb4caSwyllys 297699ebb4caSwyllys #ifdef DEBUG 297799ebb4caSwyllys printf("Successfully verify the time.\n"); 297899ebb4caSwyllys #endif /* DEBUG */ 297999ebb4caSwyllys 298099ebb4caSwyllys end: 298199ebb4caSwyllys if (derbio != NULL) 298299ebb4caSwyllys (void) BIO_free(derbio); 298399ebb4caSwyllys 298499ebb4caSwyllys if (resp != NULL) 298599ebb4caSwyllys OCSP_RESPONSE_free(resp); 298699ebb4caSwyllys 298799ebb4caSwyllys if (bs != NULL) 298899ebb4caSwyllys OCSP_BASICRESP_free(bs); 298999ebb4caSwyllys 299099ebb4caSwyllys if (id != NULL) 299199ebb4caSwyllys OCSP_CERTID_free(id); 299299ebb4caSwyllys 299399ebb4caSwyllys return (ret); 299499ebb4caSwyllys } 299599ebb4caSwyllys 299699ebb4caSwyllys static KMF_RETURN 299799ebb4caSwyllys fetch_key(KMF_HANDLE_T handle, char *path, 299899ebb4caSwyllys KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) 299999ebb4caSwyllys { 300099ebb4caSwyllys KMF_RETURN rv = KMF_OK; 300199ebb4caSwyllys EVP_PKEY *pkey; 300299ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 300399ebb4caSwyllys 300499ebb4caSwyllys /* Make sure the requested file actually exists. */ 300599ebb4caSwyllys if (access(path, F_OK) != 0) { 300699ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 300799ebb4caSwyllys } 300899ebb4caSwyllys 300999ebb4caSwyllys if (keyclass == KMF_ASYM_PRI || 301099ebb4caSwyllys keyclass == KMF_ASYM_PUB) { 301199ebb4caSwyllys pkey = openssl_load_key(handle, path); 301299ebb4caSwyllys if (pkey == NULL) { 301399ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 301499ebb4caSwyllys } 301599ebb4caSwyllys if (key != NULL) { 301699ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) 301799ebb4caSwyllys key->keyalg = KMF_RSA; 301899ebb4caSwyllys else if (pkey->type == EVP_PKEY_DSA) 301999ebb4caSwyllys key->keyalg = KMF_DSA; 302099ebb4caSwyllys 302199ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 302299ebb4caSwyllys key->keyclass = keyclass; 302399ebb4caSwyllys key->keyp = (void *)pkey; 302499ebb4caSwyllys key->israw = FALSE; 302599ebb4caSwyllys key->keylabel = path; 302699ebb4caSwyllys } else { 302799ebb4caSwyllys EVP_PKEY_free(pkey); 302899ebb4caSwyllys pkey = NULL; 302999ebb4caSwyllys } 303099ebb4caSwyllys } else if (keyclass == KMF_SYMMETRIC) { 303199ebb4caSwyllys KMF_ENCODE_FORMAT fmt; 303299ebb4caSwyllys /* 303399ebb4caSwyllys * If the file is a recognized format, 303499ebb4caSwyllys * then it is NOT a symmetric key. 303599ebb4caSwyllys */ 303699ebb4caSwyllys rv = KMF_GetFileFormat(path, &fmt); 303799ebb4caSwyllys if (rv == KMF_OK || fmt != 0) { 303899ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 303999ebb4caSwyllys } else if (rv == KMF_ERR_ENCODING) { 304099ebb4caSwyllys /* 304199ebb4caSwyllys * If we don't know the encoding, 304299ebb4caSwyllys * it is probably a symmetric key. 304399ebb4caSwyllys */ 304499ebb4caSwyllys rv = KMF_OK; 304599ebb4caSwyllys } 304699ebb4caSwyllys 304799ebb4caSwyllys if (key != NULL) { 304899ebb4caSwyllys KMF_DATA keyvalue; 304999ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 305099ebb4caSwyllys if (rkey == NULL) { 305199ebb4caSwyllys rv = KMF_ERR_MEMORY; 305299ebb4caSwyllys goto out; 305399ebb4caSwyllys } 305499ebb4caSwyllys 305599ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 305699ebb4caSwyllys rv = KMF_ReadInputFile(handle, path, &keyvalue); 305799ebb4caSwyllys if (rv != KMF_OK) 305899ebb4caSwyllys goto out; 305999ebb4caSwyllys 306099ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 306199ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 306299ebb4caSwyllys 306399ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 306499ebb4caSwyllys key->keyclass = keyclass; 306599ebb4caSwyllys key->israw = TRUE; 306699ebb4caSwyllys key->keylabel = path; 306799ebb4caSwyllys key->keyp = (void *)rkey; 306899ebb4caSwyllys } 306999ebb4caSwyllys } 307099ebb4caSwyllys out: 307199ebb4caSwyllys if (rv != KMF_OK) { 307299ebb4caSwyllys if (rkey != NULL) { 307399ebb4caSwyllys KMF_FreeRawSymKey(rkey); 307499ebb4caSwyllys } 307599ebb4caSwyllys if (pkey != NULL) 307699ebb4caSwyllys EVP_PKEY_free(pkey); 307799ebb4caSwyllys 307899ebb4caSwyllys if (key != NULL) { 307999ebb4caSwyllys key->keyalg = KMF_KEYALG_NONE; 308099ebb4caSwyllys key->keyclass = KMF_KEYCLASS_NONE; 308199ebb4caSwyllys key->keyp = NULL; 308299ebb4caSwyllys } 308399ebb4caSwyllys } 308499ebb4caSwyllys 308599ebb4caSwyllys return (rv); 308699ebb4caSwyllys } 308799ebb4caSwyllys 308899ebb4caSwyllys KMF_RETURN 308999ebb4caSwyllys OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, 309099ebb4caSwyllys KMF_KEY_HANDLE *key, uint32_t *numkeys) 309199ebb4caSwyllys { 309299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 309399ebb4caSwyllys char *fullpath = NULL; 3094*f482c776Swyllys uint32_t maxkeys; 309599ebb4caSwyllys 309699ebb4caSwyllys if (handle == NULL || params == NULL || numkeys == NULL) 309799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 309899ebb4caSwyllys 309999ebb4caSwyllys if (params->keyclass != KMF_ASYM_PUB && 310099ebb4caSwyllys params->keyclass != KMF_ASYM_PRI && 310199ebb4caSwyllys params->keyclass != KMF_SYMMETRIC) 310299ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 310399ebb4caSwyllys 310499ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 310599ebb4caSwyllys params->sslparms.keyfile); 310699ebb4caSwyllys 310799ebb4caSwyllys if (fullpath == NULL) 310899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 310999ebb4caSwyllys 3110*f482c776Swyllys maxkeys = *numkeys; 3111*f482c776Swyllys if (maxkeys == 0) 3112*f482c776Swyllys maxkeys = 0xFFFFFFFF; 3113*f482c776Swyllys 311499ebb4caSwyllys *numkeys = 0; 311599ebb4caSwyllys 311699ebb4caSwyllys if (isdir(fullpath)) { 311799ebb4caSwyllys DIR *dirp; 311899ebb4caSwyllys struct dirent *dp; 311999ebb4caSwyllys int n = 0; 312099ebb4caSwyllys 312199ebb4caSwyllys /* open all files in the directory and attempt to read them */ 312299ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 312399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 312499ebb4caSwyllys } 312599ebb4caSwyllys rewinddir(dirp); 3126*f482c776Swyllys while ((dp = readdir(dirp)) != NULL && n < maxkeys) { 312799ebb4caSwyllys if (strcmp(dp->d_name, ".") && 312899ebb4caSwyllys strcmp(dp->d_name, "..")) { 312999ebb4caSwyllys char *fname; 313099ebb4caSwyllys 313199ebb4caSwyllys fname = get_fullpath(fullpath, 313299ebb4caSwyllys (char *)&dp->d_name); 313399ebb4caSwyllys 313499ebb4caSwyllys rv = fetch_key(handle, fname, 313599ebb4caSwyllys params->keyclass, 313699ebb4caSwyllys key ? &key[n] : NULL); 313799ebb4caSwyllys 313899ebb4caSwyllys if (rv == KMF_OK) 313999ebb4caSwyllys n++; 314099ebb4caSwyllys 314199ebb4caSwyllys if (rv != KMF_OK || key == NULL) 314299ebb4caSwyllys free(fname); 314399ebb4caSwyllys } 314499ebb4caSwyllys } 314599ebb4caSwyllys (void) closedir(dirp); 314699ebb4caSwyllys free(fullpath); 314799ebb4caSwyllys (*numkeys) = n; 314899ebb4caSwyllys } else { 314999ebb4caSwyllys rv = fetch_key(handle, fullpath, params->keyclass, key); 315099ebb4caSwyllys if (rv == KMF_OK) 315199ebb4caSwyllys (*numkeys) = 1; 315299ebb4caSwyllys 315399ebb4caSwyllys if (rv != KMF_OK || key == NULL) 315499ebb4caSwyllys free(fullpath); 315599ebb4caSwyllys } 315699ebb4caSwyllys 3157*f482c776Swyllys if (rv == KMF_OK && (*numkeys) == 0) 315899ebb4caSwyllys rv = KMF_ERR_KEY_NOT_FOUND; 315999ebb4caSwyllys 316099ebb4caSwyllys return (rv); 316199ebb4caSwyllys } 316299ebb4caSwyllys 316399ebb4caSwyllys #define HANDLE_PK12_ERROR { \ 316499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); \ 316599ebb4caSwyllys rv = KMF_ERR_ENCODING; \ 316699ebb4caSwyllys goto out; \ 316799ebb4caSwyllys } 316899ebb4caSwyllys 316999ebb4caSwyllys static KMF_RETURN 317099ebb4caSwyllys write_pkcs12(KMF_HANDLE *kmfh, 317199ebb4caSwyllys BIO *bio, 317299ebb4caSwyllys KMF_CREDENTIAL *cred, 317399ebb4caSwyllys EVP_PKEY *pkey, 317499ebb4caSwyllys X509 *sslcert) 317599ebb4caSwyllys { 317699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 317799ebb4caSwyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 317899ebb4caSwyllys PKCS12_SAFEBAG *bag = NULL; 317999ebb4caSwyllys PKCS7 *cert_authsafe = NULL; 318099ebb4caSwyllys PKCS8_PRIV_KEY_INFO *p8 = NULL; 318199ebb4caSwyllys PKCS7 *key_authsafe = NULL; 318299ebb4caSwyllys STACK_OF(PKCS7) *authsafe_stack = NULL; 318399ebb4caSwyllys PKCS12 *p12_elem = NULL; 318499ebb4caSwyllys char *lab = NULL; 318599ebb4caSwyllys int lab_len = 0; 318699ebb4caSwyllys unsigned char keyid[EVP_MAX_MD_SIZE]; 318799ebb4caSwyllys unsigned int keyidlen = 0; 318899ebb4caSwyllys 318999ebb4caSwyllys /* Must have at least a cert OR a key */ 319099ebb4caSwyllys if (sslcert == NULL && pkey == NULL) 319199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 319299ebb4caSwyllys 319399ebb4caSwyllys (void) memset(keyid, 0, sizeof (keyid)); 319499ebb4caSwyllys /* 319599ebb4caSwyllys * Section 1: 319699ebb4caSwyllys * 319799ebb4caSwyllys * The first PKCS#12 container (safebag) will hold the certificates 319899ebb4caSwyllys * associated with this key. The result of this section is a 319999ebb4caSwyllys * PIN-encrypted PKCS#7 container (authsafe). If there are no 320099ebb4caSwyllys * certificates, there is no point in creating the "safebag" or the 320199ebb4caSwyllys * "authsafe" so we go to the next section. 320299ebb4caSwyllys */ 320399ebb4caSwyllys if (sslcert != NULL && pkey != NULL) { 320499ebb4caSwyllys if (X509_check_private_key(sslcert, pkey)) { 320599ebb4caSwyllys (void) X509_digest(sslcert, EVP_sha1(), keyid, 320699ebb4caSwyllys &keyidlen); 320799ebb4caSwyllys } else { 320899ebb4caSwyllys /* The key doesn't match the cert */ 320999ebb4caSwyllys HANDLE_PK12_ERROR 321099ebb4caSwyllys } 321199ebb4caSwyllys } 321299ebb4caSwyllys 321399ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 321499ebb4caSwyllys if (bag_stack == NULL) 321599ebb4caSwyllys return (KMF_ERR_MEMORY); 321699ebb4caSwyllys 321799ebb4caSwyllys if (sslcert != NULL) { 321899ebb4caSwyllys /* Convert cert from X509 struct to PKCS#12 bag */ 321999ebb4caSwyllys bag = PKCS12_x5092certbag(sslcert); 322099ebb4caSwyllys if (bag == NULL) { 322199ebb4caSwyllys HANDLE_PK12_ERROR 322299ebb4caSwyllys } 322399ebb4caSwyllys 322499ebb4caSwyllys /* Add the key id to the certificate bag. */ 322599ebb4caSwyllys if (keyidlen > 0 && 322699ebb4caSwyllys !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 322799ebb4caSwyllys HANDLE_PK12_ERROR 322899ebb4caSwyllys } 322999ebb4caSwyllys 323099ebb4caSwyllys /* Pile it on the bag_stack. */ 323199ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 323299ebb4caSwyllys HANDLE_PK12_ERROR 323399ebb4caSwyllys } 323499ebb4caSwyllys #if 0 323599ebb4caSwyllys /* No support for CA certs yet */ 323699ebb4caSwyllys if (cacerts != NULL && ncacerts > 0) { 323799ebb4caSwyllys int i; 323899ebb4caSwyllys for (i = 0; i < ncacerts; i++) { 323999ebb4caSwyllys KMF_X509_DER_CERT *c = &cacerts[i]; 324099ebb4caSwyllys X509 *ca = NULL; 324199ebb4caSwyllys 324299ebb4caSwyllys uchar_t *p = (uchar_t *)c->certificate.Data; 324399ebb4caSwyllys ca = d2i_X509(NULL, &p, 324499ebb4caSwyllys c->certificate.Length); 324599ebb4caSwyllys if (ca == NULL) { 324699ebb4caSwyllys HANDLE_PK12_ERROR 324799ebb4caSwyllys } 324899ebb4caSwyllys /* Convert CA cert to PKCS#12 bag. */ 324999ebb4caSwyllys bag = PKCS12_x5092certbag(ca); 325099ebb4caSwyllys if (bag == NULL) { 325199ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, 325299ebb4caSwyllys PKCS12_SAFEBAG_free); 325399ebb4caSwyllys HANDLE_PK12_ERROR 325499ebb4caSwyllys } 325599ebb4caSwyllys /* Pile it onto the bag_stack. */ 325699ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 325799ebb4caSwyllys HANDLE_PK12_ERROR 325899ebb4caSwyllys } 325999ebb4caSwyllys } 326099ebb4caSwyllys } 326199ebb4caSwyllys #endif 326299ebb4caSwyllys /* Turn bag_stack of certs into encrypted authsafe. */ 326399ebb4caSwyllys cert_authsafe = PKCS12_pack_p7encdata( 326499ebb4caSwyllys NID_pbe_WithSHA1And40BitRC2_CBC, 326599ebb4caSwyllys cred->cred, 326699ebb4caSwyllys cred->credlen, NULL, 0, 326799ebb4caSwyllys PKCS12_DEFAULT_ITER, 326899ebb4caSwyllys bag_stack); 326999ebb4caSwyllys 327099ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 327199ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 327299ebb4caSwyllys bag_stack = NULL; 327399ebb4caSwyllys 327499ebb4caSwyllys if (cert_authsafe == NULL) { 327599ebb4caSwyllys HANDLE_PK12_ERROR 327699ebb4caSwyllys } 327799ebb4caSwyllys } 327899ebb4caSwyllys /* 327999ebb4caSwyllys * Section 2: 328099ebb4caSwyllys * 328199ebb4caSwyllys * The second PKCS#12 container (safebag) will hold the private key 328299ebb4caSwyllys * that goes with the certificates above. The results of this section 328399ebb4caSwyllys * is an unencrypted PKCS#7 container (authsafe). If there is no 328499ebb4caSwyllys * private key, there is no point in creating the "safebag" or the 328599ebb4caSwyllys * "authsafe" so we go to the next section. 328699ebb4caSwyllys */ 328799ebb4caSwyllys if (pkey != NULL) { 328899ebb4caSwyllys p8 = EVP_PKEY2PKCS8(pkey); 328999ebb4caSwyllys if (p8 == NULL) { 329099ebb4caSwyllys HANDLE_PK12_ERROR 329199ebb4caSwyllys } 329299ebb4caSwyllys /* Put the shrouded key into a PKCS#12 bag. */ 329399ebb4caSwyllys bag = PKCS12_MAKE_SHKEYBAG( 329499ebb4caSwyllys NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 329599ebb4caSwyllys cred->cred, cred->credlen, 329699ebb4caSwyllys NULL, 0, PKCS12_DEFAULT_ITER, p8); 329799ebb4caSwyllys 329899ebb4caSwyllys /* Clean up the PKCS#8 shrouded key, don't need it now. */ 329999ebb4caSwyllys PKCS8_PRIV_KEY_INFO_free(p8); 330099ebb4caSwyllys p8 = NULL; 330199ebb4caSwyllys 330299ebb4caSwyllys if (bag == NULL) { 330399ebb4caSwyllys HANDLE_PK12_ERROR 330499ebb4caSwyllys } 330599ebb4caSwyllys if (keyidlen && 330699ebb4caSwyllys !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 330799ebb4caSwyllys HANDLE_PK12_ERROR 330899ebb4caSwyllys } 330999ebb4caSwyllys if (lab != NULL) { 331099ebb4caSwyllys if (!PKCS12_add_friendlyname(bag, 331199ebb4caSwyllys (char *)lab, lab_len)) { 331299ebb4caSwyllys HANDLE_PK12_ERROR 331399ebb4caSwyllys } 331499ebb4caSwyllys } 331599ebb4caSwyllys /* Start a PKCS#12 safebag container for the private key. */ 331699ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 331799ebb4caSwyllys if (bag_stack == NULL) { 331899ebb4caSwyllys HANDLE_PK12_ERROR 331999ebb4caSwyllys } 332099ebb4caSwyllys 332199ebb4caSwyllys /* Pile on the private key on the bag_stack. */ 332299ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 332399ebb4caSwyllys HANDLE_PK12_ERROR 332499ebb4caSwyllys } 332599ebb4caSwyllys key_authsafe = PKCS12_pack_p7data(bag_stack); 332699ebb4caSwyllys 332799ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 332899ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 332999ebb4caSwyllys bag_stack = NULL; 333099ebb4caSwyllys 333199ebb4caSwyllys if (key_authsafe == NULL) { 333299ebb4caSwyllys HANDLE_PK12_ERROR 333399ebb4caSwyllys } 333499ebb4caSwyllys } 333599ebb4caSwyllys /* 333699ebb4caSwyllys * Section 3: 333799ebb4caSwyllys * 333899ebb4caSwyllys * This is where the two PKCS#7 containers, one for the certificates 333999ebb4caSwyllys * and one for the private key, are put together into a PKCS#12 334099ebb4caSwyllys * element. This final PKCS#12 element is written to the export file. 334199ebb4caSwyllys */ 334299ebb4caSwyllys 334399ebb4caSwyllys /* Start a PKCS#7 stack. */ 334499ebb4caSwyllys authsafe_stack = sk_PKCS7_new_null(); 334599ebb4caSwyllys if (authsafe_stack == NULL) { 334699ebb4caSwyllys HANDLE_PK12_ERROR 334799ebb4caSwyllys } 334899ebb4caSwyllys if (key_authsafe != NULL) { 334999ebb4caSwyllys if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) { 335099ebb4caSwyllys HANDLE_PK12_ERROR 335199ebb4caSwyllys } 335299ebb4caSwyllys } 335399ebb4caSwyllys if (cert_authsafe != NULL) { 335499ebb4caSwyllys if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) { 335599ebb4caSwyllys HANDLE_PK12_ERROR 335699ebb4caSwyllys } 335799ebb4caSwyllys } 335899ebb4caSwyllys p12_elem = PKCS12_init(NID_pkcs7_data); 335999ebb4caSwyllys if (p12_elem == NULL) { 336099ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 336199ebb4caSwyllys HANDLE_PK12_ERROR 336299ebb4caSwyllys } 336399ebb4caSwyllys 336499ebb4caSwyllys /* Put the PKCS#7 stack into the PKCS#12 element. */ 336599ebb4caSwyllys if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) { 336699ebb4caSwyllys HANDLE_PK12_ERROR 336799ebb4caSwyllys } 336899ebb4caSwyllys /* Clear away the PKCS#7 stack, we're done with it. */ 336999ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 337099ebb4caSwyllys authsafe_stack = NULL; 337199ebb4caSwyllys 337299ebb4caSwyllys /* Set the integrity MAC on the PKCS#12 element. */ 337399ebb4caSwyllys if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen, 337499ebb4caSwyllys NULL, 0, PKCS12_DEFAULT_ITER, NULL)) { 337599ebb4caSwyllys HANDLE_PK12_ERROR 337699ebb4caSwyllys } 337799ebb4caSwyllys 337899ebb4caSwyllys /* Write the PKCS#12 element to the export file. */ 337999ebb4caSwyllys if (!i2d_PKCS12_bio(bio, p12_elem)) { 338099ebb4caSwyllys HANDLE_PK12_ERROR 338199ebb4caSwyllys } 338299ebb4caSwyllys 338399ebb4caSwyllys PKCS12_free(p12_elem); 338499ebb4caSwyllys out: 338599ebb4caSwyllys if (rv != KMF_OK) { 338699ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 338799ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 338899ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 338999ebb4caSwyllys } 339099ebb4caSwyllys return (rv); 339199ebb4caSwyllys } 339299ebb4caSwyllys 339399ebb4caSwyllys static EVP_PKEY * 339499ebb4caSwyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *key) 339599ebb4caSwyllys { 339699ebb4caSwyllys RSA *rsa = NULL; 339799ebb4caSwyllys EVP_PKEY *newkey = NULL; 339899ebb4caSwyllys 339999ebb4caSwyllys if ((rsa = RSA_new()) == NULL) 340099ebb4caSwyllys return (NULL); 340199ebb4caSwyllys 340299ebb4caSwyllys if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL) 340399ebb4caSwyllys return (NULL); 340499ebb4caSwyllys 340599ebb4caSwyllys if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) == 340699ebb4caSwyllys NULL) 340799ebb4caSwyllys return (NULL); 340899ebb4caSwyllys 340999ebb4caSwyllys if (key->priexp.val != NULL) 341099ebb4caSwyllys if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len, 341199ebb4caSwyllys rsa->d)) == NULL) 341299ebb4caSwyllys return (NULL); 341399ebb4caSwyllys 341499ebb4caSwyllys if (key->prime1.val != NULL) 341599ebb4caSwyllys if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len, 341699ebb4caSwyllys rsa->p)) == NULL) 341799ebb4caSwyllys return (NULL); 341899ebb4caSwyllys 341999ebb4caSwyllys if (key->prime2.val != NULL) 342099ebb4caSwyllys if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len, 342199ebb4caSwyllys rsa->q)) == NULL) 342299ebb4caSwyllys return (NULL); 342399ebb4caSwyllys 342499ebb4caSwyllys if (key->exp1.val != NULL) 342599ebb4caSwyllys if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, 342699ebb4caSwyllys rsa->dmp1)) == NULL) 342799ebb4caSwyllys return (NULL); 342899ebb4caSwyllys 342999ebb4caSwyllys if (key->exp2.val != NULL) 343099ebb4caSwyllys if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, 343199ebb4caSwyllys rsa->dmq1)) == NULL) 343299ebb4caSwyllys return (NULL); 343399ebb4caSwyllys 343499ebb4caSwyllys if (key->coef.val != NULL) 343599ebb4caSwyllys if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len, 343699ebb4caSwyllys rsa->iqmp)) == NULL) 343799ebb4caSwyllys return (NULL); 343899ebb4caSwyllys 343999ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 344099ebb4caSwyllys return (NULL); 344199ebb4caSwyllys 344299ebb4caSwyllys (void) EVP_PKEY_set1_RSA(newkey, rsa); 344399ebb4caSwyllys 344499ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 344599ebb4caSwyllys RSA_free(rsa); 344699ebb4caSwyllys 344799ebb4caSwyllys return (newkey); 344899ebb4caSwyllys } 344999ebb4caSwyllys 345099ebb4caSwyllys static EVP_PKEY * 345199ebb4caSwyllys ImportRawDSAKey(KMF_RAW_DSA_KEY *key) 345299ebb4caSwyllys { 345399ebb4caSwyllys DSA *dsa = NULL; 345499ebb4caSwyllys EVP_PKEY *newkey = NULL; 345599ebb4caSwyllys 345699ebb4caSwyllys if ((dsa = DSA_new()) == NULL) 345799ebb4caSwyllys return (NULL); 345899ebb4caSwyllys 345999ebb4caSwyllys if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len, 346099ebb4caSwyllys dsa->p)) == NULL) 346199ebb4caSwyllys return (NULL); 346299ebb4caSwyllys 346399ebb4caSwyllys if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len, 346499ebb4caSwyllys dsa->q)) == NULL) 346599ebb4caSwyllys return (NULL); 346699ebb4caSwyllys 346799ebb4caSwyllys if ((dsa->g = BN_bin2bn(key->base.val, key->base.len, 346899ebb4caSwyllys dsa->g)) == NULL) 346999ebb4caSwyllys return (NULL); 347099ebb4caSwyllys 347199ebb4caSwyllys if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len, 347299ebb4caSwyllys dsa->priv_key)) == NULL) 347399ebb4caSwyllys return (NULL); 347499ebb4caSwyllys 347599ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 347699ebb4caSwyllys return (NULL); 347799ebb4caSwyllys 347899ebb4caSwyllys (void) EVP_PKEY_set1_DSA(newkey, dsa); 347999ebb4caSwyllys 348099ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 348199ebb4caSwyllys DSA_free(dsa); 348299ebb4caSwyllys return (newkey); 348399ebb4caSwyllys } 348499ebb4caSwyllys 348599ebb4caSwyllys static KMF_RETURN 348699ebb4caSwyllys ExportPK12FromRawData(KMF_HANDLE_T handle, 348799ebb4caSwyllys KMF_CREDENTIAL *cred, 348899ebb4caSwyllys int numcerts, KMF_X509_DER_CERT *certlist, 348999ebb4caSwyllys int numkeys, KMF_KEY_HANDLE *keylist, 349099ebb4caSwyllys char *filename) 349199ebb4caSwyllys { 349299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 349399ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 349499ebb4caSwyllys BIO *bio = NULL; 349599ebb4caSwyllys X509 *xcert = NULL; 349699ebb4caSwyllys EVP_PKEY *pkey = NULL; 349799ebb4caSwyllys int i; 349899ebb4caSwyllys 349999ebb4caSwyllys /* 350099ebb4caSwyllys * Open the output file. 350199ebb4caSwyllys */ 350299ebb4caSwyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) { 350399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 350499ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 350599ebb4caSwyllys goto cleanup; 350699ebb4caSwyllys } 350799ebb4caSwyllys 350899ebb4caSwyllys if (numcerts > 0 && numkeys > 0) { 350999ebb4caSwyllys for (i = 0; rv == KMF_OK && i < numcerts; i++) { 351099ebb4caSwyllys KMF_RAW_KEY_DATA *key = NULL; 351199ebb4caSwyllys const uchar_t *p = certlist[i].certificate.Data; 351299ebb4caSwyllys long len = certlist[i].certificate.Length; 351399ebb4caSwyllys 351499ebb4caSwyllys if (i < numkeys) { 351599ebb4caSwyllys key = (KMF_RAW_KEY_DATA *)keylist[i].keyp; 351699ebb4caSwyllys 351799ebb4caSwyllys if (key->keytype == KMF_RSA) { 351899ebb4caSwyllys pkey = ImportRawRSAKey( 351999ebb4caSwyllys &key->rawdata.rsa); 352099ebb4caSwyllys } else if (key->keytype == KMF_DSA) { 352199ebb4caSwyllys pkey = ImportRawDSAKey( 352299ebb4caSwyllys &key->rawdata.dsa); 352399ebb4caSwyllys } else { 352499ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 352599ebb4caSwyllys } 352699ebb4caSwyllys } 352799ebb4caSwyllys 352899ebb4caSwyllys xcert = d2i_X509(NULL, &p, len); 352999ebb4caSwyllys if (xcert == NULL) { 353099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 353199ebb4caSwyllys rv = KMF_ERR_ENCODING; 353299ebb4caSwyllys } 353399ebb4caSwyllys /* Stick the key and the cert into a PKCS#12 file */ 353499ebb4caSwyllys rv = write_pkcs12(kmfh, bio, cred, pkey, xcert); 353599ebb4caSwyllys if (xcert) 353699ebb4caSwyllys X509_free(xcert); 353799ebb4caSwyllys if (pkey) 353899ebb4caSwyllys EVP_PKEY_free(pkey); 353999ebb4caSwyllys } 354099ebb4caSwyllys } 354199ebb4caSwyllys 354299ebb4caSwyllys cleanup: 354399ebb4caSwyllys 354499ebb4caSwyllys if (bio != NULL) 354599ebb4caSwyllys (void) BIO_free_all(bio); 354699ebb4caSwyllys 354799ebb4caSwyllys return (rv); 354899ebb4caSwyllys } 354999ebb4caSwyllys 355099ebb4caSwyllys KMF_RETURN 355199ebb4caSwyllys OpenSSL_ExportP12(KMF_HANDLE_T handle, 355299ebb4caSwyllys KMF_EXPORTP12_PARAMS *params, 355399ebb4caSwyllys int numcerts, KMF_X509_DER_CERT *certlist, 355499ebb4caSwyllys int numkeys, KMF_KEY_HANDLE *keylist, 355599ebb4caSwyllys char *filename) 355699ebb4caSwyllys { 355799ebb4caSwyllys KMF_RETURN rv; 355899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 355999ebb4caSwyllys KMF_FINDCERT_PARAMS fcargs; 356099ebb4caSwyllys BIO *bio = NULL; 356199ebb4caSwyllys X509 *xcert = NULL; 356299ebb4caSwyllys char *fullpath = NULL; 356399ebb4caSwyllys EVP_PKEY *pkey = NULL; 356499ebb4caSwyllys 356599ebb4caSwyllys /* 356699ebb4caSwyllys * First, find the certificate. 356799ebb4caSwyllys */ 356899ebb4caSwyllys if (params == NULL) 356999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 357099ebb4caSwyllys 357199ebb4caSwyllys /* 357299ebb4caSwyllys * If the caller already sent the raw keys and certs, 357399ebb4caSwyllys * shortcut the search and just export that 357499ebb4caSwyllys * data. 357599ebb4caSwyllys * 357699ebb4caSwyllys * One *may* export a key OR a cert by itself. 357799ebb4caSwyllys */ 357899ebb4caSwyllys if (certlist != NULL || keylist != NULL) { 357999ebb4caSwyllys rv = ExportPK12FromRawData(handle, 358099ebb4caSwyllys ¶ms->p12cred, 358199ebb4caSwyllys numcerts, certlist, 358299ebb4caSwyllys numkeys, keylist, 358399ebb4caSwyllys filename); 358499ebb4caSwyllys return (rv); 358599ebb4caSwyllys } 358699ebb4caSwyllys 358799ebb4caSwyllys if (params->sslparms.certfile != NULL) { 358899ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 358999ebb4caSwyllys params->sslparms.certfile); 359099ebb4caSwyllys 359199ebb4caSwyllys if (fullpath == NULL) 359299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 359399ebb4caSwyllys 359499ebb4caSwyllys if (isdir(fullpath)) { 359599ebb4caSwyllys free(fullpath); 359699ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 359799ebb4caSwyllys } 359899ebb4caSwyllys 359999ebb4caSwyllys (void *)memset(&fcargs, 0, sizeof (fcargs)); 360099ebb4caSwyllys fcargs.kstype = params->kstype; 360199ebb4caSwyllys fcargs.certLabel = params->certLabel; 360299ebb4caSwyllys fcargs.issuer = params->issuer; 360399ebb4caSwyllys fcargs.subject = params->subject; 360499ebb4caSwyllys fcargs.serial = params->serial; 360599ebb4caSwyllys fcargs.idstr = params->idstr; 360699ebb4caSwyllys fcargs.sslparms.dirpath = NULL; 360799ebb4caSwyllys fcargs.sslparms.certfile = fullpath; 360899ebb4caSwyllys fcargs.sslparms.format = params->sslparms.format; 360999ebb4caSwyllys 361099ebb4caSwyllys rv = load_X509cert(kmfh, &fcargs, fullpath, &xcert); 361199ebb4caSwyllys if (rv != KMF_OK) 361299ebb4caSwyllys goto end; 361399ebb4caSwyllys } 361499ebb4caSwyllys 361599ebb4caSwyllys /* 361699ebb4caSwyllys * Now find the private key. 361799ebb4caSwyllys */ 361899ebb4caSwyllys if (params->sslparms.keyfile != NULL) { 361999ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 362099ebb4caSwyllys params->sslparms.keyfile); 362199ebb4caSwyllys 362299ebb4caSwyllys if (fullpath == NULL) 362399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 362499ebb4caSwyllys 362599ebb4caSwyllys if (isdir(fullpath)) { 362699ebb4caSwyllys free(fullpath); 362799ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 362899ebb4caSwyllys } 362999ebb4caSwyllys 363099ebb4caSwyllys pkey = openssl_load_key(handle, fullpath); 363199ebb4caSwyllys if (pkey == NULL) { 363299ebb4caSwyllys rv = KMF_ERR_KEY_NOT_FOUND; 363399ebb4caSwyllys goto end; 363499ebb4caSwyllys } 363599ebb4caSwyllys } 363699ebb4caSwyllys 363799ebb4caSwyllys /* 363899ebb4caSwyllys * Open the output file. 363999ebb4caSwyllys */ 364099ebb4caSwyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) { 364199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 364299ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 364399ebb4caSwyllys goto end; 364499ebb4caSwyllys } 364599ebb4caSwyllys 364699ebb4caSwyllys /* Stick the key and the cert into a PKCS#12 file */ 364799ebb4caSwyllys rv = write_pkcs12(kmfh, bio, ¶ms->p12cred, 364899ebb4caSwyllys pkey, xcert); 364999ebb4caSwyllys 365099ebb4caSwyllys end: 365199ebb4caSwyllys if (fullpath) 365299ebb4caSwyllys free(fullpath); 365399ebb4caSwyllys if (xcert) 365499ebb4caSwyllys X509_free(xcert); 365599ebb4caSwyllys if (pkey) 365699ebb4caSwyllys EVP_PKEY_free(pkey); 365799ebb4caSwyllys if (bio) 365899ebb4caSwyllys (void) BIO_free(bio); 365999ebb4caSwyllys 366099ebb4caSwyllys return (rv); 366199ebb4caSwyllys } 366299ebb4caSwyllys 366371593db2Swyllys #define MAX_CHAIN_LENGTH 100 366471593db2Swyllys /* 366571593db2Swyllys * Helper function to extract keys and certificates from 366671593db2Swyllys * a single PEM file. Typically the file should contain a 366771593db2Swyllys * private key and an associated public key wrapped in an x509 cert. 366871593db2Swyllys * However, the file may be just a list of X509 certs with no keys. 366971593db2Swyllys */ 367071593db2Swyllys static KMF_RETURN 367102744e81Swyllys extract_objects(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, 367202744e81Swyllys char *filename, CK_UTF8CHAR *pin, 367371593db2Swyllys CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs, 367471593db2Swyllys int *numcerts) 367571593db2Swyllys /* ARGSUSED */ 367671593db2Swyllys { 367771593db2Swyllys KMF_RETURN rv = KMF_OK; 367871593db2Swyllys FILE *fp; 367971593db2Swyllys STACK_OF(X509_INFO) *x509_info_stack; 368002744e81Swyllys int i, ncerts = 0, matchcerts = 0; 368171593db2Swyllys EVP_PKEY *pkey = NULL; 368271593db2Swyllys X509_INFO *info; 368371593db2Swyllys X509 *x; 368471593db2Swyllys X509_INFO *cert_infos[MAX_CHAIN_LENGTH]; 368571593db2Swyllys KMF_DATA *certlist = NULL; 368671593db2Swyllys 368771593db2Swyllys if (priv_key) 368871593db2Swyllys *priv_key = NULL; 368971593db2Swyllys if (certs) 369071593db2Swyllys *certs = NULL; 369171593db2Swyllys fp = fopen(filename, "r"); 369271593db2Swyllys if (fp == NULL) { 369371593db2Swyllys return (KMF_ERR_OPEN_FILE); 369471593db2Swyllys } 369571593db2Swyllys x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin); 369671593db2Swyllys if (x509_info_stack == NULL) { 369771593db2Swyllys (void) fclose(fp); 369871593db2Swyllys return (KMF_ERR_ENCODING); 369971593db2Swyllys } 370071593db2Swyllys 370171593db2Swyllys /*LINTED*/ 370271593db2Swyllys while ((info = sk_X509_INFO_pop(x509_info_stack)) != NULL && 37036567ca1aSkrishna info->x509 != NULL && ncerts < MAX_CHAIN_LENGTH) { 370471593db2Swyllys cert_infos[ncerts] = info; 370571593db2Swyllys ncerts++; 370671593db2Swyllys } 370771593db2Swyllys 370871593db2Swyllys if (ncerts == 0) { 370971593db2Swyllys (void) fclose(fp); 371071593db2Swyllys return (KMF_ERR_CERT_NOT_FOUND); 371171593db2Swyllys } 371271593db2Swyllys 371371593db2Swyllys if (priv_key != NULL) { 371471593db2Swyllys rewind(fp); 371571593db2Swyllys pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin); 371671593db2Swyllys } 371771593db2Swyllys (void) fclose(fp); 371871593db2Swyllys 371971593db2Swyllys x = cert_infos[ncerts - 1]->x509; 372071593db2Swyllys /* 372171593db2Swyllys * Make sure the private key matchs the last cert in the file. 372271593db2Swyllys */ 372371593db2Swyllys if (pkey != NULL && !X509_check_private_key(x, pkey)) { 372471593db2Swyllys EVP_PKEY_free(pkey); 372571593db2Swyllys return (KMF_ERR_KEY_MISMATCH); 372671593db2Swyllys } 372771593db2Swyllys 372871593db2Swyllys certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA)); 372971593db2Swyllys if (certlist == NULL) { 373071593db2Swyllys if (pkey != NULL) 373171593db2Swyllys EVP_PKEY_free(pkey); 373271593db2Swyllys X509_INFO_free(info); 373371593db2Swyllys return (KMF_ERR_MEMORY); 373471593db2Swyllys } 373571593db2Swyllys 373671593db2Swyllys /* 373771593db2Swyllys * Convert all of the certs to DER format. 373871593db2Swyllys */ 373902744e81Swyllys matchcerts = 0; 374071593db2Swyllys for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) { 374102744e81Swyllys boolean_t match = FALSE; 374271593db2Swyllys info = cert_infos[ncerts - 1 - i]; 374371593db2Swyllys 374402744e81Swyllys if (params != NULL) { 374502744e81Swyllys rv = check_cert(info->x509, params, &match); 374602744e81Swyllys if (rv != KMF_OK || match != TRUE) { 374702744e81Swyllys X509_INFO_free(info); 374802744e81Swyllys rv = KMF_OK; 374902744e81Swyllys continue; 375002744e81Swyllys } 375102744e81Swyllys } 375202744e81Swyllys 375302744e81Swyllys rv = ssl_cert2KMFDATA(kmfh, info->x509, 375402744e81Swyllys &certlist[matchcerts++]); 375571593db2Swyllys 375671593db2Swyllys if (rv != KMF_OK) { 375771593db2Swyllys free(certlist); 375871593db2Swyllys certlist = NULL; 375902744e81Swyllys ncerts = matchcerts = 0; 376071593db2Swyllys } 376102744e81Swyllys 376271593db2Swyllys X509_INFO_free(info); 376371593db2Swyllys } 376471593db2Swyllys 376571593db2Swyllys if (numcerts != NULL) 376602744e81Swyllys *numcerts = matchcerts; 376771593db2Swyllys if (certs != NULL) 376871593db2Swyllys *certs = certlist; 376971593db2Swyllys 377071593db2Swyllys if (priv_key == NULL && pkey != NULL) 377171593db2Swyllys EVP_PKEY_free(pkey); 377271593db2Swyllys else if (priv_key != NULL && pkey != NULL) 377371593db2Swyllys *priv_key = pkey; 377471593db2Swyllys 377571593db2Swyllys return (rv); 377671593db2Swyllys } 377771593db2Swyllys 377899ebb4caSwyllys /* 377999ebb4caSwyllys * Helper function to decrypt and parse PKCS#12 import file. 378099ebb4caSwyllys */ 378199ebb4caSwyllys static KMF_RETURN 378299ebb4caSwyllys extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 378399ebb4caSwyllys EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca) 378499ebb4caSwyllys /* ARGSUSED */ 378599ebb4caSwyllys { 378699ebb4caSwyllys PKCS12 *pk12, *pk12_tmp; 378799ebb4caSwyllys EVP_PKEY *temp_pkey = NULL; 378899ebb4caSwyllys X509 *temp_cert = NULL; 378999ebb4caSwyllys STACK_OF(X509) *temp_ca = NULL; 379099ebb4caSwyllys 379199ebb4caSwyllys if ((pk12 = PKCS12_new()) == NULL) { 379299ebb4caSwyllys return (KMF_ERR_MEMORY); 379399ebb4caSwyllys } 379499ebb4caSwyllys 379599ebb4caSwyllys if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) { 379699ebb4caSwyllys /* This is ok; it seems to mean there is no more to read. */ 379799ebb4caSwyllys if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 && 379899ebb4caSwyllys ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG) 379999ebb4caSwyllys goto end_extract_pkcs12; 380099ebb4caSwyllys 380199ebb4caSwyllys PKCS12_free(pk12); 380299ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 380399ebb4caSwyllys } 380499ebb4caSwyllys pk12 = pk12_tmp; 380599ebb4caSwyllys 380699ebb4caSwyllys if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert, 380799ebb4caSwyllys &temp_ca) <= 0) { 380899ebb4caSwyllys PKCS12_free(pk12); 380999ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 381099ebb4caSwyllys } 381199ebb4caSwyllys 381299ebb4caSwyllys end_extract_pkcs12: 381399ebb4caSwyllys 381499ebb4caSwyllys *priv_key = temp_pkey; 381599ebb4caSwyllys *cert = temp_cert; 381699ebb4caSwyllys *ca = temp_ca; 381799ebb4caSwyllys 381899ebb4caSwyllys PKCS12_free(pk12); 381999ebb4caSwyllys return (KMF_OK); 382099ebb4caSwyllys } 382199ebb4caSwyllys 382299ebb4caSwyllys static KMF_RETURN 382399ebb4caSwyllys sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to) 382499ebb4caSwyllys { 382599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 382699ebb4caSwyllys uint32_t sz; 382799ebb4caSwyllys 382899ebb4caSwyllys sz = BN_num_bytes(from); 382999ebb4caSwyllys to->val = (uchar_t *)malloc(sz); 383099ebb4caSwyllys if (to->val == NULL) 383199ebb4caSwyllys return (KMF_ERR_MEMORY); 383299ebb4caSwyllys 383399ebb4caSwyllys if ((to->len = BN_bn2bin(from, to->val)) != sz) { 383499ebb4caSwyllys free(to->val); 383599ebb4caSwyllys to->val = NULL; 383699ebb4caSwyllys to->len = 0; 383799ebb4caSwyllys rv = KMF_ERR_MEMORY; 383899ebb4caSwyllys } 383999ebb4caSwyllys 384099ebb4caSwyllys return (rv); 384199ebb4caSwyllys } 384299ebb4caSwyllys 384399ebb4caSwyllys static KMF_RETURN 384499ebb4caSwyllys exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) 384599ebb4caSwyllys { 384699ebb4caSwyllys KMF_RETURN rv; 384799ebb4caSwyllys KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa; 384899ebb4caSwyllys 384999ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY)); 385099ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK) 385199ebb4caSwyllys goto cleanup; 385299ebb4caSwyllys 385399ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK) 385499ebb4caSwyllys goto cleanup; 385599ebb4caSwyllys 385699ebb4caSwyllys if (rsa->d != NULL) 385799ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK) 385899ebb4caSwyllys goto cleanup; 385999ebb4caSwyllys 386099ebb4caSwyllys if (rsa->p != NULL) 386199ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK) 386299ebb4caSwyllys goto cleanup; 386399ebb4caSwyllys 386499ebb4caSwyllys if (rsa->q != NULL) 386599ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK) 386699ebb4caSwyllys goto cleanup; 386799ebb4caSwyllys 386899ebb4caSwyllys if (rsa->dmp1 != NULL) 386999ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK) 387099ebb4caSwyllys goto cleanup; 387199ebb4caSwyllys 387299ebb4caSwyllys if (rsa->dmq1 != NULL) 387399ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK) 387499ebb4caSwyllys goto cleanup; 387599ebb4caSwyllys 387699ebb4caSwyllys if (rsa->iqmp != NULL) 387799ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK) 387899ebb4caSwyllys goto cleanup; 387999ebb4caSwyllys cleanup: 388099ebb4caSwyllys if (rv != KMF_OK) 388199ebb4caSwyllys KMF_FreeRawKey(key); 388299ebb4caSwyllys else 388399ebb4caSwyllys key->keytype = KMF_RSA; 388499ebb4caSwyllys 388599ebb4caSwyllys /* 388699ebb4caSwyllys * Free the reference to this key, SSL will not actually free 388799ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 388899ebb4caSwyllys */ 388999ebb4caSwyllys RSA_free(rsa); 389099ebb4caSwyllys 389199ebb4caSwyllys return (rv); 389299ebb4caSwyllys } 389399ebb4caSwyllys 389499ebb4caSwyllys static KMF_RETURN 389599ebb4caSwyllys exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) 389699ebb4caSwyllys { 389799ebb4caSwyllys KMF_RETURN rv; 389899ebb4caSwyllys KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa; 389999ebb4caSwyllys 390099ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY)); 390199ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK) 390299ebb4caSwyllys goto cleanup; 390399ebb4caSwyllys 390499ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK) 390599ebb4caSwyllys goto cleanup; 390699ebb4caSwyllys 390799ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK) 390899ebb4caSwyllys goto cleanup; 390999ebb4caSwyllys 391099ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK) 391199ebb4caSwyllys goto cleanup; 391299ebb4caSwyllys 391399ebb4caSwyllys cleanup: 391499ebb4caSwyllys if (rv != KMF_OK) 391599ebb4caSwyllys KMF_FreeRawKey(key); 391699ebb4caSwyllys else 391799ebb4caSwyllys key->keytype = KMF_DSA; 391899ebb4caSwyllys 391999ebb4caSwyllys /* 392099ebb4caSwyllys * Free the reference to this key, SSL will not actually free 392199ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 392299ebb4caSwyllys */ 392399ebb4caSwyllys DSA_free(dsa); 392499ebb4caSwyllys 392599ebb4caSwyllys return (rv); 392699ebb4caSwyllys } 392799ebb4caSwyllys 392899ebb4caSwyllys static KMF_RETURN 392999ebb4caSwyllys add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert, 393099ebb4caSwyllys KMF_DATA **certlist, int *ncerts) 393199ebb4caSwyllys { 393299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 393399ebb4caSwyllys KMF_DATA *list = (*certlist); 393499ebb4caSwyllys KMF_DATA cert; 393599ebb4caSwyllys int n = (*ncerts); 393699ebb4caSwyllys 393799ebb4caSwyllys if (list == NULL) { 393899ebb4caSwyllys list = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 393999ebb4caSwyllys } else { 394099ebb4caSwyllys list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1)); 394199ebb4caSwyllys } 394299ebb4caSwyllys 394399ebb4caSwyllys if (list == NULL) 394499ebb4caSwyllys return (KMF_ERR_MEMORY); 394599ebb4caSwyllys 394699ebb4caSwyllys rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert); 394799ebb4caSwyllys if (rv == KMF_OK) { 394899ebb4caSwyllys list[n] = cert; 394999ebb4caSwyllys (*ncerts) = n + 1; 395099ebb4caSwyllys 395199ebb4caSwyllys *certlist = list; 395299ebb4caSwyllys } else { 395399ebb4caSwyllys free(list); 395499ebb4caSwyllys } 395599ebb4caSwyllys 395699ebb4caSwyllys return (rv); 395799ebb4caSwyllys } 395899ebb4caSwyllys 395999ebb4caSwyllys static KMF_RETURN 396099ebb4caSwyllys add_key_to_list(KMF_RAW_KEY_DATA **keylist, 396199ebb4caSwyllys KMF_RAW_KEY_DATA *newkey, int *nkeys) 396299ebb4caSwyllys { 396399ebb4caSwyllys KMF_RAW_KEY_DATA *list = (*keylist); 396499ebb4caSwyllys int n = (*nkeys); 396599ebb4caSwyllys 396699ebb4caSwyllys if (list == NULL) { 396799ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA)); 396899ebb4caSwyllys } else { 396999ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)realloc(list, 397099ebb4caSwyllys sizeof (KMF_RAW_KEY_DATA) * (n + 1)); 397199ebb4caSwyllys } 397299ebb4caSwyllys 397399ebb4caSwyllys if (list == NULL) 397499ebb4caSwyllys return (KMF_ERR_MEMORY); 397599ebb4caSwyllys 397699ebb4caSwyllys list[n] = *newkey; 397799ebb4caSwyllys (*nkeys) = n + 1; 397899ebb4caSwyllys 397999ebb4caSwyllys *keylist = list; 398099ebb4caSwyllys 398199ebb4caSwyllys return (KMF_OK); 398299ebb4caSwyllys } 398399ebb4caSwyllys 398499ebb4caSwyllys 398599ebb4caSwyllys static KMF_RETURN 398699ebb4caSwyllys convertPK12Objects( 398799ebb4caSwyllys KMF_HANDLE *kmfh, 398899ebb4caSwyllys EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts, 398999ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys, 399099ebb4caSwyllys KMF_DATA **certlist, int *ncerts) 399199ebb4caSwyllys { 399299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 399399ebb4caSwyllys KMF_RAW_KEY_DATA key; 399499ebb4caSwyllys int i; 399599ebb4caSwyllys 399699ebb4caSwyllys if (sslkey != NULL) { 399799ebb4caSwyllys /* Convert SSL key to raw key */ 399899ebb4caSwyllys switch (sslkey->type) { 399999ebb4caSwyllys case EVP_PKEY_RSA: 400099ebb4caSwyllys rv = exportRawRSAKey(EVP_PKEY_get1_RSA(sslkey), 400199ebb4caSwyllys &key); 400299ebb4caSwyllys if (rv != KMF_OK) 400399ebb4caSwyllys return (rv); 400499ebb4caSwyllys 400599ebb4caSwyllys break; 400699ebb4caSwyllys case EVP_PKEY_DSA: 400799ebb4caSwyllys rv = exportRawDSAKey(EVP_PKEY_get1_DSA(sslkey), 400899ebb4caSwyllys &key); 400999ebb4caSwyllys if (rv != KMF_OK) 401099ebb4caSwyllys return (rv); 401199ebb4caSwyllys 401299ebb4caSwyllys break; 401399ebb4caSwyllys default: 401499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 401599ebb4caSwyllys } 401699ebb4caSwyllys 401799ebb4caSwyllys rv = add_key_to_list(keylist, &key, nkeys); 401899ebb4caSwyllys if (rv != KMF_OK) 401999ebb4caSwyllys return (rv); 402099ebb4caSwyllys } 402199ebb4caSwyllys 402299ebb4caSwyllys /* Now add the certificate to the certlist */ 402399ebb4caSwyllys if (sslcert != NULL) { 402499ebb4caSwyllys rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts); 402599ebb4caSwyllys if (rv != KMF_OK) 402699ebb4caSwyllys return (rv); 402799ebb4caSwyllys } 402899ebb4caSwyllys 402999ebb4caSwyllys /* Also add any included CA certs to the list */ 403071593db2Swyllys for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) { 403199ebb4caSwyllys X509 *c; 403299ebb4caSwyllys /* 403399ebb4caSwyllys * sk_X509_value() is macro that embeds a cast to (X509 *). 403499ebb4caSwyllys * Here it translates into ((X509 *)sk_value((ca), (i))). 403599ebb4caSwyllys * Lint is complaining about the embedded casting, and 403699ebb4caSwyllys * to fix it, you need to fix openssl header files. 403799ebb4caSwyllys */ 403899ebb4caSwyllys /* LINTED E_BAD_PTR_CAST_ALIGN */ 403999ebb4caSwyllys c = sk_X509_value(sslcacerts, i); 404099ebb4caSwyllys 404199ebb4caSwyllys /* Now add the ca cert to the certlist */ 404299ebb4caSwyllys rv = add_cert_to_list(kmfh, c, certlist, ncerts); 404399ebb4caSwyllys if (rv != KMF_OK) 404499ebb4caSwyllys return (rv); 404599ebb4caSwyllys } 404699ebb4caSwyllys return (rv); 404799ebb4caSwyllys } 404899ebb4caSwyllys 404999ebb4caSwyllys KMF_RETURN 405099ebb4caSwyllys openssl_read_pkcs12(KMF_HANDLE *kmfh, 405199ebb4caSwyllys char *filename, KMF_CREDENTIAL *cred, 405299ebb4caSwyllys KMF_DATA **certlist, int *ncerts, 405399ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys) 405499ebb4caSwyllys { 405599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 405699ebb4caSwyllys BIO *bio = NULL; 405799ebb4caSwyllys EVP_PKEY *privkey = NULL; 405899ebb4caSwyllys X509 *cert = NULL; 405999ebb4caSwyllys STACK_OF(X509) *cacerts = NULL; 406099ebb4caSwyllys 406199ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 406299ebb4caSwyllys if (bio == NULL) { 406399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 406499ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 406599ebb4caSwyllys goto end; 406699ebb4caSwyllys } 406799ebb4caSwyllys 406899ebb4caSwyllys *certlist = NULL; 406999ebb4caSwyllys *keylist = NULL; 407099ebb4caSwyllys *ncerts = 0; 407199ebb4caSwyllys *nkeys = 0; 407299ebb4caSwyllys while (rv == KMF_OK) { 407399ebb4caSwyllys rv = extract_pkcs12(bio, 407499ebb4caSwyllys (uchar_t *)cred->cred, 407599ebb4caSwyllys (uint32_t)cred->credlen, 407699ebb4caSwyllys &privkey, &cert, &cacerts); 407799ebb4caSwyllys 407899ebb4caSwyllys /* Reached end of import file? */ 407999ebb4caSwyllys if (rv == KMF_OK && privkey == NULL && 408099ebb4caSwyllys cert == NULL && cacerts == NULL) 408199ebb4caSwyllys break; 408299ebb4caSwyllys 408399ebb4caSwyllys if (rv == KMF_OK) 408499ebb4caSwyllys /* Convert keys and certs to exportable format */ 408599ebb4caSwyllys rv = convertPK12Objects(kmfh, privkey, cert, cacerts, 408699ebb4caSwyllys keylist, nkeys, certlist, ncerts); 408799ebb4caSwyllys 408899ebb4caSwyllys if (privkey) 408999ebb4caSwyllys EVP_PKEY_free(privkey); 409099ebb4caSwyllys 409199ebb4caSwyllys if (cert) 409299ebb4caSwyllys X509_free(cert); 409399ebb4caSwyllys 409499ebb4caSwyllys if (cacerts) 409599ebb4caSwyllys sk_X509_free(cacerts); 409699ebb4caSwyllys } 409799ebb4caSwyllys end: 409899ebb4caSwyllys if (bio != NULL) 409999ebb4caSwyllys (void) BIO_free(bio); 410099ebb4caSwyllys 410199ebb4caSwyllys if (privkey) 410299ebb4caSwyllys EVP_PKEY_free(privkey); 410399ebb4caSwyllys 410499ebb4caSwyllys if (cert) 410599ebb4caSwyllys X509_free(cert); 410699ebb4caSwyllys 410799ebb4caSwyllys if (cacerts) 410899ebb4caSwyllys sk_X509_free(cacerts); 410999ebb4caSwyllys 411099ebb4caSwyllys return (rv); 411199ebb4caSwyllys } 411299ebb4caSwyllys 411399ebb4caSwyllys KMF_RETURN 411471593db2Swyllys openssl_import_keypair(KMF_HANDLE *kmfh, 411571593db2Swyllys char *filename, KMF_CREDENTIAL *cred, 411671593db2Swyllys KMF_DATA **certlist, int *ncerts, 411771593db2Swyllys KMF_RAW_KEY_DATA **keylist, int *nkeys) 411871593db2Swyllys { 411971593db2Swyllys KMF_RETURN rv = KMF_OK; 412071593db2Swyllys EVP_PKEY *privkey = NULL; 412171593db2Swyllys KMF_ENCODE_FORMAT format; 412271593db2Swyllys 412371593db2Swyllys /* 412471593db2Swyllys * auto-detect the file format, regardless of what 412571593db2Swyllys * the 'format' parameters in the params say. 412671593db2Swyllys */ 412771593db2Swyllys rv = KMF_GetFileFormat(filename, &format); 412871593db2Swyllys if (rv != KMF_OK) { 412971593db2Swyllys if (rv == KMF_ERR_OPEN_FILE) 413071593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 413171593db2Swyllys return (rv); 413271593db2Swyllys } 413371593db2Swyllys 413471593db2Swyllys /* This function only works on PEM files */ 413571593db2Swyllys if (format != KMF_FORMAT_PEM && 413671593db2Swyllys format != KMF_FORMAT_PEM_KEYPAIR) 413771593db2Swyllys return (KMF_ERR_ENCODING); 413871593db2Swyllys 413971593db2Swyllys *certlist = NULL; 414071593db2Swyllys *keylist = NULL; 414171593db2Swyllys *ncerts = 0; 414271593db2Swyllys *nkeys = 0; 414302744e81Swyllys rv = extract_objects(kmfh, NULL, filename, 414471593db2Swyllys (uchar_t *)cred->cred, 414571593db2Swyllys (uint32_t)cred->credlen, 414671593db2Swyllys &privkey, certlist, ncerts); 414771593db2Swyllys 414871593db2Swyllys /* Reached end of import file? */ 414971593db2Swyllys if (rv == KMF_OK) 415071593db2Swyllys /* Convert keys and certs to exportable format */ 415171593db2Swyllys rv = convertPK12Objects(kmfh, privkey, NULL, NULL, 415271593db2Swyllys keylist, nkeys, NULL, NULL); 415371593db2Swyllys 415471593db2Swyllys end: 415571593db2Swyllys if (privkey) 415671593db2Swyllys EVP_PKEY_free(privkey); 415771593db2Swyllys 415871593db2Swyllys return (rv); 415971593db2Swyllys } 416071593db2Swyllys 416171593db2Swyllys KMF_RETURN 416299ebb4caSwyllys OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, 416399ebb4caSwyllys KMF_RAW_KEY_DATA *key) 416499ebb4caSwyllys { 416599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 416699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 416799ebb4caSwyllys char *fullpath; 416899ebb4caSwyllys EVP_PKEY *pkey = NULL; 416999ebb4caSwyllys BIO *bio = NULL; 417099ebb4caSwyllys 417199ebb4caSwyllys if (key != NULL) { 417299ebb4caSwyllys if (key->keytype == KMF_RSA) { 417399ebb4caSwyllys pkey = ImportRawRSAKey(&key->rawdata.rsa); 417499ebb4caSwyllys } else if (key->keytype == KMF_DSA) { 417599ebb4caSwyllys pkey = ImportRawDSAKey(&key->rawdata.dsa); 417699ebb4caSwyllys } else { 417799ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 417899ebb4caSwyllys } 417999ebb4caSwyllys } else { 418099ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 418199ebb4caSwyllys } 418299ebb4caSwyllys if (rv != KMF_OK || pkey == NULL) 418399ebb4caSwyllys return (rv); 418499ebb4caSwyllys 418599ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 418699ebb4caSwyllys params->sslparms.keyfile); 418799ebb4caSwyllys 418899ebb4caSwyllys if (fullpath == NULL) 418999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 419099ebb4caSwyllys 419199ebb4caSwyllys /* If the requested file exists, return an error */ 419299ebb4caSwyllys if (access(fullpath, F_OK) == 0) { 419399ebb4caSwyllys free(fullpath); 419499ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 419599ebb4caSwyllys } 419699ebb4caSwyllys 419799ebb4caSwyllys bio = BIO_new_file(fullpath, "wb"); 419899ebb4caSwyllys if (bio == NULL) { 419999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 420099ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 420199ebb4caSwyllys goto cleanup; 420299ebb4caSwyllys } 420399ebb4caSwyllys 420499ebb4caSwyllys rv = ssl_write_private_key(kmfh, 420599ebb4caSwyllys params->sslparms.format, 420699ebb4caSwyllys bio, ¶ms->cred, pkey); 420799ebb4caSwyllys 420899ebb4caSwyllys cleanup: 420999ebb4caSwyllys if (fullpath) 421099ebb4caSwyllys free(fullpath); 421199ebb4caSwyllys 421299ebb4caSwyllys if (pkey) 421399ebb4caSwyllys EVP_PKEY_free(pkey); 421499ebb4caSwyllys 421599ebb4caSwyllys if (bio) 421699ebb4caSwyllys (void) BIO_free(bio); 421799ebb4caSwyllys 421899ebb4caSwyllys /* Protect the file by making it read-only */ 421999ebb4caSwyllys if (rv == KMF_OK) { 422099ebb4caSwyllys (void) chmod(fullpath, 0400); 422199ebb4caSwyllys } 422299ebb4caSwyllys return (rv); 422399ebb4caSwyllys } 422499ebb4caSwyllys 422599ebb4caSwyllys static KMF_RETURN 422699ebb4caSwyllys create_deskey(DES_cblock **deskey) 422799ebb4caSwyllys { 422899ebb4caSwyllys DES_cblock *key; 422999ebb4caSwyllys 423099ebb4caSwyllys key = (DES_cblock *) malloc(sizeof (DES_cblock)); 423199ebb4caSwyllys if (key == NULL) { 423299ebb4caSwyllys return (KMF_ERR_MEMORY); 423399ebb4caSwyllys } 423499ebb4caSwyllys 423599ebb4caSwyllys if (DES_random_key(key) == 0) { 423699ebb4caSwyllys free(key); 423799ebb4caSwyllys return (KMF_ERR_KEYGEN_FAILED); 423899ebb4caSwyllys } 423999ebb4caSwyllys 424099ebb4caSwyllys *deskey = key; 424199ebb4caSwyllys return (KMF_OK); 424299ebb4caSwyllys } 424399ebb4caSwyllys 424499ebb4caSwyllys #define KEYGEN_RETRY 3 424599ebb4caSwyllys #define DES3_KEY_SIZE 24 424699ebb4caSwyllys 424799ebb4caSwyllys static KMF_RETURN 424899ebb4caSwyllys create_des3key(unsigned char **des3key) 424999ebb4caSwyllys { 425099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 425199ebb4caSwyllys DES_cblock *deskey1 = NULL; 425299ebb4caSwyllys DES_cblock *deskey2 = NULL; 425399ebb4caSwyllys DES_cblock *deskey3 = NULL; 425499ebb4caSwyllys unsigned char *newkey = NULL; 425599ebb4caSwyllys int retry; 425699ebb4caSwyllys 425799ebb4caSwyllys if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) { 425899ebb4caSwyllys return (KMF_ERR_MEMORY); 425999ebb4caSwyllys } 426099ebb4caSwyllys 426199ebb4caSwyllys /* create the 1st DES key */ 426299ebb4caSwyllys if ((ret = create_deskey(&deskey1)) != KMF_OK) { 426399ebb4caSwyllys goto out; 426499ebb4caSwyllys } 426599ebb4caSwyllys 426699ebb4caSwyllys /* 426799ebb4caSwyllys * Create the 2nd DES key and make sure its value is different 426899ebb4caSwyllys * from the 1st DES key. 426999ebb4caSwyllys */ 427099ebb4caSwyllys retry = 0; 427199ebb4caSwyllys do { 427299ebb4caSwyllys if (deskey2 != NULL) { 427399ebb4caSwyllys free(deskey2); 427499ebb4caSwyllys deskey2 = NULL; 427599ebb4caSwyllys } 427699ebb4caSwyllys 427799ebb4caSwyllys if ((ret = create_deskey(&deskey2)) != KMF_OK) { 427899ebb4caSwyllys goto out; 427999ebb4caSwyllys } 428099ebb4caSwyllys 428199ebb4caSwyllys if (memcmp((const void *) deskey1, (const void *) deskey2, 8) 428299ebb4caSwyllys == 0) { 428399ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 428499ebb4caSwyllys retry++; 428599ebb4caSwyllys } 428699ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 428799ebb4caSwyllys 428899ebb4caSwyllys if (ret != KMF_OK) { 428999ebb4caSwyllys goto out; 429099ebb4caSwyllys } 429199ebb4caSwyllys 429299ebb4caSwyllys /* 429399ebb4caSwyllys * Create the 3rd DES key and make sure its value is different 429499ebb4caSwyllys * from the 2nd DES key. 429599ebb4caSwyllys */ 429699ebb4caSwyllys retry = 0; 429799ebb4caSwyllys do { 429899ebb4caSwyllys if (deskey3 != NULL) { 429999ebb4caSwyllys free(deskey3); 430099ebb4caSwyllys deskey3 = NULL; 430199ebb4caSwyllys } 430299ebb4caSwyllys 430399ebb4caSwyllys if ((ret = create_deskey(&deskey3)) != KMF_OK) { 430499ebb4caSwyllys goto out; 430599ebb4caSwyllys } 430699ebb4caSwyllys 430799ebb4caSwyllys if (memcmp((const void *)deskey2, (const void *)deskey3, 8) 430899ebb4caSwyllys == 0) { 430999ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 431099ebb4caSwyllys retry++; 431199ebb4caSwyllys } 431299ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 431399ebb4caSwyllys 431499ebb4caSwyllys if (ret != KMF_OK) { 431599ebb4caSwyllys goto out; 431699ebb4caSwyllys } 431799ebb4caSwyllys 431899ebb4caSwyllys /* Concatenate 3 DES keys into a DES3 key */ 431999ebb4caSwyllys (void) memcpy((void *)newkey, (const void *)deskey1, 8); 432099ebb4caSwyllys (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8); 432199ebb4caSwyllys (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8); 432299ebb4caSwyllys *des3key = newkey; 432399ebb4caSwyllys 432499ebb4caSwyllys out: 432599ebb4caSwyllys if (deskey1 != NULL) 432699ebb4caSwyllys free(deskey1); 432799ebb4caSwyllys 432899ebb4caSwyllys if (deskey2 != NULL) 432999ebb4caSwyllys free(deskey2); 433099ebb4caSwyllys 433199ebb4caSwyllys if (deskey3 != NULL) 433299ebb4caSwyllys free(deskey3); 433399ebb4caSwyllys 433499ebb4caSwyllys if (ret != KMF_OK && newkey != NULL) 433599ebb4caSwyllys free(newkey); 433699ebb4caSwyllys 433799ebb4caSwyllys return (ret); 433899ebb4caSwyllys } 433999ebb4caSwyllys 434099ebb4caSwyllys KMF_RETURN 434199ebb4caSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, 434299ebb4caSwyllys KMF_KEY_HANDLE *symkey) 434399ebb4caSwyllys { 434499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 434599ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 434699ebb4caSwyllys char *fullpath = NULL; 434799ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 434899ebb4caSwyllys DES_cblock *deskey = NULL; 434999ebb4caSwyllys unsigned char *des3key = NULL; 435099ebb4caSwyllys unsigned char *random = NULL; 435199ebb4caSwyllys int fd = -1; 435299ebb4caSwyllys 435399ebb4caSwyllys if (kmfh == NULL) 435499ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 435599ebb4caSwyllys 435699ebb4caSwyllys if (params == NULL || params->sslparms.keyfile == NULL) { 435799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 435899ebb4caSwyllys } 435999ebb4caSwyllys 436099ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 436199ebb4caSwyllys params->sslparms.keyfile); 436299ebb4caSwyllys if (fullpath == NULL) 436399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 436499ebb4caSwyllys 436599ebb4caSwyllys /* If the requested file exists, return an error */ 436699ebb4caSwyllys if (access(fullpath, F_OK) == 0) { 436799ebb4caSwyllys free(fullpath); 436899ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 436999ebb4caSwyllys } 437099ebb4caSwyllys 437199ebb4caSwyllys fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400); 437299ebb4caSwyllys if (fd == -1) { 437399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 437499ebb4caSwyllys goto out; 437599ebb4caSwyllys } 437699ebb4caSwyllys 437799ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 437899ebb4caSwyllys if (rkey == NULL) { 437999ebb4caSwyllys ret = KMF_ERR_MEMORY; 438099ebb4caSwyllys goto out; 438199ebb4caSwyllys } 438299ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 438399ebb4caSwyllys 438499ebb4caSwyllys if (params->keytype == KMF_DES) { 438599ebb4caSwyllys if ((ret = create_deskey(&deskey)) != KMF_OK) { 438699ebb4caSwyllys goto out; 438799ebb4caSwyllys } 438899ebb4caSwyllys rkey->keydata.val = (uchar_t *)deskey; 438999ebb4caSwyllys rkey->keydata.len = 8; 439099ebb4caSwyllys 439199ebb4caSwyllys symkey->keyalg = KMF_DES; 439299ebb4caSwyllys 439399ebb4caSwyllys } else if (params->keytype == KMF_DES3) { 439499ebb4caSwyllys if ((ret = create_des3key(&des3key)) != KMF_OK) { 439599ebb4caSwyllys goto out; 439699ebb4caSwyllys } 439799ebb4caSwyllys rkey->keydata.val = (uchar_t *)des3key; 439899ebb4caSwyllys rkey->keydata.len = DES3_KEY_SIZE; 439999ebb4caSwyllys symkey->keyalg = KMF_DES3; 44009b37d296Swyllys 4401c197cb9dShylee } else if (params->keytype == KMF_AES || params->keytype == KMF_RC4 || 4402c197cb9dShylee params->keytype == KMF_GENERIC_SECRET) { 440399ebb4caSwyllys int bytes; 440499ebb4caSwyllys 440599ebb4caSwyllys if (params->keylength % 8 != 0) { 440699ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 440799ebb4caSwyllys goto out; 440899ebb4caSwyllys } 440999ebb4caSwyllys 441099ebb4caSwyllys if (params->keytype == KMF_AES) { 441199ebb4caSwyllys if (params->keylength != 128 && 441299ebb4caSwyllys params->keylength != 192 && 441399ebb4caSwyllys params->keylength != 256) { 441499ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 441599ebb4caSwyllys goto out; 441699ebb4caSwyllys } 441799ebb4caSwyllys } 441899ebb4caSwyllys 441999ebb4caSwyllys bytes = params->keylength/8; 442099ebb4caSwyllys random = malloc(bytes); 442199ebb4caSwyllys if (random == NULL) { 442299ebb4caSwyllys ret = KMF_ERR_MEMORY; 442399ebb4caSwyllys goto out; 442499ebb4caSwyllys } 442599ebb4caSwyllys if (RAND_bytes(random, bytes) != 1) { 442699ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 442799ebb4caSwyllys goto out; 442899ebb4caSwyllys } 442999ebb4caSwyllys 443099ebb4caSwyllys rkey->keydata.val = (uchar_t *)random; 443199ebb4caSwyllys rkey->keydata.len = bytes; 443299ebb4caSwyllys symkey->keyalg = params->keytype; 443399ebb4caSwyllys 443499ebb4caSwyllys } else { 443599ebb4caSwyllys ret = KMF_ERR_BAD_KEY_TYPE; 443699ebb4caSwyllys goto out; 443799ebb4caSwyllys } 443899ebb4caSwyllys 443999ebb4caSwyllys (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len); 444099ebb4caSwyllys 444199ebb4caSwyllys symkey->kstype = KMF_KEYSTORE_OPENSSL; 444299ebb4caSwyllys symkey->keyclass = KMF_SYMMETRIC; 444399ebb4caSwyllys symkey->keylabel = (char *)fullpath; 444499ebb4caSwyllys symkey->israw = TRUE; 444599ebb4caSwyllys symkey->keyp = rkey; 444699ebb4caSwyllys 444799ebb4caSwyllys out: 444899ebb4caSwyllys if (fd != -1) 444999ebb4caSwyllys (void) close(fd); 445099ebb4caSwyllys 445199ebb4caSwyllys if (ret != KMF_OK && fullpath != NULL) { 445299ebb4caSwyllys free(fullpath); 445399ebb4caSwyllys } 445499ebb4caSwyllys if (ret != KMF_OK) { 445599ebb4caSwyllys KMF_FreeRawSymKey(rkey); 445699ebb4caSwyllys symkey->keyp = NULL; 445799ebb4caSwyllys symkey->keyalg = KMF_KEYALG_NONE; 445899ebb4caSwyllys } 445999ebb4caSwyllys 446099ebb4caSwyllys return (ret); 446199ebb4caSwyllys } 446299ebb4caSwyllys 446399ebb4caSwyllys 446499ebb4caSwyllys KMF_RETURN 446599ebb4caSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params) 446699ebb4caSwyllys { 446799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 446899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 446999ebb4caSwyllys BIO *bcrl = NULL; 447099ebb4caSwyllys X509_CRL *xcrl = NULL; 447199ebb4caSwyllys X509 *xcert = NULL; 447299ebb4caSwyllys EVP_PKEY *pkey; 447399ebb4caSwyllys int sslret; 447499ebb4caSwyllys KMF_ENCODE_FORMAT crl_format; 447599ebb4caSwyllys unsigned char *p; 447699ebb4caSwyllys long len; 447799ebb4caSwyllys 447899ebb4caSwyllys if (params->crl_name == NULL || params->tacert == NULL) { 447999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 448099ebb4caSwyllys } 448199ebb4caSwyllys 448299ebb4caSwyllys ret = KMF_GetFileFormat(params->crl_name, &crl_format); 448399ebb4caSwyllys if (ret != KMF_OK) 448499ebb4caSwyllys return (ret); 448599ebb4caSwyllys 448699ebb4caSwyllys bcrl = BIO_new_file(params->crl_name, "rb"); 448799ebb4caSwyllys if (bcrl == NULL) { 448899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 448999ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 449099ebb4caSwyllys goto cleanup; 449199ebb4caSwyllys } 449299ebb4caSwyllys 449399ebb4caSwyllys if (crl_format == KMF_FORMAT_ASN1) { 449499ebb4caSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 449599ebb4caSwyllys } else if (crl_format == KMF_FORMAT_PEM) { 449699ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 449799ebb4caSwyllys } else { 449899ebb4caSwyllys ret = KMF_ERR_BAD_PARAMETER; 449999ebb4caSwyllys goto cleanup; 450099ebb4caSwyllys } 450199ebb4caSwyllys 450299ebb4caSwyllys if (xcrl == NULL) { 450399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 450499ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 450599ebb4caSwyllys goto cleanup; 450699ebb4caSwyllys } 450799ebb4caSwyllys 450899ebb4caSwyllys p = params->tacert->Data; 450999ebb4caSwyllys len = params->tacert->Length; 451099ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, len); 451199ebb4caSwyllys 451299ebb4caSwyllys if (xcert == NULL) { 451399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 451499ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 451599ebb4caSwyllys goto cleanup; 451699ebb4caSwyllys } 451799ebb4caSwyllys 451899ebb4caSwyllys /* Get issuer certificate public key */ 451999ebb4caSwyllys pkey = X509_get_pubkey(xcert); 452099ebb4caSwyllys if (!pkey) { 452199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 452299ebb4caSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 452399ebb4caSwyllys goto cleanup; 452499ebb4caSwyllys } 452599ebb4caSwyllys 452699ebb4caSwyllys /* Verify CRL signature */ 452799ebb4caSwyllys sslret = X509_CRL_verify(xcrl, pkey); 452899ebb4caSwyllys EVP_PKEY_free(pkey); 452999ebb4caSwyllys if (sslret > 0) { 453099ebb4caSwyllys ret = KMF_OK; 453199ebb4caSwyllys } else { 453299ebb4caSwyllys SET_ERROR(kmfh, sslret); 453399ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 453499ebb4caSwyllys } 453599ebb4caSwyllys 453699ebb4caSwyllys cleanup: 453799ebb4caSwyllys if (bcrl != NULL) 453899ebb4caSwyllys (void) BIO_free(bcrl); 453999ebb4caSwyllys 454099ebb4caSwyllys if (xcrl != NULL) 454199ebb4caSwyllys X509_CRL_free(xcrl); 454299ebb4caSwyllys 454399ebb4caSwyllys if (xcert != NULL) 454499ebb4caSwyllys X509_free(xcert); 454599ebb4caSwyllys 454699ebb4caSwyllys return (ret); 454799ebb4caSwyllys 454899ebb4caSwyllys } 454999ebb4caSwyllys 455099ebb4caSwyllys KMF_RETURN 455199ebb4caSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, 455299ebb4caSwyllys KMF_CHECKCRLDATE_PARAMS *params) 455399ebb4caSwyllys { 455499ebb4caSwyllys 455599ebb4caSwyllys KMF_RETURN ret = KMF_OK; 455699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 455799ebb4caSwyllys KMF_ENCODE_FORMAT crl_format; 455899ebb4caSwyllys BIO *bcrl = NULL; 455999ebb4caSwyllys X509_CRL *xcrl = NULL; 456099ebb4caSwyllys int i; 456199ebb4caSwyllys 456299ebb4caSwyllys if (params == NULL || params->crl_name == NULL) { 456399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 456499ebb4caSwyllys } 456599ebb4caSwyllys 456699ebb4caSwyllys ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format); 456799ebb4caSwyllys if (ret != KMF_OK) 456899ebb4caSwyllys return (ret); 456999ebb4caSwyllys 457099ebb4caSwyllys bcrl = BIO_new_file(params->crl_name, "rb"); 457199ebb4caSwyllys if (bcrl == NULL) { 457299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 457399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 457499ebb4caSwyllys goto cleanup; 457599ebb4caSwyllys } 457699ebb4caSwyllys 457799ebb4caSwyllys if (crl_format == KMF_FORMAT_ASN1) { 457899ebb4caSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 457999ebb4caSwyllys } else if (crl_format == KMF_FORMAT_PEM) { 458099ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 458199ebb4caSwyllys } 458299ebb4caSwyllys 458399ebb4caSwyllys if (xcrl == NULL) { 458499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 458599ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 458699ebb4caSwyllys goto cleanup; 458799ebb4caSwyllys } 458899ebb4caSwyllys 458999ebb4caSwyllys i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); 459099ebb4caSwyllys if (i >= 0) { 459199ebb4caSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 459299ebb4caSwyllys goto cleanup; 459399ebb4caSwyllys } 459499ebb4caSwyllys 459599ebb4caSwyllys if (X509_CRL_get_nextUpdate(xcrl)) { 459699ebb4caSwyllys i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); 459799ebb4caSwyllys 459899ebb4caSwyllys if (i <= 0) { 459999ebb4caSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 460099ebb4caSwyllys goto cleanup; 460199ebb4caSwyllys } 460299ebb4caSwyllys } 460399ebb4caSwyllys 460499ebb4caSwyllys ret = KMF_OK; 460599ebb4caSwyllys 460699ebb4caSwyllys cleanup: 460799ebb4caSwyllys if (bcrl != NULL) 460899ebb4caSwyllys (void) BIO_free(bcrl); 460999ebb4caSwyllys 461099ebb4caSwyllys if (xcrl != NULL) 461199ebb4caSwyllys X509_CRL_free(xcrl); 461299ebb4caSwyllys 461399ebb4caSwyllys return (ret); 461499ebb4caSwyllys } 461599ebb4caSwyllys 461699ebb4caSwyllys /* 461799ebb4caSwyllys * Check a file to see if it is a CRL file with PEM or DER format. 461899ebb4caSwyllys * If success, return its format in the "pformat" argument. 461999ebb4caSwyllys */ 462099ebb4caSwyllys KMF_RETURN 462199ebb4caSwyllys OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat) 462299ebb4caSwyllys { 462399ebb4caSwyllys KMF_RETURN ret = KMF_OK; 462499ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 462599ebb4caSwyllys BIO *bio = NULL; 462699ebb4caSwyllys X509_CRL *xcrl = NULL; 462799ebb4caSwyllys 462899ebb4caSwyllys if (filename == NULL) { 462999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 463099ebb4caSwyllys } 463199ebb4caSwyllys 463299ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 463399ebb4caSwyllys if (bio == NULL) { 463499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 463599ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 463699ebb4caSwyllys goto out; 463799ebb4caSwyllys } 463899ebb4caSwyllys 463999ebb4caSwyllys if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) { 464099ebb4caSwyllys *pformat = KMF_FORMAT_PEM; 464199ebb4caSwyllys goto out; 464299ebb4caSwyllys } 464399ebb4caSwyllys (void) BIO_free(bio); 464499ebb4caSwyllys 464599ebb4caSwyllys /* 464699ebb4caSwyllys * Now try to read it as raw DER data. 464799ebb4caSwyllys */ 464899ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 464999ebb4caSwyllys if (bio == NULL) { 465099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 465199ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 465299ebb4caSwyllys goto out; 465399ebb4caSwyllys } 465499ebb4caSwyllys 465599ebb4caSwyllys if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) { 465699ebb4caSwyllys *pformat = KMF_FORMAT_ASN1; 465799ebb4caSwyllys } else { 465899ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 465999ebb4caSwyllys } 466099ebb4caSwyllys 466199ebb4caSwyllys out: 466299ebb4caSwyllys if (bio != NULL) 466399ebb4caSwyllys (void) BIO_free(bio); 466499ebb4caSwyllys 466599ebb4caSwyllys if (xcrl != NULL) 466699ebb4caSwyllys X509_CRL_free(xcrl); 466799ebb4caSwyllys 466899ebb4caSwyllys return (ret); 466999ebb4caSwyllys } 467099ebb4caSwyllys 467199ebb4caSwyllys /* 467299ebb4caSwyllys * Check a file to see if it is a certficate file with PEM or DER format. 467399ebb4caSwyllys * If success, return its format in the pformat argument. 467499ebb4caSwyllys */ 467599ebb4caSwyllys KMF_RETURN 467699ebb4caSwyllys OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, 467799ebb4caSwyllys KMF_ENCODE_FORMAT *pformat) 467899ebb4caSwyllys { 467999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 468099ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 468199ebb4caSwyllys BIO *bio = NULL; 468299ebb4caSwyllys X509 *xcert = NULL; 468399ebb4caSwyllys 468499ebb4caSwyllys if (filename == NULL) { 468599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 468699ebb4caSwyllys } 468799ebb4caSwyllys 468899ebb4caSwyllys ret = KMF_GetFileFormat(filename, pformat); 468999ebb4caSwyllys if (ret != KMF_OK) 469099ebb4caSwyllys return (ret); 469199ebb4caSwyllys 469299ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 469399ebb4caSwyllys if (bio == NULL) { 469499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 469599ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 469699ebb4caSwyllys goto out; 469799ebb4caSwyllys } 469899ebb4caSwyllys 469999ebb4caSwyllys if ((*pformat) == KMF_FORMAT_PEM) { 470099ebb4caSwyllys if ((xcert = PEM_read_bio_X509(bio, NULL, 470199ebb4caSwyllys NULL, NULL)) == NULL) { 470299ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 470399ebb4caSwyllys } 470499ebb4caSwyllys } else if ((*pformat) == KMF_FORMAT_ASN1) { 470599ebb4caSwyllys if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) { 470699ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 470799ebb4caSwyllys } 470899ebb4caSwyllys } else { 470999ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 471099ebb4caSwyllys } 471199ebb4caSwyllys 471299ebb4caSwyllys out: 471399ebb4caSwyllys if (bio != NULL) 471499ebb4caSwyllys (void) BIO_free(bio); 471599ebb4caSwyllys 471699ebb4caSwyllys if (xcert != NULL) 471799ebb4caSwyllys X509_free(xcert); 471899ebb4caSwyllys 471999ebb4caSwyllys return (ret); 472099ebb4caSwyllys } 472199ebb4caSwyllys 472299ebb4caSwyllys KMF_RETURN 472399ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 472499ebb4caSwyllys KMF_RAW_SYM_KEY *rkey) 472599ebb4caSwyllys { 472699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 472799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 472899ebb4caSwyllys KMF_DATA keyvalue; 472999ebb4caSwyllys 473099ebb4caSwyllys if (kmfh == NULL) 473199ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 473299ebb4caSwyllys 473399ebb4caSwyllys if (symkey == NULL || rkey == NULL) 473499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 473599ebb4caSwyllys else if (symkey->keyclass != KMF_SYMMETRIC) 473699ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 473799ebb4caSwyllys 473899ebb4caSwyllys if (symkey->israw) { 473999ebb4caSwyllys KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp; 474099ebb4caSwyllys 474199ebb4caSwyllys if (rawkey == NULL || 474299ebb4caSwyllys rawkey->keydata.val == NULL || 474399ebb4caSwyllys rawkey->keydata.len == 0) 474499ebb4caSwyllys return (KMF_ERR_BAD_KEYHANDLE); 474599ebb4caSwyllys 474699ebb4caSwyllys rkey->keydata.len = rawkey->keydata.len; 474799ebb4caSwyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 474899ebb4caSwyllys return (KMF_ERR_MEMORY); 474999ebb4caSwyllys (void) memcpy(rkey->keydata.val, rawkey->keydata.val, 475099ebb4caSwyllys rkey->keydata.len); 475199ebb4caSwyllys } else { 475299ebb4caSwyllys rv = KMF_ReadInputFile(handle, symkey->keylabel, &keyvalue); 475399ebb4caSwyllys if (rv != KMF_OK) 475499ebb4caSwyllys return (rv); 475599ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 475699ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 475799ebb4caSwyllys } 475899ebb4caSwyllys 475999ebb4caSwyllys return (rv); 476099ebb4caSwyllys } 476102744e81Swyllys 476202744e81Swyllys /* 476302744e81Swyllys * id-sha1 OBJECT IDENTIFIER ::= { 476402744e81Swyllys * iso(1) identified-organization(3) oiw(14) secsig(3) 476502744e81Swyllys * algorithms(2) 26 476602744e81Swyllys * } 476702744e81Swyllys */ 476802744e81Swyllys #define ASN1_SHA1_OID_PREFIX_LEN 15 476902744e81Swyllys static uchar_t SHA1_DER_PREFIX[ASN1_SHA1_OID_PREFIX_LEN] = { 477002744e81Swyllys 0x30, 0x21, 0x30, 0x09, 477102744e81Swyllys 0x06, 0x05, 0x2b, 0x0e, 477202744e81Swyllys 0x03, 0x02, 0x1a, 0x05, 477302744e81Swyllys 0x00, 0x04, 0x14 477402744e81Swyllys }; 477502744e81Swyllys 477602744e81Swyllys /* 477702744e81Swyllys * id-md2 OBJECT IDENTIFIER ::= { 477802744e81Swyllys * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 477902744e81Swyllys * } 478002744e81Swyllys */ 478102744e81Swyllys #define ASN1_MD2_OID_PREFIX_LEN 18 478202744e81Swyllys static uchar_t MD2_DER_PREFIX[ASN1_MD2_OID_PREFIX_LEN] = { 478302744e81Swyllys 0x30, 0x20, 0x30, 0x0c, 478402744e81Swyllys 0x06, 0x08, 0x2a, 0x86, 478502744e81Swyllys 0x48, 0x86, 0xf7, 0x0d, 478602744e81Swyllys 0x02, 0x02, 0x05, 0x00, 478702744e81Swyllys 0x04, 0x10 478802744e81Swyllys }; 478902744e81Swyllys 479002744e81Swyllys /* 479102744e81Swyllys * id-md5 OBJECT IDENTIFIER ::= { 479202744e81Swyllys * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 479302744e81Swyllys * } 479402744e81Swyllys */ 479502744e81Swyllys #define ASN1_MD5_OID_PREFIX_LEN 18 479602744e81Swyllys static uchar_t MD5_DER_PREFIX[ASN1_MD5_OID_PREFIX_LEN] = { 479702744e81Swyllys 0x30, 0x20, 0x30, 0x0c, 479802744e81Swyllys 0x06, 0x08, 0x2a, 0x86, 479902744e81Swyllys 0x48, 0x86, 0xf7, 0x0d, 480002744e81Swyllys 0x02, 0x05, 0x05, 0x00, 480102744e81Swyllys 0x04, 0x10 480202744e81Swyllys }; 480302744e81Swyllys 480402744e81Swyllys KMF_RETURN 480502744e81Swyllys OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle, 480602744e81Swyllys KMF_ALGORITHM_INDEX algid, KMF_DATA *indata, 480702744e81Swyllys KMF_DATA *insig, KMF_DATA *cert) 480802744e81Swyllys { 480902744e81Swyllys KMF_RETURN ret = KMF_OK; 481002744e81Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 481102744e81Swyllys X509 *xcert = NULL; 481202744e81Swyllys EVP_PKEY *pkey = NULL; 481302744e81Swyllys uchar_t *p; 481402744e81Swyllys uchar_t *rsaout = NULL; 481502744e81Swyllys uchar_t *pfx = NULL; 481602744e81Swyllys const EVP_MD *md; 481702744e81Swyllys int pfxlen = 0, len; 481802744e81Swyllys 481902744e81Swyllys if (handle == NULL || indata == NULL || 482002744e81Swyllys indata->Data == NULL || indata->Length == 0 || 482102744e81Swyllys insig == NULL|| insig->Data == NULL || insig->Length == 0 || 482202744e81Swyllys cert == NULL || cert->Data == NULL || cert->Length == 0) 482302744e81Swyllys return (KMF_ERR_BAD_PARAMETER); 482402744e81Swyllys 482502744e81Swyllys p = cert->Data; 482602744e81Swyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, cert->Length); 482702744e81Swyllys if (xcert == NULL) { 482802744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 482902744e81Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 483002744e81Swyllys goto cleanup; 483102744e81Swyllys } 483202744e81Swyllys 483302744e81Swyllys pkey = X509_get_pubkey(xcert); 483402744e81Swyllys if (!pkey) { 483502744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 483602744e81Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 483702744e81Swyllys goto cleanup; 483802744e81Swyllys } 483902744e81Swyllys 484002744e81Swyllys if (algid != KMF_ALGID_NONE) { 484102744e81Swyllys switch (algid) { 484202744e81Swyllys case KMF_ALGID_MD5WithRSA: 484302744e81Swyllys md = EVP_md5(); 484402744e81Swyllys break; 484502744e81Swyllys case KMF_ALGID_MD2WithRSA: 484602744e81Swyllys md = EVP_md2(); 484702744e81Swyllys break; 484802744e81Swyllys case KMF_ALGID_SHA1WithRSA: 484902744e81Swyllys md = EVP_sha1(); 485002744e81Swyllys break; 485102744e81Swyllys case KMF_ALGID_RSA: 485202744e81Swyllys md = NULL; 485302744e81Swyllys break; 485402744e81Swyllys default: 485502744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 485602744e81Swyllys goto cleanup; 485702744e81Swyllys } 485802744e81Swyllys } else { 485902744e81Swyllys /* Get the hash type from the cert signature */ 486002744e81Swyllys md = EVP_get_digestbyobj(xcert->sig_alg->algorithm); 486102744e81Swyllys if (md == NULL) { 486202744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 486302744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 486402744e81Swyllys goto cleanup; 486502744e81Swyllys } 486602744e81Swyllys } 48679b37d296Swyllys if (md != NULL) { 486802744e81Swyllys switch (EVP_MD_type(md)) { 486902744e81Swyllys case NID_md2: 487002744e81Swyllys case NID_md2WithRSAEncryption: 487102744e81Swyllys pfxlen = ASN1_MD2_OID_PREFIX_LEN; 487202744e81Swyllys pfx = MD2_DER_PREFIX; 487302744e81Swyllys break; 487402744e81Swyllys case NID_md5: 487502744e81Swyllys case NID_md5WithRSAEncryption: 487602744e81Swyllys pfxlen = ASN1_MD5_OID_PREFIX_LEN; 487702744e81Swyllys pfx = MD5_DER_PREFIX; 487802744e81Swyllys break; 487902744e81Swyllys case NID_sha1: 488002744e81Swyllys case NID_sha1WithRSAEncryption: 488102744e81Swyllys pfxlen = ASN1_SHA1_OID_PREFIX_LEN; 488202744e81Swyllys pfx = SHA1_DER_PREFIX; 488302744e81Swyllys break; 488402744e81Swyllys default: /* Unsupported */ 488502744e81Swyllys pfxlen = 0; 488602744e81Swyllys pfx = NULL; 488702744e81Swyllys break; 488802744e81Swyllys } 48899b37d296Swyllys } 489002744e81Swyllys 489102744e81Swyllys /* RSA with no hash is a special case */ 489202744e81Swyllys rsaout = malloc(RSA_size(pkey->pkey.rsa)); 489302744e81Swyllys if (rsaout == NULL) 489402744e81Swyllys return (KMF_ERR_MEMORY); 489502744e81Swyllys 489602744e81Swyllys /* Decrypt the input signature */ 489702744e81Swyllys len = RSA_public_decrypt(insig->Length, 489802744e81Swyllys insig->Data, rsaout, pkey->pkey.rsa, RSA_PKCS1_PADDING); 489902744e81Swyllys if (len < 1) { 490002744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 490102744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 490202744e81Swyllys } else { 490302744e81Swyllys size_t hashlen = 0; 490402744e81Swyllys uint32_t dlen; 490502744e81Swyllys char *digest = NULL; 490602744e81Swyllys 490702744e81Swyllys /* 490802744e81Swyllys * If the AlgId requires it, hash the input data before 490902744e81Swyllys * comparing it to the decrypted signature. 491002744e81Swyllys */ 491102744e81Swyllys if (md) { 491202744e81Swyllys EVP_MD_CTX ctx; 491302744e81Swyllys 491402744e81Swyllys hashlen = md->md_size; 491502744e81Swyllys 491602744e81Swyllys digest = malloc(hashlen + pfxlen); 491702744e81Swyllys if (digest == NULL) 491802744e81Swyllys return (KMF_ERR_MEMORY); 491902744e81Swyllys /* Add the prefix to the comparison buffer. */ 492002744e81Swyllys if (pfx && pfxlen > 0) { 492102744e81Swyllys (void) memcpy(digest, pfx, pfxlen); 492202744e81Swyllys } 492302744e81Swyllys (void) EVP_DigestInit(&ctx, md); 492402744e81Swyllys (void) EVP_DigestUpdate(&ctx, indata->Data, 492502744e81Swyllys indata->Length); 492602744e81Swyllys 492702744e81Swyllys /* Add the digest AFTER the ASN1 prefix */ 492802744e81Swyllys (void) EVP_DigestFinal(&ctx, 492902744e81Swyllys (uchar_t *)digest + pfxlen, &dlen); 493002744e81Swyllys 493102744e81Swyllys dlen += pfxlen; 493202744e81Swyllys } else { 493302744e81Swyllys digest = (char *)indata->Data; 493402744e81Swyllys dlen = indata->Length; 493502744e81Swyllys } 493602744e81Swyllys 493702744e81Swyllys /* 493802744e81Swyllys * The result of the RSA decryption should be ASN1(OID | Hash). 493902744e81Swyllys * Compare the output hash to the input data for the final 494002744e81Swyllys * result. 494102744e81Swyllys */ 494202744e81Swyllys if (memcmp(rsaout, digest, dlen)) 494302744e81Swyllys ret = KMF_ERR_INTERNAL; 494402744e81Swyllys else 494502744e81Swyllys ret = KMF_OK; 494602744e81Swyllys 494702744e81Swyllys /* If we had to allocate space for the digest, free it now */ 494802744e81Swyllys if (hashlen) 494902744e81Swyllys free(digest); 495002744e81Swyllys } 495102744e81Swyllys cleanup: 495202744e81Swyllys if (pkey) 495302744e81Swyllys EVP_PKEY_free(pkey); 495402744e81Swyllys 495502744e81Swyllys if (xcert) 495602744e81Swyllys X509_free(xcert); 495702744e81Swyllys 495802744e81Swyllys if (rsaout) 495902744e81Swyllys free(rsaout); 496002744e81Swyllys 496102744e81Swyllys return (ret); 496202744e81Swyllys } 4963