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 uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 10799ebb4caSwyllys 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 10899ebb4caSwyllys 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 10999ebb4caSwyllys 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 11099ebb4caSwyllys 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 11199ebb4caSwyllys 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 11299ebb4caSwyllys 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 11399ebb4caSwyllys 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 11499ebb4caSwyllys 0x91 }; 11599ebb4caSwyllys 11699ebb4caSwyllys static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 11799ebb4caSwyllys 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 11899ebb4caSwyllys 0x8e, 0xda, 0xce, 0x91, 0x5f }; 11999ebb4caSwyllys 12099ebb4caSwyllys static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 12199ebb4caSwyllys 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 12299ebb4caSwyllys 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 12399ebb4caSwyllys 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 12499ebb4caSwyllys 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 12599ebb4caSwyllys 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 12699ebb4caSwyllys 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 12799ebb4caSwyllys 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 12899ebb4caSwyllys 0x02 }; 12999ebb4caSwyllys 13099ebb4caSwyllys #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \ 13199ebb4caSwyllys h->lasterr.errcode = c; 13299ebb4caSwyllys 13399ebb4caSwyllys #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c; 13499ebb4caSwyllys 135*5b3e1433Swyllys /* 136*5b3e1433Swyllys * Declare some new macros for managing stacks of EVP_PKEYS, similar to 137*5b3e1433Swyllys * what wanboot did. 138*5b3e1433Swyllys */ 139*5b3e1433Swyllys DECLARE_STACK_OF(EVP_PKEY) 140*5b3e1433Swyllys 141*5b3e1433Swyllys #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY) 142*5b3e1433Swyllys #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st)) 143*5b3e1433Swyllys #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st)) 144*5b3e1433Swyllys #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i)) 145*5b3e1433Swyllys #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val)) 146*5b3e1433Swyllys #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \ 147*5b3e1433Swyllys (free_func)) 148*5b3e1433Swyllys 14999ebb4caSwyllys mutex_t init_lock = DEFAULTMUTEX; 15099ebb4caSwyllys static int ssl_initialized = 0; 15130a5e8faSwyllys static BIO *bio_err = NULL; 15230a5e8faSwyllys 15330a5e8faSwyllys static int 15430a5e8faSwyllys test_for_file(char *, mode_t); 155*5b3e1433Swyllys static KMF_RETURN 156*5b3e1433Swyllys openssl_parse_bag(PKCS12_SAFEBAG *, char *, int, 157*5b3e1433Swyllys STACK_OF(EVP_PKEY) *, STACK_OF(X509) *); 158*5b3e1433Swyllys 159*5b3e1433Swyllys static KMF_RETURN 160*5b3e1433Swyllys local_export_pk12(KMF_HANDLE_T, KMF_CREDENTIAL *, int, KMF_X509_DER_CERT *, 161*5b3e1433Swyllys int, KMF_KEY_HANDLE *, char *); 162*5b3e1433Swyllys 163*5b3e1433Swyllys static KMF_RETURN set_pkey_attrib(EVP_PKEY *, ASN1_TYPE *, int); 16499ebb4caSwyllys 16571593db2Swyllys static KMF_RETURN 16630a5e8faSwyllys extract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *, 16702744e81Swyllys CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *); 16871593db2Swyllys 16971593db2Swyllys static KMF_RETURN 17030a5e8faSwyllys kmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, 17130a5e8faSwyllys char *, KMF_DATA *); 17230a5e8faSwyllys 17330a5e8faSwyllys static KMF_RETURN 17430a5e8faSwyllys load_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, 17530a5e8faSwyllys char *, KMF_DATA **, uint32_t *); 17671593db2Swyllys 17702744e81Swyllys static KMF_RETURN 17802744e81Swyllys sslBN2KMFBN(BIGNUM *, KMF_BIGINT *); 17902744e81Swyllys 18002744e81Swyllys static EVP_PKEY * 18102744e81Swyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *); 18202744e81Swyllys 18330a5e8faSwyllys static KMF_RETURN 18430a5e8faSwyllys convertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *); 18530a5e8faSwyllys 18699ebb4caSwyllys KMF_RETURN 18730a5e8faSwyllys OpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 18899ebb4caSwyllys 18999ebb4caSwyllys void 19099ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); 19199ebb4caSwyllys 19299ebb4caSwyllys KMF_RETURN 19330a5e8faSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); 19499ebb4caSwyllys 19599ebb4caSwyllys KMF_RETURN 19630a5e8faSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); 19799ebb4caSwyllys 19899ebb4caSwyllys KMF_RETURN 19930a5e8faSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 20030a5e8faSwyllys 20130a5e8faSwyllys KMF_RETURN 20230a5e8faSwyllys OpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 20399ebb4caSwyllys 20499ebb4caSwyllys KMF_RETURN 20599ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 20699ebb4caSwyllys 20799ebb4caSwyllys KMF_RETURN 20899ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 20999ebb4caSwyllys KMF_DATA *, KMF_DATA *); 21099ebb4caSwyllys 21199ebb4caSwyllys KMF_RETURN 21230a5e8faSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 21399ebb4caSwyllys 21499ebb4caSwyllys KMF_RETURN 21530a5e8faSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 21699ebb4caSwyllys 21799ebb4caSwyllys KMF_RETURN 21830a5e8faSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 21999ebb4caSwyllys 22099ebb4caSwyllys KMF_RETURN 22130a5e8faSwyllys OpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 22299ebb4caSwyllys 22399ebb4caSwyllys KMF_RETURN 22430a5e8faSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 22599ebb4caSwyllys 22699ebb4caSwyllys KMF_RETURN 22799ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *, 22899ebb4caSwyllys KMF_PRINTABLE_ITEM, char *); 22999ebb4caSwyllys 23099ebb4caSwyllys KMF_RETURN 23199ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T, char **); 23299ebb4caSwyllys 23399ebb4caSwyllys KMF_RETURN 23430a5e8faSwyllys OpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 23599ebb4caSwyllys 23699ebb4caSwyllys KMF_RETURN 23799ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 23899ebb4caSwyllys KMF_DATA *, KMF_DATA *); 23999ebb4caSwyllys 24099ebb4caSwyllys KMF_RETURN 24130a5e8faSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 24299ebb4caSwyllys 24399ebb4caSwyllys KMF_RETURN 24430a5e8faSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 24599ebb4caSwyllys 24699ebb4caSwyllys KMF_RETURN 24730a5e8faSwyllys OpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 24899ebb4caSwyllys 24999ebb4caSwyllys KMF_RETURN 25030a5e8faSwyllys OpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 25199ebb4caSwyllys 25299ebb4caSwyllys KMF_RETURN 25330a5e8faSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 25499ebb4caSwyllys 25599ebb4caSwyllys KMF_RETURN 25699ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 25799ebb4caSwyllys 25899ebb4caSwyllys KMF_RETURN 25930a5e8faSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *); 26099ebb4caSwyllys 26199ebb4caSwyllys KMF_RETURN 26230a5e8faSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T, char *); 26399ebb4caSwyllys 26402744e81Swyllys KMF_RETURN 26502744e81Swyllys OpenSSL_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, 26602744e81Swyllys KMF_DATA *, KMF_DATA *, KMF_DATA *); 26702744e81Swyllys 26899ebb4caSwyllys static 26999ebb4caSwyllys KMF_PLUGIN_FUNCLIST openssl_plugin_table = 27099ebb4caSwyllys { 27199ebb4caSwyllys 1, /* Version */ 27299ebb4caSwyllys NULL, /* ConfigureKeystore */ 27399ebb4caSwyllys OpenSSL_FindCert, 27499ebb4caSwyllys OpenSSL_FreeKMFCert, 27599ebb4caSwyllys OpenSSL_StoreCert, 27699ebb4caSwyllys NULL, /* ImportCert */ 27799ebb4caSwyllys OpenSSL_ImportCRL, 27899ebb4caSwyllys OpenSSL_DeleteCert, 27999ebb4caSwyllys OpenSSL_DeleteCRL, 28099ebb4caSwyllys OpenSSL_CreateKeypair, 28199ebb4caSwyllys OpenSSL_FindKey, 28299ebb4caSwyllys OpenSSL_EncodePubKeyData, 28399ebb4caSwyllys OpenSSL_SignData, 28499ebb4caSwyllys OpenSSL_DeleteKey, 28599ebb4caSwyllys OpenSSL_ListCRL, 28699ebb4caSwyllys NULL, /* FindCRL */ 28799ebb4caSwyllys OpenSSL_FindCertInCRL, 28899ebb4caSwyllys OpenSSL_GetErrorString, 28930a5e8faSwyllys OpenSSL_FindPrikeyByCert, 29099ebb4caSwyllys OpenSSL_DecryptData, 29130a5e8faSwyllys OpenSSL_ExportPK12, 29299ebb4caSwyllys OpenSSL_CreateSymKey, 29399ebb4caSwyllys OpenSSL_GetSymKeyValue, 29499ebb4caSwyllys NULL, /* SetTokenPin */ 29502744e81Swyllys OpenSSL_VerifyDataWithCert, 29630a5e8faSwyllys OpenSSL_StoreKey, 29799ebb4caSwyllys NULL /* Finalize */ 29899ebb4caSwyllys }; 29999ebb4caSwyllys 30099ebb4caSwyllys static mutex_t *lock_cs; 30199ebb4caSwyllys static long *lock_count; 30299ebb4caSwyllys 30399ebb4caSwyllys static void 30499ebb4caSwyllys /*ARGSUSED*/ 30599ebb4caSwyllys locking_cb(int mode, int type, char *file, int line) 30699ebb4caSwyllys { 30799ebb4caSwyllys if (mode & CRYPTO_LOCK) { 30899ebb4caSwyllys (void) mutex_lock(&(lock_cs[type])); 30999ebb4caSwyllys lock_count[type]++; 31099ebb4caSwyllys } else { 31199ebb4caSwyllys (void) mutex_unlock(&(lock_cs[type])); 31299ebb4caSwyllys } 31399ebb4caSwyllys } 31499ebb4caSwyllys 31599ebb4caSwyllys static unsigned long 31699ebb4caSwyllys thread_id() 31799ebb4caSwyllys { 31899ebb4caSwyllys return ((unsigned long)thr_self()); 31999ebb4caSwyllys } 32099ebb4caSwyllys 32199ebb4caSwyllys KMF_PLUGIN_FUNCLIST * 32299ebb4caSwyllys KMF_Plugin_Initialize() 32399ebb4caSwyllys { 32499ebb4caSwyllys int i; 32599ebb4caSwyllys 32699ebb4caSwyllys (void) mutex_lock(&init_lock); 32799ebb4caSwyllys if (!ssl_initialized) { 32899ebb4caSwyllys OpenSSL_add_all_algorithms(); 32999ebb4caSwyllys 33099ebb4caSwyllys /* Enable error strings for reporting */ 33199ebb4caSwyllys ERR_load_crypto_strings(); 33299ebb4caSwyllys 33399ebb4caSwyllys /* 33499ebb4caSwyllys * Add support for extension OIDs that are not yet in the 33599ebb4caSwyllys * openssl default set. 33699ebb4caSwyllys */ 33799ebb4caSwyllys (void) OBJ_create("2.5.29.30", "nameConstraints", 33899ebb4caSwyllys "X509v3 Name Constraints"); 33999ebb4caSwyllys (void) OBJ_create("2.5.29.33", "policyMappings", 34099ebb4caSwyllys "X509v3 Policy Mappings"); 34199ebb4caSwyllys (void) OBJ_create("2.5.29.36", "policyConstraints", 34299ebb4caSwyllys "X509v3 Policy Constraints"); 34399ebb4caSwyllys (void) OBJ_create("2.5.29.46", "freshestCRL", 34499ebb4caSwyllys "X509v3 Freshest CRL"); 34599ebb4caSwyllys (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy", 34699ebb4caSwyllys "X509v3 Inhibit Any-Policy"); 34799ebb4caSwyllys /* 34899ebb4caSwyllys * Set up for thread-safe operation. 34999ebb4caSwyllys */ 35099ebb4caSwyllys lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t)); 35199ebb4caSwyllys if (lock_cs == NULL) { 35299ebb4caSwyllys (void) mutex_unlock(&init_lock); 35399ebb4caSwyllys return (NULL); 35499ebb4caSwyllys } 35599ebb4caSwyllys 35699ebb4caSwyllys lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long)); 35799ebb4caSwyllys if (lock_count == NULL) { 35899ebb4caSwyllys OPENSSL_free(lock_cs); 35999ebb4caSwyllys (void) mutex_unlock(&init_lock); 36099ebb4caSwyllys return (NULL); 36199ebb4caSwyllys } 36299ebb4caSwyllys 36399ebb4caSwyllys for (i = 0; i < CRYPTO_num_locks(); i++) { 36499ebb4caSwyllys lock_count[i] = 0; 36599ebb4caSwyllys (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL); 36699ebb4caSwyllys } 36799ebb4caSwyllys 36899ebb4caSwyllys CRYPTO_set_id_callback((unsigned long (*)())thread_id); 36999ebb4caSwyllys CRYPTO_set_locking_callback((void (*)())locking_cb); 37099ebb4caSwyllys ssl_initialized = 1; 37199ebb4caSwyllys } 37299ebb4caSwyllys (void) mutex_unlock(&init_lock); 37399ebb4caSwyllys 37499ebb4caSwyllys return (&openssl_plugin_table); 37599ebb4caSwyllys } 37699ebb4caSwyllys /* 37799ebb4caSwyllys * Convert an SSL DN to a KMF DN. 37899ebb4caSwyllys */ 37999ebb4caSwyllys static KMF_RETURN 38099ebb4caSwyllys get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN) 38199ebb4caSwyllys { 38299ebb4caSwyllys KMF_DATA derdata; 38399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 38499ebb4caSwyllys uchar_t *tmp; 38599ebb4caSwyllys 38699ebb4caSwyllys /* Convert to raw DER format */ 38799ebb4caSwyllys derdata.Length = i2d_X509_NAME(sslDN, NULL); 38899ebb4caSwyllys if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length)) 38999ebb4caSwyllys == NULL) { 39099ebb4caSwyllys return (KMF_ERR_MEMORY); 39199ebb4caSwyllys } 39299ebb4caSwyllys (void) i2d_X509_NAME(sslDN, &tmp); 39399ebb4caSwyllys 39499ebb4caSwyllys /* Decode to KMF format */ 39599ebb4caSwyllys rv = DerDecodeName(&derdata, kmfDN); 39699ebb4caSwyllys if (rv != KMF_OK) { 39799ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 39899ebb4caSwyllys } 39999ebb4caSwyllys OPENSSL_free(derdata.Data); 40099ebb4caSwyllys 40199ebb4caSwyllys return (rv); 40299ebb4caSwyllys } 40399ebb4caSwyllys 40430a5e8faSwyllys int 40599ebb4caSwyllys isdir(char *path) 40699ebb4caSwyllys { 40799ebb4caSwyllys struct stat s; 40899ebb4caSwyllys 40999ebb4caSwyllys if (stat(path, &s) == -1) 41099ebb4caSwyllys return (0); 41199ebb4caSwyllys 41230a5e8faSwyllys return ((s.st_mode & S_IFMT) == S_IFDIR); 41399ebb4caSwyllys } 41499ebb4caSwyllys 41599ebb4caSwyllys static KMF_RETURN 41699ebb4caSwyllys ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert) 41799ebb4caSwyllys { 41899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 41999ebb4caSwyllys unsigned char *buf = NULL, *p; 42099ebb4caSwyllys int len; 42199ebb4caSwyllys 42299ebb4caSwyllys /* 42399ebb4caSwyllys * Convert the X509 internal struct to DER encoded data 42499ebb4caSwyllys */ 42599ebb4caSwyllys if ((len = i2d_X509(x509cert, NULL)) < 0) { 42699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 42799ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 42899ebb4caSwyllys goto cleanup; 42999ebb4caSwyllys } 43099ebb4caSwyllys if ((buf = malloc(len)) == NULL) { 43199ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 43299ebb4caSwyllys rv = KMF_ERR_MEMORY; 43399ebb4caSwyllys goto cleanup; 43499ebb4caSwyllys } 43599ebb4caSwyllys 43699ebb4caSwyllys /* 43799ebb4caSwyllys * i2d_X509 will increment the buf pointer so that we need to 43899ebb4caSwyllys * save it. 43999ebb4caSwyllys */ 44099ebb4caSwyllys p = buf; 44199ebb4caSwyllys if ((len = i2d_X509(x509cert, &p)) < 0) { 44299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 44399ebb4caSwyllys free(buf); 44499ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 44599ebb4caSwyllys goto cleanup; 44699ebb4caSwyllys } 44799ebb4caSwyllys 44899ebb4caSwyllys /* caller's responsibility to free it */ 44999ebb4caSwyllys cert->Data = buf; 45099ebb4caSwyllys cert->Length = len; 45199ebb4caSwyllys 45299ebb4caSwyllys cleanup: 45399ebb4caSwyllys if (rv != KMF_OK) { 45499ebb4caSwyllys if (buf) 45599ebb4caSwyllys free(buf); 45699ebb4caSwyllys cert->Data = NULL; 45799ebb4caSwyllys cert->Length = 0; 45899ebb4caSwyllys } 45999ebb4caSwyllys 46099ebb4caSwyllys return (rv); 46199ebb4caSwyllys } 46299ebb4caSwyllys 46330a5e8faSwyllys 46499ebb4caSwyllys static KMF_RETURN 46530a5e8faSwyllys check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial, 46630a5e8faSwyllys boolean_t *match) 46799ebb4caSwyllys { 46899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 46999ebb4caSwyllys boolean_t findIssuer = FALSE; 47099ebb4caSwyllys boolean_t findSubject = FALSE; 47199ebb4caSwyllys boolean_t findSerial = FALSE; 47299ebb4caSwyllys KMF_X509_NAME issuerDN, subjectDN; 47399ebb4caSwyllys KMF_X509_NAME certIssuerDN, certSubjectDN; 47499ebb4caSwyllys 47599ebb4caSwyllys *match = FALSE; 47699ebb4caSwyllys if (xcert == NULL) { 47799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 47899ebb4caSwyllys } 47999ebb4caSwyllys 48099ebb4caSwyllys (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME)); 48199ebb4caSwyllys (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME)); 48299ebb4caSwyllys (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME)); 48399ebb4caSwyllys (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME)); 48499ebb4caSwyllys 48530a5e8faSwyllys if (issuer != NULL && strlen(issuer)) { 48630a5e8faSwyllys rv = kmf_dn_parser(issuer, &issuerDN); 48799ebb4caSwyllys if (rv != KMF_OK) 48899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 48999ebb4caSwyllys 49099ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); 49199ebb4caSwyllys if (rv != KMF_OK) { 49230a5e8faSwyllys kmf_free_dn(&issuerDN); 49399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 49499ebb4caSwyllys } 49599ebb4caSwyllys 49699ebb4caSwyllys findIssuer = TRUE; 49799ebb4caSwyllys } 49830a5e8faSwyllys if (subject != NULL && strlen(subject)) { 49930a5e8faSwyllys rv = kmf_dn_parser(subject, &subjectDN); 50099ebb4caSwyllys if (rv != KMF_OK) { 50199ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 50299ebb4caSwyllys goto cleanup; 50399ebb4caSwyllys } 50499ebb4caSwyllys 50599ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN); 50699ebb4caSwyllys if (rv != KMF_OK) { 50799ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 50899ebb4caSwyllys goto cleanup; 50999ebb4caSwyllys } 51099ebb4caSwyllys findSubject = TRUE; 51199ebb4caSwyllys } 51230a5e8faSwyllys if (serial != NULL && serial->val != NULL) 51399ebb4caSwyllys findSerial = TRUE; 51499ebb4caSwyllys 51599ebb4caSwyllys if (findSerial) { 51699ebb4caSwyllys BIGNUM *bn; 51799ebb4caSwyllys 51899ebb4caSwyllys /* Comparing BIGNUMs is a pain! */ 51999ebb4caSwyllys bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL); 52099ebb4caSwyllys if (bn != NULL) { 52199ebb4caSwyllys int bnlen = BN_num_bytes(bn); 52299ebb4caSwyllys 52330a5e8faSwyllys if (bnlen == serial->len) { 52499ebb4caSwyllys uchar_t *a = malloc(bnlen); 52599ebb4caSwyllys if (a == NULL) { 52699ebb4caSwyllys rv = KMF_ERR_MEMORY; 52799ebb4caSwyllys BN_free(bn); 52899ebb4caSwyllys goto cleanup; 52999ebb4caSwyllys } 53099ebb4caSwyllys bnlen = BN_bn2bin(bn, a); 53130a5e8faSwyllys *match = (memcmp(a, serial->val, serial->len) == 53230a5e8faSwyllys 0); 53399ebb4caSwyllys rv = KMF_OK; 53499ebb4caSwyllys free(a); 53599ebb4caSwyllys } 53699ebb4caSwyllys BN_free(bn); 53799ebb4caSwyllys if (!(*match)) 53899ebb4caSwyllys goto cleanup; 53999ebb4caSwyllys } else { 54099ebb4caSwyllys rv = KMF_OK; 54199ebb4caSwyllys goto cleanup; 54299ebb4caSwyllys } 54399ebb4caSwyllys } 54499ebb4caSwyllys if (findIssuer) { 54530a5e8faSwyllys *match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0); 54630a5e8faSwyllys if ((*match) == B_FALSE) { 54730a5e8faSwyllys /* stop checking and bail */ 54899ebb4caSwyllys rv = KMF_OK; 54999ebb4caSwyllys goto cleanup; 55099ebb4caSwyllys } 55199ebb4caSwyllys } 55299ebb4caSwyllys if (findSubject) { 55330a5e8faSwyllys *match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0); 55430a5e8faSwyllys if ((*match) == B_FALSE) { 55530a5e8faSwyllys /* stop checking and bail */ 55699ebb4caSwyllys rv = KMF_OK; 55799ebb4caSwyllys goto cleanup; 55899ebb4caSwyllys } 55999ebb4caSwyllys } 56099ebb4caSwyllys 56199ebb4caSwyllys *match = TRUE; 56299ebb4caSwyllys cleanup: 56399ebb4caSwyllys if (findIssuer) { 56430a5e8faSwyllys kmf_free_dn(&issuerDN); 56530a5e8faSwyllys kmf_free_dn(&certIssuerDN); 56699ebb4caSwyllys } 56799ebb4caSwyllys if (findSubject) { 56830a5e8faSwyllys kmf_free_dn(&subjectDN); 56930a5e8faSwyllys kmf_free_dn(&certSubjectDN); 57099ebb4caSwyllys } 57199ebb4caSwyllys 57299ebb4caSwyllys return (rv); 57399ebb4caSwyllys } 57499ebb4caSwyllys 57530a5e8faSwyllys 57630a5e8faSwyllys /* 57730a5e8faSwyllys * This function loads a certificate file into an X509 data structure, and 57830a5e8faSwyllys * checks if its issuer, subject or the serial number matches with those 57930a5e8faSwyllys * values. If it matches, then return the X509 data structure. 58030a5e8faSwyllys */ 58199ebb4caSwyllys static KMF_RETURN 58299ebb4caSwyllys load_X509cert(KMF_HANDLE *kmfh, 58330a5e8faSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 58430a5e8faSwyllys char *pathname, X509 **outcert) 58599ebb4caSwyllys { 58699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 58799ebb4caSwyllys X509 *xcert = NULL; 58899ebb4caSwyllys BIO *bcert = NULL; 58999ebb4caSwyllys boolean_t match = FALSE; 59099ebb4caSwyllys KMF_ENCODE_FORMAT format; 59199ebb4caSwyllys 59299ebb4caSwyllys /* 59399ebb4caSwyllys * auto-detect the file format, regardless of what 59499ebb4caSwyllys * the 'format' parameters in the params say. 59599ebb4caSwyllys */ 59630a5e8faSwyllys rv = kmf_get_file_format(pathname, &format); 59799ebb4caSwyllys if (rv != KMF_OK) { 59899ebb4caSwyllys if (rv == KMF_ERR_OPEN_FILE) 59999ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 60099ebb4caSwyllys return (rv); 60199ebb4caSwyllys } 60299ebb4caSwyllys 60399ebb4caSwyllys /* Not ASN1(DER) format */ 60499ebb4caSwyllys if ((bcert = BIO_new_file(pathname, "rb")) == NULL) { 60599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 60699ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 60799ebb4caSwyllys goto cleanup; 60899ebb4caSwyllys } 60999ebb4caSwyllys 61099ebb4caSwyllys if (format == KMF_FORMAT_PEM) 61199ebb4caSwyllys xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL); 61299ebb4caSwyllys else if (format == KMF_FORMAT_ASN1) 61399ebb4caSwyllys xcert = d2i_X509_bio(bcert, NULL); 61499ebb4caSwyllys else if (format == KMF_FORMAT_PKCS12) { 61599ebb4caSwyllys PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL); 61699ebb4caSwyllys if (p12 != NULL) { 61799ebb4caSwyllys (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL); 61899ebb4caSwyllys PKCS12_free(p12); 61999ebb4caSwyllys p12 = NULL; 62099ebb4caSwyllys } else { 62199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 62299ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 62399ebb4caSwyllys } 62499ebb4caSwyllys } else { 62599ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 62699ebb4caSwyllys goto cleanup; 62799ebb4caSwyllys } 62899ebb4caSwyllys 62999ebb4caSwyllys if (xcert == NULL) { 63099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 63199ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 63299ebb4caSwyllys goto cleanup; 63399ebb4caSwyllys } 63499ebb4caSwyllys 63530a5e8faSwyllys if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK || 63630a5e8faSwyllys match == FALSE) { 63799ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 63899ebb4caSwyllys goto cleanup; 63999ebb4caSwyllys } 64099ebb4caSwyllys 64199ebb4caSwyllys if (outcert != NULL) { 64299ebb4caSwyllys *outcert = xcert; 64399ebb4caSwyllys } 64499ebb4caSwyllys 64599ebb4caSwyllys cleanup: 64699ebb4caSwyllys if (bcert != NULL) (void) BIO_free(bcert); 64799ebb4caSwyllys if (rv != KMF_OK && xcert != NULL) 64899ebb4caSwyllys X509_free(xcert); 64999ebb4caSwyllys 65099ebb4caSwyllys return (rv); 65199ebb4caSwyllys } 65299ebb4caSwyllys 65371593db2Swyllys static int 65471593db2Swyllys datacmp(const void *a, const void *b) 65571593db2Swyllys { 65671593db2Swyllys KMF_DATA *adata = (KMF_DATA *)a; 65771593db2Swyllys KMF_DATA *bdata = (KMF_DATA *)b; 65871593db2Swyllys if (adata->Length > bdata->Length) 65971593db2Swyllys return (-1); 66071593db2Swyllys if (adata->Length < bdata->Length) 66171593db2Swyllys return (1); 66271593db2Swyllys return (0); 66371593db2Swyllys } 66471593db2Swyllys 66571593db2Swyllys static KMF_RETURN 66630a5e8faSwyllys load_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial, 66730a5e8faSwyllys KMF_CERT_VALIDITY validity, char *pathname, 66871593db2Swyllys KMF_DATA **certlist, uint32_t *numcerts) 66971593db2Swyllys { 67071593db2Swyllys KMF_RETURN rv = KMF_OK; 67171593db2Swyllys int i; 67271593db2Swyllys KMF_DATA *certs = NULL; 67371593db2Swyllys int nc = 0; 67471593db2Swyllys int hits = 0; 67571593db2Swyllys KMF_ENCODE_FORMAT format; 67671593db2Swyllys 67730a5e8faSwyllys rv = kmf_get_file_format(pathname, &format); 67871593db2Swyllys if (rv != KMF_OK) { 67971593db2Swyllys if (rv == KMF_ERR_OPEN_FILE) 68071593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 68171593db2Swyllys return (rv); 68271593db2Swyllys } 68371593db2Swyllys if (format == KMF_FORMAT_ASN1) { 68471593db2Swyllys /* load a single certificate */ 68571593db2Swyllys certs = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 68671593db2Swyllys if (certs == NULL) 68771593db2Swyllys return (KMF_ERR_MEMORY); 68871593db2Swyllys certs->Data = NULL; 68971593db2Swyllys certs->Length = 0; 69030a5e8faSwyllys rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, 69130a5e8faSwyllys pathname, certs); 69271593db2Swyllys if (rv == KMF_OK) { 69371593db2Swyllys *certlist = certs; 69471593db2Swyllys *numcerts = 1; 69571593db2Swyllys } 69671593db2Swyllys return (rv); 69771593db2Swyllys } else if (format == KMF_FORMAT_PKCS12) { 69871593db2Swyllys /* We need a credential to access a PKCS#12 file */ 69971593db2Swyllys rv = KMF_ERR_BAD_CERT_FORMAT; 70071593db2Swyllys } else if (format == KMF_FORMAT_PEM || 70171593db2Swyllys format != KMF_FORMAT_PEM_KEYPAIR) { 70271593db2Swyllys 70371593db2Swyllys /* This function only works on PEM files */ 70430a5e8faSwyllys rv = extract_pem(kmfh, issuer, subject, serial, pathname, 70534acef67Swyllys (uchar_t *)NULL, 0, NULL, &certs, &nc); 70671593db2Swyllys } else { 70771593db2Swyllys return (KMF_ERR_ENCODING); 70871593db2Swyllys } 70971593db2Swyllys 71071593db2Swyllys if (rv != KMF_OK) 71171593db2Swyllys return (rv); 71271593db2Swyllys 71371593db2Swyllys for (i = 0; i < nc; i++) { 71430a5e8faSwyllys if (validity == KMF_NONEXPIRED_CERTS) { 71530a5e8faSwyllys rv = kmf_check_cert_date(kmfh, &certs[i]); 71630a5e8faSwyllys } else if (validity == KMF_EXPIRED_CERTS) { 71730a5e8faSwyllys rv = kmf_check_cert_date(kmfh, &certs[i]); 71871593db2Swyllys if (rv == KMF_OK) 71971593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 72071593db2Swyllys if (rv == KMF_ERR_VALIDITY_PERIOD) 72171593db2Swyllys rv = KMF_OK; 72271593db2Swyllys } 72371593db2Swyllys if (rv != KMF_OK) { 72471593db2Swyllys /* Remove this cert from the list by clearing it. */ 72530a5e8faSwyllys kmf_free_data(&certs[i]); 72671593db2Swyllys } else { 72771593db2Swyllys hits++; /* count valid certs found */ 72871593db2Swyllys } 72971593db2Swyllys rv = KMF_OK; 73071593db2Swyllys } 73171593db2Swyllys if (rv == KMF_OK && hits == 0) { 73271593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 73371593db2Swyllys } else if (rv == KMF_OK && hits > 0) { 73471593db2Swyllys /* 73571593db2Swyllys * Sort the list of certs by length to put the cleared ones 73671593db2Swyllys * at the end so they don't get accessed by the caller. 73771593db2Swyllys */ 73871593db2Swyllys qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp); 73971593db2Swyllys *certlist = certs; 74071593db2Swyllys 74171593db2Swyllys /* since we sorted the list, just return the number of hits */ 74271593db2Swyllys *numcerts = hits; 74371593db2Swyllys } 74471593db2Swyllys return (rv); 74571593db2Swyllys } 74671593db2Swyllys 74730a5e8faSwyllys 74899ebb4caSwyllys static KMF_RETURN 74999ebb4caSwyllys kmf_load_cert(KMF_HANDLE *kmfh, 75030a5e8faSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 75130a5e8faSwyllys KMF_CERT_VALIDITY validity, 75299ebb4caSwyllys char *pathname, 75399ebb4caSwyllys KMF_DATA *cert) 75499ebb4caSwyllys { 75599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 75699ebb4caSwyllys X509 *x509cert = NULL; 75799ebb4caSwyllys 75830a5e8faSwyllys rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert); 75999ebb4caSwyllys if (rv == KMF_OK && x509cert != NULL && cert != NULL) { 76099ebb4caSwyllys rv = ssl_cert2KMFDATA(kmfh, x509cert, cert); 76199ebb4caSwyllys if (rv != KMF_OK) { 76299ebb4caSwyllys goto cleanup; 76399ebb4caSwyllys } 76430a5e8faSwyllys if (validity == KMF_NONEXPIRED_CERTS) { 76530a5e8faSwyllys rv = kmf_check_cert_date(kmfh, cert); 76630a5e8faSwyllys } else if (validity == KMF_EXPIRED_CERTS) { 76730a5e8faSwyllys rv = kmf_check_cert_date(kmfh, cert); 76899ebb4caSwyllys if (rv == KMF_OK) { 76999ebb4caSwyllys /* 77099ebb4caSwyllys * This is a valid cert so skip it. 77199ebb4caSwyllys */ 77299ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 77399ebb4caSwyllys } 77499ebb4caSwyllys if (rv == KMF_ERR_VALIDITY_PERIOD) { 77599ebb4caSwyllys /* 77699ebb4caSwyllys * We want to return success when we 77799ebb4caSwyllys * find an invalid cert. 77899ebb4caSwyllys */ 77999ebb4caSwyllys rv = KMF_OK; 78099ebb4caSwyllys goto cleanup; 78199ebb4caSwyllys } 78299ebb4caSwyllys } 78399ebb4caSwyllys } 78499ebb4caSwyllys cleanup: 78599ebb4caSwyllys if (x509cert != NULL) 78699ebb4caSwyllys X509_free(x509cert); 78799ebb4caSwyllys 78899ebb4caSwyllys return (rv); 78999ebb4caSwyllys } 79099ebb4caSwyllys 79102744e81Swyllys static KMF_RETURN 79202744e81Swyllys readAltFormatPrivateKey(KMF_DATA *filedata, EVP_PKEY **pkey) 79302744e81Swyllys { 79402744e81Swyllys KMF_RETURN ret = KMF_OK; 79502744e81Swyllys KMF_RAW_RSA_KEY rsa; 79602744e81Swyllys BerElement *asn1 = NULL; 79702744e81Swyllys BerValue filebuf; 79802744e81Swyllys BerValue OID = { NULL, 0 }; 79902744e81Swyllys BerValue *Mod = NULL, *PubExp = NULL; 80002744e81Swyllys BerValue *PriExp = NULL, *Prime1 = NULL, *Prime2 = NULL; 80102744e81Swyllys BerValue *Coef = NULL; 80202744e81Swyllys BIGNUM *D = NULL, *P = NULL, *Q = NULL, *COEF = NULL; 80302744e81Swyllys BIGNUM *Exp1 = NULL, *Exp2 = NULL, *pminus1 = NULL; 80402744e81Swyllys BIGNUM *qminus1 = NULL; 80502744e81Swyllys BN_CTX *ctx = NULL; 80602744e81Swyllys 80702744e81Swyllys *pkey = NULL; 80802744e81Swyllys 80902744e81Swyllys filebuf.bv_val = (char *)filedata->Data; 81002744e81Swyllys filebuf.bv_len = filedata->Length; 81102744e81Swyllys 81202744e81Swyllys asn1 = kmfder_init(&filebuf); 81302744e81Swyllys if (asn1 == NULL) { 81402744e81Swyllys ret = KMF_ERR_MEMORY; 81502744e81Swyllys goto out; 81602744e81Swyllys } 81702744e81Swyllys 81802744e81Swyllys if (kmfber_scanf(asn1, "{{Dn{IIIIII}}}", 81902744e81Swyllys &OID, &Mod, &PubExp, &PriExp, &Prime1, 82002744e81Swyllys &Prime2, &Coef) == -1) { 82102744e81Swyllys ret = KMF_ERR_ENCODING; 82202744e81Swyllys goto out; 82302744e81Swyllys } 82402744e81Swyllys 82502744e81Swyllys /* 82602744e81Swyllys * We have to derive the 2 Exponents using Bignumber math. 82702744e81Swyllys * Exp1 = PriExp mod (Prime1 - 1) 82802744e81Swyllys * Exp2 = PriExp mod (Prime2 - 1) 82902744e81Swyllys */ 83002744e81Swyllys 83102744e81Swyllys /* D = PrivateExponent */ 83202744e81Swyllys D = BN_bin2bn((const uchar_t *)PriExp->bv_val, PriExp->bv_len, D); 83302744e81Swyllys if (D == NULL) { 83402744e81Swyllys ret = KMF_ERR_MEMORY; 83502744e81Swyllys goto out; 83602744e81Swyllys } 83702744e81Swyllys 83802744e81Swyllys /* P = Prime1 (first prime factor of Modulus) */ 83902744e81Swyllys P = BN_bin2bn((const uchar_t *)Prime1->bv_val, Prime1->bv_len, P); 84002744e81Swyllys if (D == NULL) { 84102744e81Swyllys ret = KMF_ERR_MEMORY; 84202744e81Swyllys goto out; 84302744e81Swyllys } 84402744e81Swyllys 84502744e81Swyllys /* Q = Prime2 (second prime factor of Modulus) */ 84602744e81Swyllys Q = BN_bin2bn((const uchar_t *)Prime2->bv_val, Prime2->bv_len, Q); 84702744e81Swyllys 84802744e81Swyllys if ((ctx = BN_CTX_new()) == NULL) { 84902744e81Swyllys ret = KMF_ERR_MEMORY; 85002744e81Swyllys goto out; 85102744e81Swyllys } 85202744e81Swyllys 85302744e81Swyllys /* Compute (P - 1) */ 85402744e81Swyllys pminus1 = BN_new(); 85502744e81Swyllys (void) BN_sub(pminus1, P, BN_value_one()); 85602744e81Swyllys 85702744e81Swyllys /* Exponent1 = D mod (P - 1) */ 85802744e81Swyllys Exp1 = BN_new(); 85902744e81Swyllys (void) BN_mod(Exp1, D, pminus1, ctx); 86002744e81Swyllys 86102744e81Swyllys /* Compute (Q - 1) */ 86202744e81Swyllys qminus1 = BN_new(); 86302744e81Swyllys (void) BN_sub(qminus1, Q, BN_value_one()); 86402744e81Swyllys 86502744e81Swyllys /* Exponent2 = D mod (Q - 1) */ 86602744e81Swyllys Exp2 = BN_new(); 86702744e81Swyllys (void) BN_mod(Exp2, D, qminus1, ctx); 86802744e81Swyllys 86902744e81Swyllys /* Coef = (Inverse Q) mod P */ 87002744e81Swyllys COEF = BN_new(); 87102744e81Swyllys (void) BN_mod_inverse(COEF, Q, P, ctx); 87202744e81Swyllys 87302744e81Swyllys /* Convert back to KMF format */ 87402744e81Swyllys (void) memset(&rsa, 0, sizeof (rsa)); 87502744e81Swyllys 87602744e81Swyllys if ((ret = sslBN2KMFBN(Exp1, &rsa.exp1)) != KMF_OK) 87702744e81Swyllys goto out; 87802744e81Swyllys if ((ret = sslBN2KMFBN(Exp2, &rsa.exp2)) != KMF_OK) 87902744e81Swyllys goto out; 88002744e81Swyllys if ((ret = sslBN2KMFBN(COEF, &rsa.coef)) != KMF_OK) 88102744e81Swyllys goto out; 88202744e81Swyllys 88302744e81Swyllys rsa.mod.val = (uchar_t *)Mod->bv_val; 88402744e81Swyllys rsa.mod.len = Mod->bv_len; 88502744e81Swyllys 88602744e81Swyllys rsa.pubexp.val = (uchar_t *)PubExp->bv_val; 88702744e81Swyllys rsa.pubexp.len = PubExp->bv_len; 88802744e81Swyllys 88902744e81Swyllys rsa.priexp.val = (uchar_t *)PriExp->bv_val; 89002744e81Swyllys rsa.priexp.len = PriExp->bv_len; 89102744e81Swyllys 89202744e81Swyllys rsa.prime1.val = (uchar_t *)Prime1->bv_val; 89302744e81Swyllys rsa.prime1.len = Prime1->bv_len; 89402744e81Swyllys 89502744e81Swyllys rsa.prime2.val = (uchar_t *)Prime2->bv_val; 89602744e81Swyllys rsa.prime2.len = Prime2->bv_len; 89702744e81Swyllys 89802744e81Swyllys *pkey = ImportRawRSAKey(&rsa); 89902744e81Swyllys out: 90002744e81Swyllys if (asn1 != NULL) 90102744e81Swyllys kmfber_free(asn1, 1); 90202744e81Swyllys 90302744e81Swyllys if (OID.bv_val) { 90402744e81Swyllys free(OID.bv_val); 90502744e81Swyllys } 90602744e81Swyllys if (PriExp) 90702744e81Swyllys free(PriExp); 90802744e81Swyllys 90902744e81Swyllys if (Mod) 91002744e81Swyllys free(Mod); 91102744e81Swyllys 91202744e81Swyllys if (PubExp) 91302744e81Swyllys free(PubExp); 91402744e81Swyllys 91502744e81Swyllys if (Coef) { 91602744e81Swyllys (void) memset(Coef->bv_val, 0, Coef->bv_len); 91702744e81Swyllys free(Coef->bv_val); 91802744e81Swyllys free(Coef); 91902744e81Swyllys } 92002744e81Swyllys if (Prime1) 92102744e81Swyllys free(Prime1); 92202744e81Swyllys if (Prime2) 92302744e81Swyllys free(Prime2); 92402744e81Swyllys 92502744e81Swyllys if (ctx != NULL) 92602744e81Swyllys BN_CTX_free(ctx); 92702744e81Swyllys 92802744e81Swyllys if (D) 92902744e81Swyllys BN_clear_free(D); 93002744e81Swyllys if (P) 93102744e81Swyllys BN_clear_free(P); 93202744e81Swyllys if (Q) 93302744e81Swyllys BN_clear_free(Q); 93402744e81Swyllys if (pminus1) 93502744e81Swyllys BN_clear_free(pminus1); 93602744e81Swyllys if (qminus1) 93702744e81Swyllys BN_clear_free(qminus1); 93802744e81Swyllys if (Exp1) 93902744e81Swyllys BN_clear_free(Exp1); 94002744e81Swyllys if (Exp2) 94102744e81Swyllys BN_clear_free(Exp2); 94202744e81Swyllys 94302744e81Swyllys return (ret); 94402744e81Swyllys 94502744e81Swyllys } 94602744e81Swyllys 94799ebb4caSwyllys static EVP_PKEY * 94899ebb4caSwyllys openssl_load_key(KMF_HANDLE_T handle, const char *file) 94999ebb4caSwyllys { 95099ebb4caSwyllys BIO *keyfile = NULL; 95199ebb4caSwyllys EVP_PKEY *pkey = NULL; 95299ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 95399ebb4caSwyllys KMF_ENCODE_FORMAT format; 95402744e81Swyllys KMF_RETURN rv; 95502744e81Swyllys KMF_DATA filedata; 95699ebb4caSwyllys 95799ebb4caSwyllys if (file == NULL) { 95899ebb4caSwyllys return (NULL); 95999ebb4caSwyllys } 96099ebb4caSwyllys 96130a5e8faSwyllys if (kmf_get_file_format((char *)file, &format) != KMF_OK) 96299ebb4caSwyllys return (NULL); 96399ebb4caSwyllys 96499ebb4caSwyllys keyfile = BIO_new_file(file, "rb"); 96599ebb4caSwyllys if (keyfile == NULL) { 96699ebb4caSwyllys goto end; 96799ebb4caSwyllys } 96899ebb4caSwyllys 96902744e81Swyllys if (format == KMF_FORMAT_ASN1) { 97099ebb4caSwyllys pkey = d2i_PrivateKey_bio(keyfile, NULL); 97102744e81Swyllys if (pkey == NULL) { 97202744e81Swyllys 97302744e81Swyllys (void) BIO_free(keyfile); 97402744e81Swyllys keyfile = NULL; 97502744e81Swyllys /* Try odd ASN.1 variations */ 97630a5e8faSwyllys rv = kmf_read_input_file(kmfh, (char *)file, 97702744e81Swyllys &filedata); 97802744e81Swyllys if (rv == KMF_OK) { 97902744e81Swyllys (void) readAltFormatPrivateKey(&filedata, 98002744e81Swyllys &pkey); 98130a5e8faSwyllys kmf_free_data(&filedata); 98202744e81Swyllys } 98302744e81Swyllys } 98402744e81Swyllys } else if (format == KMF_FORMAT_PEM || 98502744e81Swyllys format == KMF_FORMAT_PEM_KEYPAIR) { 98699ebb4caSwyllys pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL); 98702744e81Swyllys if (pkey == NULL) { 98802744e81Swyllys KMF_DATA derdata; 98902744e81Swyllys /* 99002744e81Swyllys * Check if this is the alt. format 99102744e81Swyllys * RSA private key file. 99202744e81Swyllys */ 99330a5e8faSwyllys rv = kmf_read_input_file(kmfh, (char *)file, 99402744e81Swyllys &filedata); 99502744e81Swyllys if (rv == KMF_OK) { 99602744e81Swyllys uchar_t *d = NULL; 99702744e81Swyllys int len; 99830a5e8faSwyllys rv = kmf_pem_to_der(filedata.Data, 99902744e81Swyllys filedata.Length, &d, &len); 100002744e81Swyllys if (rv == KMF_OK && d != NULL) { 100102744e81Swyllys derdata.Data = d; 100202744e81Swyllys derdata.Length = (size_t)len; 100302744e81Swyllys (void) readAltFormatPrivateKey( 100402744e81Swyllys &derdata, &pkey); 100502744e81Swyllys free(d); 100602744e81Swyllys } 100730a5e8faSwyllys kmf_free_data(&filedata); 100802744e81Swyllys } 100902744e81Swyllys } 101002744e81Swyllys } 101199ebb4caSwyllys 101299ebb4caSwyllys end: 101399ebb4caSwyllys if (pkey == NULL) 101499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 101599ebb4caSwyllys 101699ebb4caSwyllys if (keyfile != NULL) 101799ebb4caSwyllys (void) BIO_free(keyfile); 101899ebb4caSwyllys 101999ebb4caSwyllys return (pkey); 102099ebb4caSwyllys } 102199ebb4caSwyllys 102299ebb4caSwyllys KMF_RETURN 102330a5e8faSwyllys OpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 102499ebb4caSwyllys { 102599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 102699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1027f482c776Swyllys int i, n; 1028f482c776Swyllys uint32_t maxcerts = 0; 102930a5e8faSwyllys uint32_t *num_certs; 103030a5e8faSwyllys KMF_X509_DER_CERT *kmf_cert = NULL; 103130a5e8faSwyllys char *dirpath = NULL; 103230a5e8faSwyllys char *filename = NULL; 103330a5e8faSwyllys char *fullpath = NULL; 103430a5e8faSwyllys char *issuer = NULL; 103530a5e8faSwyllys char *subject = NULL; 103630a5e8faSwyllys KMF_BIGINT *serial = NULL; 103730a5e8faSwyllys KMF_CERT_VALIDITY validity; 103899ebb4caSwyllys 103930a5e8faSwyllys num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 104030a5e8faSwyllys if (num_certs == NULL) 104199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 104299ebb4caSwyllys 104330a5e8faSwyllys /* num_certs should reference the size of kmf_cert */ 1044f482c776Swyllys maxcerts = *num_certs; 1045f482c776Swyllys if (maxcerts == 0) 1046f482c776Swyllys maxcerts = 0xFFFFFFFF; 104799ebb4caSwyllys *num_certs = 0; 104899ebb4caSwyllys 104930a5e8faSwyllys /* Get the optional returned certificate list */ 105030a5e8faSwyllys kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, 105130a5e8faSwyllys numattr); 105299ebb4caSwyllys 105330a5e8faSwyllys /* 105430a5e8faSwyllys * The dirpath attribute and the filename attribute can not be NULL 105530a5e8faSwyllys * at the same time. 105630a5e8faSwyllys */ 105730a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 105830a5e8faSwyllys filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 105930a5e8faSwyllys numattr); 106030a5e8faSwyllys 106130a5e8faSwyllys fullpath = get_fullpath(dirpath, filename); 106299ebb4caSwyllys if (fullpath == NULL) 106399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 106499ebb4caSwyllys 106530a5e8faSwyllys /* Get optional search criteria attributes */ 106630a5e8faSwyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 106730a5e8faSwyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 106830a5e8faSwyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 106930a5e8faSwyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, 107030a5e8faSwyllys &validity, NULL); 107130a5e8faSwyllys if (rv != KMF_OK) { 107230a5e8faSwyllys validity = KMF_ALL_CERTS; 107330a5e8faSwyllys rv = KMF_OK; 107430a5e8faSwyllys } 107530a5e8faSwyllys 107699ebb4caSwyllys if (isdir(fullpath)) { 107799ebb4caSwyllys DIR *dirp; 107899ebb4caSwyllys struct dirent *dp; 107999ebb4caSwyllys 1080f482c776Swyllys n = 0; 108199ebb4caSwyllys /* open all files in the directory and attempt to read them */ 108299ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 108399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 108499ebb4caSwyllys } 108599ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 108699ebb4caSwyllys char *fname; 108771593db2Swyllys KMF_DATA *certlist = NULL; 1088f482c776Swyllys uint32_t loaded_certs = 0; 108971593db2Swyllys 109099ebb4caSwyllys if (strcmp(dp->d_name, ".") == 0 || 109199ebb4caSwyllys strcmp(dp->d_name, "..") == 0) 109299ebb4caSwyllys continue; 109399ebb4caSwyllys 109434acef67Swyllys fname = get_fullpath(fullpath, (char *)&dp->d_name); 109599ebb4caSwyllys 109630a5e8faSwyllys rv = load_certs(kmfh, issuer, subject, serial, 109730a5e8faSwyllys validity, fname, &certlist, &loaded_certs); 109899ebb4caSwyllys 109999ebb4caSwyllys if (rv != KMF_OK) { 110099ebb4caSwyllys free(fname); 110171593db2Swyllys if (certlist != NULL) { 1102f482c776Swyllys for (i = 0; i < loaded_certs; i++) 110330a5e8faSwyllys kmf_free_data(&certlist[i]); 110471593db2Swyllys free(certlist); 110571593db2Swyllys } 110699ebb4caSwyllys continue; 110799ebb4caSwyllys } 110899ebb4caSwyllys 110999ebb4caSwyllys /* If load succeeds, add certdata to the list */ 111099ebb4caSwyllys if (kmf_cert != NULL) { 1111f482c776Swyllys for (i = 0; i < loaded_certs && 1112b4058258Swyllys n < maxcerts; i++) { 111371593db2Swyllys kmf_cert[n].certificate.Data = 111471593db2Swyllys certlist[i].Data; 111599ebb4caSwyllys kmf_cert[n].certificate.Length = 111671593db2Swyllys certlist[i].Length; 111799ebb4caSwyllys 111899ebb4caSwyllys kmf_cert[n].kmf_private.keystore_type = 111999ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 112099ebb4caSwyllys kmf_cert[n].kmf_private.flags = 112199ebb4caSwyllys KMF_FLAG_CERT_VALID; 112271593db2Swyllys kmf_cert[n].kmf_private.label = 112371593db2Swyllys strdup(fname); 112499ebb4caSwyllys n++; 112599ebb4caSwyllys } 1126b4058258Swyllys /* 1127b4058258Swyllys * If maxcerts < loaded_certs, clean up the 1128b4058258Swyllys * certs that were not used. 1129b4058258Swyllys */ 1130f482c776Swyllys for (; i < loaded_certs; i++) 113130a5e8faSwyllys kmf_free_data(&certlist[i]); 1132f482c776Swyllys } else { 1133f482c776Swyllys for (i = 0; i < loaded_certs; i++) 113430a5e8faSwyllys kmf_free_data(&certlist[i]); 1135f482c776Swyllys n += loaded_certs; 113671593db2Swyllys } 1137f482c776Swyllys free(certlist); 113871593db2Swyllys free(fname); 113971593db2Swyllys } 114099ebb4caSwyllys (*num_certs) = n; 114199ebb4caSwyllys if (*num_certs == 0) 114299ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 114330a5e8faSwyllys if (*num_certs > 0) 114499ebb4caSwyllys rv = KMF_OK; 114599ebb4caSwyllys exit: 114699ebb4caSwyllys (void) closedir(dirp); 114799ebb4caSwyllys } else { 114871593db2Swyllys KMF_DATA *certlist = NULL; 1149f482c776Swyllys uint32_t loaded_certs = 0; 115071593db2Swyllys 115130a5e8faSwyllys rv = load_certs(kmfh, issuer, subject, serial, validity, 115230a5e8faSwyllys fullpath, &certlist, &loaded_certs); 115399ebb4caSwyllys if (rv != KMF_OK) { 115499ebb4caSwyllys free(fullpath); 115599ebb4caSwyllys return (rv); 115699ebb4caSwyllys } 115799ebb4caSwyllys 1158f482c776Swyllys n = 0; 115971593db2Swyllys if (kmf_cert != NULL && certlist != NULL) { 1160f482c776Swyllys for (i = 0; i < loaded_certs && i < maxcerts; i++) { 1161f482c776Swyllys kmf_cert[n].certificate.Data = 116271593db2Swyllys certlist[i].Data; 1163f482c776Swyllys kmf_cert[n].certificate.Length = 116471593db2Swyllys certlist[i].Length; 1165f482c776Swyllys kmf_cert[n].kmf_private.keystore_type = 116699ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 1167f482c776Swyllys kmf_cert[n].kmf_private.flags = 116871593db2Swyllys KMF_FLAG_CERT_VALID; 1169f482c776Swyllys kmf_cert[n].kmf_private.label = 117071593db2Swyllys strdup(fullpath); 1171f482c776Swyllys n++; 117271593db2Swyllys } 1173f482c776Swyllys /* If maxcerts < loaded_certs, clean up */ 1174f482c776Swyllys for (; i < loaded_certs; i++) 117530a5e8faSwyllys kmf_free_data(&certlist[i]); 1176f482c776Swyllys } else if (certlist != NULL) { 1177f482c776Swyllys for (i = 0; i < loaded_certs; i++) 117830a5e8faSwyllys kmf_free_data(&certlist[i]); 1179f482c776Swyllys n = loaded_certs; 1180f482c776Swyllys } 118130a5e8faSwyllys if (certlist != NULL) 118271593db2Swyllys free(certlist); 1183f482c776Swyllys *num_certs = n; 118499ebb4caSwyllys } 118599ebb4caSwyllys 118699ebb4caSwyllys free(fullpath); 118799ebb4caSwyllys 118899ebb4caSwyllys return (rv); 118999ebb4caSwyllys } 119099ebb4caSwyllys 119199ebb4caSwyllys void 119299ebb4caSwyllys /*ARGSUSED*/ 119399ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, 119499ebb4caSwyllys KMF_X509_DER_CERT *kmf_cert) 119599ebb4caSwyllys { 119699ebb4caSwyllys if (kmf_cert != NULL) { 119799ebb4caSwyllys if (kmf_cert->certificate.Data != NULL) { 119899ebb4caSwyllys free(kmf_cert->certificate.Data); 119999ebb4caSwyllys kmf_cert->certificate.Data = NULL; 120099ebb4caSwyllys kmf_cert->certificate.Length = 0; 120199ebb4caSwyllys } 120299ebb4caSwyllys if (kmf_cert->kmf_private.label) 120399ebb4caSwyllys free(kmf_cert->kmf_private.label); 120499ebb4caSwyllys } 120599ebb4caSwyllys } 120699ebb4caSwyllys 120730a5e8faSwyllys /*ARGSUSED*/ 120899ebb4caSwyllys KMF_RETURN 120930a5e8faSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 121099ebb4caSwyllys { 121199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 121230a5e8faSwyllys KMF_DATA *cert = NULL; 121330a5e8faSwyllys char *outfilename = NULL; 121430a5e8faSwyllys char *dirpath = NULL; 121530a5e8faSwyllys char *fullpath = NULL; 121699ebb4caSwyllys KMF_ENCODE_FORMAT format; 121799ebb4caSwyllys 121830a5e8faSwyllys /* Get the cert data */ 121930a5e8faSwyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 122030a5e8faSwyllys if (cert == NULL || cert->Data == NULL) 122199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 122299ebb4caSwyllys 122330a5e8faSwyllys /* Check the output filename and directory attributes. */ 122430a5e8faSwyllys outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 122530a5e8faSwyllys numattr); 122630a5e8faSwyllys if (outfilename == NULL) 122730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 122899ebb4caSwyllys 122930a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 123030a5e8faSwyllys fullpath = get_fullpath(dirpath, outfilename); 123199ebb4caSwyllys if (fullpath == NULL) 123230a5e8faSwyllys return (KMF_ERR_BAD_CERTFILE); 123399ebb4caSwyllys 123430a5e8faSwyllys /* Check the optional format attribute */ 123530a5e8faSwyllys ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 123630a5e8faSwyllys &format, NULL); 123730a5e8faSwyllys if (ret != KMF_OK) { 123830a5e8faSwyllys /* If there is no format attribute, then default to PEM */ 123930a5e8faSwyllys format = KMF_FORMAT_PEM; 124099ebb4caSwyllys ret = KMF_OK; 124130a5e8faSwyllys } else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) { 124230a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 124399ebb4caSwyllys goto out; 124499ebb4caSwyllys } 124599ebb4caSwyllys 124630a5e8faSwyllys /* Store the certificate in the file with the specified format */ 124730a5e8faSwyllys ret = kmf_create_cert_file(cert, format, fullpath); 124899ebb4caSwyllys 124999ebb4caSwyllys out: 125099ebb4caSwyllys if (fullpath != NULL) 125199ebb4caSwyllys free(fullpath); 125299ebb4caSwyllys 125399ebb4caSwyllys return (ret); 125499ebb4caSwyllys } 125599ebb4caSwyllys 125630a5e8faSwyllys 125799ebb4caSwyllys KMF_RETURN 125830a5e8faSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 125999ebb4caSwyllys { 126099ebb4caSwyllys KMF_RETURN rv; 126199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 126299ebb4caSwyllys KMF_DATA certdata = {NULL, 0}; 126330a5e8faSwyllys char *dirpath = NULL; 126430a5e8faSwyllys char *filename = NULL; 126530a5e8faSwyllys char *fullpath = NULL; 126630a5e8faSwyllys char *issuer = NULL; 126730a5e8faSwyllys char *subject = NULL; 126830a5e8faSwyllys KMF_BIGINT *serial = NULL; 126930a5e8faSwyllys KMF_CERT_VALIDITY validity; 127099ebb4caSwyllys 127130a5e8faSwyllys /* 127230a5e8faSwyllys * Get the DIRPATH and CERT_FILENAME attributes. They can not be 127330a5e8faSwyllys * NULL at the same time. 127430a5e8faSwyllys */ 127530a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 127630a5e8faSwyllys filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 127730a5e8faSwyllys numattr); 127830a5e8faSwyllys fullpath = get_fullpath(dirpath, filename); 127999ebb4caSwyllys if (fullpath == NULL) 128099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 128199ebb4caSwyllys 128230a5e8faSwyllys /* Get optional search criteria attributes */ 128330a5e8faSwyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 128430a5e8faSwyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 128530a5e8faSwyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 128630a5e8faSwyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, 128730a5e8faSwyllys &validity, NULL); 128830a5e8faSwyllys if (rv != KMF_OK) { 128930a5e8faSwyllys validity = KMF_ALL_CERTS; 129030a5e8faSwyllys rv = KMF_OK; 129130a5e8faSwyllys } 129230a5e8faSwyllys 129399ebb4caSwyllys if (isdir(fullpath)) { 129499ebb4caSwyllys DIR *dirp; 129599ebb4caSwyllys struct dirent *dp; 129699ebb4caSwyllys 129799ebb4caSwyllys /* open all files in the directory and attempt to read them */ 129899ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 129999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 130099ebb4caSwyllys } 130199ebb4caSwyllys 130299ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 130399ebb4caSwyllys if (strcmp(dp->d_name, ".") != 0 && 130499ebb4caSwyllys strcmp(dp->d_name, "..") != 0) { 130599ebb4caSwyllys char *fname; 130699ebb4caSwyllys 130799ebb4caSwyllys fname = get_fullpath(fullpath, 130899ebb4caSwyllys (char *)&dp->d_name); 130999ebb4caSwyllys 131099ebb4caSwyllys if (fname == NULL) { 131199ebb4caSwyllys rv = KMF_ERR_MEMORY; 131299ebb4caSwyllys break; 131399ebb4caSwyllys } 131499ebb4caSwyllys 131530a5e8faSwyllys rv = kmf_load_cert(kmfh, issuer, subject, 131630a5e8faSwyllys serial, validity, fname, &certdata); 131799ebb4caSwyllys 131899ebb4caSwyllys if (rv == KMF_ERR_CERT_NOT_FOUND) { 131999ebb4caSwyllys free(fname); 132099ebb4caSwyllys if (certdata.Data) 132199ebb4caSwyllys free(certdata.Data); 132299ebb4caSwyllys rv = KMF_OK; 132399ebb4caSwyllys continue; 132499ebb4caSwyllys } else if (rv != KMF_OK) { 132599ebb4caSwyllys free(fname); 132699ebb4caSwyllys break; 132799ebb4caSwyllys } 132899ebb4caSwyllys 132999ebb4caSwyllys if (unlink(fname) != 0) { 133099ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 133199ebb4caSwyllys rv = KMF_ERR_INTERNAL; 133299ebb4caSwyllys free(fname); 133399ebb4caSwyllys break; 133499ebb4caSwyllys } 133599ebb4caSwyllys free(fname); 133699ebb4caSwyllys if (certdata.Data) 133799ebb4caSwyllys free(certdata.Data); 133899ebb4caSwyllys } 133999ebb4caSwyllys } 134099ebb4caSwyllys (void) closedir(dirp); 134199ebb4caSwyllys } else { 134299ebb4caSwyllys /* Just try to load a single certificate */ 134330a5e8faSwyllys rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, 134430a5e8faSwyllys fullpath, &certdata); 134599ebb4caSwyllys if (rv == KMF_OK) { 134699ebb4caSwyllys if (unlink(fullpath) != 0) { 134799ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 134899ebb4caSwyllys rv = KMF_ERR_INTERNAL; 134999ebb4caSwyllys } 135099ebb4caSwyllys } 135199ebb4caSwyllys } 135299ebb4caSwyllys 135399ebb4caSwyllys out: 135499ebb4caSwyllys if (fullpath != NULL) 135599ebb4caSwyllys free(fullpath); 135699ebb4caSwyllys 135799ebb4caSwyllys if (certdata.Data) 135899ebb4caSwyllys free(certdata.Data); 135999ebb4caSwyllys 136099ebb4caSwyllys return (rv); 136199ebb4caSwyllys } 136299ebb4caSwyllys 136399ebb4caSwyllys KMF_RETURN 136499ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 136599ebb4caSwyllys KMF_DATA *keydata) 136699ebb4caSwyllys { 136799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 136899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 136999ebb4caSwyllys int n; 137099ebb4caSwyllys 137199ebb4caSwyllys if (key == NULL || keydata == NULL || 137299ebb4caSwyllys key->keyp == NULL) 137399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 137499ebb4caSwyllys 137599ebb4caSwyllys if (key->keyalg == KMF_RSA) { 137699ebb4caSwyllys RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp); 137799ebb4caSwyllys 137899ebb4caSwyllys if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) { 137999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 138099ebb4caSwyllys return (KMF_ERR_ENCODING); 138199ebb4caSwyllys } 138299ebb4caSwyllys RSA_free(pubkey); 138399ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 138499ebb4caSwyllys DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp); 138599ebb4caSwyllys 138699ebb4caSwyllys if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) { 138799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 138899ebb4caSwyllys return (KMF_ERR_ENCODING); 138999ebb4caSwyllys } 139099ebb4caSwyllys DSA_free(pubkey); 139199ebb4caSwyllys } else { 139299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 139399ebb4caSwyllys } 139499ebb4caSwyllys keydata->Length = n; 139599ebb4caSwyllys 139699ebb4caSwyllys cleanup: 139799ebb4caSwyllys if (rv != KMF_OK) { 139899ebb4caSwyllys if (keydata->Data) 139999ebb4caSwyllys free(keydata->Data); 140099ebb4caSwyllys keydata->Data = NULL; 140199ebb4caSwyllys keydata->Length = 0; 140299ebb4caSwyllys } 140399ebb4caSwyllys 140499ebb4caSwyllys return (rv); 140599ebb4caSwyllys } 140699ebb4caSwyllys 140799ebb4caSwyllys static KMF_RETURN 140830a5e8faSwyllys ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, 140930a5e8faSwyllys KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private) 141099ebb4caSwyllys { 141199ebb4caSwyllys int rv = 0; 141299ebb4caSwyllys RSA *rsa; 141399ebb4caSwyllys DSA *dsa; 141499ebb4caSwyllys 1415*5b3e1433Swyllys if (pkey == NULL || out == NULL) 1416*5b3e1433Swyllys return (KMF_ERR_BAD_PARAMETER); 1417*5b3e1433Swyllys 141899ebb4caSwyllys switch (format) { 141999ebb4caSwyllys case KMF_FORMAT_ASN1: 142099ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 142199ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 142230a5e8faSwyllys if (private) 142399ebb4caSwyllys rv = i2d_RSAPrivateKey_bio(out, rsa); 142430a5e8faSwyllys else 142530a5e8faSwyllys rv = i2d_RSAPublicKey_bio(out, rsa); 142699ebb4caSwyllys RSA_free(rsa); 142799ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 142899ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 142999ebb4caSwyllys rv = i2d_DSAPrivateKey_bio(out, dsa); 143099ebb4caSwyllys DSA_free(dsa); 143199ebb4caSwyllys } 143299ebb4caSwyllys if (rv == 1) { 143399ebb4caSwyllys rv = KMF_OK; 143499ebb4caSwyllys } else { 143599ebb4caSwyllys SET_ERROR(kmfh, rv); 143699ebb4caSwyllys } 143799ebb4caSwyllys break; 143899ebb4caSwyllys case KMF_FORMAT_PEM: 143999ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 144099ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 144130a5e8faSwyllys if (private) 144299ebb4caSwyllys rv = PEM_write_bio_RSAPrivateKey(out, 144330a5e8faSwyllys rsa, NULL, NULL, 0, NULL, 144430a5e8faSwyllys (cred != NULL ? cred->cred : NULL)); 144530a5e8faSwyllys else 144630a5e8faSwyllys rv = PEM_write_bio_RSAPublicKey(out, 144730a5e8faSwyllys rsa); 144899ebb4caSwyllys RSA_free(rsa); 144999ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 145099ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 145199ebb4caSwyllys rv = PEM_write_bio_DSAPrivateKey(out, 145230a5e8faSwyllys dsa, NULL, NULL, 0, NULL, 145330a5e8faSwyllys (cred != NULL ? cred->cred : NULL)); 145499ebb4caSwyllys DSA_free(dsa); 145599ebb4caSwyllys } 145699ebb4caSwyllys 145799ebb4caSwyllys if (rv == 1) { 145899ebb4caSwyllys rv = KMF_OK; 145999ebb4caSwyllys } else { 146099ebb4caSwyllys SET_ERROR(kmfh, rv); 146199ebb4caSwyllys } 146299ebb4caSwyllys break; 146399ebb4caSwyllys 146499ebb4caSwyllys default: 146599ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 146699ebb4caSwyllys } 146799ebb4caSwyllys 146899ebb4caSwyllys return (rv); 146999ebb4caSwyllys } 147099ebb4caSwyllys 147199ebb4caSwyllys KMF_RETURN 147230a5e8faSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, 147330a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 147499ebb4caSwyllys { 147599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 147699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 147799ebb4caSwyllys uint32_t eValue = 0x010001; 147899ebb4caSwyllys RSA *sslPrivKey = NULL; 147999ebb4caSwyllys DSA *sslDSAKey = NULL; 148099ebb4caSwyllys EVP_PKEY *eprikey = NULL; 148199ebb4caSwyllys EVP_PKEY *epubkey = NULL; 148299ebb4caSwyllys BIO *out = NULL; 148330a5e8faSwyllys KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL; 148430a5e8faSwyllys uint32_t keylen = 1024; 148530a5e8faSwyllys uint32_t keylen_size = sizeof (uint32_t); 148630a5e8faSwyllys boolean_t storekey = TRUE; 148730a5e8faSwyllys KMF_KEY_ALG keytype = KMF_RSA; 148899ebb4caSwyllys 148930a5e8faSwyllys rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr, 149030a5e8faSwyllys &storekey, NULL); 149130a5e8faSwyllys if (rv != KMF_OK) { 149230a5e8faSwyllys /* "storekey" is optional. Default is TRUE */ 149330a5e8faSwyllys rv = KMF_OK; 149499ebb4caSwyllys } 149599ebb4caSwyllys 149630a5e8faSwyllys rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 149730a5e8faSwyllys (void *)&keytype, NULL); 149830a5e8faSwyllys if (rv != KMF_OK) 149930a5e8faSwyllys /* keytype is optional. KMF_RSA is default */ 150030a5e8faSwyllys rv = KMF_OK; 150199ebb4caSwyllys 150230a5e8faSwyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); 150330a5e8faSwyllys if (pubkey == NULL) 150499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 150599ebb4caSwyllys 150630a5e8faSwyllys privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); 150730a5e8faSwyllys if (privkey == NULL) 150830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 150930a5e8faSwyllys 151030a5e8faSwyllys (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); 151130a5e8faSwyllys (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); 151299ebb4caSwyllys 151399ebb4caSwyllys eprikey = EVP_PKEY_new(); 151499ebb4caSwyllys if (eprikey == NULL) { 151599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 151699ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 151799ebb4caSwyllys goto cleanup; 151899ebb4caSwyllys } 151999ebb4caSwyllys epubkey = EVP_PKEY_new(); 152099ebb4caSwyllys if (epubkey == NULL) { 152199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 152299ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 152399ebb4caSwyllys goto cleanup; 152499ebb4caSwyllys } 152530a5e8faSwyllys if (keytype == KMF_RSA) { 152630a5e8faSwyllys KMF_BIGINT *rsaexp = NULL; 152799ebb4caSwyllys 152830a5e8faSwyllys rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr); 152930a5e8faSwyllys if (rsaexp != NULL) { 153030a5e8faSwyllys if (rsaexp->len > 0 && 153130a5e8faSwyllys rsaexp->len <= sizeof (eValue) && 153230a5e8faSwyllys rsaexp->val != NULL) { 153330a5e8faSwyllys /*LINTED*/ 153430a5e8faSwyllys eValue = *(uint32_t *)rsaexp->val; 153530a5e8faSwyllys } else { 153630a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 153730a5e8faSwyllys goto cleanup; 153830a5e8faSwyllys } 153930a5e8faSwyllys } else { 154030a5e8faSwyllys /* RSA Exponent is optional. Default is 0x10001 */ 154130a5e8faSwyllys rv = KMF_OK; 154230a5e8faSwyllys } 154330a5e8faSwyllys 154430a5e8faSwyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 154530a5e8faSwyllys &keylen, &keylen_size); 154630a5e8faSwyllys if (rv == KMF_ERR_ATTR_NOT_FOUND) 154730a5e8faSwyllys /* keylen is optional, default is 1024 */ 154830a5e8faSwyllys rv = KMF_OK; 154930a5e8faSwyllys if (rv != KMF_OK) { 155030a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 155130a5e8faSwyllys goto cleanup; 155230a5e8faSwyllys } 155330a5e8faSwyllys 155430a5e8faSwyllys sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL); 155599ebb4caSwyllys if (sslPrivKey == NULL) { 155699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 155799ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 155899ebb4caSwyllys } else { 155930a5e8faSwyllys (void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey); 156099ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 156199ebb4caSwyllys privkey->keyalg = KMF_RSA; 156299ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 156399ebb4caSwyllys privkey->israw = FALSE; 156499ebb4caSwyllys privkey->keyp = (void *)eprikey; 156530a5e8faSwyllys 156699ebb4caSwyllys /* OpenSSL derives the public key from the private */ 156730a5e8faSwyllys (void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey); 156899ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 156999ebb4caSwyllys pubkey->keyalg = KMF_RSA; 157099ebb4caSwyllys pubkey->israw = FALSE; 157199ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 157299ebb4caSwyllys pubkey->keyp = (void *)epubkey; 157399ebb4caSwyllys } 157430a5e8faSwyllys } else if (keytype == KMF_DSA) { 157530a5e8faSwyllys DSA *dp; 157699ebb4caSwyllys sslDSAKey = DSA_new(); 157799ebb4caSwyllys if (sslDSAKey == NULL) { 157899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 157999ebb4caSwyllys return (KMF_ERR_MEMORY); 158099ebb4caSwyllys } 158199ebb4caSwyllys 158299ebb4caSwyllys if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) == 158399ebb4caSwyllys NULL) { 158499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 158599ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 158699ebb4caSwyllys goto cleanup; 158799ebb4caSwyllys } 158899ebb4caSwyllys if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) == 158999ebb4caSwyllys NULL) { 159099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 159199ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 159299ebb4caSwyllys goto cleanup; 159399ebb4caSwyllys } 159499ebb4caSwyllys if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) == 159599ebb4caSwyllys NULL) { 159699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 159799ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 159899ebb4caSwyllys goto cleanup; 159999ebb4caSwyllys } 160099ebb4caSwyllys 160199ebb4caSwyllys if (!DSA_generate_key(sslDSAKey)) { 160299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 160399ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 160499ebb4caSwyllys goto cleanup; 160599ebb4caSwyllys } 160699ebb4caSwyllys 160799ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 160899ebb4caSwyllys privkey->keyalg = KMF_DSA; 160999ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 161099ebb4caSwyllys privkey->israw = FALSE; 161199ebb4caSwyllys if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { 161299ebb4caSwyllys privkey->keyp = (void *)eprikey; 161399ebb4caSwyllys } else { 161499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 161599ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 161699ebb4caSwyllys goto cleanup; 161799ebb4caSwyllys } 161830a5e8faSwyllys dp = DSA_new(); 161999ebb4caSwyllys /* Make a copy for the public key */ 162099ebb4caSwyllys if (dp != NULL) { 162199ebb4caSwyllys if ((dp->p = BN_new()) == NULL) { 162299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 162399ebb4caSwyllys rv = KMF_ERR_MEMORY; 162499ebb4caSwyllys DSA_free(dp); 162599ebb4caSwyllys goto cleanup; 162699ebb4caSwyllys } 162799ebb4caSwyllys if ((dp->q = BN_new()) == NULL) { 162899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 162999ebb4caSwyllys rv = KMF_ERR_MEMORY; 163099ebb4caSwyllys BN_free(dp->p); 163199ebb4caSwyllys DSA_free(dp); 163299ebb4caSwyllys goto cleanup; 163399ebb4caSwyllys } 163499ebb4caSwyllys if ((dp->g = BN_new()) == NULL) { 163599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 163699ebb4caSwyllys rv = KMF_ERR_MEMORY; 163799ebb4caSwyllys BN_free(dp->q); 163899ebb4caSwyllys BN_free(dp->p); 163999ebb4caSwyllys DSA_free(dp); 164099ebb4caSwyllys goto cleanup; 164199ebb4caSwyllys } 164299ebb4caSwyllys if ((dp->pub_key = BN_new()) == NULL) { 164399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 164499ebb4caSwyllys rv = KMF_ERR_MEMORY; 164599ebb4caSwyllys BN_free(dp->q); 164699ebb4caSwyllys BN_free(dp->p); 164799ebb4caSwyllys BN_free(dp->g); 164899ebb4caSwyllys DSA_free(dp); 164999ebb4caSwyllys goto cleanup; 165099ebb4caSwyllys } 165199ebb4caSwyllys (void) BN_copy(dp->p, sslDSAKey->p); 165299ebb4caSwyllys (void) BN_copy(dp->q, sslDSAKey->q); 165399ebb4caSwyllys (void) BN_copy(dp->g, sslDSAKey->g); 165499ebb4caSwyllys (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); 165599ebb4caSwyllys 165699ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 165799ebb4caSwyllys pubkey->keyalg = KMF_DSA; 165899ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 165999ebb4caSwyllys pubkey->israw = FALSE; 166099ebb4caSwyllys 166199ebb4caSwyllys if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { 166299ebb4caSwyllys pubkey->keyp = (void *)epubkey; 166399ebb4caSwyllys } else { 166499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 166599ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 166699ebb4caSwyllys goto cleanup; 166799ebb4caSwyllys } 166899ebb4caSwyllys } 166999ebb4caSwyllys } 167099ebb4caSwyllys 167199ebb4caSwyllys if (rv != KMF_OK) { 167299ebb4caSwyllys goto cleanup; 167399ebb4caSwyllys } 167499ebb4caSwyllys 167530a5e8faSwyllys if (storekey) { 167630a5e8faSwyllys KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */ 167730a5e8faSwyllys int i = 0; 167830a5e8faSwyllys char *keyfile = NULL, *dirpath = NULL; 167930a5e8faSwyllys KMF_ENCODE_FORMAT format; 168030a5e8faSwyllys /* 168130a5e8faSwyllys * Construct a new attribute arrray and call openssl_store_key 168230a5e8faSwyllys */ 168330a5e8faSwyllys kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR, 168430a5e8faSwyllys privkey, sizeof (privkey)); 168530a5e8faSwyllys i++; 168630a5e8faSwyllys 168730a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 168830a5e8faSwyllys if (dirpath != NULL) { 168930a5e8faSwyllys storeattrs[i].type = KMF_DIRPATH_ATTR; 169030a5e8faSwyllys storeattrs[i].pValue = dirpath; 169130a5e8faSwyllys storeattrs[i].valueLen = strlen(dirpath); 169230a5e8faSwyllys i++; 169330a5e8faSwyllys } else { 169430a5e8faSwyllys rv = KMF_OK; /* DIRPATH is optional */ 169599ebb4caSwyllys } 169630a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, 169730a5e8faSwyllys attrlist, numattr); 169830a5e8faSwyllys if (keyfile != NULL) { 169930a5e8faSwyllys storeattrs[i].type = KMF_KEY_FILENAME_ATTR; 170030a5e8faSwyllys storeattrs[i].pValue = keyfile; 170130a5e8faSwyllys storeattrs[i].valueLen = strlen(keyfile); 170230a5e8faSwyllys i++; 170330a5e8faSwyllys } else { 170430a5e8faSwyllys goto cleanup; /* KEYFILE is required */ 170530a5e8faSwyllys } 170630a5e8faSwyllys rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 170730a5e8faSwyllys (void *)&format, NULL); 170830a5e8faSwyllys if (rv == KMF_OK) { 170930a5e8faSwyllys storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR; 171030a5e8faSwyllys storeattrs[i].pValue = &format; 171130a5e8faSwyllys storeattrs[i].valueLen = sizeof (format); 171230a5e8faSwyllys i++; 171330a5e8faSwyllys } 171430a5e8faSwyllys 171530a5e8faSwyllys rv = OpenSSL_StoreKey(handle, i, storeattrs); 171630a5e8faSwyllys } 171799ebb4caSwyllys 171899ebb4caSwyllys cleanup: 171999ebb4caSwyllys if (rv != KMF_OK) { 172099ebb4caSwyllys if (eprikey != NULL) 172199ebb4caSwyllys EVP_PKEY_free(eprikey); 172299ebb4caSwyllys 172399ebb4caSwyllys if (epubkey != NULL) 172499ebb4caSwyllys EVP_PKEY_free(epubkey); 172599ebb4caSwyllys 172699ebb4caSwyllys if (pubkey->keylabel) { 172799ebb4caSwyllys free(pubkey->keylabel); 172899ebb4caSwyllys pubkey->keylabel = NULL; 172999ebb4caSwyllys } 173099ebb4caSwyllys 173199ebb4caSwyllys if (privkey->keylabel) { 173299ebb4caSwyllys free(privkey->keylabel); 173399ebb4caSwyllys privkey->keylabel = NULL; 173499ebb4caSwyllys } 173599ebb4caSwyllys 173699ebb4caSwyllys pubkey->keyp = NULL; 173799ebb4caSwyllys privkey->keyp = NULL; 173899ebb4caSwyllys } 173999ebb4caSwyllys 174099ebb4caSwyllys if (sslPrivKey) 174199ebb4caSwyllys RSA_free(sslPrivKey); 174299ebb4caSwyllys 174399ebb4caSwyllys if (sslDSAKey) 174499ebb4caSwyllys DSA_free(sslDSAKey); 174599ebb4caSwyllys 174699ebb4caSwyllys if (out != NULL) 174799ebb4caSwyllys (void) BIO_free(out); 174899ebb4caSwyllys 174999ebb4caSwyllys return (rv); 175099ebb4caSwyllys } 175199ebb4caSwyllys 175299ebb4caSwyllys KMF_RETURN 175399ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 175499ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output) 175599ebb4caSwyllys { 175699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 175799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 175899ebb4caSwyllys KMF_ALGORITHM_INDEX AlgId; 175999ebb4caSwyllys EVP_MD_CTX ctx; 176099ebb4caSwyllys const EVP_MD *md; 176102744e81Swyllys 176299ebb4caSwyllys if (key == NULL || AlgOID == NULL || 176399ebb4caSwyllys tobesigned == NULL || output == NULL || 176499ebb4caSwyllys tobesigned->Data == NULL || 176599ebb4caSwyllys output->Data == NULL) 176699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 176799ebb4caSwyllys 176899ebb4caSwyllys /* Map the OID to an OpenSSL algorithm */ 176930a5e8faSwyllys AlgId = x509_algoid_to_algid(AlgOID); 177099ebb4caSwyllys if (AlgId == KMF_ALGID_NONE) 177199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 177299ebb4caSwyllys 177399ebb4caSwyllys if (key->keyalg == KMF_RSA) { 177499ebb4caSwyllys EVP_PKEY *pkey = (EVP_PKEY *)key->keyp; 177599ebb4caSwyllys uchar_t *p; 177602744e81Swyllys int len; 177799ebb4caSwyllys if (AlgId == KMF_ALGID_MD5WithRSA) 177899ebb4caSwyllys md = EVP_md5(); 177999ebb4caSwyllys else if (AlgId == KMF_ALGID_MD2WithRSA) 178099ebb4caSwyllys md = EVP_md2(); 178199ebb4caSwyllys else if (AlgId == KMF_ALGID_SHA1WithRSA) 178299ebb4caSwyllys md = EVP_sha1(); 178302744e81Swyllys else if (AlgId == KMF_ALGID_RSA) 178402744e81Swyllys md = NULL; 178599ebb4caSwyllys else 178699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 178799ebb4caSwyllys 178802744e81Swyllys if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) { 178902744e81Swyllys RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey); 179099ebb4caSwyllys 179102744e81Swyllys p = output->Data; 179202744e81Swyllys if ((len = RSA_private_encrypt(tobesigned->Length, 179302744e81Swyllys tobesigned->Data, p, rsa, 179402744e81Swyllys RSA_PKCS1_PADDING)) <= 0) { 179502744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 179602744e81Swyllys ret = KMF_ERR_INTERNAL; 179702744e81Swyllys } 179802744e81Swyllys output->Length = len; 179902744e81Swyllys } else { 180099ebb4caSwyllys (void) EVP_MD_CTX_init(&ctx); 180199ebb4caSwyllys (void) EVP_SignInit_ex(&ctx, md, NULL); 180299ebb4caSwyllys (void) EVP_SignUpdate(&ctx, tobesigned->Data, 180399ebb4caSwyllys (uint32_t)tobesigned->Length); 180499ebb4caSwyllys len = (uint32_t)output->Length; 180599ebb4caSwyllys p = output->Data; 180602744e81Swyllys if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) { 180799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 180802744e81Swyllys len = 0; 180902744e81Swyllys ret = KMF_ERR_INTERNAL; 181099ebb4caSwyllys } 181199ebb4caSwyllys output->Length = len; 181299ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 181302744e81Swyllys } 181499ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 181599ebb4caSwyllys DSA *dsa = EVP_PKEY_get1_DSA(key->keyp); 181699ebb4caSwyllys 181799ebb4caSwyllys uchar_t hash[EVP_MAX_MD_SIZE]; 181899ebb4caSwyllys uint32_t hashlen; 181999ebb4caSwyllys DSA_SIG *dsasig; 182099ebb4caSwyllys 182199ebb4caSwyllys /* 182299ebb4caSwyllys * OpenSSL EVP_Sign operation automatically converts to 182399ebb4caSwyllys * ASN.1 output so we do the operations separately so we 182499ebb4caSwyllys * are assured of NOT getting ASN.1 output returned. 182599ebb4caSwyllys * KMF does not want ASN.1 encoded results because 182699ebb4caSwyllys * not all mechanisms return ASN.1 encodings (PKCS#11 182799ebb4caSwyllys * and NSS return raw signature data). 182899ebb4caSwyllys */ 182999ebb4caSwyllys md = EVP_sha1(); 183099ebb4caSwyllys EVP_MD_CTX_init(&ctx); 183199ebb4caSwyllys (void) EVP_DigestInit_ex(&ctx, md, NULL); 183299ebb4caSwyllys (void) EVP_DigestUpdate(&ctx, tobesigned->Data, 183399ebb4caSwyllys tobesigned->Length); 183499ebb4caSwyllys (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen); 183599ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 183699ebb4caSwyllys 183799ebb4caSwyllys dsasig = DSA_do_sign(hash, hashlen, dsa); 183899ebb4caSwyllys if (dsasig != NULL) { 183999ebb4caSwyllys int i; 184099ebb4caSwyllys output->Length = i = BN_bn2bin(dsasig->r, output->Data); 184199ebb4caSwyllys output->Length += BN_bn2bin(dsasig->s, 184299ebb4caSwyllys &output->Data[i]); 184399ebb4caSwyllys DSA_SIG_free(dsasig); 184499ebb4caSwyllys } else { 184599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 184699ebb4caSwyllys } 184799ebb4caSwyllys } else { 184899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 184999ebb4caSwyllys } 185099ebb4caSwyllys cleanup: 185199ebb4caSwyllys return (ret); 185299ebb4caSwyllys } 185399ebb4caSwyllys 185499ebb4caSwyllys KMF_RETURN 185599ebb4caSwyllys /*ARGSUSED*/ 185630a5e8faSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T handle, 185730a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 185899ebb4caSwyllys { 185999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 186030a5e8faSwyllys KMF_KEY_HANDLE *key; 186130a5e8faSwyllys boolean_t destroy = B_TRUE; 186230a5e8faSwyllys 186330a5e8faSwyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 186499ebb4caSwyllys if (key == NULL || key->keyp == NULL) 186599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 186699ebb4caSwyllys 186730a5e8faSwyllys rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, 186830a5e8faSwyllys (void *)&destroy, NULL); 186930a5e8faSwyllys if (rv != KMF_OK) { 187030a5e8faSwyllys /* "destroy" is optional. Default is TRUE */ 187130a5e8faSwyllys rv = KMF_OK; 187230a5e8faSwyllys } 187330a5e8faSwyllys 187499ebb4caSwyllys if (key->keyclass != KMF_ASYM_PUB && 187599ebb4caSwyllys key->keyclass != KMF_ASYM_PRI && 187699ebb4caSwyllys key->keyclass != KMF_SYMMETRIC) 187799ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 187899ebb4caSwyllys 187999ebb4caSwyllys if (key->keyclass == KMF_SYMMETRIC) { 188030a5e8faSwyllys kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp); 188199ebb4caSwyllys key->keyp = NULL; 188299ebb4caSwyllys } else { 188399ebb4caSwyllys if (key->keyp != NULL) { 188499ebb4caSwyllys EVP_PKEY_free(key->keyp); 188599ebb4caSwyllys key->keyp = NULL; 188699ebb4caSwyllys } 188799ebb4caSwyllys } 188899ebb4caSwyllys 188999ebb4caSwyllys if (key->keylabel != NULL) { 189099ebb4caSwyllys EVP_PKEY *pkey = NULL; 189199ebb4caSwyllys /* If the file exists, make sure it is a proper key. */ 189299ebb4caSwyllys pkey = openssl_load_key(handle, key->keylabel); 189399ebb4caSwyllys if (pkey == NULL) { 1894*5b3e1433Swyllys if (key->keylabel != NULL) { 189599ebb4caSwyllys free(key->keylabel); 189699ebb4caSwyllys key->keylabel = NULL; 1897*5b3e1433Swyllys } 189899ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 189999ebb4caSwyllys } 190099ebb4caSwyllys EVP_PKEY_free(pkey); 190199ebb4caSwyllys 190299ebb4caSwyllys if (destroy) { 190399ebb4caSwyllys if (unlink(key->keylabel) != 0) { 190499ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 190599ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 190699ebb4caSwyllys rv = KMF_ERR_INTERNAL; 190799ebb4caSwyllys } 190899ebb4caSwyllys } 190999ebb4caSwyllys if (key->keylabel != NULL) { 191099ebb4caSwyllys free(key->keylabel); 191199ebb4caSwyllys key->keylabel = NULL; 191299ebb4caSwyllys } 191399ebb4caSwyllys } 191499ebb4caSwyllys return (rv); 191599ebb4caSwyllys } 191699ebb4caSwyllys 191799ebb4caSwyllys KMF_RETURN 191899ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 191999ebb4caSwyllys { 192099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 192199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 192299ebb4caSwyllys char str[256]; /* OpenSSL needs at least 120 byte buffer */ 192399ebb4caSwyllys 192499ebb4caSwyllys ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str)); 192599ebb4caSwyllys if (strlen(str)) { 192699ebb4caSwyllys *msgstr = (char *)strdup(str); 192799ebb4caSwyllys if ((*msgstr) == NULL) 192899ebb4caSwyllys ret = KMF_ERR_MEMORY; 192999ebb4caSwyllys } else { 193099ebb4caSwyllys *msgstr = NULL; 193199ebb4caSwyllys } 193299ebb4caSwyllys 193399ebb4caSwyllys return (ret); 193499ebb4caSwyllys } 193599ebb4caSwyllys 193699ebb4caSwyllys static int 193799ebb4caSwyllys ext2NID(int kmfext) 193899ebb4caSwyllys { 193999ebb4caSwyllys switch (kmfext) { 194099ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 194199ebb4caSwyllys return (NID_key_usage); 194299ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 194399ebb4caSwyllys return (NID_private_key_usage_period); 194499ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 194599ebb4caSwyllys return (NID_certificate_policies); 194699ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 194799ebb4caSwyllys return (NID_subject_alt_name); 194899ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 194999ebb4caSwyllys return (NID_issuer_alt_name); 195099ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 195199ebb4caSwyllys return (NID_basic_constraints); 195299ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 195399ebb4caSwyllys return (NID_ext_key_usage); 195499ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 195599ebb4caSwyllys return (NID_authority_key_identifier); 195699ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 195799ebb4caSwyllys return (NID_crl_distribution_points); 195899ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 195999ebb4caSwyllys return (NID_subject_key_identifier); 196099ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 196199ebb4caSwyllys return (OBJ_sn2nid("policyMappings")); 196299ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 196399ebb4caSwyllys return (OBJ_sn2nid("nameConstraints")); 196499ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 196599ebb4caSwyllys return (OBJ_sn2nid("policyConstraints")); 196699ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 196799ebb4caSwyllys return (OBJ_sn2nid("inhibitAnyPolicy")); 196899ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 196999ebb4caSwyllys return (OBJ_sn2nid("freshestCRL")); 197099ebb4caSwyllys default: 197199ebb4caSwyllys return (NID_undef); 197299ebb4caSwyllys } 197399ebb4caSwyllys } 197499ebb4caSwyllys 197599ebb4caSwyllys KMF_RETURN 197699ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, 197799ebb4caSwyllys KMF_PRINTABLE_ITEM flag, char *resultStr) 197899ebb4caSwyllys { 197999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 198099ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 198199ebb4caSwyllys X509 *xcert = NULL; 198299ebb4caSwyllys unsigned char *outbuf = NULL; 198399ebb4caSwyllys unsigned char *outbuf_p; 198499ebb4caSwyllys char *tmpstr = NULL; 198599ebb4caSwyllys int j; 198699ebb4caSwyllys int ext_index, nid, len; 198799ebb4caSwyllys BIO *mem = NULL; 198899ebb4caSwyllys STACK *emlst = NULL; 198999ebb4caSwyllys X509_EXTENSION *ex; 199099ebb4caSwyllys X509_CINF *ci; 199199ebb4caSwyllys 199299ebb4caSwyllys if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) { 199399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 199499ebb4caSwyllys } 199599ebb4caSwyllys 199699ebb4caSwyllys /* copy cert data to outbuf */ 199799ebb4caSwyllys outbuf = malloc(pcert->Length); 199899ebb4caSwyllys if (outbuf == NULL) { 199999ebb4caSwyllys return (KMF_ERR_MEMORY); 200099ebb4caSwyllys } 200199ebb4caSwyllys (void) memcpy(outbuf, pcert->Data, pcert->Length); 200299ebb4caSwyllys 200399ebb4caSwyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 200499ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length); 200599ebb4caSwyllys if (xcert == NULL) { 200699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 200799ebb4caSwyllys ret = KMF_ERR_ENCODING; 200899ebb4caSwyllys goto out; 200999ebb4caSwyllys } 201099ebb4caSwyllys 201199ebb4caSwyllys mem = BIO_new(BIO_s_mem()); 201299ebb4caSwyllys if (mem == NULL) { 201399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 201499ebb4caSwyllys ret = KMF_ERR_MEMORY; 201599ebb4caSwyllys goto out; 201699ebb4caSwyllys } 201799ebb4caSwyllys 201899ebb4caSwyllys switch (flag) { 201999ebb4caSwyllys case KMF_CERT_ISSUER: 202099ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0, 202199ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 202299ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 202399ebb4caSwyllys break; 202499ebb4caSwyllys 202599ebb4caSwyllys case KMF_CERT_SUBJECT: 202699ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0, 202799ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 202899ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 202999ebb4caSwyllys break; 203099ebb4caSwyllys 203199ebb4caSwyllys case KMF_CERT_VERSION: 203299ebb4caSwyllys tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version); 203399ebb4caSwyllys (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN); 203499ebb4caSwyllys OPENSSL_free(tmpstr); 203599ebb4caSwyllys len = strlen(resultStr); 203699ebb4caSwyllys break; 203799ebb4caSwyllys 203899ebb4caSwyllys case KMF_CERT_SERIALNUM: 203999ebb4caSwyllys if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) { 204099ebb4caSwyllys (void) strcpy(resultStr, "0x"); 204199ebb4caSwyllys len = BIO_gets(mem, &resultStr[2], 204299ebb4caSwyllys KMF_CERT_PRINTABLE_LEN - 2); 204399ebb4caSwyllys } 204499ebb4caSwyllys break; 204599ebb4caSwyllys 204699ebb4caSwyllys case KMF_CERT_NOTBEFORE: 204799ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert)); 204899ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 204999ebb4caSwyllys break; 205099ebb4caSwyllys 205199ebb4caSwyllys case KMF_CERT_NOTAFTER: 205299ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert)); 205399ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 205499ebb4caSwyllys break; 205599ebb4caSwyllys 205699ebb4caSwyllys case KMF_CERT_PUBKEY_DATA: 205799ebb4caSwyllys { 205899ebb4caSwyllys EVP_PKEY *pkey = X509_get_pubkey(xcert); 205999ebb4caSwyllys if (pkey == NULL) { 206099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 206199ebb4caSwyllys ret = KMF_ERR_ENCODING; 206299ebb4caSwyllys goto out; 206399ebb4caSwyllys } 206499ebb4caSwyllys 206599ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 206699ebb4caSwyllys (void) BIO_printf(mem, 206799ebb4caSwyllys "RSA Public Key: (%d bit)\n", 206899ebb4caSwyllys BN_num_bits(pkey->pkey.rsa->n)); 206999ebb4caSwyllys (void) RSA_print(mem, pkey->pkey.rsa, 0); 207099ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 207199ebb4caSwyllys (void) BIO_printf(mem, 207299ebb4caSwyllys "%12sDSA Public Key:\n", ""); 207399ebb4caSwyllys (void) DSA_print(mem, pkey->pkey.dsa, 0); 207499ebb4caSwyllys } else { 207599ebb4caSwyllys (void) BIO_printf(mem, 207699ebb4caSwyllys "%12sUnknown Public Key:\n", ""); 207799ebb4caSwyllys } 207899ebb4caSwyllys (void) BIO_printf(mem, "\n"); 207999ebb4caSwyllys EVP_PKEY_free(pkey); 208099ebb4caSwyllys } 208199ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 208299ebb4caSwyllys break; 208399ebb4caSwyllys case KMF_CERT_SIGNATURE_ALG: 208499ebb4caSwyllys case KMF_CERT_PUBKEY_ALG: 208599ebb4caSwyllys if (flag == KMF_CERT_SIGNATURE_ALG) { 208699ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 208799ebb4caSwyllys xcert->sig_alg->algorithm); 208899ebb4caSwyllys } else { 208999ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 209099ebb4caSwyllys xcert->cert_info->key->algor->algorithm); 209199ebb4caSwyllys } 209299ebb4caSwyllys 209399ebb4caSwyllys if (len > 0) { 209499ebb4caSwyllys len = BIO_read(mem, resultStr, 209599ebb4caSwyllys KMF_CERT_PRINTABLE_LEN); 209699ebb4caSwyllys } 209799ebb4caSwyllys break; 209899ebb4caSwyllys 209999ebb4caSwyllys case KMF_CERT_EMAIL: 210099ebb4caSwyllys emlst = X509_get1_email(xcert); 210199ebb4caSwyllys for (j = 0; j < sk_num(emlst); j++) 210299ebb4caSwyllys (void) BIO_printf(mem, "%s\n", sk_value(emlst, j)); 210399ebb4caSwyllys 210499ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 210599ebb4caSwyllys X509_email_free(emlst); 210699ebb4caSwyllys break; 210799ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 210899ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 210999ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 211099ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 211199ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 211299ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 211399ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 211499ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 211599ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 211699ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 211799ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 211899ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 211999ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 212099ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 212199ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 212299ebb4caSwyllys nid = ext2NID(flag); 212399ebb4caSwyllys if (nid == NID_undef) { 212499ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 212599ebb4caSwyllys goto out; 212699ebb4caSwyllys } 212799ebb4caSwyllys ci = xcert->cert_info; 212899ebb4caSwyllys 212999ebb4caSwyllys ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1); 213099ebb4caSwyllys if (ext_index == -1) { 213199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 213299ebb4caSwyllys 213399ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 213499ebb4caSwyllys goto out; 213599ebb4caSwyllys } 213699ebb4caSwyllys ex = X509v3_get_ext(ci->extensions, ext_index); 213799ebb4caSwyllys 213899ebb4caSwyllys (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); 213999ebb4caSwyllys 214099ebb4caSwyllys if (BIO_printf(mem, ": %s\n", 214130a5e8faSwyllys X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) { 214299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 214399ebb4caSwyllys ret = KMF_ERR_ENCODING; 214499ebb4caSwyllys goto out; 214599ebb4caSwyllys } 214699ebb4caSwyllys if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) { 214799ebb4caSwyllys (void) BIO_printf(mem, "%*s", 4, ""); 214899ebb4caSwyllys (void) M_ASN1_OCTET_STRING_print(mem, ex->value); 214999ebb4caSwyllys } 215099ebb4caSwyllys if (BIO_write(mem, "\n", 1) <= 0) { 215199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 215299ebb4caSwyllys ret = KMF_ERR_ENCODING; 215399ebb4caSwyllys goto out; 215499ebb4caSwyllys } 215599ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 215699ebb4caSwyllys } 215799ebb4caSwyllys if (len <= 0) { 215899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 215999ebb4caSwyllys ret = KMF_ERR_ENCODING; 216099ebb4caSwyllys } 216199ebb4caSwyllys 216299ebb4caSwyllys out: 216399ebb4caSwyllys if (outbuf != NULL) { 216499ebb4caSwyllys free(outbuf); 216599ebb4caSwyllys } 216699ebb4caSwyllys 216799ebb4caSwyllys if (xcert != NULL) { 216899ebb4caSwyllys X509_free(xcert); 216999ebb4caSwyllys } 217099ebb4caSwyllys 217199ebb4caSwyllys if (mem != NULL) { 217299ebb4caSwyllys (void) BIO_free(mem); 217399ebb4caSwyllys } 217499ebb4caSwyllys 217599ebb4caSwyllys return (ret); 217699ebb4caSwyllys } 217730a5e8faSwyllys 217899ebb4caSwyllys KMF_RETURN 217999ebb4caSwyllys /*ARGSUSED*/ 218030a5e8faSwyllys OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, 218130a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 218299ebb4caSwyllys { 218399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 218430a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 218530a5e8faSwyllys KMF_KEY_CLASS keyclass = KMF_ASYM_PRI; 218630a5e8faSwyllys KMF_KEY_HANDLE *key = NULL; 218730a5e8faSwyllys uint32_t numkeys = 1; /* 1 key only */ 218830a5e8faSwyllys char *dirpath = NULL; 218930a5e8faSwyllys char *keyfile = NULL; 219030a5e8faSwyllys KMF_ATTRIBUTE new_attrlist[16]; 219130a5e8faSwyllys int i = 0; 219299ebb4caSwyllys 219399ebb4caSwyllys /* 219499ebb4caSwyllys * This is really just a FindKey operation, reuse the 219599ebb4caSwyllys * FindKey function. 219699ebb4caSwyllys */ 219730a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 219830a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 219930a5e8faSwyllys i++; 220099ebb4caSwyllys 220130a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 220230a5e8faSwyllys KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t)); 220330a5e8faSwyllys i++; 220499ebb4caSwyllys 220530a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 220630a5e8faSwyllys KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); 220730a5e8faSwyllys i++; 220830a5e8faSwyllys 220930a5e8faSwyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 221030a5e8faSwyllys if (key == NULL) { 221130a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 221230a5e8faSwyllys } else { 221330a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 221430a5e8faSwyllys KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); 221530a5e8faSwyllys i++; 221630a5e8faSwyllys } 221730a5e8faSwyllys 221830a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 221930a5e8faSwyllys if (dirpath != NULL) { 222030a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 222130a5e8faSwyllys KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); 222230a5e8faSwyllys i++; 222330a5e8faSwyllys } 222430a5e8faSwyllys 222530a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 222630a5e8faSwyllys if (keyfile == NULL) 222730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 222830a5e8faSwyllys else { 222930a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 223030a5e8faSwyllys KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); 223130a5e8faSwyllys i++; 223230a5e8faSwyllys } 223330a5e8faSwyllys 223430a5e8faSwyllys rv = OpenSSL_FindKey(handle, i, new_attrlist); 223599ebb4caSwyllys return (rv); 223699ebb4caSwyllys } 223799ebb4caSwyllys 223899ebb4caSwyllys KMF_RETURN 223999ebb4caSwyllys /*ARGSUSED*/ 224099ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 224199ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *ciphertext, 224299ebb4caSwyllys KMF_DATA *output) 224399ebb4caSwyllys { 224499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 224599ebb4caSwyllys RSA *rsa = NULL; 224699ebb4caSwyllys unsigned int in_len = 0, out_len = 0; 224799ebb4caSwyllys unsigned int total_decrypted = 0, modulus_len = 0; 224899ebb4caSwyllys uint8_t *in_data, *out_data; 224999ebb4caSwyllys int i, blocks; 225099ebb4caSwyllys 225199ebb4caSwyllys if (key == NULL || AlgOID == NULL || 225299ebb4caSwyllys ciphertext == NULL || output == NULL || 225399ebb4caSwyllys ciphertext->Data == NULL || 225499ebb4caSwyllys output->Data == NULL) 225599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 225699ebb4caSwyllys 225799ebb4caSwyllys if (key->keyalg == KMF_RSA) { 225899ebb4caSwyllys rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp); 225999ebb4caSwyllys modulus_len = RSA_size(rsa); 226099ebb4caSwyllys } else { 226199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 226299ebb4caSwyllys } 226399ebb4caSwyllys 226499ebb4caSwyllys blocks = ciphertext->Length/modulus_len; 226599ebb4caSwyllys out_data = output->Data; 226699ebb4caSwyllys in_data = ciphertext->Data; 226799ebb4caSwyllys out_len = modulus_len - 11; 226899ebb4caSwyllys in_len = modulus_len; 226999ebb4caSwyllys 227099ebb4caSwyllys for (i = 0; i < blocks; i++) { 227199ebb4caSwyllys out_len = RSA_private_decrypt(in_len, 227299ebb4caSwyllys in_data, out_data, rsa, RSA_PKCS1_PADDING); 227399ebb4caSwyllys 227499ebb4caSwyllys if (out_len == 0) { 227599ebb4caSwyllys ret = KMF_ERR_INTERNAL; 227699ebb4caSwyllys goto cleanup; 227799ebb4caSwyllys } 227899ebb4caSwyllys 227999ebb4caSwyllys out_data += out_len; 228099ebb4caSwyllys total_decrypted += out_len; 228199ebb4caSwyllys in_data += in_len; 228299ebb4caSwyllys } 228399ebb4caSwyllys 228499ebb4caSwyllys output->Length = total_decrypted; 228599ebb4caSwyllys 228699ebb4caSwyllys cleanup: 228799ebb4caSwyllys RSA_free(rsa); 228899ebb4caSwyllys if (ret != KMF_OK) 228999ebb4caSwyllys output->Length = 0; 229099ebb4caSwyllys 229199ebb4caSwyllys return (ret); 229299ebb4caSwyllys 229399ebb4caSwyllys } 229499ebb4caSwyllys 229599ebb4caSwyllys /* 229699ebb4caSwyllys * This function will create a certid from issuer_cert and user_cert. 229799ebb4caSwyllys * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate 229899ebb4caSwyllys * certid memory after use. 229999ebb4caSwyllys */ 230099ebb4caSwyllys static KMF_RETURN 230199ebb4caSwyllys create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert, 230299ebb4caSwyllys const KMF_DATA *user_cert, OCSP_CERTID **certid) 230399ebb4caSwyllys { 230499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 230599ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 230699ebb4caSwyllys X509 *issuer = NULL; 230799ebb4caSwyllys X509 *cert = NULL; 230899ebb4caSwyllys unsigned char *ptmp; 230999ebb4caSwyllys 231099ebb4caSwyllys if (issuer_cert == NULL || user_cert == NULL) { 231199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 231299ebb4caSwyllys } 231399ebb4caSwyllys 231499ebb4caSwyllys /* convert the DER-encoded issuer cert to an internal X509 */ 231599ebb4caSwyllys ptmp = issuer_cert->Data; 231699ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 231799ebb4caSwyllys issuer_cert->Length); 231899ebb4caSwyllys if (issuer == NULL) { 231999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 232099ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 232199ebb4caSwyllys goto end; 232299ebb4caSwyllys } 232399ebb4caSwyllys 232499ebb4caSwyllys /* convert the DER-encoded user cert to an internal X509 */ 232599ebb4caSwyllys ptmp = user_cert->Data; 232699ebb4caSwyllys cert = d2i_X509(NULL, (const uchar_t **)&ptmp, 232799ebb4caSwyllys user_cert->Length); 232899ebb4caSwyllys if (cert == NULL) { 232999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 233099ebb4caSwyllys 233199ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_CERT; 233299ebb4caSwyllys goto end; 233399ebb4caSwyllys } 233499ebb4caSwyllys 233599ebb4caSwyllys /* create a CERTID */ 233699ebb4caSwyllys *certid = OCSP_cert_to_id(NULL, cert, issuer); 233799ebb4caSwyllys if (*certid == NULL) { 233899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 233999ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 234099ebb4caSwyllys goto end; 234199ebb4caSwyllys } 234299ebb4caSwyllys 234399ebb4caSwyllys end: 234499ebb4caSwyllys if (issuer != NULL) { 234599ebb4caSwyllys X509_free(issuer); 234699ebb4caSwyllys } 234799ebb4caSwyllys 234899ebb4caSwyllys if (cert != NULL) { 234999ebb4caSwyllys X509_free(cert); 235099ebb4caSwyllys } 235199ebb4caSwyllys 235299ebb4caSwyllys return (ret); 235399ebb4caSwyllys } 235499ebb4caSwyllys 235599ebb4caSwyllys KMF_RETURN 235630a5e8faSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, 235730a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 235899ebb4caSwyllys { 235999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 236099ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 236199ebb4caSwyllys OCSP_CERTID *id = NULL; 236299ebb4caSwyllys OCSP_REQUEST *req = NULL; 236399ebb4caSwyllys BIO *derbio = NULL; 236430a5e8faSwyllys char *reqfile; 236530a5e8faSwyllys KMF_DATA *issuer_cert; 236630a5e8faSwyllys KMF_DATA *user_cert; 236799ebb4caSwyllys 236830a5e8faSwyllys user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, 236930a5e8faSwyllys attrlist, numattr); 237030a5e8faSwyllys if (user_cert == NULL) 237199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 237299ebb4caSwyllys 237330a5e8faSwyllys issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, 237430a5e8faSwyllys attrlist, numattr); 237530a5e8faSwyllys if (issuer_cert == NULL) 237630a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 237730a5e8faSwyllys 237830a5e8faSwyllys reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR, 237930a5e8faSwyllys attrlist, numattr); 238030a5e8faSwyllys if (reqfile == NULL) 238130a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 238230a5e8faSwyllys 238330a5e8faSwyllys ret = create_certid(handle, issuer_cert, user_cert, &id); 238499ebb4caSwyllys if (ret != KMF_OK) { 238599ebb4caSwyllys return (ret); 238699ebb4caSwyllys } 238799ebb4caSwyllys 238899ebb4caSwyllys /* Create an OCSP request */ 238999ebb4caSwyllys req = OCSP_REQUEST_new(); 239099ebb4caSwyllys if (req == NULL) { 239199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 239299ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 239399ebb4caSwyllys goto end; 239499ebb4caSwyllys } 239599ebb4caSwyllys 239699ebb4caSwyllys if (!OCSP_request_add0_id(req, id)) { 239799ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 239899ebb4caSwyllys goto end; 239999ebb4caSwyllys } 240099ebb4caSwyllys 240199ebb4caSwyllys /* Write the request to the output file with DER encoding */ 240299ebb4caSwyllys derbio = BIO_new_file(reqfile, "wb"); 240399ebb4caSwyllys if (!derbio) { 240499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 240599ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 240699ebb4caSwyllys goto end; 240799ebb4caSwyllys } 240899ebb4caSwyllys if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) { 240999ebb4caSwyllys ret = KMF_ERR_ENCODING; 241099ebb4caSwyllys } 241199ebb4caSwyllys 241299ebb4caSwyllys end: 241399ebb4caSwyllys /* 241499ebb4caSwyllys * We don't need to free "id" explicitely, because OCSP_REQUEST_free() 241599ebb4caSwyllys * will deallocate certid's space also. 241699ebb4caSwyllys */ 241799ebb4caSwyllys if (req != NULL) { 241899ebb4caSwyllys OCSP_REQUEST_free(req); 241999ebb4caSwyllys } 242099ebb4caSwyllys 242199ebb4caSwyllys if (derbio != NULL) { 242299ebb4caSwyllys (void) BIO_free(derbio); 242399ebb4caSwyllys } 242499ebb4caSwyllys 242599ebb4caSwyllys return (ret); 242699ebb4caSwyllys } 242799ebb4caSwyllys 242899ebb4caSwyllys /* ocsp_find_signer_sk() is copied from openssl source */ 242999ebb4caSwyllys static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 243099ebb4caSwyllys { 243199ebb4caSwyllys int i; 243299ebb4caSwyllys unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 243399ebb4caSwyllys 243499ebb4caSwyllys /* Easy if lookup by name */ 243599ebb4caSwyllys if (id->type == V_OCSP_RESPID_NAME) 243699ebb4caSwyllys return (X509_find_by_subject(certs, id->value.byName)); 243799ebb4caSwyllys 243899ebb4caSwyllys /* Lookup by key hash */ 243999ebb4caSwyllys 244099ebb4caSwyllys /* If key hash isn't SHA1 length then forget it */ 244199ebb4caSwyllys if (id->value.byKey->length != SHA_DIGEST_LENGTH) 244299ebb4caSwyllys return (NULL); 244399ebb4caSwyllys 244499ebb4caSwyllys keyhash = id->value.byKey->data; 244599ebb4caSwyllys /* Calculate hash of each key and compare */ 244699ebb4caSwyllys for (i = 0; i < sk_X509_num(certs); i++) { 244799ebb4caSwyllys /*LINTED*/ 244899ebb4caSwyllys X509 *x = sk_X509_value(certs, i); 2449*5b3e1433Swyllys /* Use pubkey_digest to get the key ID value */ 245099ebb4caSwyllys (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 245199ebb4caSwyllys if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 245299ebb4caSwyllys return (x); 245399ebb4caSwyllys } 245499ebb4caSwyllys return (NULL); 245599ebb4caSwyllys } 245699ebb4caSwyllys 245799ebb4caSwyllys /* ocsp_find_signer() is copied from openssl source */ 245899ebb4caSwyllys /*ARGSUSED*/ 245999ebb4caSwyllys static int 246099ebb4caSwyllys ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, 246199ebb4caSwyllys X509_STORE *st, unsigned long flags) 246299ebb4caSwyllys { 246399ebb4caSwyllys X509 *signer; 246499ebb4caSwyllys OCSP_RESPID *rid = bs->tbsResponseData->responderId; 246599ebb4caSwyllys if ((signer = ocsp_find_signer_sk(certs, rid))) { 246699ebb4caSwyllys *psigner = signer; 246799ebb4caSwyllys return (2); 246899ebb4caSwyllys } 246999ebb4caSwyllys if (!(flags & OCSP_NOINTERN) && 247099ebb4caSwyllys (signer = ocsp_find_signer_sk(bs->certs, rid))) { 247199ebb4caSwyllys *psigner = signer; 247299ebb4caSwyllys return (1); 247399ebb4caSwyllys } 247499ebb4caSwyllys /* Maybe lookup from store if by subject name */ 247599ebb4caSwyllys 247699ebb4caSwyllys *psigner = NULL; 247799ebb4caSwyllys return (0); 247899ebb4caSwyllys } 247999ebb4caSwyllys 248099ebb4caSwyllys /* 248199ebb4caSwyllys * This function will verify the signature of a basic response, using 248299ebb4caSwyllys * the public key from the OCSP responder certificate. 248399ebb4caSwyllys */ 248499ebb4caSwyllys static KMF_RETURN 248599ebb4caSwyllys check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, 248699ebb4caSwyllys KMF_DATA *signer_cert, KMF_DATA *issuer_cert) 248799ebb4caSwyllys { 248899ebb4caSwyllys KMF_RETURN ret = KMF_OK; 248999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 249099ebb4caSwyllys STACK_OF(X509) *cert_stack = NULL; 249199ebb4caSwyllys X509 *signer = NULL; 249299ebb4caSwyllys X509 *issuer = NULL; 249399ebb4caSwyllys EVP_PKEY *skey = NULL; 249499ebb4caSwyllys unsigned char *ptmp; 249599ebb4caSwyllys 249699ebb4caSwyllys 249799ebb4caSwyllys if (bs == NULL || issuer_cert == NULL) 249899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 249999ebb4caSwyllys 250099ebb4caSwyllys /* 250199ebb4caSwyllys * Find the certificate that signed the basic response. 250299ebb4caSwyllys * 250399ebb4caSwyllys * If signer_cert is not NULL, we will use that as the signer cert. 250499ebb4caSwyllys * Otherwise, we will check if the issuer cert is actually the signer. 250599ebb4caSwyllys * If we still do not find a signer, we will look for it from the 250699ebb4caSwyllys * certificate list came with the response file. 250799ebb4caSwyllys */ 250899ebb4caSwyllys if (signer_cert != NULL) { 250999ebb4caSwyllys ptmp = signer_cert->Data; 251099ebb4caSwyllys signer = d2i_X509(NULL, (const uchar_t **)&ptmp, 251199ebb4caSwyllys signer_cert->Length); 251299ebb4caSwyllys if (signer == NULL) { 251399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 251499ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 251599ebb4caSwyllys goto end; 251699ebb4caSwyllys } 251799ebb4caSwyllys } else { 251899ebb4caSwyllys /* 251999ebb4caSwyllys * Convert the issuer cert into X509 and push it into a 252099ebb4caSwyllys * stack to be used by ocsp_find_signer(). 252199ebb4caSwyllys */ 252299ebb4caSwyllys ptmp = issuer_cert->Data; 252399ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 252499ebb4caSwyllys issuer_cert->Length); 252599ebb4caSwyllys if (issuer == NULL) { 252699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 252799ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 252899ebb4caSwyllys goto end; 252999ebb4caSwyllys } 253099ebb4caSwyllys 253199ebb4caSwyllys if ((cert_stack = sk_X509_new_null()) == NULL) { 253299ebb4caSwyllys ret = KMF_ERR_INTERNAL; 253399ebb4caSwyllys goto end; 253499ebb4caSwyllys } 253599ebb4caSwyllys 253699ebb4caSwyllys if (sk_X509_push(cert_stack, issuer) == NULL) { 253799ebb4caSwyllys ret = KMF_ERR_INTERNAL; 253899ebb4caSwyllys goto end; 253999ebb4caSwyllys } 254099ebb4caSwyllys 254199ebb4caSwyllys ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0); 254299ebb4caSwyllys if (!ret) { 254399ebb4caSwyllys /* can not find the signer */ 254499ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 254599ebb4caSwyllys goto end; 254699ebb4caSwyllys } 254799ebb4caSwyllys } 254899ebb4caSwyllys 254999ebb4caSwyllys /* Verify the signature of the response */ 255099ebb4caSwyllys skey = X509_get_pubkey(signer); 255199ebb4caSwyllys if (skey == NULL) { 255299ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 255399ebb4caSwyllys goto end; 255499ebb4caSwyllys } 255599ebb4caSwyllys 255699ebb4caSwyllys ret = OCSP_BASICRESP_verify(bs, skey, 0); 255799ebb4caSwyllys if (ret == 0) { 255899ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE; 255999ebb4caSwyllys goto end; 256099ebb4caSwyllys } 256199ebb4caSwyllys 256299ebb4caSwyllys end: 256399ebb4caSwyllys if (issuer != NULL) { 256499ebb4caSwyllys X509_free(issuer); 256599ebb4caSwyllys } 256699ebb4caSwyllys 256799ebb4caSwyllys if (signer != NULL) { 256899ebb4caSwyllys X509_free(signer); 256999ebb4caSwyllys } 257099ebb4caSwyllys 257199ebb4caSwyllys if (skey != NULL) { 257299ebb4caSwyllys EVP_PKEY_free(skey); 257399ebb4caSwyllys } 257499ebb4caSwyllys 257599ebb4caSwyllys if (cert_stack != NULL) { 257699ebb4caSwyllys sk_X509_free(cert_stack); 257799ebb4caSwyllys } 257899ebb4caSwyllys 257999ebb4caSwyllys return (ret); 258099ebb4caSwyllys } 258199ebb4caSwyllys 258299ebb4caSwyllys 258399ebb4caSwyllys 258499ebb4caSwyllys KMF_RETURN 258599ebb4caSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, 258630a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 258799ebb4caSwyllys { 258899ebb4caSwyllys KMF_RETURN ret = KMF_OK; 258999ebb4caSwyllys BIO *derbio = NULL; 259099ebb4caSwyllys OCSP_RESPONSE *resp = NULL; 259199ebb4caSwyllys OCSP_BASICRESP *bs = NULL; 259299ebb4caSwyllys OCSP_CERTID *id = NULL; 259399ebb4caSwyllys OCSP_SINGLERESP *single = NULL; 259499ebb4caSwyllys ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 259599ebb4caSwyllys int index, status, reason; 259630a5e8faSwyllys KMF_DATA *issuer_cert; 259730a5e8faSwyllys KMF_DATA *user_cert; 259830a5e8faSwyllys KMF_DATA *signer_cert; 259930a5e8faSwyllys KMF_DATA *response; 260030a5e8faSwyllys int *response_reason, *response_status, *cert_status; 260130a5e8faSwyllys boolean_t ignore_response_sign = B_FALSE; /* default is FALSE */ 260230a5e8faSwyllys uint32_t response_lifetime; 260399ebb4caSwyllys 260430a5e8faSwyllys issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, 260530a5e8faSwyllys attrlist, numattr); 260630a5e8faSwyllys if (issuer_cert == NULL) 260799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 260899ebb4caSwyllys 260930a5e8faSwyllys user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, 261030a5e8faSwyllys attrlist, numattr); 261130a5e8faSwyllys if (user_cert == NULL) 261299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 261330a5e8faSwyllys 261430a5e8faSwyllys response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, 261530a5e8faSwyllys attrlist, numattr); 261630a5e8faSwyllys if (response == NULL) 261730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 261830a5e8faSwyllys 261930a5e8faSwyllys response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR, 262030a5e8faSwyllys attrlist, numattr); 262130a5e8faSwyllys if (response_status == NULL) 262230a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 262330a5e8faSwyllys 262430a5e8faSwyllys response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR, 262530a5e8faSwyllys attrlist, numattr); 262630a5e8faSwyllys if (response_reason == NULL) 262730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 262830a5e8faSwyllys 262930a5e8faSwyllys cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, 263030a5e8faSwyllys attrlist, numattr); 263130a5e8faSwyllys if (cert_status == NULL) 263230a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 263399ebb4caSwyllys 263499ebb4caSwyllys /* Read in the response */ 263530a5e8faSwyllys derbio = BIO_new_mem_buf(response->Data, response->Length); 263699ebb4caSwyllys if (!derbio) { 263799ebb4caSwyllys ret = KMF_ERR_MEMORY; 263899ebb4caSwyllys return (ret); 263999ebb4caSwyllys } 264099ebb4caSwyllys 264199ebb4caSwyllys resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 264299ebb4caSwyllys if (resp == NULL) { 264399ebb4caSwyllys ret = KMF_ERR_OCSP_MALFORMED_RESPONSE; 264499ebb4caSwyllys goto end; 264599ebb4caSwyllys } 264699ebb4caSwyllys 264799ebb4caSwyllys /* Check the response status */ 264899ebb4caSwyllys status = OCSP_response_status(resp); 264930a5e8faSwyllys *response_status = status; 265099ebb4caSwyllys if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 265199ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_STATUS; 265299ebb4caSwyllys goto end; 265399ebb4caSwyllys } 265499ebb4caSwyllys 265599ebb4caSwyllys #ifdef DEBUG 265699ebb4caSwyllys printf("Successfully checked the response file status.\n"); 265799ebb4caSwyllys #endif /* DEBUG */ 265899ebb4caSwyllys 265999ebb4caSwyllys /* Extract basic response */ 266099ebb4caSwyllys bs = OCSP_response_get1_basic(resp); 266199ebb4caSwyllys if (bs == NULL) { 266299ebb4caSwyllys ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE; 266399ebb4caSwyllys goto end; 266499ebb4caSwyllys } 266599ebb4caSwyllys 266699ebb4caSwyllys #ifdef DEBUG 266799ebb4caSwyllys printf("Successfully retrieved the basic response.\n"); 266899ebb4caSwyllys #endif /* DEBUG */ 266999ebb4caSwyllys 267099ebb4caSwyllys /* Check the basic response signature if required */ 267130a5e8faSwyllys ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr, 267230a5e8faSwyllys (void *)&ignore_response_sign, NULL); 267330a5e8faSwyllys if (ret != KMF_OK) 267430a5e8faSwyllys ret = KMF_OK; 267530a5e8faSwyllys 267630a5e8faSwyllys signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, 267730a5e8faSwyllys attrlist, numattr); 267830a5e8faSwyllys 267930a5e8faSwyllys if (ignore_response_sign == B_FALSE) { 268099ebb4caSwyllys ret = check_response_signature(handle, bs, 268130a5e8faSwyllys signer_cert, issuer_cert); 268299ebb4caSwyllys if (ret != KMF_OK) 268399ebb4caSwyllys goto end; 268499ebb4caSwyllys } 268599ebb4caSwyllys 268699ebb4caSwyllys #ifdef DEBUG 268799ebb4caSwyllys printf("Successfully verified the response signature.\n"); 268899ebb4caSwyllys #endif /* DEBUG */ 268999ebb4caSwyllys 269099ebb4caSwyllys /* Create a certid for the certificate in question */ 269130a5e8faSwyllys ret = create_certid(handle, issuer_cert, user_cert, &id); 269299ebb4caSwyllys if (ret != KMF_OK) { 269399ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 269499ebb4caSwyllys goto end; 269599ebb4caSwyllys } 269699ebb4caSwyllys 269799ebb4caSwyllys #ifdef DEBUG 269899ebb4caSwyllys printf("successfully created a certid for the cert.\n"); 269999ebb4caSwyllys #endif /* DEBUG */ 270099ebb4caSwyllys 270199ebb4caSwyllys /* Find the index of the single response for the certid */ 270299ebb4caSwyllys index = OCSP_resp_find(bs, id, -1); 270399ebb4caSwyllys if (index < 0) { 270499ebb4caSwyllys /* cound not find this certificate in the response */ 270599ebb4caSwyllys ret = KMF_ERR_OCSP_UNKNOWN_CERT; 270699ebb4caSwyllys goto end; 270799ebb4caSwyllys } 270899ebb4caSwyllys 270999ebb4caSwyllys #ifdef DEBUG 271099ebb4caSwyllys printf("Successfully found the single response index for the cert.\n"); 271199ebb4caSwyllys #endif /* DEBUG */ 271299ebb4caSwyllys 271399ebb4caSwyllys /* Retrieve the single response and get the cert status */ 271499ebb4caSwyllys single = OCSP_resp_get0(bs, index); 271599ebb4caSwyllys status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, 271699ebb4caSwyllys &nextupd); 271799ebb4caSwyllys if (status == V_OCSP_CERTSTATUS_GOOD) { 271830a5e8faSwyllys *cert_status = OCSP_GOOD; 271999ebb4caSwyllys } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { 272030a5e8faSwyllys *cert_status = OCSP_UNKNOWN; 272199ebb4caSwyllys } else { /* revoked */ 272230a5e8faSwyllys *cert_status = OCSP_REVOKED; 272330a5e8faSwyllys *response_reason = reason; 272499ebb4caSwyllys } 272599ebb4caSwyllys ret = KMF_OK; 272699ebb4caSwyllys 272730a5e8faSwyllys /* resp. time is optional, so we don't care about the return code. */ 272830a5e8faSwyllys (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr, 272930a5e8faSwyllys (void *)&response_lifetime, NULL); 273030a5e8faSwyllys 273199ebb4caSwyllys if (!OCSP_check_validity(thisupd, nextupd, 300, 273230a5e8faSwyllys response_lifetime)) { 273399ebb4caSwyllys ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; 273499ebb4caSwyllys goto end; 273599ebb4caSwyllys } 273699ebb4caSwyllys 273799ebb4caSwyllys #ifdef DEBUG 273899ebb4caSwyllys printf("Successfully verify the time.\n"); 273999ebb4caSwyllys #endif /* DEBUG */ 274099ebb4caSwyllys 274199ebb4caSwyllys end: 274299ebb4caSwyllys if (derbio != NULL) 274399ebb4caSwyllys (void) BIO_free(derbio); 274499ebb4caSwyllys 274599ebb4caSwyllys if (resp != NULL) 274699ebb4caSwyllys OCSP_RESPONSE_free(resp); 274799ebb4caSwyllys 274899ebb4caSwyllys if (bs != NULL) 274999ebb4caSwyllys OCSP_BASICRESP_free(bs); 275099ebb4caSwyllys 275199ebb4caSwyllys if (id != NULL) 275299ebb4caSwyllys OCSP_CERTID_free(id); 275399ebb4caSwyllys 275499ebb4caSwyllys return (ret); 275599ebb4caSwyllys } 275699ebb4caSwyllys 275799ebb4caSwyllys static KMF_RETURN 275899ebb4caSwyllys fetch_key(KMF_HANDLE_T handle, char *path, 275999ebb4caSwyllys KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) 276099ebb4caSwyllys { 276199ebb4caSwyllys KMF_RETURN rv = KMF_OK; 276230a5e8faSwyllys EVP_PKEY *pkey = NULL; 276399ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 276499ebb4caSwyllys 276599ebb4caSwyllys if (keyclass == KMF_ASYM_PRI || 276699ebb4caSwyllys keyclass == KMF_ASYM_PUB) { 276799ebb4caSwyllys pkey = openssl_load_key(handle, path); 276899ebb4caSwyllys if (pkey == NULL) { 276999ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 277099ebb4caSwyllys } 277199ebb4caSwyllys if (key != NULL) { 277299ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) 277399ebb4caSwyllys key->keyalg = KMF_RSA; 277499ebb4caSwyllys else if (pkey->type == EVP_PKEY_DSA) 277599ebb4caSwyllys key->keyalg = KMF_DSA; 277699ebb4caSwyllys 277799ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 277899ebb4caSwyllys key->keyclass = keyclass; 277999ebb4caSwyllys key->keyp = (void *)pkey; 278099ebb4caSwyllys key->israw = FALSE; 2781*5b3e1433Swyllys if (path != NULL && 2782*5b3e1433Swyllys ((key->keylabel = strdup(path)) == NULL)) { 2783*5b3e1433Swyllys EVP_PKEY_free(pkey); 2784*5b3e1433Swyllys return (KMF_ERR_MEMORY); 2785*5b3e1433Swyllys } 278699ebb4caSwyllys } else { 278799ebb4caSwyllys EVP_PKEY_free(pkey); 278899ebb4caSwyllys pkey = NULL; 278999ebb4caSwyllys } 279099ebb4caSwyllys } else if (keyclass == KMF_SYMMETRIC) { 279199ebb4caSwyllys KMF_ENCODE_FORMAT fmt; 279299ebb4caSwyllys /* 279399ebb4caSwyllys * If the file is a recognized format, 279499ebb4caSwyllys * then it is NOT a symmetric key. 279599ebb4caSwyllys */ 279630a5e8faSwyllys rv = kmf_get_file_format(path, &fmt); 279799ebb4caSwyllys if (rv == KMF_OK || fmt != 0) { 279899ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 279999ebb4caSwyllys } else if (rv == KMF_ERR_ENCODING) { 280099ebb4caSwyllys /* 280199ebb4caSwyllys * If we don't know the encoding, 280299ebb4caSwyllys * it is probably a symmetric key. 280399ebb4caSwyllys */ 280499ebb4caSwyllys rv = KMF_OK; 280530a5e8faSwyllys } else if (rv == KMF_ERR_OPEN_FILE) { 280630a5e8faSwyllys return (KMF_ERR_KEY_NOT_FOUND); 280799ebb4caSwyllys } 280899ebb4caSwyllys 280999ebb4caSwyllys if (key != NULL) { 281099ebb4caSwyllys KMF_DATA keyvalue; 281199ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 281299ebb4caSwyllys if (rkey == NULL) { 281399ebb4caSwyllys rv = KMF_ERR_MEMORY; 281499ebb4caSwyllys goto out; 281599ebb4caSwyllys } 281699ebb4caSwyllys 281799ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 281830a5e8faSwyllys rv = kmf_read_input_file(handle, path, &keyvalue); 281999ebb4caSwyllys if (rv != KMF_OK) 282099ebb4caSwyllys goto out; 282199ebb4caSwyllys 282299ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 282399ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 282499ebb4caSwyllys 282599ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 282699ebb4caSwyllys key->keyclass = keyclass; 282799ebb4caSwyllys key->israw = TRUE; 282899ebb4caSwyllys key->keyp = (void *)rkey; 2829*5b3e1433Swyllys if (path != NULL && 2830*5b3e1433Swyllys ((key->keylabel = strdup(path)) == NULL)) { 2831*5b3e1433Swyllys rv = KMF_ERR_MEMORY; 2832*5b3e1433Swyllys } 283399ebb4caSwyllys } 283499ebb4caSwyllys } 283599ebb4caSwyllys out: 283699ebb4caSwyllys if (rv != KMF_OK) { 283799ebb4caSwyllys if (rkey != NULL) { 283830a5e8faSwyllys kmf_free_raw_sym_key(rkey); 283999ebb4caSwyllys } 284099ebb4caSwyllys if (pkey != NULL) 284199ebb4caSwyllys EVP_PKEY_free(pkey); 284299ebb4caSwyllys 284399ebb4caSwyllys if (key != NULL) { 284499ebb4caSwyllys key->keyalg = KMF_KEYALG_NONE; 284599ebb4caSwyllys key->keyclass = KMF_KEYCLASS_NONE; 284699ebb4caSwyllys key->keyp = NULL; 284799ebb4caSwyllys } 284899ebb4caSwyllys } 284999ebb4caSwyllys 285099ebb4caSwyllys return (rv); 285199ebb4caSwyllys } 285299ebb4caSwyllys 285399ebb4caSwyllys KMF_RETURN 285430a5e8faSwyllys OpenSSL_FindKey(KMF_HANDLE_T handle, 285530a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 285699ebb4caSwyllys { 285799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 285899ebb4caSwyllys char *fullpath = NULL; 2859f482c776Swyllys uint32_t maxkeys; 286030a5e8faSwyllys KMF_KEY_HANDLE *key; 286130a5e8faSwyllys uint32_t *numkeys; 286230a5e8faSwyllys KMF_KEY_CLASS keyclass; 286330a5e8faSwyllys KMF_RAW_KEY_DATA *rawkey; 286430a5e8faSwyllys char *dirpath; 286530a5e8faSwyllys char *keyfile; 286699ebb4caSwyllys 286730a5e8faSwyllys if (handle == NULL) 286899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 286999ebb4caSwyllys 287030a5e8faSwyllys numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 287130a5e8faSwyllys if (numkeys == NULL) 287230a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 287330a5e8faSwyllys 287430a5e8faSwyllys rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, 287530a5e8faSwyllys (void *)&keyclass, NULL); 287630a5e8faSwyllys if (rv != KMF_OK) 287730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 287830a5e8faSwyllys 287930a5e8faSwyllys if (keyclass != KMF_ASYM_PUB && 288030a5e8faSwyllys keyclass != KMF_ASYM_PRI && 288130a5e8faSwyllys keyclass != KMF_SYMMETRIC) 288299ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 288399ebb4caSwyllys 288430a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 288530a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 288630a5e8faSwyllys 288730a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 288899ebb4caSwyllys 288999ebb4caSwyllys if (fullpath == NULL) 289099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 289199ebb4caSwyllys 2892f482c776Swyllys maxkeys = *numkeys; 2893f482c776Swyllys if (maxkeys == 0) 2894f482c776Swyllys maxkeys = 0xFFFFFFFF; 289599ebb4caSwyllys *numkeys = 0; 289699ebb4caSwyllys 289730a5e8faSwyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 289830a5e8faSwyllys /* it is okay to have "keys" contains NULL */ 289930a5e8faSwyllys 290030a5e8faSwyllys /* 290130a5e8faSwyllys * The caller may want a list of the raw key data as well. 290230a5e8faSwyllys * Useful for importing keys from a file into other keystores. 290330a5e8faSwyllys */ 290430a5e8faSwyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); 290530a5e8faSwyllys 290699ebb4caSwyllys if (isdir(fullpath)) { 290799ebb4caSwyllys DIR *dirp; 290899ebb4caSwyllys struct dirent *dp; 290999ebb4caSwyllys int n = 0; 291099ebb4caSwyllys 291199ebb4caSwyllys /* open all files in the directory and attempt to read them */ 291299ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 291399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 291499ebb4caSwyllys } 291599ebb4caSwyllys rewinddir(dirp); 2916f482c776Swyllys while ((dp = readdir(dirp)) != NULL && n < maxkeys) { 291799ebb4caSwyllys if (strcmp(dp->d_name, ".") && 291899ebb4caSwyllys strcmp(dp->d_name, "..")) { 291999ebb4caSwyllys char *fname; 292099ebb4caSwyllys 292199ebb4caSwyllys fname = get_fullpath(fullpath, 292299ebb4caSwyllys (char *)&dp->d_name); 292399ebb4caSwyllys 292499ebb4caSwyllys rv = fetch_key(handle, fname, 292530a5e8faSwyllys keyclass, key ? &key[n] : NULL); 292699ebb4caSwyllys 292730a5e8faSwyllys if (rv == KMF_OK) { 292830a5e8faSwyllys if (key != NULL && rawkey != NULL) 292930a5e8faSwyllys rv = convertToRawKey( 293030a5e8faSwyllys key[n].keyp, &rawkey[n]); 293199ebb4caSwyllys n++; 293230a5e8faSwyllys } 293399ebb4caSwyllys 293499ebb4caSwyllys if (rv != KMF_OK || key == NULL) 293599ebb4caSwyllys free(fname); 293699ebb4caSwyllys } 293799ebb4caSwyllys } 293899ebb4caSwyllys (void) closedir(dirp); 293999ebb4caSwyllys free(fullpath); 294099ebb4caSwyllys (*numkeys) = n; 294199ebb4caSwyllys } else { 294230a5e8faSwyllys rv = fetch_key(handle, fullpath, keyclass, key); 294399ebb4caSwyllys if (rv == KMF_OK) 294499ebb4caSwyllys (*numkeys) = 1; 294599ebb4caSwyllys 294699ebb4caSwyllys if (rv != KMF_OK || key == NULL) 294799ebb4caSwyllys free(fullpath); 294830a5e8faSwyllys 294930a5e8faSwyllys if (rv == KMF_OK && key != NULL && rawkey != NULL) { 295030a5e8faSwyllys rv = convertToRawKey(key->keyp, rawkey); 295130a5e8faSwyllys } 295299ebb4caSwyllys } 295399ebb4caSwyllys 2954f482c776Swyllys if (rv == KMF_OK && (*numkeys) == 0) 295599ebb4caSwyllys rv = KMF_ERR_KEY_NOT_FOUND; 295699ebb4caSwyllys 295799ebb4caSwyllys return (rv); 295899ebb4caSwyllys } 295999ebb4caSwyllys 296099ebb4caSwyllys #define HANDLE_PK12_ERROR { \ 296199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); \ 296299ebb4caSwyllys rv = KMF_ERR_ENCODING; \ 296399ebb4caSwyllys goto out; \ 296499ebb4caSwyllys } 296599ebb4caSwyllys 2966*5b3e1433Swyllys static int 2967*5b3e1433Swyllys add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert) 296899ebb4caSwyllys { 2969*5b3e1433Swyllys if (xcert != NULL && xcert->aux != NULL && 2970*5b3e1433Swyllys xcert->aux->alias != NULL) { 2971*5b3e1433Swyllys if (PKCS12_add_friendlyname_asc(bag, 2972*5b3e1433Swyllys (const char *)xcert->aux->alias->data, 2973*5b3e1433Swyllys xcert->aux->alias->length) == 0) 2974*5b3e1433Swyllys return (0); 2975*5b3e1433Swyllys } 2976*5b3e1433Swyllys return (1); 2977*5b3e1433Swyllys } 2978*5b3e1433Swyllys 2979*5b3e1433Swyllys static PKCS7 * 2980*5b3e1433Swyllys add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred, 2981*5b3e1433Swyllys uchar_t *keyid, unsigned int keyidlen) 2982*5b3e1433Swyllys { 298399ebb4caSwyllys PKCS12_SAFEBAG *bag = NULL; 298499ebb4caSwyllys PKCS7 *cert_authsafe = NULL; 2985*5b3e1433Swyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack; 298699ebb4caSwyllys 298799ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 298899ebb4caSwyllys if (bag_stack == NULL) 2989*5b3e1433Swyllys return (NULL); 299099ebb4caSwyllys 299199ebb4caSwyllys /* Convert cert from X509 struct to PKCS#12 bag */ 299299ebb4caSwyllys bag = PKCS12_x5092certbag(sslcert); 299399ebb4caSwyllys if (bag == NULL) { 2994*5b3e1433Swyllys goto out; 299599ebb4caSwyllys } 299699ebb4caSwyllys 299799ebb4caSwyllys /* Add the key id to the certificate bag. */ 2998*5b3e1433Swyllys if (keyidlen > 0 && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 2999*5b3e1433Swyllys goto out; 300099ebb4caSwyllys } 300199ebb4caSwyllys 3002*5b3e1433Swyllys if (!add_alias_to_bag(bag, sslcert)) 3003*5b3e1433Swyllys goto out; 3004*5b3e1433Swyllys 300599ebb4caSwyllys /* Pile it on the bag_stack. */ 300699ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 3007*5b3e1433Swyllys goto out; 300899ebb4caSwyllys } 300999ebb4caSwyllys /* Turn bag_stack of certs into encrypted authsafe. */ 301099ebb4caSwyllys cert_authsafe = PKCS12_pack_p7encdata( 301199ebb4caSwyllys NID_pbe_WithSHA1And40BitRC2_CBC, 301234acef67Swyllys cred->cred, cred->credlen, NULL, 0, 301334acef67Swyllys PKCS12_DEFAULT_ITER, bag_stack); 301499ebb4caSwyllys 3015*5b3e1433Swyllys out: 3016*5b3e1433Swyllys if (bag_stack != NULL) 301799ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 301899ebb4caSwyllys 3019*5b3e1433Swyllys return (cert_authsafe); 302099ebb4caSwyllys } 3021*5b3e1433Swyllys 3022*5b3e1433Swyllys static PKCS7 * 3023*5b3e1433Swyllys add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred, 3024*5b3e1433Swyllys uchar_t *keyid, unsigned int keyidlen, 3025*5b3e1433Swyllys char *label, int label_len) 3026*5b3e1433Swyllys { 3027*5b3e1433Swyllys PKCS8_PRIV_KEY_INFO *p8 = NULL; 3028*5b3e1433Swyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 3029*5b3e1433Swyllys PKCS12_SAFEBAG *bag = NULL; 3030*5b3e1433Swyllys PKCS7 *key_authsafe = NULL; 3031*5b3e1433Swyllys 303299ebb4caSwyllys p8 = EVP_PKEY2PKCS8(pkey); 303399ebb4caSwyllys if (p8 == NULL) { 3034*5b3e1433Swyllys return (NULL); 303599ebb4caSwyllys } 303699ebb4caSwyllys /* Put the shrouded key into a PKCS#12 bag. */ 303799ebb4caSwyllys bag = PKCS12_MAKE_SHKEYBAG( 303899ebb4caSwyllys NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 303999ebb4caSwyllys cred->cred, cred->credlen, 304099ebb4caSwyllys NULL, 0, PKCS12_DEFAULT_ITER, p8); 304199ebb4caSwyllys 304299ebb4caSwyllys /* Clean up the PKCS#8 shrouded key, don't need it now. */ 304399ebb4caSwyllys PKCS8_PRIV_KEY_INFO_free(p8); 304499ebb4caSwyllys p8 = NULL; 304599ebb4caSwyllys 304699ebb4caSwyllys if (bag == NULL) { 3047*5b3e1433Swyllys return (NULL); 304899ebb4caSwyllys } 3049*5b3e1433Swyllys if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) 3050*5b3e1433Swyllys goto out; 3051*5b3e1433Swyllys if (label != NULL && !PKCS12_add_friendlyname(bag, label, label_len)) 3052*5b3e1433Swyllys goto out; 3053*5b3e1433Swyllys 305499ebb4caSwyllys /* Start a PKCS#12 safebag container for the private key. */ 305599ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 3056*5b3e1433Swyllys if (bag_stack == NULL) 3057*5b3e1433Swyllys goto out; 305899ebb4caSwyllys 305999ebb4caSwyllys /* Pile on the private key on the bag_stack. */ 3060*5b3e1433Swyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) 3061*5b3e1433Swyllys goto out; 3062*5b3e1433Swyllys 306399ebb4caSwyllys key_authsafe = PKCS12_pack_p7data(bag_stack); 306499ebb4caSwyllys 3065*5b3e1433Swyllys out: 3066*5b3e1433Swyllys if (bag_stack != NULL) 306799ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 306899ebb4caSwyllys bag_stack = NULL; 3069*5b3e1433Swyllys return (key_authsafe); 307099ebb4caSwyllys } 307199ebb4caSwyllys 307299ebb4caSwyllys static EVP_PKEY * 307399ebb4caSwyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *key) 307499ebb4caSwyllys { 307599ebb4caSwyllys RSA *rsa = NULL; 307699ebb4caSwyllys EVP_PKEY *newkey = NULL; 307799ebb4caSwyllys 307899ebb4caSwyllys if ((rsa = RSA_new()) == NULL) 307999ebb4caSwyllys return (NULL); 308099ebb4caSwyllys 308199ebb4caSwyllys if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL) 308299ebb4caSwyllys return (NULL); 308399ebb4caSwyllys 308499ebb4caSwyllys if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) == 308599ebb4caSwyllys NULL) 308699ebb4caSwyllys return (NULL); 308799ebb4caSwyllys 308899ebb4caSwyllys if (key->priexp.val != NULL) 308999ebb4caSwyllys if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len, 309099ebb4caSwyllys rsa->d)) == NULL) 309199ebb4caSwyllys return (NULL); 309299ebb4caSwyllys 309399ebb4caSwyllys if (key->prime1.val != NULL) 309499ebb4caSwyllys if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len, 309599ebb4caSwyllys rsa->p)) == NULL) 309699ebb4caSwyllys return (NULL); 309799ebb4caSwyllys 309899ebb4caSwyllys if (key->prime2.val != NULL) 309999ebb4caSwyllys if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len, 310099ebb4caSwyllys rsa->q)) == NULL) 310199ebb4caSwyllys return (NULL); 310299ebb4caSwyllys 310399ebb4caSwyllys if (key->exp1.val != NULL) 310499ebb4caSwyllys if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, 310599ebb4caSwyllys rsa->dmp1)) == NULL) 310699ebb4caSwyllys return (NULL); 310799ebb4caSwyllys 310899ebb4caSwyllys if (key->exp2.val != NULL) 310999ebb4caSwyllys if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, 311099ebb4caSwyllys rsa->dmq1)) == NULL) 311199ebb4caSwyllys return (NULL); 311299ebb4caSwyllys 311399ebb4caSwyllys if (key->coef.val != NULL) 311499ebb4caSwyllys if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len, 311599ebb4caSwyllys rsa->iqmp)) == NULL) 311699ebb4caSwyllys return (NULL); 311799ebb4caSwyllys 311899ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 311999ebb4caSwyllys return (NULL); 312099ebb4caSwyllys 312199ebb4caSwyllys (void) EVP_PKEY_set1_RSA(newkey, rsa); 312299ebb4caSwyllys 312399ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 312499ebb4caSwyllys RSA_free(rsa); 312599ebb4caSwyllys 312699ebb4caSwyllys return (newkey); 312799ebb4caSwyllys } 312899ebb4caSwyllys 312999ebb4caSwyllys static EVP_PKEY * 313099ebb4caSwyllys ImportRawDSAKey(KMF_RAW_DSA_KEY *key) 313199ebb4caSwyllys { 313299ebb4caSwyllys DSA *dsa = NULL; 313399ebb4caSwyllys EVP_PKEY *newkey = NULL; 313499ebb4caSwyllys 313599ebb4caSwyllys if ((dsa = DSA_new()) == NULL) 313699ebb4caSwyllys return (NULL); 313799ebb4caSwyllys 313899ebb4caSwyllys if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len, 313999ebb4caSwyllys dsa->p)) == NULL) 314099ebb4caSwyllys return (NULL); 314199ebb4caSwyllys 314299ebb4caSwyllys if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len, 314399ebb4caSwyllys dsa->q)) == NULL) 314499ebb4caSwyllys return (NULL); 314599ebb4caSwyllys 314699ebb4caSwyllys if ((dsa->g = BN_bin2bn(key->base.val, key->base.len, 314799ebb4caSwyllys dsa->g)) == NULL) 314899ebb4caSwyllys return (NULL); 314999ebb4caSwyllys 315099ebb4caSwyllys if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len, 315199ebb4caSwyllys dsa->priv_key)) == NULL) 315299ebb4caSwyllys return (NULL); 315399ebb4caSwyllys 315430a5e8faSwyllys if (key->pubvalue.val != NULL) { 315530a5e8faSwyllys if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val, 315630a5e8faSwyllys key->pubvalue.len, dsa->pub_key)) == NULL) 315730a5e8faSwyllys return (NULL); 315830a5e8faSwyllys } 315930a5e8faSwyllys 316099ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 316199ebb4caSwyllys return (NULL); 316299ebb4caSwyllys 316399ebb4caSwyllys (void) EVP_PKEY_set1_DSA(newkey, dsa); 316499ebb4caSwyllys 316599ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 316699ebb4caSwyllys DSA_free(dsa); 316799ebb4caSwyllys return (newkey); 316899ebb4caSwyllys } 316999ebb4caSwyllys 3170*5b3e1433Swyllys static EVP_PKEY * 3171*5b3e1433Swyllys raw_key_to_pkey(KMF_KEY_HANDLE *key) 3172*5b3e1433Swyllys { 3173*5b3e1433Swyllys EVP_PKEY *pkey = NULL; 3174*5b3e1433Swyllys KMF_RAW_KEY_DATA *rawkey; 3175*5b3e1433Swyllys ASN1_TYPE *attr = NULL; 3176*5b3e1433Swyllys KMF_RETURN ret; 3177*5b3e1433Swyllys 3178*5b3e1433Swyllys if (key == NULL || !key->israw) 3179*5b3e1433Swyllys return (NULL); 3180*5b3e1433Swyllys 3181*5b3e1433Swyllys rawkey = (KMF_RAW_KEY_DATA *)key->keyp; 3182*5b3e1433Swyllys if (rawkey->keytype == KMF_RSA) { 3183*5b3e1433Swyllys pkey = ImportRawRSAKey(&rawkey->rawdata.rsa); 3184*5b3e1433Swyllys } else if (rawkey->keytype == KMF_DSA) { 3185*5b3e1433Swyllys pkey = ImportRawDSAKey(&rawkey->rawdata.dsa); 3186*5b3e1433Swyllys } else { 3187*5b3e1433Swyllys /* wrong kind of key */ 3188*5b3e1433Swyllys return (NULL); 3189*5b3e1433Swyllys } 3190*5b3e1433Swyllys 3191*5b3e1433Swyllys if (rawkey->label != NULL) { 3192*5b3e1433Swyllys if ((attr = ASN1_TYPE_new()) == NULL) { 3193*5b3e1433Swyllys EVP_PKEY_free(pkey); 3194*5b3e1433Swyllys return (NULL); 3195*5b3e1433Swyllys } 3196*5b3e1433Swyllys attr->value.bmpstring = ASN1_STRING_type_new(V_ASN1_BMPSTRING); 3197*5b3e1433Swyllys (void) ASN1_STRING_set(attr->value.bmpstring, rawkey->label, 3198*5b3e1433Swyllys strlen(rawkey->label)); 3199*5b3e1433Swyllys attr->type = V_ASN1_BMPSTRING; 3200*5b3e1433Swyllys attr->value.ptr = (char *)attr->value.bmpstring; 3201*5b3e1433Swyllys ret = set_pkey_attrib(pkey, attr, NID_friendlyName); 3202*5b3e1433Swyllys if (ret != KMF_OK) { 3203*5b3e1433Swyllys EVP_PKEY_free(pkey); 3204*5b3e1433Swyllys ASN1_TYPE_free(attr); 3205*5b3e1433Swyllys return (NULL); 3206*5b3e1433Swyllys } 3207*5b3e1433Swyllys } 3208*5b3e1433Swyllys if (rawkey->id.Data != NULL) { 3209*5b3e1433Swyllys if ((attr = ASN1_TYPE_new()) == NULL) { 3210*5b3e1433Swyllys EVP_PKEY_free(pkey); 3211*5b3e1433Swyllys return (NULL); 3212*5b3e1433Swyllys } 3213*5b3e1433Swyllys attr->value.octet_string = 3214*5b3e1433Swyllys ASN1_STRING_type_new(V_ASN1_OCTET_STRING); 3215*5b3e1433Swyllys attr->type = V_ASN1_OCTET_STRING; 3216*5b3e1433Swyllys (void) ASN1_STRING_set(attr->value.octet_string, 3217*5b3e1433Swyllys rawkey->id.Data, rawkey->id.Length); 3218*5b3e1433Swyllys attr->value.ptr = (char *)attr->value.octet_string; 3219*5b3e1433Swyllys ret = set_pkey_attrib(pkey, attr, NID_localKeyID); 3220*5b3e1433Swyllys if (ret != KMF_OK) { 3221*5b3e1433Swyllys EVP_PKEY_free(pkey); 3222*5b3e1433Swyllys ASN1_TYPE_free(attr); 3223*5b3e1433Swyllys return (NULL); 3224*5b3e1433Swyllys } 3225*5b3e1433Swyllys } 3226*5b3e1433Swyllys return (pkey); 3227*5b3e1433Swyllys } 3228*5b3e1433Swyllys 3229*5b3e1433Swyllys /* 3230*5b3e1433Swyllys * Search a list of private keys to find one that goes with the certificate. 3231*5b3e1433Swyllys */ 3232*5b3e1433Swyllys static EVP_PKEY * 3233*5b3e1433Swyllys find_matching_key(X509 *xcert, int numkeys, KMF_KEY_HANDLE *keylist) 3234*5b3e1433Swyllys { 3235*5b3e1433Swyllys int i; 3236*5b3e1433Swyllys EVP_PKEY *pkey = NULL; 3237*5b3e1433Swyllys 3238*5b3e1433Swyllys if (numkeys == 0 || keylist == NULL || xcert == NULL) 3239*5b3e1433Swyllys return (NULL); 3240*5b3e1433Swyllys for (i = 0; i < numkeys; i++) { 3241*5b3e1433Swyllys if (keylist[i].israw) 3242*5b3e1433Swyllys pkey = raw_key_to_pkey(&keylist[i]); 3243*5b3e1433Swyllys else 3244*5b3e1433Swyllys pkey = (EVP_PKEY *)keylist[i].keyp; 3245*5b3e1433Swyllys if (pkey != NULL) { 3246*5b3e1433Swyllys if (X509_check_private_key(xcert, pkey)) { 3247*5b3e1433Swyllys return (pkey); 3248*5b3e1433Swyllys } else { 3249*5b3e1433Swyllys EVP_PKEY_free(pkey); 3250*5b3e1433Swyllys pkey = NULL; 3251*5b3e1433Swyllys } 3252*5b3e1433Swyllys } 3253*5b3e1433Swyllys } 3254*5b3e1433Swyllys return (pkey); 3255*5b3e1433Swyllys } 3256*5b3e1433Swyllys 325799ebb4caSwyllys static KMF_RETURN 3258*5b3e1433Swyllys local_export_pk12(KMF_HANDLE_T handle, 325999ebb4caSwyllys KMF_CREDENTIAL *cred, 326099ebb4caSwyllys int numcerts, KMF_X509_DER_CERT *certlist, 326199ebb4caSwyllys int numkeys, KMF_KEY_HANDLE *keylist, 326299ebb4caSwyllys char *filename) 326399ebb4caSwyllys { 326499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 326599ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 326699ebb4caSwyllys BIO *bio = NULL; 3267*5b3e1433Swyllys PKCS7 *cert_authsafe = NULL; 3268*5b3e1433Swyllys PKCS7 *key_authsafe = NULL; 3269*5b3e1433Swyllys STACK_OF(PKCS7) *authsafe_stack = NULL; 3270*5b3e1433Swyllys PKCS12 *p12_elem = NULL; 327199ebb4caSwyllys int i; 327299ebb4caSwyllys 3273*5b3e1433Swyllys if (numcerts == 0 && numkeys == 0) 3274*5b3e1433Swyllys return (KMF_ERR_BAD_PARAMETER); 3275*5b3e1433Swyllys 327699ebb4caSwyllys /* 327799ebb4caSwyllys * Open the output file. 327899ebb4caSwyllys */ 327999ebb4caSwyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) { 328099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 328199ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 328299ebb4caSwyllys goto cleanup; 328399ebb4caSwyllys } 328499ebb4caSwyllys 3285*5b3e1433Swyllys /* Start a PKCS#7 stack. */ 3286*5b3e1433Swyllys authsafe_stack = sk_PKCS7_new_null(); 3287*5b3e1433Swyllys if (authsafe_stack == NULL) { 3288*5b3e1433Swyllys rv = KMF_ERR_MEMORY; 3289*5b3e1433Swyllys goto cleanup; 3290*5b3e1433Swyllys } 3291*5b3e1433Swyllys if (numcerts > 0) { 329299ebb4caSwyllys for (i = 0; rv == KMF_OK && i < numcerts; i++) { 329399ebb4caSwyllys const uchar_t *p = certlist[i].certificate.Data; 329499ebb4caSwyllys long len = certlist[i].certificate.Length; 3295*5b3e1433Swyllys X509 *xcert = NULL; 3296*5b3e1433Swyllys EVP_PKEY *pkey = NULL; 3297*5b3e1433Swyllys unsigned char keyid[EVP_MAX_MD_SIZE]; 3298*5b3e1433Swyllys unsigned int keyidlen = 0; 329999ebb4caSwyllys 330099ebb4caSwyllys xcert = d2i_X509(NULL, &p, len); 330199ebb4caSwyllys if (xcert == NULL) { 330299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 330399ebb4caSwyllys rv = KMF_ERR_ENCODING; 330499ebb4caSwyllys } 3305*5b3e1433Swyllys if (certlist[i].kmf_private.label != NULL) { 3306*5b3e1433Swyllys /* Set alias attribute */ 3307*5b3e1433Swyllys (void) X509_alias_set1(xcert, 3308*5b3e1433Swyllys (uchar_t *)certlist[i].kmf_private.label, 3309*5b3e1433Swyllys strlen(certlist[i].kmf_private.label)); 3310*5b3e1433Swyllys } 3311*5b3e1433Swyllys /* Check if there is a key corresponding to this cert */ 3312*5b3e1433Swyllys pkey = find_matching_key(xcert, numkeys, keylist); 3313*5b3e1433Swyllys 3314*5b3e1433Swyllys /* 3315*5b3e1433Swyllys * If key is found, get fingerprint and create a 3316*5b3e1433Swyllys * safebag. 3317*5b3e1433Swyllys */ 3318*5b3e1433Swyllys if (pkey != NULL) { 3319*5b3e1433Swyllys (void) X509_digest(xcert, EVP_sha1(), 3320*5b3e1433Swyllys keyid, &keyidlen); 3321*5b3e1433Swyllys key_authsafe = add_key_to_safe(pkey, cred, 3322*5b3e1433Swyllys keyid, keyidlen, 3323*5b3e1433Swyllys certlist[i].kmf_private.label, 3324*5b3e1433Swyllys (certlist[i].kmf_private.label ? 3325*5b3e1433Swyllys strlen(certlist[i].kmf_private.label) : 0)); 3326*5b3e1433Swyllys 3327*5b3e1433Swyllys if (key_authsafe == NULL) { 3328*5b3e1433Swyllys X509_free(xcert); 3329*5b3e1433Swyllys EVP_PKEY_free(pkey); 3330*5b3e1433Swyllys goto cleanup; 3331*5b3e1433Swyllys } 3332*5b3e1433Swyllys /* Put the key safe into the Auth Safe */ 3333*5b3e1433Swyllys if (!sk_PKCS7_push(authsafe_stack, 3334*5b3e1433Swyllys key_authsafe)) { 3335*5b3e1433Swyllys X509_free(xcert); 3336*5b3e1433Swyllys EVP_PKEY_free(pkey); 3337*5b3e1433Swyllys goto cleanup; 3338*5b3e1433Swyllys } 3339*5b3e1433Swyllys } 3340*5b3e1433Swyllys 3341*5b3e1433Swyllys /* create a certificate safebag */ 3342*5b3e1433Swyllys cert_authsafe = add_cert_to_safe(xcert, cred, keyid, 3343*5b3e1433Swyllys keyidlen); 3344*5b3e1433Swyllys if (cert_authsafe == NULL) { 3345*5b3e1433Swyllys X509_free(xcert); 3346*5b3e1433Swyllys EVP_PKEY_free(pkey); 3347*5b3e1433Swyllys goto cleanup; 3348*5b3e1433Swyllys } 3349*5b3e1433Swyllys if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) { 3350*5b3e1433Swyllys X509_free(xcert); 3351*5b3e1433Swyllys EVP_PKEY_free(pkey); 3352*5b3e1433Swyllys goto cleanup; 3353*5b3e1433Swyllys } 3354*5b3e1433Swyllys 335599ebb4caSwyllys X509_free(xcert); 335699ebb4caSwyllys if (pkey) 335799ebb4caSwyllys EVP_PKEY_free(pkey); 335899ebb4caSwyllys } 3359*5b3e1433Swyllys } else if (numcerts == 0 && numkeys > 0) { 3360*5b3e1433Swyllys /* 3361*5b3e1433Swyllys * If only adding keys to the file. 3362*5b3e1433Swyllys */ 3363*5b3e1433Swyllys for (i = 0; i < numkeys; i++) { 3364*5b3e1433Swyllys EVP_PKEY *pkey = NULL; 3365*5b3e1433Swyllys 3366*5b3e1433Swyllys if (keylist[i].israw) 3367*5b3e1433Swyllys pkey = raw_key_to_pkey(&keylist[i]); 3368*5b3e1433Swyllys else 3369*5b3e1433Swyllys pkey = (EVP_PKEY *)keylist[i].keyp; 3370*5b3e1433Swyllys 3371*5b3e1433Swyllys if (pkey == NULL) 3372*5b3e1433Swyllys continue; 3373*5b3e1433Swyllys 3374*5b3e1433Swyllys key_authsafe = add_key_to_safe(pkey, cred, 3375*5b3e1433Swyllys NULL, 0, NULL, 0); 3376*5b3e1433Swyllys 3377*5b3e1433Swyllys if (key_authsafe == NULL) { 3378*5b3e1433Swyllys EVP_PKEY_free(pkey); 3379*5b3e1433Swyllys goto cleanup; 3380*5b3e1433Swyllys } 3381*5b3e1433Swyllys if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) { 3382*5b3e1433Swyllys EVP_PKEY_free(pkey); 3383*5b3e1433Swyllys goto cleanup; 3384*5b3e1433Swyllys } 3385*5b3e1433Swyllys } 3386*5b3e1433Swyllys } 3387*5b3e1433Swyllys p12_elem = PKCS12_init(NID_pkcs7_data); 3388*5b3e1433Swyllys if (p12_elem == NULL) { 3389*5b3e1433Swyllys goto cleanup; 339099ebb4caSwyllys } 339199ebb4caSwyllys 3392*5b3e1433Swyllys /* Put the PKCS#7 stack into the PKCS#12 element. */ 3393*5b3e1433Swyllys if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) { 3394*5b3e1433Swyllys goto cleanup; 3395*5b3e1433Swyllys } 3396*5b3e1433Swyllys 3397*5b3e1433Swyllys /* Set the integrity MAC on the PKCS#12 element. */ 3398*5b3e1433Swyllys if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen, 3399*5b3e1433Swyllys NULL, 0, PKCS12_DEFAULT_ITER, NULL)) { 3400*5b3e1433Swyllys goto cleanup; 3401*5b3e1433Swyllys } 3402*5b3e1433Swyllys 3403*5b3e1433Swyllys /* Write the PKCS#12 element to the export file. */ 3404*5b3e1433Swyllys if (!i2d_PKCS12_bio(bio, p12_elem)) { 3405*5b3e1433Swyllys goto cleanup; 3406*5b3e1433Swyllys } 3407*5b3e1433Swyllys PKCS12_free(p12_elem); 3408*5b3e1433Swyllys 340999ebb4caSwyllys cleanup: 3410*5b3e1433Swyllys /* Clear away the PKCS#7 stack, we're done with it. */ 3411*5b3e1433Swyllys if (authsafe_stack) 3412*5b3e1433Swyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 341399ebb4caSwyllys 341499ebb4caSwyllys if (bio != NULL) 341599ebb4caSwyllys (void) BIO_free_all(bio); 341699ebb4caSwyllys 341799ebb4caSwyllys return (rv); 341899ebb4caSwyllys } 341999ebb4caSwyllys 342099ebb4caSwyllys KMF_RETURN 342130a5e8faSwyllys openssl_build_pk12(KMF_HANDLE_T handle, int numcerts, 342230a5e8faSwyllys KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist, 342330a5e8faSwyllys KMF_CREDENTIAL *p12cred, char *filename) 342430a5e8faSwyllys { 342530a5e8faSwyllys KMF_RETURN rv; 342630a5e8faSwyllys 342730a5e8faSwyllys if (certlist == NULL && keylist == NULL) 342830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 342930a5e8faSwyllys 3430*5b3e1433Swyllys rv = local_export_pk12(handle, p12cred, numcerts, certlist, 343130a5e8faSwyllys numkeys, keylist, filename); 343230a5e8faSwyllys 343330a5e8faSwyllys return (rv); 343430a5e8faSwyllys } 343530a5e8faSwyllys 343630a5e8faSwyllys KMF_RETURN 343730a5e8faSwyllys OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 343899ebb4caSwyllys { 343999ebb4caSwyllys KMF_RETURN rv; 344099ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 344199ebb4caSwyllys char *fullpath = NULL; 344230a5e8faSwyllys char *dirpath = NULL; 344330a5e8faSwyllys char *certfile = NULL; 344430a5e8faSwyllys char *keyfile = NULL; 344530a5e8faSwyllys char *filename = NULL; 344630a5e8faSwyllys KMF_CREDENTIAL *p12cred = NULL; 3447*5b3e1433Swyllys KMF_X509_DER_CERT certdata; 3448*5b3e1433Swyllys KMF_KEY_HANDLE key; 3449*5b3e1433Swyllys int gotkey = 0; 3450*5b3e1433Swyllys int gotcert = 0; 345130a5e8faSwyllys 345230a5e8faSwyllys if (handle == NULL) 345330a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 345499ebb4caSwyllys 345599ebb4caSwyllys /* 345699ebb4caSwyllys * First, find the certificate. 345799ebb4caSwyllys */ 345830a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 345930a5e8faSwyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 346030a5e8faSwyllys if (certfile != NULL) { 346130a5e8faSwyllys fullpath = get_fullpath(dirpath, certfile); 346299ebb4caSwyllys if (fullpath == NULL) 346399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 346499ebb4caSwyllys 346599ebb4caSwyllys if (isdir(fullpath)) { 346699ebb4caSwyllys free(fullpath); 346799ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 346899ebb4caSwyllys } 346999ebb4caSwyllys 3470*5b3e1433Swyllys (void) memset(&certdata, 0, sizeof (certdata)); 3471*5b3e1433Swyllys rv = kmf_load_cert(kmfh, NULL, NULL, NULL, NULL, 3472*5b3e1433Swyllys fullpath, &certdata.certificate); 347399ebb4caSwyllys if (rv != KMF_OK) 347499ebb4caSwyllys goto end; 347530a5e8faSwyllys 3476*5b3e1433Swyllys gotcert++; 3477*5b3e1433Swyllys certdata.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL; 347830a5e8faSwyllys free(fullpath); 347999ebb4caSwyllys } 348099ebb4caSwyllys 348199ebb4caSwyllys /* 348299ebb4caSwyllys * Now find the private key. 348399ebb4caSwyllys */ 348430a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 348530a5e8faSwyllys if (keyfile != NULL) { 348630a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 348799ebb4caSwyllys if (fullpath == NULL) 348899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 348999ebb4caSwyllys 349099ebb4caSwyllys if (isdir(fullpath)) { 349199ebb4caSwyllys free(fullpath); 349299ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 349399ebb4caSwyllys } 349499ebb4caSwyllys 3495*5b3e1433Swyllys (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE)); 3496*5b3e1433Swyllys rv = fetch_key(handle, fullpath, KMF_ASYM_PRI, &key); 3497*5b3e1433Swyllys if (rv != KMF_OK) 349899ebb4caSwyllys goto end; 3499*5b3e1433Swyllys gotkey++; 350099ebb4caSwyllys } 350199ebb4caSwyllys 350299ebb4caSwyllys /* 350399ebb4caSwyllys * Open the output file. 350499ebb4caSwyllys */ 350530a5e8faSwyllys filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, 350630a5e8faSwyllys numattr); 350730a5e8faSwyllys if (filename == NULL) { 350830a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 350930a5e8faSwyllys goto end; 351030a5e8faSwyllys } 351130a5e8faSwyllys 351299ebb4caSwyllys /* Stick the key and the cert into a PKCS#12 file */ 351330a5e8faSwyllys p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); 351430a5e8faSwyllys if (p12cred == NULL) { 351530a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 351630a5e8faSwyllys goto end; 351730a5e8faSwyllys } 351830a5e8faSwyllys 3519*5b3e1433Swyllys rv = local_export_pk12(handle, p12cred, 1, &certdata, 3520*5b3e1433Swyllys 1, &key, filename); 352199ebb4caSwyllys 352299ebb4caSwyllys end: 352399ebb4caSwyllys if (fullpath) 352499ebb4caSwyllys free(fullpath); 352599ebb4caSwyllys 3526*5b3e1433Swyllys if (gotcert) 3527*5b3e1433Swyllys kmf_free_kmf_cert(handle, &certdata); 3528*5b3e1433Swyllys if (gotkey) 3529*5b3e1433Swyllys kmf_free_kmf_key(handle, &key); 353099ebb4caSwyllys return (rv); 353199ebb4caSwyllys } 353299ebb4caSwyllys 353371593db2Swyllys /* 353471593db2Swyllys * Helper function to extract keys and certificates from 353571593db2Swyllys * a single PEM file. Typically the file should contain a 353671593db2Swyllys * private key and an associated public key wrapped in an x509 cert. 353771593db2Swyllys * However, the file may be just a list of X509 certs with no keys. 353871593db2Swyllys */ 353971593db2Swyllys static KMF_RETURN 354030a5e8faSwyllys extract_pem(KMF_HANDLE *kmfh, 354130a5e8faSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 354202744e81Swyllys char *filename, CK_UTF8CHAR *pin, 354371593db2Swyllys CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs, 354471593db2Swyllys int *numcerts) 354571593db2Swyllys /* ARGSUSED */ 354671593db2Swyllys { 354771593db2Swyllys KMF_RETURN rv = KMF_OK; 354871593db2Swyllys FILE *fp; 354934acef67Swyllys STACK_OF(X509_INFO) *x509_info_stack = NULL; 355002744e81Swyllys int i, ncerts = 0, matchcerts = 0; 355171593db2Swyllys EVP_PKEY *pkey = NULL; 355271593db2Swyllys X509_INFO *info; 355371593db2Swyllys X509 *x; 3554*5b3e1433Swyllys X509_INFO **cert_infos = NULL; 355571593db2Swyllys KMF_DATA *certlist = NULL; 355671593db2Swyllys 355771593db2Swyllys if (priv_key) 355871593db2Swyllys *priv_key = NULL; 355971593db2Swyllys if (certs) 356071593db2Swyllys *certs = NULL; 356171593db2Swyllys fp = fopen(filename, "r"); 3562*5b3e1433Swyllys if (fp == NULL) 356371593db2Swyllys return (KMF_ERR_OPEN_FILE); 3564*5b3e1433Swyllys 356571593db2Swyllys x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin); 356671593db2Swyllys if (x509_info_stack == NULL) { 356771593db2Swyllys (void) fclose(fp); 356871593db2Swyllys return (KMF_ERR_ENCODING); 356971593db2Swyllys } 3570*5b3e1433Swyllys cert_infos = (X509_INFO **)malloc(sk_X509_INFO_num(x509_info_stack) * 3571*5b3e1433Swyllys sizeof (X509_INFO *)); 3572*5b3e1433Swyllys if (cert_infos == NULL) { 3573*5b3e1433Swyllys (void) fclose(fp); 3574*5b3e1433Swyllys rv = KMF_ERR_MEMORY; 3575*5b3e1433Swyllys goto err; 3576*5b3e1433Swyllys } 357771593db2Swyllys 3578*5b3e1433Swyllys for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) { 357971593db2Swyllys /* LINTED */ 358034acef67Swyllys cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i); 358171593db2Swyllys ncerts++; 358271593db2Swyllys } 358371593db2Swyllys 358471593db2Swyllys if (ncerts == 0) { 358571593db2Swyllys (void) fclose(fp); 358634acef67Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 358734acef67Swyllys goto err; 358871593db2Swyllys } 358971593db2Swyllys 359071593db2Swyllys if (priv_key != NULL) { 359171593db2Swyllys rewind(fp); 359271593db2Swyllys pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin); 359371593db2Swyllys } 359471593db2Swyllys (void) fclose(fp); 359571593db2Swyllys 359671593db2Swyllys x = cert_infos[ncerts - 1]->x509; 359771593db2Swyllys /* 359871593db2Swyllys * Make sure the private key matchs the last cert in the file. 359971593db2Swyllys */ 360071593db2Swyllys if (pkey != NULL && !X509_check_private_key(x, pkey)) { 360171593db2Swyllys EVP_PKEY_free(pkey); 360234acef67Swyllys rv = KMF_ERR_KEY_MISMATCH; 360334acef67Swyllys goto err; 360471593db2Swyllys } 360571593db2Swyllys 360671593db2Swyllys certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA)); 360771593db2Swyllys if (certlist == NULL) { 360871593db2Swyllys if (pkey != NULL) 360971593db2Swyllys EVP_PKEY_free(pkey); 361034acef67Swyllys rv = KMF_ERR_MEMORY; 361134acef67Swyllys goto err; 361271593db2Swyllys } 361371593db2Swyllys 361471593db2Swyllys /* 361571593db2Swyllys * Convert all of the certs to DER format. 361671593db2Swyllys */ 361702744e81Swyllys matchcerts = 0; 361871593db2Swyllys for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) { 361902744e81Swyllys boolean_t match = FALSE; 362071593db2Swyllys info = cert_infos[ncerts - 1 - i]; 362171593db2Swyllys 362230a5e8faSwyllys rv = check_cert(info->x509, issuer, subject, serial, &match); 362302744e81Swyllys if (rv != KMF_OK || match != TRUE) { 362402744e81Swyllys rv = KMF_OK; 362502744e81Swyllys continue; 362602744e81Swyllys } 362702744e81Swyllys 362802744e81Swyllys rv = ssl_cert2KMFDATA(kmfh, info->x509, 362902744e81Swyllys &certlist[matchcerts++]); 363071593db2Swyllys 363171593db2Swyllys if (rv != KMF_OK) { 363271593db2Swyllys free(certlist); 363371593db2Swyllys certlist = NULL; 363402744e81Swyllys ncerts = matchcerts = 0; 363571593db2Swyllys } 363671593db2Swyllys } 363771593db2Swyllys 363871593db2Swyllys if (numcerts != NULL) 363902744e81Swyllys *numcerts = matchcerts; 364071593db2Swyllys if (certs != NULL) 364171593db2Swyllys *certs = certlist; 364271593db2Swyllys 364371593db2Swyllys if (priv_key == NULL && pkey != NULL) 364471593db2Swyllys EVP_PKEY_free(pkey); 364571593db2Swyllys else if (priv_key != NULL && pkey != NULL) 364671593db2Swyllys *priv_key = pkey; 364771593db2Swyllys 364834acef67Swyllys err: 364934acef67Swyllys /* Cleanup the stack of X509 info records */ 365034acef67Swyllys for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) { 365134acef67Swyllys /*LINTED*/ 365234acef67Swyllys info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i); 365334acef67Swyllys X509_INFO_free(info); 365434acef67Swyllys } 365534acef67Swyllys if (x509_info_stack) 365634acef67Swyllys sk_X509_INFO_free(x509_info_stack); 365734acef67Swyllys 3658*5b3e1433Swyllys if (cert_infos != NULL) 3659*5b3e1433Swyllys free(cert_infos); 3660*5b3e1433Swyllys 366171593db2Swyllys return (rv); 366271593db2Swyllys } 366371593db2Swyllys 3664*5b3e1433Swyllys static KMF_RETURN 3665*5b3e1433Swyllys openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin, 3666*5b3e1433Swyllys STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs) 3667*5b3e1433Swyllys { 3668*5b3e1433Swyllys KMF_RETURN ret; 3669*5b3e1433Swyllys int i; 3670*5b3e1433Swyllys 3671*5b3e1433Swyllys for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 3672*5b3e1433Swyllys /*LINTED*/ 3673*5b3e1433Swyllys PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i); 3674*5b3e1433Swyllys ret = openssl_parse_bag(bag, pin, (pin ? strlen(pin) : 0), 3675*5b3e1433Swyllys keys, certs); 3676*5b3e1433Swyllys 3677*5b3e1433Swyllys if (ret != KMF_OK) 3678*5b3e1433Swyllys return (ret); 3679*5b3e1433Swyllys } 3680*5b3e1433Swyllys 3681*5b3e1433Swyllys return (ret); 3682*5b3e1433Swyllys } 3683*5b3e1433Swyllys 3684*5b3e1433Swyllys static KMF_RETURN 3685*5b3e1433Swyllys set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid) 3686*5b3e1433Swyllys { 3687*5b3e1433Swyllys X509_ATTRIBUTE *attr = NULL; 3688*5b3e1433Swyllys 3689*5b3e1433Swyllys if (pkey == NULL || attrib == NULL) 3690*5b3e1433Swyllys return (KMF_ERR_BAD_PARAMETER); 3691*5b3e1433Swyllys 3692*5b3e1433Swyllys if (pkey->attributes == NULL) { 3693*5b3e1433Swyllys pkey->attributes = sk_X509_ATTRIBUTE_new_null(); 3694*5b3e1433Swyllys if (pkey->attributes == NULL) 3695*5b3e1433Swyllys return (KMF_ERR_MEMORY); 3696*5b3e1433Swyllys } 3697*5b3e1433Swyllys attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr); 3698*5b3e1433Swyllys if (attr != NULL) { 3699*5b3e1433Swyllys int i; 3700*5b3e1433Swyllys X509_ATTRIBUTE *a; 3701*5b3e1433Swyllys for (i = 0; 3702*5b3e1433Swyllys i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) { 3703*5b3e1433Swyllys /*LINTED*/ 3704*5b3e1433Swyllys a = sk_X509_ATTRIBUTE_value(pkey->attributes, i); 3705*5b3e1433Swyllys if (OBJ_obj2nid(a->object) == nid) { 3706*5b3e1433Swyllys X509_ATTRIBUTE_free(a); 3707*5b3e1433Swyllys /*LINTED*/ 3708*5b3e1433Swyllys sk_X509_ATTRIBUTE_set(pkey->attributes, 3709*5b3e1433Swyllys i, attr); 3710*5b3e1433Swyllys return (KMF_OK); 3711*5b3e1433Swyllys } 3712*5b3e1433Swyllys } 3713*5b3e1433Swyllys if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) { 3714*5b3e1433Swyllys X509_ATTRIBUTE_free(attr); 3715*5b3e1433Swyllys return (KMF_ERR_MEMORY); 3716*5b3e1433Swyllys } 3717*5b3e1433Swyllys } else { 3718*5b3e1433Swyllys return (KMF_ERR_MEMORY); 3719*5b3e1433Swyllys } 3720*5b3e1433Swyllys 3721*5b3e1433Swyllys return (KMF_OK); 3722*5b3e1433Swyllys } 3723*5b3e1433Swyllys 3724*5b3e1433Swyllys static KMF_RETURN 3725*5b3e1433Swyllys openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen, 3726*5b3e1433Swyllys STACK_OF(EVP_PKEY) *keylist, STACK_OF(X509) *certlist) 3727*5b3e1433Swyllys { 3728*5b3e1433Swyllys KMF_RETURN ret = KMF_OK; 3729*5b3e1433Swyllys PKCS8_PRIV_KEY_INFO *p8 = NULL; 3730*5b3e1433Swyllys EVP_PKEY *pkey = NULL; 3731*5b3e1433Swyllys X509 *xcert = NULL; 3732*5b3e1433Swyllys ASN1_TYPE *keyid = NULL; 3733*5b3e1433Swyllys ASN1_TYPE *fname = NULL; 3734*5b3e1433Swyllys uchar_t *data = NULL; 3735*5b3e1433Swyllys 3736*5b3e1433Swyllys keyid = PKCS12_get_attr(bag, NID_localKeyID); 3737*5b3e1433Swyllys fname = PKCS12_get_attr(bag, NID_friendlyName); 3738*5b3e1433Swyllys 3739*5b3e1433Swyllys switch (M_PKCS12_bag_type(bag)) { 3740*5b3e1433Swyllys case NID_keyBag: 3741*5b3e1433Swyllys if (keylist == NULL) 3742*5b3e1433Swyllys goto end; 3743*5b3e1433Swyllys pkey = EVP_PKCS82PKEY(bag->value.keybag); 3744*5b3e1433Swyllys if (pkey == NULL) 3745*5b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 3746*5b3e1433Swyllys 3747*5b3e1433Swyllys break; 3748*5b3e1433Swyllys case NID_pkcs8ShroudedKeyBag: 3749*5b3e1433Swyllys if (keylist == NULL) 3750*5b3e1433Swyllys goto end; 3751*5b3e1433Swyllys p8 = M_PKCS12_decrypt_skey(bag, pass, passlen); 3752*5b3e1433Swyllys if (p8 == NULL) 3753*5b3e1433Swyllys return (KMF_ERR_AUTH_FAILED); 3754*5b3e1433Swyllys pkey = EVP_PKCS82PKEY(p8); 3755*5b3e1433Swyllys PKCS8_PRIV_KEY_INFO_free(p8); 3756*5b3e1433Swyllys if (pkey == NULL) 3757*5b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 3758*5b3e1433Swyllys break; 3759*5b3e1433Swyllys case NID_certBag: 3760*5b3e1433Swyllys if (certlist == NULL) 3761*5b3e1433Swyllys goto end; 3762*5b3e1433Swyllys if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) 3763*5b3e1433Swyllys return (KMF_ERR_PKCS12_FORMAT); 3764*5b3e1433Swyllys xcert = M_PKCS12_certbag2x509(bag); 3765*5b3e1433Swyllys if (xcert == NULL) { 3766*5b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 3767*5b3e1433Swyllys goto end; 3768*5b3e1433Swyllys } 3769*5b3e1433Swyllys if (keyid != NULL) { 3770*5b3e1433Swyllys if (X509_keyid_set1(xcert, 3771*5b3e1433Swyllys keyid->value.octet_string->data, 3772*5b3e1433Swyllys keyid->value.octet_string->length) == 0) { 3773*5b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 3774*5b3e1433Swyllys goto end; 3775*5b3e1433Swyllys } 3776*5b3e1433Swyllys } 3777*5b3e1433Swyllys if (fname != NULL) { 3778*5b3e1433Swyllys int len, r; 3779*5b3e1433Swyllys len = ASN1_STRING_to_UTF8(&data, 3780*5b3e1433Swyllys fname->value.asn1_string); 3781*5b3e1433Swyllys if (len > 0 && data != NULL) { 3782*5b3e1433Swyllys r = X509_alias_set1(xcert, data, len); 3783*5b3e1433Swyllys if (r == NULL) { 3784*5b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 3785*5b3e1433Swyllys goto end; 3786*5b3e1433Swyllys } 3787*5b3e1433Swyllys } else { 3788*5b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 3789*5b3e1433Swyllys goto end; 3790*5b3e1433Swyllys } 3791*5b3e1433Swyllys } 3792*5b3e1433Swyllys if (sk_X509_push(certlist, xcert) == 0) 3793*5b3e1433Swyllys ret = KMF_ERR_MEMORY; 3794*5b3e1433Swyllys else 3795*5b3e1433Swyllys xcert = NULL; 3796*5b3e1433Swyllys break; 3797*5b3e1433Swyllys case NID_safeContentsBag: 3798*5b3e1433Swyllys return (openssl_parse_bags(bag->value.safes, pass, 3799*5b3e1433Swyllys keylist, certlist)); 3800*5b3e1433Swyllys default: 3801*5b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 3802*5b3e1433Swyllys break; 3803*5b3e1433Swyllys } 3804*5b3e1433Swyllys 3805*5b3e1433Swyllys /* 3806*5b3e1433Swyllys * Set the ID and/or FriendlyName attributes on the key. 3807*5b3e1433Swyllys * If converting to PKCS11 objects, these can translate to CKA_ID 3808*5b3e1433Swyllys * and CKA_LABEL values. 3809*5b3e1433Swyllys */ 3810*5b3e1433Swyllys if (pkey != NULL && ret == KMF_OK) { 3811*5b3e1433Swyllys ASN1_TYPE *attr = NULL; 3812*5b3e1433Swyllys if (keyid != NULL && keyid->type == V_ASN1_OCTET_STRING) { 3813*5b3e1433Swyllys if ((attr = ASN1_TYPE_new()) == NULL) 3814*5b3e1433Swyllys return (KMF_ERR_MEMORY); 3815*5b3e1433Swyllys attr->value.octet_string = 3816*5b3e1433Swyllys ASN1_STRING_dup(keyid->value.octet_string); 3817*5b3e1433Swyllys attr->type = V_ASN1_OCTET_STRING; 3818*5b3e1433Swyllys attr->value.ptr = (char *)attr->value.octet_string; 3819*5b3e1433Swyllys ret = set_pkey_attrib(pkey, attr, NID_localKeyID); 3820*5b3e1433Swyllys OPENSSL_free(attr); 3821*5b3e1433Swyllys } 3822*5b3e1433Swyllys 3823*5b3e1433Swyllys if (ret == KMF_OK && fname != NULL && 3824*5b3e1433Swyllys fname->type == V_ASN1_BMPSTRING) { 3825*5b3e1433Swyllys if ((attr = ASN1_TYPE_new()) == NULL) 3826*5b3e1433Swyllys return (KMF_ERR_MEMORY); 3827*5b3e1433Swyllys attr->value.bmpstring = 3828*5b3e1433Swyllys ASN1_STRING_dup(fname->value.bmpstring); 3829*5b3e1433Swyllys attr->type = V_ASN1_BMPSTRING; 3830*5b3e1433Swyllys attr->value.ptr = (char *)attr->value.bmpstring; 3831*5b3e1433Swyllys ret = set_pkey_attrib(pkey, attr, NID_friendlyName); 3832*5b3e1433Swyllys OPENSSL_free(attr); 3833*5b3e1433Swyllys } 3834*5b3e1433Swyllys 3835*5b3e1433Swyllys if (ret == KMF_OK && keylist != NULL && 3836*5b3e1433Swyllys sk_EVP_PKEY_push(keylist, pkey) == 0) 3837*5b3e1433Swyllys ret = KMF_ERR_MEMORY; 3838*5b3e1433Swyllys } 3839*5b3e1433Swyllys if (ret == KMF_OK && keylist != NULL) 3840*5b3e1433Swyllys pkey = NULL; 3841*5b3e1433Swyllys end: 3842*5b3e1433Swyllys if (pkey != NULL) 3843*5b3e1433Swyllys EVP_PKEY_free(pkey); 3844*5b3e1433Swyllys if (xcert != NULL) 3845*5b3e1433Swyllys X509_free(xcert); 3846*5b3e1433Swyllys if (data != NULL) 3847*5b3e1433Swyllys OPENSSL_free(data); 3848*5b3e1433Swyllys 3849*5b3e1433Swyllys return (ret); 3850*5b3e1433Swyllys } 3851*5b3e1433Swyllys 3852*5b3e1433Swyllys static KMF_RETURN 3853*5b3e1433Swyllys openssl_pkcs12_parse(PKCS12 *p12, char *pin, 3854*5b3e1433Swyllys STACK_OF(EVP_PKEY) *keys, 3855*5b3e1433Swyllys STACK_OF(X509) *certs, 3856*5b3e1433Swyllys STACK_OF(X509) *ca) 3857*5b3e1433Swyllys /*ARGSUSED*/ 3858*5b3e1433Swyllys { 3859*5b3e1433Swyllys KMF_RETURN ret = KMF_OK; 3860*5b3e1433Swyllys STACK_OF(PKCS7) *asafes = NULL; 3861*5b3e1433Swyllys STACK_OF(PKCS12_SAFEBAG) *bags = NULL; 3862*5b3e1433Swyllys int i, bagnid; 3863*5b3e1433Swyllys PKCS7 *p7; 3864*5b3e1433Swyllys 3865*5b3e1433Swyllys if (p12 == NULL || (keys == NULL && certs == NULL)) 3866*5b3e1433Swyllys return (KMF_ERR_BAD_PARAMETER); 3867*5b3e1433Swyllys 3868*5b3e1433Swyllys if (pin == NULL || *pin == NULL) { 3869*5b3e1433Swyllys if (PKCS12_verify_mac(p12, NULL, 0)) { 3870*5b3e1433Swyllys pin = NULL; 3871*5b3e1433Swyllys } else if (PKCS12_verify_mac(p12, "", 0)) { 3872*5b3e1433Swyllys pin = ""; 3873*5b3e1433Swyllys } else { 3874*5b3e1433Swyllys return (KMF_ERR_AUTH_FAILED); 3875*5b3e1433Swyllys } 3876*5b3e1433Swyllys } else if (!PKCS12_verify_mac(p12, pin, -1)) { 3877*5b3e1433Swyllys return (KMF_ERR_AUTH_FAILED); 3878*5b3e1433Swyllys } 3879*5b3e1433Swyllys 3880*5b3e1433Swyllys if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) 3881*5b3e1433Swyllys return (KMF_ERR_PKCS12_FORMAT); 3882*5b3e1433Swyllys 3883*5b3e1433Swyllys for (i = 0; ret == KMF_OK && i < sk_PKCS7_num(asafes); i++) { 3884*5b3e1433Swyllys bags = NULL; 3885*5b3e1433Swyllys /*LINTED*/ 3886*5b3e1433Swyllys p7 = sk_PKCS7_value(asafes, i); 3887*5b3e1433Swyllys bagnid = OBJ_obj2nid(p7->type); 3888*5b3e1433Swyllys 3889*5b3e1433Swyllys if (bagnid == NID_pkcs7_data) { 3890*5b3e1433Swyllys bags = PKCS12_unpack_p7data(p7); 3891*5b3e1433Swyllys } else if (bagnid == NID_pkcs7_encrypted) { 3892*5b3e1433Swyllys bags = PKCS12_unpack_p7encdata(p7, pin, 3893*5b3e1433Swyllys (pin ? strlen(pin) : 0)); 3894*5b3e1433Swyllys } else { 3895*5b3e1433Swyllys continue; 3896*5b3e1433Swyllys } 3897*5b3e1433Swyllys if (bags == NULL) { 3898*5b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 3899*5b3e1433Swyllys goto out; 3900*5b3e1433Swyllys } 3901*5b3e1433Swyllys 3902*5b3e1433Swyllys if (openssl_parse_bags(bags, pin, keys, certs) != KMF_OK) 3903*5b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 3904*5b3e1433Swyllys 3905*5b3e1433Swyllys sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 3906*5b3e1433Swyllys } 3907*5b3e1433Swyllys out: 3908*5b3e1433Swyllys if (asafes != NULL) 3909*5b3e1433Swyllys sk_PKCS7_pop_free(asafes, PKCS7_free); 3910*5b3e1433Swyllys 3911*5b3e1433Swyllys return (ret); 3912*5b3e1433Swyllys } 3913*5b3e1433Swyllys 391499ebb4caSwyllys /* 391599ebb4caSwyllys * Helper function to decrypt and parse PKCS#12 import file. 391699ebb4caSwyllys */ 391799ebb4caSwyllys static KMF_RETURN 391899ebb4caSwyllys extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 3919*5b3e1433Swyllys STACK_OF(EVP_PKEY) **priv_key, STACK_OF(X509) **certs, 3920*5b3e1433Swyllys STACK_OF(X509) **ca) 392199ebb4caSwyllys /* ARGSUSED */ 392299ebb4caSwyllys { 392399ebb4caSwyllys PKCS12 *pk12, *pk12_tmp; 3924*5b3e1433Swyllys STACK_OF(EVP_PKEY) *pkeylist = NULL; 3925*5b3e1433Swyllys STACK_OF(X509) *xcertlist = NULL; 3926*5b3e1433Swyllys STACK_OF(X509) *cacertlist = NULL; 392799ebb4caSwyllys 392899ebb4caSwyllys if ((pk12 = PKCS12_new()) == NULL) { 392999ebb4caSwyllys return (KMF_ERR_MEMORY); 393099ebb4caSwyllys } 393199ebb4caSwyllys 393299ebb4caSwyllys if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) { 393399ebb4caSwyllys /* This is ok; it seems to mean there is no more to read. */ 393499ebb4caSwyllys if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 && 393599ebb4caSwyllys ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG) 393699ebb4caSwyllys goto end_extract_pkcs12; 393799ebb4caSwyllys 393899ebb4caSwyllys PKCS12_free(pk12); 393999ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 394099ebb4caSwyllys } 394199ebb4caSwyllys pk12 = pk12_tmp; 394299ebb4caSwyllys 3943*5b3e1433Swyllys xcertlist = sk_X509_new_null(); 3944*5b3e1433Swyllys if (xcertlist == NULL) { 3945*5b3e1433Swyllys PKCS12_free(pk12); 3946*5b3e1433Swyllys return (KMF_ERR_MEMORY); 3947*5b3e1433Swyllys } 3948*5b3e1433Swyllys pkeylist = sk_EVP_PKEY_new_null(); 3949*5b3e1433Swyllys if (pkeylist == NULL) { 3950*5b3e1433Swyllys sk_X509_pop_free(xcertlist, X509_free); 3951*5b3e1433Swyllys PKCS12_free(pk12); 3952*5b3e1433Swyllys return (KMF_ERR_MEMORY); 3953*5b3e1433Swyllys } 3954*5b3e1433Swyllys 3955*5b3e1433Swyllys if (openssl_pkcs12_parse(pk12, (char *)pin, pkeylist, xcertlist, 3956*5b3e1433Swyllys cacertlist) != KMF_OK) { 3957*5b3e1433Swyllys sk_X509_pop_free(xcertlist, X509_free); 3958*5b3e1433Swyllys sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free); 395999ebb4caSwyllys PKCS12_free(pk12); 396099ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 396199ebb4caSwyllys } 396299ebb4caSwyllys 3963*5b3e1433Swyllys if (priv_key && pkeylist) 3964*5b3e1433Swyllys *priv_key = pkeylist; 3965*5b3e1433Swyllys else if (pkeylist) 3966*5b3e1433Swyllys sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free); 3967*5b3e1433Swyllys if (certs && xcertlist) 3968*5b3e1433Swyllys *certs = xcertlist; 3969*5b3e1433Swyllys else if (xcertlist) 3970*5b3e1433Swyllys sk_X509_pop_free(xcertlist, X509_free); 3971*5b3e1433Swyllys if (ca && cacertlist) 3972*5b3e1433Swyllys *ca = cacertlist; 3973*5b3e1433Swyllys else if (cacertlist) 3974*5b3e1433Swyllys sk_X509_pop_free(cacertlist, X509_free); 397599ebb4caSwyllys 3976*5b3e1433Swyllys end_extract_pkcs12: 397799ebb4caSwyllys 397899ebb4caSwyllys PKCS12_free(pk12); 397999ebb4caSwyllys return (KMF_OK); 398099ebb4caSwyllys } 398199ebb4caSwyllys 398299ebb4caSwyllys static KMF_RETURN 398399ebb4caSwyllys sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to) 398499ebb4caSwyllys { 398599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 398699ebb4caSwyllys uint32_t sz; 398799ebb4caSwyllys 398899ebb4caSwyllys sz = BN_num_bytes(from); 398999ebb4caSwyllys to->val = (uchar_t *)malloc(sz); 399099ebb4caSwyllys if (to->val == NULL) 399199ebb4caSwyllys return (KMF_ERR_MEMORY); 399299ebb4caSwyllys 399399ebb4caSwyllys if ((to->len = BN_bn2bin(from, to->val)) != sz) { 399499ebb4caSwyllys free(to->val); 399599ebb4caSwyllys to->val = NULL; 399699ebb4caSwyllys to->len = 0; 399799ebb4caSwyllys rv = KMF_ERR_MEMORY; 399899ebb4caSwyllys } 399999ebb4caSwyllys 400099ebb4caSwyllys return (rv); 400199ebb4caSwyllys } 400299ebb4caSwyllys 400399ebb4caSwyllys static KMF_RETURN 400499ebb4caSwyllys exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) 400599ebb4caSwyllys { 400699ebb4caSwyllys KMF_RETURN rv; 400799ebb4caSwyllys KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa; 400899ebb4caSwyllys 400999ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY)); 401099ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK) 401199ebb4caSwyllys goto cleanup; 401299ebb4caSwyllys 401399ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK) 401499ebb4caSwyllys goto cleanup; 401599ebb4caSwyllys 401699ebb4caSwyllys if (rsa->d != NULL) 401799ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK) 401899ebb4caSwyllys goto cleanup; 401999ebb4caSwyllys 402099ebb4caSwyllys if (rsa->p != NULL) 402199ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK) 402299ebb4caSwyllys goto cleanup; 402399ebb4caSwyllys 402499ebb4caSwyllys if (rsa->q != NULL) 402599ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK) 402699ebb4caSwyllys goto cleanup; 402799ebb4caSwyllys 402899ebb4caSwyllys if (rsa->dmp1 != NULL) 402999ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK) 403099ebb4caSwyllys goto cleanup; 403199ebb4caSwyllys 403299ebb4caSwyllys if (rsa->dmq1 != NULL) 403399ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK) 403499ebb4caSwyllys goto cleanup; 403599ebb4caSwyllys 403699ebb4caSwyllys if (rsa->iqmp != NULL) 403799ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK) 403899ebb4caSwyllys goto cleanup; 403999ebb4caSwyllys cleanup: 404099ebb4caSwyllys if (rv != KMF_OK) 404130a5e8faSwyllys kmf_free_raw_key(key); 404299ebb4caSwyllys else 404399ebb4caSwyllys key->keytype = KMF_RSA; 404499ebb4caSwyllys 404599ebb4caSwyllys /* 404699ebb4caSwyllys * Free the reference to this key, SSL will not actually free 404799ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 404899ebb4caSwyllys */ 404999ebb4caSwyllys RSA_free(rsa); 405099ebb4caSwyllys 405199ebb4caSwyllys return (rv); 405299ebb4caSwyllys } 405399ebb4caSwyllys 405499ebb4caSwyllys static KMF_RETURN 405599ebb4caSwyllys exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) 405699ebb4caSwyllys { 405799ebb4caSwyllys KMF_RETURN rv; 405899ebb4caSwyllys KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa; 405999ebb4caSwyllys 406099ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY)); 406199ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK) 406299ebb4caSwyllys goto cleanup; 406399ebb4caSwyllys 406499ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK) 406599ebb4caSwyllys goto cleanup; 406699ebb4caSwyllys 406799ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK) 406899ebb4caSwyllys goto cleanup; 406999ebb4caSwyllys 407099ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK) 407199ebb4caSwyllys goto cleanup; 407299ebb4caSwyllys 407399ebb4caSwyllys cleanup: 407499ebb4caSwyllys if (rv != KMF_OK) 407530a5e8faSwyllys kmf_free_raw_key(key); 407699ebb4caSwyllys else 407799ebb4caSwyllys key->keytype = KMF_DSA; 407899ebb4caSwyllys 407999ebb4caSwyllys /* 408099ebb4caSwyllys * Free the reference to this key, SSL will not actually free 408199ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 408299ebb4caSwyllys */ 408399ebb4caSwyllys DSA_free(dsa); 408499ebb4caSwyllys 408599ebb4caSwyllys return (rv); 408699ebb4caSwyllys } 408799ebb4caSwyllys 408899ebb4caSwyllys static KMF_RETURN 408999ebb4caSwyllys add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert, 4090*5b3e1433Swyllys KMF_X509_DER_CERT **certlist, int *ncerts) 409199ebb4caSwyllys { 409299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 4093*5b3e1433Swyllys KMF_X509_DER_CERT *list = (*certlist); 4094*5b3e1433Swyllys KMF_X509_DER_CERT cert; 409599ebb4caSwyllys int n = (*ncerts); 409699ebb4caSwyllys 409799ebb4caSwyllys if (list == NULL) { 4098*5b3e1433Swyllys list = (KMF_X509_DER_CERT *)malloc(sizeof (KMF_X509_DER_CERT)); 409999ebb4caSwyllys } else { 4100*5b3e1433Swyllys list = (KMF_X509_DER_CERT *)realloc(list, 4101*5b3e1433Swyllys sizeof (KMF_X509_DER_CERT) * (n + 1)); 410299ebb4caSwyllys } 410399ebb4caSwyllys 410499ebb4caSwyllys if (list == NULL) 410599ebb4caSwyllys return (KMF_ERR_MEMORY); 410699ebb4caSwyllys 4107*5b3e1433Swyllys (void) memset(&cert, 0, sizeof (cert)); 4108*5b3e1433Swyllys rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert.certificate); 410999ebb4caSwyllys if (rv == KMF_OK) { 4110*5b3e1433Swyllys int len = 0; 4111*5b3e1433Swyllys /* Get the alias name for the cert if there is one */ 4112*5b3e1433Swyllys char *a = (char *)X509_alias_get0(sslcert, &len); 4113*5b3e1433Swyllys if (a != NULL) 4114*5b3e1433Swyllys cert.kmf_private.label = strdup(a); 4115*5b3e1433Swyllys cert.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL; 4116*5b3e1433Swyllys 411799ebb4caSwyllys list[n] = cert; 411899ebb4caSwyllys (*ncerts) = n + 1; 411999ebb4caSwyllys 412099ebb4caSwyllys *certlist = list; 412199ebb4caSwyllys } else { 412299ebb4caSwyllys free(list); 412399ebb4caSwyllys } 412499ebb4caSwyllys 412599ebb4caSwyllys return (rv); 412699ebb4caSwyllys } 412799ebb4caSwyllys 412899ebb4caSwyllys static KMF_RETURN 412999ebb4caSwyllys add_key_to_list(KMF_RAW_KEY_DATA **keylist, 413099ebb4caSwyllys KMF_RAW_KEY_DATA *newkey, int *nkeys) 413199ebb4caSwyllys { 413299ebb4caSwyllys KMF_RAW_KEY_DATA *list = (*keylist); 413399ebb4caSwyllys int n = (*nkeys); 413499ebb4caSwyllys 413599ebb4caSwyllys if (list == NULL) { 413699ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA)); 413799ebb4caSwyllys } else { 413899ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)realloc(list, 413999ebb4caSwyllys sizeof (KMF_RAW_KEY_DATA) * (n + 1)); 414099ebb4caSwyllys } 414199ebb4caSwyllys 414299ebb4caSwyllys if (list == NULL) 414399ebb4caSwyllys return (KMF_ERR_MEMORY); 414499ebb4caSwyllys 414599ebb4caSwyllys list[n] = *newkey; 414699ebb4caSwyllys (*nkeys) = n + 1; 414799ebb4caSwyllys 414899ebb4caSwyllys *keylist = list; 414999ebb4caSwyllys 415099ebb4caSwyllys return (KMF_OK); 415199ebb4caSwyllys } 415299ebb4caSwyllys 4153*5b3e1433Swyllys static X509_ATTRIBUTE * 4154*5b3e1433Swyllys find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid) 4155*5b3e1433Swyllys { 4156*5b3e1433Swyllys X509_ATTRIBUTE *a; 4157*5b3e1433Swyllys int i; 4158*5b3e1433Swyllys 4159*5b3e1433Swyllys if (attrs == NULL) 4160*5b3e1433Swyllys return (NULL); 4161*5b3e1433Swyllys 4162*5b3e1433Swyllys for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { 4163*5b3e1433Swyllys /*LINTED*/ 4164*5b3e1433Swyllys a = sk_X509_ATTRIBUTE_value(attrs, i); 4165*5b3e1433Swyllys if (OBJ_obj2nid(a->object) == nid) 4166*5b3e1433Swyllys return (a); 4167*5b3e1433Swyllys } 4168*5b3e1433Swyllys return (NULL); 4169*5b3e1433Swyllys } 4170*5b3e1433Swyllys 417130a5e8faSwyllys static KMF_RETURN 417230a5e8faSwyllys convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key) 417330a5e8faSwyllys { 417430a5e8faSwyllys KMF_RETURN rv = KMF_OK; 4175*5b3e1433Swyllys X509_ATTRIBUTE *attr; 417630a5e8faSwyllys 417730a5e8faSwyllys if (pkey == NULL || key == NULL) 417830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 417930a5e8faSwyllys /* Convert SSL key to raw key */ 418030a5e8faSwyllys switch (pkey->type) { 418130a5e8faSwyllys case EVP_PKEY_RSA: 418230a5e8faSwyllys rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey), 418330a5e8faSwyllys key); 418430a5e8faSwyllys if (rv != KMF_OK) 418530a5e8faSwyllys return (rv); 418630a5e8faSwyllys break; 418730a5e8faSwyllys case EVP_PKEY_DSA: 418830a5e8faSwyllys rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey), 418930a5e8faSwyllys key); 419030a5e8faSwyllys if (rv != KMF_OK) 419130a5e8faSwyllys return (rv); 419230a5e8faSwyllys break; 419330a5e8faSwyllys default: 419430a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 419530a5e8faSwyllys } 4196*5b3e1433Swyllys /* 4197*5b3e1433Swyllys * If friendlyName, add it to record. 4198*5b3e1433Swyllys */ 4199*5b3e1433Swyllys attr = find_attr(pkey->attributes, NID_friendlyName); 4200*5b3e1433Swyllys if (attr != NULL) { 4201*5b3e1433Swyllys ASN1_TYPE *ty = NULL; 4202*5b3e1433Swyllys int numattr = sk_ASN1_TYPE_num(attr->value.set); 4203*5b3e1433Swyllys if (attr->single == 0 && numattr > 0) { 4204*5b3e1433Swyllys /*LINTED*/ 4205*5b3e1433Swyllys ty = sk_ASN1_TYPE_value(attr->value.set, 0); 4206*5b3e1433Swyllys } 4207*5b3e1433Swyllys if (ty != NULL) { 4208*5b3e1433Swyllys key->label = uni2asc(ty->value.bmpstring->data, 4209*5b3e1433Swyllys ty->value.bmpstring->length); 4210*5b3e1433Swyllys } 4211*5b3e1433Swyllys } else { 4212*5b3e1433Swyllys key->label = NULL; 4213*5b3e1433Swyllys } 4214*5b3e1433Swyllys 4215*5b3e1433Swyllys /* 4216*5b3e1433Swyllys * If KeyID, add it to record as a KMF_DATA object. 4217*5b3e1433Swyllys */ 4218*5b3e1433Swyllys attr = find_attr(pkey->attributes, NID_localKeyID); 4219*5b3e1433Swyllys if (attr != NULL) { 4220*5b3e1433Swyllys ASN1_TYPE *ty = NULL; 4221*5b3e1433Swyllys int numattr = sk_ASN1_TYPE_num(attr->value.set); 4222*5b3e1433Swyllys if (attr->single == 0 && numattr > 0) { 4223*5b3e1433Swyllys /*LINTED*/ 4224*5b3e1433Swyllys ty = sk_ASN1_TYPE_value(attr->value.set, 0); 4225*5b3e1433Swyllys } 4226*5b3e1433Swyllys key->id.Data = (uchar_t *)malloc( 4227*5b3e1433Swyllys ty->value.octet_string->length); 4228*5b3e1433Swyllys if (key->id.Data == NULL) 4229*5b3e1433Swyllys return (KMF_ERR_MEMORY); 4230*5b3e1433Swyllys (void) memcpy(key->id.Data, ty->value.octet_string->data, 4231*5b3e1433Swyllys ty->value.octet_string->length); 4232*5b3e1433Swyllys key->id.Length = ty->value.octet_string->length; 4233*5b3e1433Swyllys } else { 4234*5b3e1433Swyllys (void) memset(&key->id, 0, sizeof (KMF_DATA)); 4235*5b3e1433Swyllys } 423630a5e8faSwyllys 423730a5e8faSwyllys return (rv); 423830a5e8faSwyllys } 423999ebb4caSwyllys 424099ebb4caSwyllys static KMF_RETURN 424199ebb4caSwyllys convertPK12Objects( 424299ebb4caSwyllys KMF_HANDLE *kmfh, 4243*5b3e1433Swyllys STACK_OF(EVP_PKEY) *sslkeys, 4244*5b3e1433Swyllys STACK_OF(X509) *sslcert, 4245*5b3e1433Swyllys STACK_OF(X509) *sslcacerts, 424699ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys, 4247*5b3e1433Swyllys KMF_X509_DER_CERT **certlist, int *ncerts) 424899ebb4caSwyllys { 424999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 425099ebb4caSwyllys KMF_RAW_KEY_DATA key; 425199ebb4caSwyllys int i; 425299ebb4caSwyllys 4253*5b3e1433Swyllys for (i = 0; sslkeys != NULL && i < sk_EVP_PKEY_num(sslkeys); i++) { 4254*5b3e1433Swyllys /*LINTED*/ 4255*5b3e1433Swyllys EVP_PKEY *pkey = sk_EVP_PKEY_value(sslkeys, i); 4256*5b3e1433Swyllys rv = convertToRawKey(pkey, &key); 425730a5e8faSwyllys if (rv == KMF_OK) 425899ebb4caSwyllys rv = add_key_to_list(keylist, &key, nkeys); 425930a5e8faSwyllys 426099ebb4caSwyllys if (rv != KMF_OK) 426199ebb4caSwyllys return (rv); 426299ebb4caSwyllys } 426399ebb4caSwyllys 426499ebb4caSwyllys /* Now add the certificate to the certlist */ 4265*5b3e1433Swyllys for (i = 0; sslcert != NULL && i < sk_X509_num(sslcert); i++) { 4266*5b3e1433Swyllys /*LINTED*/ 4267*5b3e1433Swyllys X509 *cert = sk_X509_value(sslcert, i); 4268*5b3e1433Swyllys rv = add_cert_to_list(kmfh, cert, certlist, ncerts); 426999ebb4caSwyllys if (rv != KMF_OK) 427099ebb4caSwyllys return (rv); 427199ebb4caSwyllys } 427299ebb4caSwyllys 427399ebb4caSwyllys /* Also add any included CA certs to the list */ 427471593db2Swyllys for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) { 427599ebb4caSwyllys X509 *c; 427699ebb4caSwyllys /* 427799ebb4caSwyllys * sk_X509_value() is macro that embeds a cast to (X509 *). 427899ebb4caSwyllys * Here it translates into ((X509 *)sk_value((ca), (i))). 427999ebb4caSwyllys * Lint is complaining about the embedded casting, and 428099ebb4caSwyllys * to fix it, you need to fix openssl header files. 428199ebb4caSwyllys */ 428299ebb4caSwyllys /* LINTED E_BAD_PTR_CAST_ALIGN */ 428399ebb4caSwyllys c = sk_X509_value(sslcacerts, i); 428499ebb4caSwyllys 428599ebb4caSwyllys /* Now add the ca cert to the certlist */ 428699ebb4caSwyllys rv = add_cert_to_list(kmfh, c, certlist, ncerts); 428799ebb4caSwyllys if (rv != KMF_OK) 428899ebb4caSwyllys return (rv); 428999ebb4caSwyllys } 429099ebb4caSwyllys return (rv); 429199ebb4caSwyllys } 429299ebb4caSwyllys 429399ebb4caSwyllys KMF_RETURN 429430a5e8faSwyllys openssl_import_objects(KMF_HANDLE *kmfh, 429599ebb4caSwyllys char *filename, KMF_CREDENTIAL *cred, 4296*5b3e1433Swyllys KMF_X509_DER_CERT **certlist, int *ncerts, 429799ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys) 429899ebb4caSwyllys { 429999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 430030a5e8faSwyllys KMF_ENCODE_FORMAT format; 430130a5e8faSwyllys BIO *bio = NULL; 4302*5b3e1433Swyllys STACK_OF(EVP_PKEY) *privkeys = NULL; 4303*5b3e1433Swyllys STACK_OF(X509) *certs = NULL; 430499ebb4caSwyllys STACK_OF(X509) *cacerts = NULL; 430599ebb4caSwyllys 430630a5e8faSwyllys /* 430730a5e8faSwyllys * auto-detect the file format, regardless of what 430830a5e8faSwyllys * the 'format' parameters in the params say. 430930a5e8faSwyllys */ 431030a5e8faSwyllys rv = kmf_get_file_format(filename, &format); 431130a5e8faSwyllys if (rv != KMF_OK) { 431230a5e8faSwyllys return (rv); 431330a5e8faSwyllys } 431430a5e8faSwyllys 431530a5e8faSwyllys /* This function only works for PEM or PKCS#12 files */ 431630a5e8faSwyllys if (format != KMF_FORMAT_PEM && 431730a5e8faSwyllys format != KMF_FORMAT_PEM_KEYPAIR && 431830a5e8faSwyllys format != KMF_FORMAT_PKCS12) 431930a5e8faSwyllys return (KMF_ERR_ENCODING); 432030a5e8faSwyllys 432130a5e8faSwyllys *certlist = NULL; 432230a5e8faSwyllys *keylist = NULL; 432330a5e8faSwyllys *ncerts = 0; 432430a5e8faSwyllys *nkeys = 0; 432530a5e8faSwyllys 432630a5e8faSwyllys if (format == KMF_FORMAT_PKCS12) { 432799ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 432899ebb4caSwyllys if (bio == NULL) { 432999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 433099ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 433199ebb4caSwyllys goto end; 433299ebb4caSwyllys } 433399ebb4caSwyllys 433434acef67Swyllys rv = extract_pkcs12(bio, (uchar_t *)cred->cred, 4335*5b3e1433Swyllys (uint32_t)cred->credlen, &privkeys, &certs, &cacerts); 433699ebb4caSwyllys 433799ebb4caSwyllys if (rv == KMF_OK) 433899ebb4caSwyllys /* Convert keys and certs to exportable format */ 4339*5b3e1433Swyllys rv = convertPK12Objects(kmfh, privkeys, certs, cacerts, 434099ebb4caSwyllys keylist, nkeys, certlist, ncerts); 434130a5e8faSwyllys } else { 4342*5b3e1433Swyllys EVP_PKEY *pkey; 4343*5b3e1433Swyllys KMF_DATA *certdata = NULL; 4344*5b3e1433Swyllys KMF_X509_DER_CERT *kmfcerts = NULL; 4345*5b3e1433Swyllys int i; 434630a5e8faSwyllys rv = extract_pem(kmfh, NULL, NULL, NULL, filename, 434734acef67Swyllys (uchar_t *)cred->cred, (uint32_t)cred->credlen, 4348*5b3e1433Swyllys &pkey, &certdata, ncerts); 434971593db2Swyllys 435071593db2Swyllys /* Reached end of import file? */ 4351*5b3e1433Swyllys if (rv == KMF_OK && pkey != NULL) { 4352*5b3e1433Swyllys privkeys = sk_EVP_PKEY_new_null(); 4353*5b3e1433Swyllys if (privkeys == NULL) { 4354*5b3e1433Swyllys rv = KMF_ERR_MEMORY; 4355*5b3e1433Swyllys goto end; 4356*5b3e1433Swyllys } 4357*5b3e1433Swyllys (void) sk_EVP_PKEY_push(privkeys, pkey); 4358*5b3e1433Swyllys /* convert the certificate list here */ 4359*5b3e1433Swyllys if (*ncerts > 0 && certlist != NULL) { 4360*5b3e1433Swyllys kmfcerts = (KMF_X509_DER_CERT *)malloc(*ncerts * 4361*5b3e1433Swyllys sizeof (KMF_X509_DER_CERT)); 4362*5b3e1433Swyllys if (kmfcerts == NULL) { 4363*5b3e1433Swyllys rv = KMF_ERR_MEMORY; 4364*5b3e1433Swyllys goto end; 4365*5b3e1433Swyllys } 4366*5b3e1433Swyllys (void) memset(kmfcerts, 0, *ncerts * 4367*5b3e1433Swyllys sizeof (KMF_X509_DER_CERT)); 4368*5b3e1433Swyllys for (i = 0; i < *ncerts; i++) { 4369*5b3e1433Swyllys kmfcerts[i].certificate = certdata[i]; 4370*5b3e1433Swyllys kmfcerts[i].kmf_private.keystore_type = 4371*5b3e1433Swyllys KMF_KEYSTORE_OPENSSL; 4372*5b3e1433Swyllys } 4373*5b3e1433Swyllys *certlist = kmfcerts; 4374*5b3e1433Swyllys } 4375*5b3e1433Swyllys /* 4376*5b3e1433Swyllys * Convert keys to exportable format, the certs 4377*5b3e1433Swyllys * are already OK. 4378*5b3e1433Swyllys */ 4379*5b3e1433Swyllys rv = convertPK12Objects(kmfh, privkeys, NULL, NULL, 438071593db2Swyllys keylist, nkeys, NULL, NULL); 438130a5e8faSwyllys } 4382*5b3e1433Swyllys } 438371593db2Swyllys end: 438430a5e8faSwyllys if (bio != NULL) 438599ebb4caSwyllys (void) BIO_free(bio); 438699ebb4caSwyllys 4387*5b3e1433Swyllys if (privkeys) 4388*5b3e1433Swyllys sk_EVP_PKEY_pop_free(privkeys, EVP_PKEY_free); 4389*5b3e1433Swyllys if (certs) 4390*5b3e1433Swyllys sk_X509_pop_free(certs, X509_free); 439130a5e8faSwyllys if (cacerts) 4392*5b3e1433Swyllys sk_X509_pop_free(cacerts, X509_free); 439330a5e8faSwyllys 439499ebb4caSwyllys return (rv); 439599ebb4caSwyllys } 439699ebb4caSwyllys 439799ebb4caSwyllys static KMF_RETURN 439899ebb4caSwyllys create_deskey(DES_cblock **deskey) 439999ebb4caSwyllys { 440099ebb4caSwyllys DES_cblock *key; 440199ebb4caSwyllys 440299ebb4caSwyllys key = (DES_cblock *) malloc(sizeof (DES_cblock)); 440399ebb4caSwyllys if (key == NULL) { 440499ebb4caSwyllys return (KMF_ERR_MEMORY); 440599ebb4caSwyllys } 440699ebb4caSwyllys 440799ebb4caSwyllys if (DES_random_key(key) == 0) { 440899ebb4caSwyllys free(key); 440999ebb4caSwyllys return (KMF_ERR_KEYGEN_FAILED); 441099ebb4caSwyllys } 441199ebb4caSwyllys 441299ebb4caSwyllys *deskey = key; 441399ebb4caSwyllys return (KMF_OK); 441499ebb4caSwyllys } 441599ebb4caSwyllys 441699ebb4caSwyllys #define KEYGEN_RETRY 3 441799ebb4caSwyllys #define DES3_KEY_SIZE 24 441899ebb4caSwyllys 441999ebb4caSwyllys static KMF_RETURN 442099ebb4caSwyllys create_des3key(unsigned char **des3key) 442199ebb4caSwyllys { 442299ebb4caSwyllys KMF_RETURN ret = KMF_OK; 442399ebb4caSwyllys DES_cblock *deskey1 = NULL; 442499ebb4caSwyllys DES_cblock *deskey2 = NULL; 442599ebb4caSwyllys DES_cblock *deskey3 = NULL; 442699ebb4caSwyllys unsigned char *newkey = NULL; 442799ebb4caSwyllys int retry; 442899ebb4caSwyllys 442999ebb4caSwyllys if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) { 443099ebb4caSwyllys return (KMF_ERR_MEMORY); 443199ebb4caSwyllys } 443299ebb4caSwyllys 443399ebb4caSwyllys /* create the 1st DES key */ 443499ebb4caSwyllys if ((ret = create_deskey(&deskey1)) != KMF_OK) { 443599ebb4caSwyllys goto out; 443699ebb4caSwyllys } 443799ebb4caSwyllys 443899ebb4caSwyllys /* 443999ebb4caSwyllys * Create the 2nd DES key and make sure its value is different 444099ebb4caSwyllys * from the 1st DES key. 444199ebb4caSwyllys */ 444299ebb4caSwyllys retry = 0; 444399ebb4caSwyllys do { 444499ebb4caSwyllys if (deskey2 != NULL) { 444599ebb4caSwyllys free(deskey2); 444699ebb4caSwyllys deskey2 = NULL; 444799ebb4caSwyllys } 444899ebb4caSwyllys 444999ebb4caSwyllys if ((ret = create_deskey(&deskey2)) != KMF_OK) { 445099ebb4caSwyllys goto out; 445199ebb4caSwyllys } 445299ebb4caSwyllys 445399ebb4caSwyllys if (memcmp((const void *) deskey1, (const void *) deskey2, 8) 445499ebb4caSwyllys == 0) { 445599ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 445699ebb4caSwyllys retry++; 445799ebb4caSwyllys } 445899ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 445999ebb4caSwyllys 446099ebb4caSwyllys if (ret != KMF_OK) { 446199ebb4caSwyllys goto out; 446299ebb4caSwyllys } 446399ebb4caSwyllys 446499ebb4caSwyllys /* 446599ebb4caSwyllys * Create the 3rd DES key and make sure its value is different 446699ebb4caSwyllys * from the 2nd DES key. 446799ebb4caSwyllys */ 446899ebb4caSwyllys retry = 0; 446999ebb4caSwyllys do { 447099ebb4caSwyllys if (deskey3 != NULL) { 447199ebb4caSwyllys free(deskey3); 447299ebb4caSwyllys deskey3 = NULL; 447399ebb4caSwyllys } 447499ebb4caSwyllys 447599ebb4caSwyllys if ((ret = create_deskey(&deskey3)) != KMF_OK) { 447699ebb4caSwyllys goto out; 447799ebb4caSwyllys } 447899ebb4caSwyllys 447999ebb4caSwyllys if (memcmp((const void *)deskey2, (const void *)deskey3, 8) 448099ebb4caSwyllys == 0) { 448199ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 448299ebb4caSwyllys retry++; 448399ebb4caSwyllys } 448499ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 448599ebb4caSwyllys 448699ebb4caSwyllys if (ret != KMF_OK) { 448799ebb4caSwyllys goto out; 448899ebb4caSwyllys } 448999ebb4caSwyllys 449099ebb4caSwyllys /* Concatenate 3 DES keys into a DES3 key */ 449199ebb4caSwyllys (void) memcpy((void *)newkey, (const void *)deskey1, 8); 449299ebb4caSwyllys (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8); 449399ebb4caSwyllys (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8); 449499ebb4caSwyllys *des3key = newkey; 449599ebb4caSwyllys 449699ebb4caSwyllys out: 449799ebb4caSwyllys if (deskey1 != NULL) 449899ebb4caSwyllys free(deskey1); 449999ebb4caSwyllys 450099ebb4caSwyllys if (deskey2 != NULL) 450199ebb4caSwyllys free(deskey2); 450299ebb4caSwyllys 450399ebb4caSwyllys if (deskey3 != NULL) 450499ebb4caSwyllys free(deskey3); 450599ebb4caSwyllys 450699ebb4caSwyllys if (ret != KMF_OK && newkey != NULL) 450799ebb4caSwyllys free(newkey); 450899ebb4caSwyllys 450999ebb4caSwyllys return (ret); 451099ebb4caSwyllys } 451199ebb4caSwyllys 451299ebb4caSwyllys KMF_RETURN 451330a5e8faSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T handle, 451430a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 451599ebb4caSwyllys { 451699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 451799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 451899ebb4caSwyllys char *fullpath = NULL; 451999ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 452099ebb4caSwyllys DES_cblock *deskey = NULL; 452199ebb4caSwyllys unsigned char *des3key = NULL; 452299ebb4caSwyllys unsigned char *random = NULL; 452399ebb4caSwyllys int fd = -1; 452430a5e8faSwyllys KMF_KEY_HANDLE *symkey; 452530a5e8faSwyllys KMF_KEY_ALG keytype; 452630a5e8faSwyllys uint32_t keylen; 452730a5e8faSwyllys uint32_t keylen_size = sizeof (keylen); 452830a5e8faSwyllys char *dirpath; 452930a5e8faSwyllys char *keyfile; 453099ebb4caSwyllys 453199ebb4caSwyllys if (kmfh == NULL) 453299ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 453399ebb4caSwyllys 453430a5e8faSwyllys symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 453530a5e8faSwyllys if (symkey == NULL) 453699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 453799ebb4caSwyllys 453830a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 453930a5e8faSwyllys 454030a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 454130a5e8faSwyllys if (keyfile == NULL) 454230a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 454330a5e8faSwyllys 454430a5e8faSwyllys ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 454530a5e8faSwyllys (void *)&keytype, NULL); 454630a5e8faSwyllys if (ret != KMF_OK) 454730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 454830a5e8faSwyllys 454930a5e8faSwyllys ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 455030a5e8faSwyllys &keylen, &keylen_size); 455130a5e8faSwyllys if (ret == KMF_ERR_ATTR_NOT_FOUND && 455230a5e8faSwyllys (keytype == KMF_DES || keytype == KMF_DES3)) 455330a5e8faSwyllys /* keylength is not required for DES and 3DES */ 455430a5e8faSwyllys ret = KMF_OK; 455530a5e8faSwyllys if (ret != KMF_OK) 455630a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 455730a5e8faSwyllys 455830a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 455999ebb4caSwyllys if (fullpath == NULL) 456099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 456199ebb4caSwyllys 456299ebb4caSwyllys /* If the requested file exists, return an error */ 456330a5e8faSwyllys if (test_for_file(fullpath, 0400) == 1) { 456499ebb4caSwyllys free(fullpath); 456599ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 456699ebb4caSwyllys } 456799ebb4caSwyllys 456899ebb4caSwyllys fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400); 456999ebb4caSwyllys if (fd == -1) { 457099ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 457199ebb4caSwyllys goto out; 457299ebb4caSwyllys } 457399ebb4caSwyllys 457499ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 457599ebb4caSwyllys if (rkey == NULL) { 457699ebb4caSwyllys ret = KMF_ERR_MEMORY; 457799ebb4caSwyllys goto out; 457899ebb4caSwyllys } 457999ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 458099ebb4caSwyllys 458130a5e8faSwyllys if (keytype == KMF_DES) { 458299ebb4caSwyllys if ((ret = create_deskey(&deskey)) != KMF_OK) { 458399ebb4caSwyllys goto out; 458499ebb4caSwyllys } 458599ebb4caSwyllys rkey->keydata.val = (uchar_t *)deskey; 458699ebb4caSwyllys rkey->keydata.len = 8; 458799ebb4caSwyllys 458899ebb4caSwyllys symkey->keyalg = KMF_DES; 458999ebb4caSwyllys 459030a5e8faSwyllys } else if (keytype == KMF_DES3) { 459199ebb4caSwyllys if ((ret = create_des3key(&des3key)) != KMF_OK) { 459299ebb4caSwyllys goto out; 459399ebb4caSwyllys } 459499ebb4caSwyllys rkey->keydata.val = (uchar_t *)des3key; 459599ebb4caSwyllys rkey->keydata.len = DES3_KEY_SIZE; 459699ebb4caSwyllys symkey->keyalg = KMF_DES3; 45979b37d296Swyllys 459830a5e8faSwyllys } else if (keytype == KMF_AES || keytype == KMF_RC4 || 459930a5e8faSwyllys keytype == KMF_GENERIC_SECRET) { 460099ebb4caSwyllys int bytes; 460199ebb4caSwyllys 460230a5e8faSwyllys if (keylen % 8 != 0) { 460399ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 460499ebb4caSwyllys goto out; 460599ebb4caSwyllys } 460699ebb4caSwyllys 460730a5e8faSwyllys if (keytype == KMF_AES) { 460830a5e8faSwyllys if (keylen != 128 && 460930a5e8faSwyllys keylen != 192 && 461030a5e8faSwyllys keylen != 256) { 461199ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 461299ebb4caSwyllys goto out; 461399ebb4caSwyllys } 461499ebb4caSwyllys } 461599ebb4caSwyllys 461630a5e8faSwyllys bytes = keylen/8; 461799ebb4caSwyllys random = malloc(bytes); 461899ebb4caSwyllys if (random == NULL) { 461999ebb4caSwyllys ret = KMF_ERR_MEMORY; 462099ebb4caSwyllys goto out; 462199ebb4caSwyllys } 462299ebb4caSwyllys if (RAND_bytes(random, bytes) != 1) { 462399ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 462499ebb4caSwyllys goto out; 462599ebb4caSwyllys } 462699ebb4caSwyllys 462799ebb4caSwyllys rkey->keydata.val = (uchar_t *)random; 462899ebb4caSwyllys rkey->keydata.len = bytes; 462930a5e8faSwyllys symkey->keyalg = keytype; 463099ebb4caSwyllys 463199ebb4caSwyllys } else { 463299ebb4caSwyllys ret = KMF_ERR_BAD_KEY_TYPE; 463399ebb4caSwyllys goto out; 463499ebb4caSwyllys } 463599ebb4caSwyllys 463699ebb4caSwyllys (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len); 463799ebb4caSwyllys 463899ebb4caSwyllys symkey->kstype = KMF_KEYSTORE_OPENSSL; 463999ebb4caSwyllys symkey->keyclass = KMF_SYMMETRIC; 464099ebb4caSwyllys symkey->keylabel = (char *)fullpath; 464199ebb4caSwyllys symkey->israw = TRUE; 464299ebb4caSwyllys symkey->keyp = rkey; 464399ebb4caSwyllys 464499ebb4caSwyllys out: 464599ebb4caSwyllys if (fd != -1) 464699ebb4caSwyllys (void) close(fd); 464799ebb4caSwyllys 464899ebb4caSwyllys if (ret != KMF_OK && fullpath != NULL) { 464999ebb4caSwyllys free(fullpath); 465099ebb4caSwyllys } 465199ebb4caSwyllys if (ret != KMF_OK) { 465230a5e8faSwyllys kmf_free_raw_sym_key(rkey); 465399ebb4caSwyllys symkey->keyp = NULL; 465499ebb4caSwyllys symkey->keyalg = KMF_KEYALG_NONE; 465599ebb4caSwyllys } 465699ebb4caSwyllys 465799ebb4caSwyllys return (ret); 465899ebb4caSwyllys } 465999ebb4caSwyllys 466099ebb4caSwyllys /* 466199ebb4caSwyllys * Check a file to see if it is a CRL file with PEM or DER format. 466299ebb4caSwyllys * If success, return its format in the "pformat" argument. 466399ebb4caSwyllys */ 466499ebb4caSwyllys KMF_RETURN 466599ebb4caSwyllys OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat) 466699ebb4caSwyllys { 466799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 466899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 466999ebb4caSwyllys BIO *bio = NULL; 467099ebb4caSwyllys X509_CRL *xcrl = NULL; 467199ebb4caSwyllys 467299ebb4caSwyllys if (filename == NULL) { 467399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 467499ebb4caSwyllys } 467599ebb4caSwyllys 467699ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 467799ebb4caSwyllys if (bio == NULL) { 467899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 467999ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 468099ebb4caSwyllys goto out; 468199ebb4caSwyllys } 468299ebb4caSwyllys 468399ebb4caSwyllys if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) { 468499ebb4caSwyllys *pformat = KMF_FORMAT_PEM; 468599ebb4caSwyllys goto out; 468699ebb4caSwyllys } 468799ebb4caSwyllys (void) BIO_free(bio); 468899ebb4caSwyllys 468999ebb4caSwyllys /* 469099ebb4caSwyllys * Now try to read it as raw DER data. 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 ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) { 470099ebb4caSwyllys *pformat = KMF_FORMAT_ASN1; 470199ebb4caSwyllys } else { 470299ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 470399ebb4caSwyllys } 470499ebb4caSwyllys 470599ebb4caSwyllys out: 470699ebb4caSwyllys if (bio != NULL) 470799ebb4caSwyllys (void) BIO_free(bio); 470899ebb4caSwyllys 470999ebb4caSwyllys if (xcrl != NULL) 471099ebb4caSwyllys X509_CRL_free(xcrl); 471199ebb4caSwyllys 471299ebb4caSwyllys return (ret); 471399ebb4caSwyllys } 471499ebb4caSwyllys 471599ebb4caSwyllys /* 471699ebb4caSwyllys * Check a file to see if it is a certficate file with PEM or DER format. 471799ebb4caSwyllys * If success, return its format in the pformat argument. 471899ebb4caSwyllys */ 471999ebb4caSwyllys KMF_RETURN 472099ebb4caSwyllys OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, 472199ebb4caSwyllys KMF_ENCODE_FORMAT *pformat) 472299ebb4caSwyllys { 472399ebb4caSwyllys KMF_RETURN ret = KMF_OK; 472499ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 472599ebb4caSwyllys BIO *bio = NULL; 472699ebb4caSwyllys X509 *xcert = NULL; 472799ebb4caSwyllys 472899ebb4caSwyllys if (filename == NULL) { 472999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 473099ebb4caSwyllys } 473199ebb4caSwyllys 473230a5e8faSwyllys ret = kmf_get_file_format(filename, pformat); 473399ebb4caSwyllys if (ret != KMF_OK) 473499ebb4caSwyllys return (ret); 473599ebb4caSwyllys 473699ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 473799ebb4caSwyllys if (bio == NULL) { 473899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 473999ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 474099ebb4caSwyllys goto out; 474199ebb4caSwyllys } 474299ebb4caSwyllys 474399ebb4caSwyllys if ((*pformat) == KMF_FORMAT_PEM) { 474499ebb4caSwyllys if ((xcert = PEM_read_bio_X509(bio, NULL, 474599ebb4caSwyllys NULL, NULL)) == NULL) { 474699ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 474799ebb4caSwyllys } 474899ebb4caSwyllys } else if ((*pformat) == KMF_FORMAT_ASN1) { 474999ebb4caSwyllys if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) { 475099ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 475199ebb4caSwyllys } 475299ebb4caSwyllys } else { 475399ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 475499ebb4caSwyllys } 475599ebb4caSwyllys 475699ebb4caSwyllys out: 475799ebb4caSwyllys if (bio != NULL) 475899ebb4caSwyllys (void) BIO_free(bio); 475999ebb4caSwyllys 476099ebb4caSwyllys if (xcert != NULL) 476199ebb4caSwyllys X509_free(xcert); 476299ebb4caSwyllys 476399ebb4caSwyllys return (ret); 476499ebb4caSwyllys } 476599ebb4caSwyllys 476699ebb4caSwyllys KMF_RETURN 476799ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 476899ebb4caSwyllys KMF_RAW_SYM_KEY *rkey) 476999ebb4caSwyllys { 477099ebb4caSwyllys KMF_RETURN rv = KMF_OK; 477199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 477299ebb4caSwyllys KMF_DATA keyvalue; 477399ebb4caSwyllys 477499ebb4caSwyllys if (kmfh == NULL) 477599ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 477699ebb4caSwyllys 477799ebb4caSwyllys if (symkey == NULL || rkey == NULL) 477899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 477999ebb4caSwyllys else if (symkey->keyclass != KMF_SYMMETRIC) 478099ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 478199ebb4caSwyllys 478299ebb4caSwyllys if (symkey->israw) { 478399ebb4caSwyllys KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp; 478499ebb4caSwyllys 478599ebb4caSwyllys if (rawkey == NULL || 478699ebb4caSwyllys rawkey->keydata.val == NULL || 478799ebb4caSwyllys rawkey->keydata.len == 0) 478899ebb4caSwyllys return (KMF_ERR_BAD_KEYHANDLE); 478999ebb4caSwyllys 479099ebb4caSwyllys rkey->keydata.len = rawkey->keydata.len; 479199ebb4caSwyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 479299ebb4caSwyllys return (KMF_ERR_MEMORY); 479399ebb4caSwyllys (void) memcpy(rkey->keydata.val, rawkey->keydata.val, 479499ebb4caSwyllys rkey->keydata.len); 479599ebb4caSwyllys } else { 479630a5e8faSwyllys rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue); 479799ebb4caSwyllys if (rv != KMF_OK) 479899ebb4caSwyllys return (rv); 479999ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 480099ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 480199ebb4caSwyllys } 480299ebb4caSwyllys 480399ebb4caSwyllys return (rv); 480499ebb4caSwyllys } 480502744e81Swyllys 480602744e81Swyllys /* 480702744e81Swyllys * id-sha1 OBJECT IDENTIFIER ::= { 480802744e81Swyllys * iso(1) identified-organization(3) oiw(14) secsig(3) 480902744e81Swyllys * algorithms(2) 26 481002744e81Swyllys * } 481102744e81Swyllys */ 481202744e81Swyllys #define ASN1_SHA1_OID_PREFIX_LEN 15 481302744e81Swyllys static uchar_t SHA1_DER_PREFIX[ASN1_SHA1_OID_PREFIX_LEN] = { 481402744e81Swyllys 0x30, 0x21, 0x30, 0x09, 481502744e81Swyllys 0x06, 0x05, 0x2b, 0x0e, 481602744e81Swyllys 0x03, 0x02, 0x1a, 0x05, 481702744e81Swyllys 0x00, 0x04, 0x14 481802744e81Swyllys }; 481902744e81Swyllys 482002744e81Swyllys /* 482102744e81Swyllys * id-md2 OBJECT IDENTIFIER ::= { 482202744e81Swyllys * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 482302744e81Swyllys * } 482402744e81Swyllys */ 482502744e81Swyllys #define ASN1_MD2_OID_PREFIX_LEN 18 482602744e81Swyllys static uchar_t MD2_DER_PREFIX[ASN1_MD2_OID_PREFIX_LEN] = { 482702744e81Swyllys 0x30, 0x20, 0x30, 0x0c, 482802744e81Swyllys 0x06, 0x08, 0x2a, 0x86, 482902744e81Swyllys 0x48, 0x86, 0xf7, 0x0d, 483002744e81Swyllys 0x02, 0x02, 0x05, 0x00, 483102744e81Swyllys 0x04, 0x10 483202744e81Swyllys }; 483302744e81Swyllys 483402744e81Swyllys /* 483502744e81Swyllys * id-md5 OBJECT IDENTIFIER ::= { 483602744e81Swyllys * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 483702744e81Swyllys * } 483802744e81Swyllys */ 483902744e81Swyllys #define ASN1_MD5_OID_PREFIX_LEN 18 484002744e81Swyllys static uchar_t MD5_DER_PREFIX[ASN1_MD5_OID_PREFIX_LEN] = { 484102744e81Swyllys 0x30, 0x20, 0x30, 0x0c, 484202744e81Swyllys 0x06, 0x08, 0x2a, 0x86, 484302744e81Swyllys 0x48, 0x86, 0xf7, 0x0d, 484402744e81Swyllys 0x02, 0x05, 0x05, 0x00, 484502744e81Swyllys 0x04, 0x10 484602744e81Swyllys }; 484702744e81Swyllys 484802744e81Swyllys KMF_RETURN 484902744e81Swyllys OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle, 485002744e81Swyllys KMF_ALGORITHM_INDEX algid, KMF_DATA *indata, 485102744e81Swyllys KMF_DATA *insig, KMF_DATA *cert) 485202744e81Swyllys { 485302744e81Swyllys KMF_RETURN ret = KMF_OK; 485402744e81Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 485502744e81Swyllys X509 *xcert = NULL; 485602744e81Swyllys EVP_PKEY *pkey = NULL; 485702744e81Swyllys uchar_t *p; 485802744e81Swyllys uchar_t *rsaout = NULL; 485902744e81Swyllys uchar_t *pfx = NULL; 486002744e81Swyllys const EVP_MD *md; 486102744e81Swyllys int pfxlen = 0, len; 486202744e81Swyllys 486302744e81Swyllys if (handle == NULL || indata == NULL || 486402744e81Swyllys indata->Data == NULL || indata->Length == 0 || 486502744e81Swyllys insig == NULL|| insig->Data == NULL || insig->Length == 0 || 486602744e81Swyllys cert == NULL || cert->Data == NULL || cert->Length == 0) 486702744e81Swyllys return (KMF_ERR_BAD_PARAMETER); 486802744e81Swyllys 486902744e81Swyllys p = cert->Data; 487002744e81Swyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, cert->Length); 487102744e81Swyllys if (xcert == NULL) { 487202744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 487302744e81Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 487402744e81Swyllys goto cleanup; 487502744e81Swyllys } 487602744e81Swyllys 487702744e81Swyllys pkey = X509_get_pubkey(xcert); 487830a5e8faSwyllys if (pkey == NULL) { 487902744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 488002744e81Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 488102744e81Swyllys goto cleanup; 488202744e81Swyllys } 488302744e81Swyllys 488402744e81Swyllys if (algid != KMF_ALGID_NONE) { 488502744e81Swyllys switch (algid) { 488602744e81Swyllys case KMF_ALGID_MD5WithRSA: 488702744e81Swyllys md = EVP_md5(); 488802744e81Swyllys break; 488902744e81Swyllys case KMF_ALGID_MD2WithRSA: 489002744e81Swyllys md = EVP_md2(); 489102744e81Swyllys break; 489202744e81Swyllys case KMF_ALGID_SHA1WithRSA: 489302744e81Swyllys md = EVP_sha1(); 489402744e81Swyllys break; 489502744e81Swyllys case KMF_ALGID_RSA: 489602744e81Swyllys md = NULL; 489702744e81Swyllys break; 489802744e81Swyllys default: 489902744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 490002744e81Swyllys goto cleanup; 490102744e81Swyllys } 490202744e81Swyllys } else { 490302744e81Swyllys /* Get the hash type from the cert signature */ 490402744e81Swyllys md = EVP_get_digestbyobj(xcert->sig_alg->algorithm); 490502744e81Swyllys if (md == NULL) { 490602744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 490702744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 490802744e81Swyllys goto cleanup; 490902744e81Swyllys } 491002744e81Swyllys } 49119b37d296Swyllys if (md != NULL) { 491202744e81Swyllys switch (EVP_MD_type(md)) { 491302744e81Swyllys case NID_md2: 491402744e81Swyllys case NID_md2WithRSAEncryption: 491502744e81Swyllys pfxlen = ASN1_MD2_OID_PREFIX_LEN; 491602744e81Swyllys pfx = MD2_DER_PREFIX; 491702744e81Swyllys break; 491802744e81Swyllys case NID_md5: 491902744e81Swyllys case NID_md5WithRSAEncryption: 492002744e81Swyllys pfxlen = ASN1_MD5_OID_PREFIX_LEN; 492102744e81Swyllys pfx = MD5_DER_PREFIX; 492202744e81Swyllys break; 492302744e81Swyllys case NID_sha1: 492402744e81Swyllys case NID_sha1WithRSAEncryption: 492502744e81Swyllys pfxlen = ASN1_SHA1_OID_PREFIX_LEN; 492602744e81Swyllys pfx = SHA1_DER_PREFIX; 492702744e81Swyllys break; 492802744e81Swyllys default: /* Unsupported */ 492902744e81Swyllys pfxlen = 0; 493002744e81Swyllys pfx = NULL; 493102744e81Swyllys break; 493202744e81Swyllys } 49339b37d296Swyllys } 493402744e81Swyllys 493502744e81Swyllys /* RSA with no hash is a special case */ 493602744e81Swyllys rsaout = malloc(RSA_size(pkey->pkey.rsa)); 493702744e81Swyllys if (rsaout == NULL) 493802744e81Swyllys return (KMF_ERR_MEMORY); 493902744e81Swyllys 494002744e81Swyllys /* Decrypt the input signature */ 494102744e81Swyllys len = RSA_public_decrypt(insig->Length, 494202744e81Swyllys insig->Data, rsaout, pkey->pkey.rsa, RSA_PKCS1_PADDING); 494302744e81Swyllys if (len < 1) { 494402744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 494502744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 494602744e81Swyllys } else { 494702744e81Swyllys size_t hashlen = 0; 494802744e81Swyllys uint32_t dlen; 494902744e81Swyllys char *digest = NULL; 495002744e81Swyllys 495102744e81Swyllys /* 495202744e81Swyllys * If the AlgId requires it, hash the input data before 495302744e81Swyllys * comparing it to the decrypted signature. 495402744e81Swyllys */ 495502744e81Swyllys if (md) { 495602744e81Swyllys EVP_MD_CTX ctx; 495702744e81Swyllys 495802744e81Swyllys hashlen = md->md_size; 495902744e81Swyllys 496002744e81Swyllys digest = malloc(hashlen + pfxlen); 496102744e81Swyllys if (digest == NULL) 496202744e81Swyllys return (KMF_ERR_MEMORY); 496302744e81Swyllys /* Add the prefix to the comparison buffer. */ 496402744e81Swyllys if (pfx && pfxlen > 0) { 496502744e81Swyllys (void) memcpy(digest, pfx, pfxlen); 496602744e81Swyllys } 496702744e81Swyllys (void) EVP_DigestInit(&ctx, md); 496802744e81Swyllys (void) EVP_DigestUpdate(&ctx, indata->Data, 496902744e81Swyllys indata->Length); 497002744e81Swyllys 497102744e81Swyllys /* Add the digest AFTER the ASN1 prefix */ 497202744e81Swyllys (void) EVP_DigestFinal(&ctx, 497302744e81Swyllys (uchar_t *)digest + pfxlen, &dlen); 497402744e81Swyllys 497502744e81Swyllys dlen += pfxlen; 497602744e81Swyllys } else { 497702744e81Swyllys digest = (char *)indata->Data; 497802744e81Swyllys dlen = indata->Length; 497902744e81Swyllys } 498002744e81Swyllys 498102744e81Swyllys /* 498202744e81Swyllys * The result of the RSA decryption should be ASN1(OID | Hash). 498302744e81Swyllys * Compare the output hash to the input data for the final 498402744e81Swyllys * result. 498502744e81Swyllys */ 498602744e81Swyllys if (memcmp(rsaout, digest, dlen)) 498702744e81Swyllys ret = KMF_ERR_INTERNAL; 498802744e81Swyllys else 498902744e81Swyllys ret = KMF_OK; 499002744e81Swyllys 499102744e81Swyllys /* If we had to allocate space for the digest, free it now */ 499202744e81Swyllys if (hashlen) 499302744e81Swyllys free(digest); 499402744e81Swyllys } 499502744e81Swyllys cleanup: 499602744e81Swyllys if (pkey) 499702744e81Swyllys EVP_PKEY_free(pkey); 499802744e81Swyllys 499902744e81Swyllys if (xcert) 500002744e81Swyllys X509_free(xcert); 500102744e81Swyllys 500202744e81Swyllys if (rsaout) 500302744e81Swyllys free(rsaout); 500402744e81Swyllys 500502744e81Swyllys return (ret); 500602744e81Swyllys } 500730a5e8faSwyllys 500830a5e8faSwyllys /* 500930a5e8faSwyllys * substitute for the unsafe access(2) function. 501030a5e8faSwyllys * If the file in question already exists, return 1. 501130a5e8faSwyllys * else 0. If an error occurs during testing (other 501230a5e8faSwyllys * than EEXIST), return -1. 501330a5e8faSwyllys */ 501430a5e8faSwyllys static int 501530a5e8faSwyllys test_for_file(char *filename, mode_t mode) 501630a5e8faSwyllys { 501730a5e8faSwyllys int fd; 501830a5e8faSwyllys 501930a5e8faSwyllys /* 502030a5e8faSwyllys * Try to create the file with the EXCL flag. 502130a5e8faSwyllys * The call should fail if the file exists. 502230a5e8faSwyllys */ 502330a5e8faSwyllys fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode); 502430a5e8faSwyllys if (fd == -1 && errno == EEXIST) 502530a5e8faSwyllys return (1); 502630a5e8faSwyllys else if (fd == -1) /* some other error */ 502730a5e8faSwyllys return (-1); 502830a5e8faSwyllys 502930a5e8faSwyllys /* The file did NOT exist. Delete the testcase. */ 503030a5e8faSwyllys (void) close(fd); 503130a5e8faSwyllys (void) unlink(filename); 503230a5e8faSwyllys return (0); 503330a5e8faSwyllys } 503430a5e8faSwyllys 503530a5e8faSwyllys KMF_RETURN 503630a5e8faSwyllys OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr, 503730a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 503830a5e8faSwyllys { 503930a5e8faSwyllys KMF_RETURN rv = KMF_OK; 504030a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 504130a5e8faSwyllys KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL; 504230a5e8faSwyllys KMF_RAW_KEY_DATA *rawkey; 504330a5e8faSwyllys EVP_PKEY *pkey = NULL; 504430a5e8faSwyllys KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM; 504530a5e8faSwyllys KMF_CREDENTIAL cred = {NULL, 0}; 504630a5e8faSwyllys BIO *out = NULL; 504730a5e8faSwyllys int keys = 0; 504830a5e8faSwyllys char *fullpath = NULL; 504930a5e8faSwyllys char *keyfile = NULL; 505030a5e8faSwyllys char *dirpath = NULL; 505130a5e8faSwyllys 505230a5e8faSwyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); 505330a5e8faSwyllys if (pubkey != NULL) 505430a5e8faSwyllys keys++; 505530a5e8faSwyllys 505630a5e8faSwyllys prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); 505730a5e8faSwyllys if (prikey != NULL) 505830a5e8faSwyllys keys++; 505930a5e8faSwyllys 506030a5e8faSwyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); 506130a5e8faSwyllys if (rawkey != NULL) 506230a5e8faSwyllys keys++; 506330a5e8faSwyllys 506430a5e8faSwyllys /* 506530a5e8faSwyllys * Exactly 1 type of key must be passed to this function. 506630a5e8faSwyllys */ 506730a5e8faSwyllys if (keys != 1) 506830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 506930a5e8faSwyllys 507030a5e8faSwyllys keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, 507130a5e8faSwyllys numattr); 507230a5e8faSwyllys if (keyfile == NULL) 507330a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 507430a5e8faSwyllys 507530a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 507630a5e8faSwyllys 507730a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 507830a5e8faSwyllys 507930a5e8faSwyllys /* Once we have the full path, we don't need the pieces */ 508030a5e8faSwyllys if (fullpath == NULL) 508130a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 508230a5e8faSwyllys 508330a5e8faSwyllys /* If the requested file exists, return an error */ 508430a5e8faSwyllys if (test_for_file(fullpath, 0400) == 1) { 508530a5e8faSwyllys free(fullpath); 508630a5e8faSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 508730a5e8faSwyllys } 508830a5e8faSwyllys 508930a5e8faSwyllys rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 509030a5e8faSwyllys &format, NULL); 509130a5e8faSwyllys if (rv != KMF_OK) 509230a5e8faSwyllys /* format is optional. */ 509330a5e8faSwyllys rv = KMF_OK; 509430a5e8faSwyllys 509530a5e8faSwyllys /* CRED is not required for OpenSSL files */ 509630a5e8faSwyllys (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, 509730a5e8faSwyllys &cred, NULL); 509830a5e8faSwyllys 509930a5e8faSwyllys /* Store the private key to the keyfile */ 510030a5e8faSwyllys out = BIO_new_file(fullpath, "wb"); 510130a5e8faSwyllys if (out == NULL) { 510230a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 510330a5e8faSwyllys rv = KMF_ERR_OPEN_FILE; 510430a5e8faSwyllys goto end; 510530a5e8faSwyllys } 510630a5e8faSwyllys 510730a5e8faSwyllys if (prikey != NULL && prikey->keyp != NULL) { 510830a5e8faSwyllys if (prikey->keyalg == KMF_RSA || 510930a5e8faSwyllys prikey->keyalg == KMF_DSA) { 511030a5e8faSwyllys pkey = (EVP_PKEY *)prikey->keyp; 511130a5e8faSwyllys 511230a5e8faSwyllys rv = ssl_write_key(kmfh, format, 511330a5e8faSwyllys out, &cred, pkey, TRUE); 511430a5e8faSwyllys 511530a5e8faSwyllys if (rv == KMF_OK && prikey->keylabel == NULL) { 511630a5e8faSwyllys prikey->keylabel = strdup(fullpath); 511730a5e8faSwyllys if (prikey->keylabel == NULL) 511830a5e8faSwyllys rv = KMF_ERR_MEMORY; 511930a5e8faSwyllys } 512030a5e8faSwyllys } 512130a5e8faSwyllys } else if (pubkey != NULL && pubkey->keyp != NULL) { 512230a5e8faSwyllys if (pubkey->keyalg == KMF_RSA || 512330a5e8faSwyllys pubkey->keyalg == KMF_DSA) { 512430a5e8faSwyllys pkey = (EVP_PKEY *)pubkey->keyp; 512530a5e8faSwyllys 512630a5e8faSwyllys rv = ssl_write_key(kmfh, format, 512730a5e8faSwyllys out, &cred, pkey, FALSE); 512830a5e8faSwyllys 512930a5e8faSwyllys if (rv == KMF_OK && pubkey->keylabel == NULL) { 513030a5e8faSwyllys pubkey->keylabel = strdup(fullpath); 513130a5e8faSwyllys if (pubkey->keylabel == NULL) 513230a5e8faSwyllys rv = KMF_ERR_MEMORY; 513330a5e8faSwyllys } 513430a5e8faSwyllys } 513530a5e8faSwyllys } else if (rawkey != NULL) { 513630a5e8faSwyllys /* RAW keys are always private */ 513730a5e8faSwyllys if (rawkey->keytype == KMF_RSA) { 513830a5e8faSwyllys pkey = ImportRawRSAKey(&rawkey->rawdata.rsa); 513930a5e8faSwyllys } else if (rawkey->keytype == KMF_DSA) { 514030a5e8faSwyllys pkey = ImportRawDSAKey(&rawkey->rawdata.dsa); 514130a5e8faSwyllys } else { 514230a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 514330a5e8faSwyllys } 5144*5b3e1433Swyllys if (pkey != NULL) { 5145*5b3e1433Swyllys rv = ssl_write_key(kmfh, format, out, 5146*5b3e1433Swyllys &cred, pkey, TRUE); 5147*5b3e1433Swyllys EVP_PKEY_free(pkey); 5148*5b3e1433Swyllys } 514930a5e8faSwyllys } 515030a5e8faSwyllys 515130a5e8faSwyllys end: 515230a5e8faSwyllys 515330a5e8faSwyllys if (out) 515430a5e8faSwyllys (void) BIO_free(out); 515530a5e8faSwyllys 5156*5b3e1433Swyllys 515730a5e8faSwyllys if (rv == KMF_OK) 515830a5e8faSwyllys (void) chmod(fullpath, 0400); 515930a5e8faSwyllys 516030a5e8faSwyllys free(fullpath); 516130a5e8faSwyllys return (rv); 516230a5e8faSwyllys } 516330a5e8faSwyllys 516430a5e8faSwyllys KMF_RETURN 516530a5e8faSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 516630a5e8faSwyllys { 516730a5e8faSwyllys KMF_RETURN ret = KMF_OK; 516830a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 516930a5e8faSwyllys X509_CRL *xcrl = NULL; 517030a5e8faSwyllys X509 *xcert = NULL; 517130a5e8faSwyllys EVP_PKEY *pkey; 517230a5e8faSwyllys KMF_ENCODE_FORMAT format; 517330a5e8faSwyllys BIO *in = NULL, *out = NULL; 517430a5e8faSwyllys int openssl_ret = 0; 517530a5e8faSwyllys KMF_ENCODE_FORMAT outformat; 517630a5e8faSwyllys boolean_t crlcheck = FALSE; 517730a5e8faSwyllys char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile; 517830a5e8faSwyllys 517930a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 518030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 518130a5e8faSwyllys } 518230a5e8faSwyllys 518330a5e8faSwyllys /* CRL check is optional */ 518430a5e8faSwyllys (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr, 518530a5e8faSwyllys &crlcheck, NULL); 518630a5e8faSwyllys 518730a5e8faSwyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 518830a5e8faSwyllys if (crlcheck == B_TRUE && certfile == NULL) { 518930a5e8faSwyllys return (KMF_ERR_BAD_CERTFILE); 519030a5e8faSwyllys } 519130a5e8faSwyllys 519230a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 519330a5e8faSwyllys incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr); 519430a5e8faSwyllys outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr); 519530a5e8faSwyllys 519630a5e8faSwyllys crlfile = get_fullpath(dirpath, incrl); 519730a5e8faSwyllys 519830a5e8faSwyllys if (crlfile == NULL) 519930a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 520030a5e8faSwyllys 520130a5e8faSwyllys outcrlfile = get_fullpath(dirpath, outcrl); 520230a5e8faSwyllys if (outcrlfile == NULL) 520330a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 520430a5e8faSwyllys 520530a5e8faSwyllys if (isdir(outcrlfile)) { 520630a5e8faSwyllys free(outcrlfile); 520730a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 520830a5e8faSwyllys } 520930a5e8faSwyllys 521030a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 521130a5e8faSwyllys if (ret != KMF_OK) { 521230a5e8faSwyllys free(outcrlfile); 521330a5e8faSwyllys return (ret); 521430a5e8faSwyllys } 521530a5e8faSwyllys 521630a5e8faSwyllys in = BIO_new_file(crlfile, "rb"); 521730a5e8faSwyllys if (in == NULL) { 521830a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 521930a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 522030a5e8faSwyllys goto end; 522130a5e8faSwyllys } 522230a5e8faSwyllys 522330a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 522430a5e8faSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 522530a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 522630a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 522730a5e8faSwyllys } 522830a5e8faSwyllys 522930a5e8faSwyllys if (xcrl == NULL) { 523030a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 523130a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 523230a5e8faSwyllys goto end; 523330a5e8faSwyllys } 523430a5e8faSwyllys 523530a5e8faSwyllys /* If bypasscheck is specified, no need to verify. */ 523630a5e8faSwyllys if (crlcheck == B_FALSE) 523730a5e8faSwyllys goto output; 523830a5e8faSwyllys 523930a5e8faSwyllys ret = kmf_is_cert_file(handle, certfile, &format); 524030a5e8faSwyllys if (ret != KMF_OK) 524130a5e8faSwyllys goto end; 524230a5e8faSwyllys 524330a5e8faSwyllys /* Read in the CA cert file and convert to X509 */ 524430a5e8faSwyllys if (BIO_read_filename(in, certfile) <= 0) { 524530a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 524630a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 524730a5e8faSwyllys goto end; 524830a5e8faSwyllys } 524930a5e8faSwyllys 525030a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 525130a5e8faSwyllys xcert = d2i_X509_bio(in, NULL); 525230a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 525330a5e8faSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 525430a5e8faSwyllys } else { 525530a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 525630a5e8faSwyllys goto end; 525730a5e8faSwyllys } 525830a5e8faSwyllys 525930a5e8faSwyllys if (xcert == NULL) { 526030a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 526130a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 526230a5e8faSwyllys goto end; 526330a5e8faSwyllys } 526430a5e8faSwyllys /* Now get the public key from the CA cert */ 526530a5e8faSwyllys pkey = X509_get_pubkey(xcert); 526630a5e8faSwyllys if (pkey == NULL) { 526730a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 526830a5e8faSwyllys ret = KMF_ERR_BAD_CERTFILE; 526930a5e8faSwyllys goto end; 527030a5e8faSwyllys } 527130a5e8faSwyllys 527230a5e8faSwyllys /* Verify the CRL with the CA's public key */ 527330a5e8faSwyllys openssl_ret = X509_CRL_verify(xcrl, pkey); 527430a5e8faSwyllys EVP_PKEY_free(pkey); 527530a5e8faSwyllys if (openssl_ret > 0) { 527630a5e8faSwyllys ret = KMF_OK; /* verify succeed */ 527730a5e8faSwyllys } else { 527830a5e8faSwyllys SET_ERROR(kmfh, openssl_ret); 527930a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 528030a5e8faSwyllys } 528130a5e8faSwyllys 528230a5e8faSwyllys output: 528330a5e8faSwyllys ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 528430a5e8faSwyllys &outformat, NULL); 528530a5e8faSwyllys if (ret != KMF_OK) { 528630a5e8faSwyllys ret = KMF_OK; 528730a5e8faSwyllys outformat = KMF_FORMAT_PEM; 528830a5e8faSwyllys } 528930a5e8faSwyllys 529030a5e8faSwyllys out = BIO_new_file(outcrlfile, "wb"); 529130a5e8faSwyllys if (out == NULL) { 529230a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 529330a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 529430a5e8faSwyllys goto end; 529530a5e8faSwyllys } 529630a5e8faSwyllys 529730a5e8faSwyllys if (outformat == KMF_FORMAT_ASN1) { 529830a5e8faSwyllys openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); 529930a5e8faSwyllys } else if (outformat == KMF_FORMAT_PEM) { 530030a5e8faSwyllys openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); 530130a5e8faSwyllys } else { 530230a5e8faSwyllys ret = KMF_ERR_BAD_PARAMETER; 530330a5e8faSwyllys goto end; 530430a5e8faSwyllys } 530530a5e8faSwyllys 530630a5e8faSwyllys if (openssl_ret <= 0) { 530730a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 530830a5e8faSwyllys ret = KMF_ERR_WRITE_FILE; 530930a5e8faSwyllys } else { 531030a5e8faSwyllys ret = KMF_OK; 531130a5e8faSwyllys } 531230a5e8faSwyllys 531330a5e8faSwyllys end: 531430a5e8faSwyllys if (xcrl != NULL) 531530a5e8faSwyllys X509_CRL_free(xcrl); 531630a5e8faSwyllys 531730a5e8faSwyllys if (xcert != NULL) 531830a5e8faSwyllys X509_free(xcert); 531930a5e8faSwyllys 532030a5e8faSwyllys if (in != NULL) 532130a5e8faSwyllys (void) BIO_free(in); 532230a5e8faSwyllys 532330a5e8faSwyllys if (out != NULL) 532430a5e8faSwyllys (void) BIO_free(out); 532530a5e8faSwyllys 532630a5e8faSwyllys if (outcrlfile != NULL) 532730a5e8faSwyllys free(outcrlfile); 532830a5e8faSwyllys 532930a5e8faSwyllys return (ret); 533030a5e8faSwyllys } 533130a5e8faSwyllys 533230a5e8faSwyllys KMF_RETURN 533330a5e8faSwyllys OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 533430a5e8faSwyllys { 533530a5e8faSwyllys KMF_RETURN ret = KMF_OK; 533630a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 533730a5e8faSwyllys X509_CRL *x = NULL; 533830a5e8faSwyllys KMF_ENCODE_FORMAT format; 533930a5e8faSwyllys char *crlfile = NULL; 534030a5e8faSwyllys BIO *in = NULL; 534130a5e8faSwyllys BIO *mem = NULL; 534230a5e8faSwyllys long len; 534330a5e8faSwyllys char *memptr; 534430a5e8faSwyllys char *data = NULL; 534530a5e8faSwyllys char **crldata; 534630a5e8faSwyllys char *crlfilename, *dirpath; 534730a5e8faSwyllys 534830a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 534930a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 535030a5e8faSwyllys } 535130a5e8faSwyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 535230a5e8faSwyllys attrlist, numattr); 535330a5e8faSwyllys if (crlfilename == NULL) 535430a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 535530a5e8faSwyllys 535630a5e8faSwyllys crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR, 535730a5e8faSwyllys attrlist, numattr); 535830a5e8faSwyllys 535930a5e8faSwyllys if (crldata == NULL) 536030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 536130a5e8faSwyllys 536230a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 536330a5e8faSwyllys 536430a5e8faSwyllys crlfile = get_fullpath(dirpath, crlfilename); 536530a5e8faSwyllys 536630a5e8faSwyllys if (crlfile == NULL) 536730a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 536830a5e8faSwyllys 536930a5e8faSwyllys if (isdir(crlfile)) { 537030a5e8faSwyllys free(crlfile); 537130a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 537230a5e8faSwyllys } 537330a5e8faSwyllys 537430a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 537530a5e8faSwyllys if (ret != KMF_OK) { 537630a5e8faSwyllys free(crlfile); 537730a5e8faSwyllys return (ret); 537830a5e8faSwyllys } 537930a5e8faSwyllys 538030a5e8faSwyllys if (bio_err == NULL) 538130a5e8faSwyllys bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 538230a5e8faSwyllys 538330a5e8faSwyllys in = BIO_new_file(crlfile, "rb"); 538430a5e8faSwyllys if (in == NULL) { 538530a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 538630a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 538730a5e8faSwyllys goto end; 538830a5e8faSwyllys } 538930a5e8faSwyllys 539030a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 539130a5e8faSwyllys x = d2i_X509_CRL_bio(in, NULL); 539230a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 539330a5e8faSwyllys x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 539430a5e8faSwyllys } 539530a5e8faSwyllys 539630a5e8faSwyllys if (x == NULL) { /* should not happen */ 539730a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 539830a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 539930a5e8faSwyllys goto end; 540030a5e8faSwyllys } 540130a5e8faSwyllys 540230a5e8faSwyllys mem = BIO_new(BIO_s_mem()); 540330a5e8faSwyllys if (mem == NULL) { 540430a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 540530a5e8faSwyllys ret = KMF_ERR_MEMORY; 540630a5e8faSwyllys goto end; 540730a5e8faSwyllys } 540830a5e8faSwyllys 540930a5e8faSwyllys (void) X509_CRL_print(mem, x); 541030a5e8faSwyllys len = BIO_get_mem_data(mem, &memptr); 541130a5e8faSwyllys if (len <= 0) { 541230a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 541330a5e8faSwyllys ret = KMF_ERR_MEMORY; 541430a5e8faSwyllys goto end; 541530a5e8faSwyllys } 541630a5e8faSwyllys 541730a5e8faSwyllys data = malloc(len + 1); 541830a5e8faSwyllys if (data == NULL) { 541930a5e8faSwyllys ret = KMF_ERR_MEMORY; 542030a5e8faSwyllys goto end; 542130a5e8faSwyllys } 542230a5e8faSwyllys 542330a5e8faSwyllys (void) memcpy(data, memptr, len); 542430a5e8faSwyllys data[len] = '\0'; 542530a5e8faSwyllys *crldata = data; 542630a5e8faSwyllys 542730a5e8faSwyllys end: 542830a5e8faSwyllys if (x != NULL) 542930a5e8faSwyllys X509_CRL_free(x); 543030a5e8faSwyllys 543130a5e8faSwyllys if (crlfile != NULL) 543230a5e8faSwyllys free(crlfile); 543330a5e8faSwyllys 543430a5e8faSwyllys if (in != NULL) 543530a5e8faSwyllys (void) BIO_free(in); 543630a5e8faSwyllys 543730a5e8faSwyllys if (mem != NULL) 543830a5e8faSwyllys (void) BIO_free(mem); 543930a5e8faSwyllys 544030a5e8faSwyllys return (ret); 544130a5e8faSwyllys } 544230a5e8faSwyllys 544330a5e8faSwyllys KMF_RETURN 544430a5e8faSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 544530a5e8faSwyllys { 544630a5e8faSwyllys KMF_RETURN ret = KMF_OK; 544730a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 544830a5e8faSwyllys KMF_ENCODE_FORMAT format; 544930a5e8faSwyllys char *crlfile = NULL; 545030a5e8faSwyllys BIO *in = NULL; 545130a5e8faSwyllys char *crlfilename, *dirpath; 545230a5e8faSwyllys 545330a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 545430a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 545530a5e8faSwyllys } 545630a5e8faSwyllys 545730a5e8faSwyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 545830a5e8faSwyllys attrlist, numattr); 545930a5e8faSwyllys 546030a5e8faSwyllys if (crlfilename == NULL) 546130a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 546230a5e8faSwyllys 546330a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 546430a5e8faSwyllys 546530a5e8faSwyllys crlfile = get_fullpath(dirpath, crlfilename); 546630a5e8faSwyllys 546730a5e8faSwyllys if (crlfile == NULL) 546830a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 546930a5e8faSwyllys 547030a5e8faSwyllys if (isdir(crlfile)) { 547130a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 547230a5e8faSwyllys goto end; 547330a5e8faSwyllys } 547430a5e8faSwyllys 547530a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 547630a5e8faSwyllys if (ret != KMF_OK) 547730a5e8faSwyllys goto end; 547830a5e8faSwyllys 547930a5e8faSwyllys if (unlink(crlfile) != 0) { 548030a5e8faSwyllys SET_SYS_ERROR(kmfh, errno); 548130a5e8faSwyllys ret = KMF_ERR_INTERNAL; 548230a5e8faSwyllys goto end; 548330a5e8faSwyllys } 548430a5e8faSwyllys 548530a5e8faSwyllys end: 548630a5e8faSwyllys if (in != NULL) 548730a5e8faSwyllys (void) BIO_free(in); 548830a5e8faSwyllys if (crlfile != NULL) 548930a5e8faSwyllys free(crlfile); 549030a5e8faSwyllys 549130a5e8faSwyllys return (ret); 549230a5e8faSwyllys } 549330a5e8faSwyllys 549430a5e8faSwyllys KMF_RETURN 549530a5e8faSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 549630a5e8faSwyllys { 549730a5e8faSwyllys KMF_RETURN ret = KMF_OK; 549830a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 549930a5e8faSwyllys KMF_ENCODE_FORMAT format; 550030a5e8faSwyllys BIO *in = NULL; 550130a5e8faSwyllys X509 *xcert = NULL; 550230a5e8faSwyllys X509_CRL *xcrl = NULL; 550330a5e8faSwyllys STACK_OF(X509_REVOKED) *revoke_stack = NULL; 550430a5e8faSwyllys X509_REVOKED *revoke; 550530a5e8faSwyllys int i; 550630a5e8faSwyllys char *crlfilename, *crlfile, *dirpath, *certfile; 550730a5e8faSwyllys 550830a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 550930a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 551030a5e8faSwyllys } 551130a5e8faSwyllys 551230a5e8faSwyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 551330a5e8faSwyllys attrlist, numattr); 551430a5e8faSwyllys 551530a5e8faSwyllys if (crlfilename == NULL) 551630a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 551730a5e8faSwyllys 551830a5e8faSwyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 551930a5e8faSwyllys if (certfile == NULL) 552030a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 552130a5e8faSwyllys 552230a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 552330a5e8faSwyllys 552430a5e8faSwyllys crlfile = get_fullpath(dirpath, crlfilename); 552530a5e8faSwyllys 552630a5e8faSwyllys if (crlfile == NULL) 552730a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 552830a5e8faSwyllys 552930a5e8faSwyllys if (isdir(crlfile)) { 553030a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 553130a5e8faSwyllys goto end; 553230a5e8faSwyllys } 553330a5e8faSwyllys 553430a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 553530a5e8faSwyllys if (ret != KMF_OK) 553630a5e8faSwyllys goto end; 553730a5e8faSwyllys 553830a5e8faSwyllys /* Read the CRL file and load it into a X509_CRL structure */ 553930a5e8faSwyllys in = BIO_new_file(crlfilename, "rb"); 554030a5e8faSwyllys if (in == NULL) { 554130a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 554230a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 554330a5e8faSwyllys goto end; 554430a5e8faSwyllys } 554530a5e8faSwyllys 554630a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 554730a5e8faSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 554830a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 554930a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 555030a5e8faSwyllys } 555130a5e8faSwyllys 555230a5e8faSwyllys if (xcrl == NULL) { 555330a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 555430a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 555530a5e8faSwyllys goto end; 555630a5e8faSwyllys } 555730a5e8faSwyllys (void) BIO_free(in); 555830a5e8faSwyllys 555930a5e8faSwyllys /* Read the Certificate file and load it into a X509 structure */ 556030a5e8faSwyllys ret = kmf_is_cert_file(handle, certfile, &format); 556130a5e8faSwyllys if (ret != KMF_OK) 556230a5e8faSwyllys goto end; 556330a5e8faSwyllys 556430a5e8faSwyllys in = BIO_new_file(certfile, "rb"); 556530a5e8faSwyllys if (in == NULL) { 556630a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 556730a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 556830a5e8faSwyllys goto end; 556930a5e8faSwyllys } 557030a5e8faSwyllys 557130a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 557230a5e8faSwyllys xcert = d2i_X509_bio(in, NULL); 557330a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 557430a5e8faSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 557530a5e8faSwyllys } 557630a5e8faSwyllys 557730a5e8faSwyllys if (xcert == NULL) { 557830a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 557930a5e8faSwyllys ret = KMF_ERR_BAD_CERTFILE; 558030a5e8faSwyllys goto end; 558130a5e8faSwyllys } 558230a5e8faSwyllys 558330a5e8faSwyllys /* Check if the certificate and the CRL have same issuer */ 558430a5e8faSwyllys if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { 558530a5e8faSwyllys ret = KMF_ERR_ISSUER; 558630a5e8faSwyllys goto end; 558730a5e8faSwyllys } 558830a5e8faSwyllys 558930a5e8faSwyllys /* Check to see if the certificate serial number is revoked */ 559030a5e8faSwyllys revoke_stack = X509_CRL_get_REVOKED(xcrl); 559130a5e8faSwyllys if (sk_X509_REVOKED_num(revoke_stack) <= 0) { 559230a5e8faSwyllys /* No revoked certificates in the CRL file */ 559330a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 559430a5e8faSwyllys ret = KMF_ERR_EMPTY_CRL; 559530a5e8faSwyllys goto end; 559630a5e8faSwyllys } 559730a5e8faSwyllys 559830a5e8faSwyllys for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { 559930a5e8faSwyllys /*LINTED*/ 560030a5e8faSwyllys revoke = sk_X509_REVOKED_value(revoke_stack, i); 560130a5e8faSwyllys if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, 560230a5e8faSwyllys revoke->serialNumber) == 0) { 560330a5e8faSwyllys break; 560430a5e8faSwyllys } 560530a5e8faSwyllys } 560630a5e8faSwyllys 560730a5e8faSwyllys if (i < sk_X509_REVOKED_num(revoke_stack)) { 560830a5e8faSwyllys ret = KMF_OK; 560930a5e8faSwyllys } else { 561030a5e8faSwyllys ret = KMF_ERR_NOT_REVOKED; 561130a5e8faSwyllys } 561230a5e8faSwyllys 561330a5e8faSwyllys end: 561430a5e8faSwyllys if (in != NULL) 561530a5e8faSwyllys (void) BIO_free(in); 561630a5e8faSwyllys if (xcrl != NULL) 561730a5e8faSwyllys X509_CRL_free(xcrl); 561830a5e8faSwyllys if (xcert != NULL) 561930a5e8faSwyllys X509_free(xcert); 562030a5e8faSwyllys 562130a5e8faSwyllys return (ret); 562230a5e8faSwyllys } 562330a5e8faSwyllys 562430a5e8faSwyllys KMF_RETURN 562530a5e8faSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert) 562630a5e8faSwyllys { 562730a5e8faSwyllys KMF_RETURN ret = KMF_OK; 562830a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 562930a5e8faSwyllys BIO *bcrl = NULL; 563030a5e8faSwyllys X509_CRL *xcrl = NULL; 563130a5e8faSwyllys X509 *xcert = NULL; 563230a5e8faSwyllys EVP_PKEY *pkey; 563330a5e8faSwyllys int sslret; 563430a5e8faSwyllys KMF_ENCODE_FORMAT crl_format; 563530a5e8faSwyllys unsigned char *p; 563630a5e8faSwyllys long len; 563730a5e8faSwyllys 563830a5e8faSwyllys if (handle == NULL || crlname == NULL || tacert == NULL) { 563930a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 564030a5e8faSwyllys } 564130a5e8faSwyllys 564230a5e8faSwyllys ret = kmf_get_file_format(crlname, &crl_format); 564330a5e8faSwyllys if (ret != KMF_OK) 564430a5e8faSwyllys return (ret); 564530a5e8faSwyllys 564630a5e8faSwyllys bcrl = BIO_new_file(crlname, "rb"); 564730a5e8faSwyllys if (bcrl == NULL) { 564830a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 564930a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 565030a5e8faSwyllys goto cleanup; 565130a5e8faSwyllys } 565230a5e8faSwyllys 565330a5e8faSwyllys if (crl_format == KMF_FORMAT_ASN1) { 565430a5e8faSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 565530a5e8faSwyllys } else if (crl_format == KMF_FORMAT_PEM) { 565630a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 565730a5e8faSwyllys } else { 565830a5e8faSwyllys ret = KMF_ERR_BAD_PARAMETER; 565930a5e8faSwyllys goto cleanup; 566030a5e8faSwyllys } 566130a5e8faSwyllys 566230a5e8faSwyllys if (xcrl == NULL) { 566330a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 566430a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 566530a5e8faSwyllys goto cleanup; 566630a5e8faSwyllys } 566730a5e8faSwyllys 566830a5e8faSwyllys p = tacert->Data; 566930a5e8faSwyllys len = tacert->Length; 567030a5e8faSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, len); 567130a5e8faSwyllys 567230a5e8faSwyllys if (xcert == NULL) { 567330a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 567430a5e8faSwyllys ret = KMF_ERR_BAD_CERTFILE; 567530a5e8faSwyllys goto cleanup; 567630a5e8faSwyllys } 567730a5e8faSwyllys 567830a5e8faSwyllys /* Get issuer certificate public key */ 567930a5e8faSwyllys pkey = X509_get_pubkey(xcert); 568030a5e8faSwyllys if (pkey == NULL) { 568130a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 568230a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 568330a5e8faSwyllys goto cleanup; 568430a5e8faSwyllys } 568530a5e8faSwyllys 568630a5e8faSwyllys /* Verify CRL signature */ 568730a5e8faSwyllys sslret = X509_CRL_verify(xcrl, pkey); 568830a5e8faSwyllys EVP_PKEY_free(pkey); 568930a5e8faSwyllys if (sslret > 0) { 569030a5e8faSwyllys ret = KMF_OK; 569130a5e8faSwyllys } else { 569230a5e8faSwyllys SET_ERROR(kmfh, sslret); 569330a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 569430a5e8faSwyllys } 569530a5e8faSwyllys 569630a5e8faSwyllys cleanup: 569730a5e8faSwyllys if (bcrl != NULL) 569830a5e8faSwyllys (void) BIO_free(bcrl); 569930a5e8faSwyllys 570030a5e8faSwyllys if (xcrl != NULL) 570130a5e8faSwyllys X509_CRL_free(xcrl); 570230a5e8faSwyllys 570330a5e8faSwyllys if (xcert != NULL) 570430a5e8faSwyllys X509_free(xcert); 570530a5e8faSwyllys 570630a5e8faSwyllys return (ret); 570730a5e8faSwyllys 570830a5e8faSwyllys } 570930a5e8faSwyllys 571030a5e8faSwyllys KMF_RETURN 571130a5e8faSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname) 571230a5e8faSwyllys { 571330a5e8faSwyllys KMF_RETURN ret = KMF_OK; 571430a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 571530a5e8faSwyllys KMF_ENCODE_FORMAT crl_format; 571630a5e8faSwyllys BIO *bcrl = NULL; 571730a5e8faSwyllys X509_CRL *xcrl = NULL; 571830a5e8faSwyllys int i; 571930a5e8faSwyllys 572030a5e8faSwyllys if (handle == NULL || crlname == NULL) { 572130a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 572230a5e8faSwyllys } 572330a5e8faSwyllys 572430a5e8faSwyllys ret = kmf_is_crl_file(handle, crlname, &crl_format); 572530a5e8faSwyllys if (ret != KMF_OK) 572630a5e8faSwyllys return (ret); 572730a5e8faSwyllys 572830a5e8faSwyllys bcrl = BIO_new_file(crlname, "rb"); 572930a5e8faSwyllys if (bcrl == NULL) { 573030a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 573130a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 573230a5e8faSwyllys goto cleanup; 573330a5e8faSwyllys } 573430a5e8faSwyllys 5735*5b3e1433Swyllys if (crl_format == KMF_FORMAT_ASN1) 573630a5e8faSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 5737*5b3e1433Swyllys else if (crl_format == KMF_FORMAT_PEM) 573830a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 573930a5e8faSwyllys 574030a5e8faSwyllys if (xcrl == NULL) { 574130a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 574230a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 574330a5e8faSwyllys goto cleanup; 574430a5e8faSwyllys } 574530a5e8faSwyllys i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); 574630a5e8faSwyllys if (i >= 0) { 574730a5e8faSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 574830a5e8faSwyllys goto cleanup; 574930a5e8faSwyllys } 575030a5e8faSwyllys if (X509_CRL_get_nextUpdate(xcrl)) { 575130a5e8faSwyllys i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); 575230a5e8faSwyllys 575330a5e8faSwyllys if (i <= 0) { 575430a5e8faSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 575530a5e8faSwyllys goto cleanup; 575630a5e8faSwyllys } 575730a5e8faSwyllys } 575830a5e8faSwyllys 575930a5e8faSwyllys ret = KMF_OK; 576030a5e8faSwyllys 576130a5e8faSwyllys cleanup: 576230a5e8faSwyllys if (bcrl != NULL) 576330a5e8faSwyllys (void) BIO_free(bcrl); 576430a5e8faSwyllys 576530a5e8faSwyllys if (xcrl != NULL) 576630a5e8faSwyllys X509_CRL_free(xcrl); 576730a5e8faSwyllys 576830a5e8faSwyllys return (ret); 576930a5e8faSwyllys } 5770