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 13599ebb4caSwyllys mutex_t init_lock = DEFAULTMUTEX; 13699ebb4caSwyllys static int ssl_initialized = 0; 137*30a5e8faSwyllys static BIO *bio_err = NULL; 138*30a5e8faSwyllys 139*30a5e8faSwyllys static int 140*30a5e8faSwyllys test_for_file(char *, mode_t); 14199ebb4caSwyllys 14271593db2Swyllys static KMF_RETURN 143*30a5e8faSwyllys extract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *, 14402744e81Swyllys CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *); 14571593db2Swyllys 14671593db2Swyllys static KMF_RETURN 147*30a5e8faSwyllys kmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, 148*30a5e8faSwyllys char *, KMF_DATA *); 149*30a5e8faSwyllys 150*30a5e8faSwyllys static KMF_RETURN 151*30a5e8faSwyllys load_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, 152*30a5e8faSwyllys char *, KMF_DATA **, uint32_t *); 15371593db2Swyllys 15402744e81Swyllys static KMF_RETURN 15502744e81Swyllys sslBN2KMFBN(BIGNUM *, KMF_BIGINT *); 15602744e81Swyllys 15702744e81Swyllys static EVP_PKEY * 15802744e81Swyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *); 15902744e81Swyllys 160*30a5e8faSwyllys static KMF_RETURN 161*30a5e8faSwyllys convertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *); 162*30a5e8faSwyllys 16399ebb4caSwyllys KMF_RETURN 164*30a5e8faSwyllys OpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 16599ebb4caSwyllys 16699ebb4caSwyllys void 16799ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); 16899ebb4caSwyllys 16999ebb4caSwyllys KMF_RETURN 170*30a5e8faSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); 17199ebb4caSwyllys 17299ebb4caSwyllys KMF_RETURN 173*30a5e8faSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); 17499ebb4caSwyllys 17599ebb4caSwyllys KMF_RETURN 176*30a5e8faSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 177*30a5e8faSwyllys 178*30a5e8faSwyllys KMF_RETURN 179*30a5e8faSwyllys OpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 18099ebb4caSwyllys 18199ebb4caSwyllys KMF_RETURN 18299ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 18399ebb4caSwyllys 18499ebb4caSwyllys KMF_RETURN 18599ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 18699ebb4caSwyllys KMF_DATA *, KMF_DATA *); 18799ebb4caSwyllys 18899ebb4caSwyllys KMF_RETURN 189*30a5e8faSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 19099ebb4caSwyllys 19199ebb4caSwyllys KMF_RETURN 192*30a5e8faSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 19399ebb4caSwyllys 19499ebb4caSwyllys KMF_RETURN 195*30a5e8faSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 19699ebb4caSwyllys 19799ebb4caSwyllys KMF_RETURN 198*30a5e8faSwyllys OpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 19999ebb4caSwyllys 20099ebb4caSwyllys KMF_RETURN 201*30a5e8faSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 20299ebb4caSwyllys 20399ebb4caSwyllys KMF_RETURN 20499ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *, 20599ebb4caSwyllys KMF_PRINTABLE_ITEM, char *); 20699ebb4caSwyllys 20799ebb4caSwyllys KMF_RETURN 20899ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T, char **); 20999ebb4caSwyllys 21099ebb4caSwyllys KMF_RETURN 211*30a5e8faSwyllys OpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 21299ebb4caSwyllys 21399ebb4caSwyllys KMF_RETURN 21499ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 21599ebb4caSwyllys KMF_DATA *, KMF_DATA *); 21699ebb4caSwyllys 21799ebb4caSwyllys KMF_RETURN 218*30a5e8faSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 21999ebb4caSwyllys 22099ebb4caSwyllys KMF_RETURN 221*30a5e8faSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 22299ebb4caSwyllys 22399ebb4caSwyllys KMF_RETURN 224*30a5e8faSwyllys OpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 22599ebb4caSwyllys 22699ebb4caSwyllys KMF_RETURN 227*30a5e8faSwyllys OpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 22899ebb4caSwyllys 22999ebb4caSwyllys KMF_RETURN 230*30a5e8faSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 23199ebb4caSwyllys 23299ebb4caSwyllys KMF_RETURN 23399ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 23499ebb4caSwyllys 23599ebb4caSwyllys KMF_RETURN 236*30a5e8faSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *); 23799ebb4caSwyllys 23899ebb4caSwyllys KMF_RETURN 239*30a5e8faSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T, char *); 24099ebb4caSwyllys 24102744e81Swyllys KMF_RETURN 24202744e81Swyllys OpenSSL_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, 24302744e81Swyllys KMF_DATA *, KMF_DATA *, KMF_DATA *); 24402744e81Swyllys 24599ebb4caSwyllys static 24699ebb4caSwyllys KMF_PLUGIN_FUNCLIST openssl_plugin_table = 24799ebb4caSwyllys { 24899ebb4caSwyllys 1, /* Version */ 24999ebb4caSwyllys NULL, /* ConfigureKeystore */ 25099ebb4caSwyllys OpenSSL_FindCert, 25199ebb4caSwyllys OpenSSL_FreeKMFCert, 25299ebb4caSwyllys OpenSSL_StoreCert, 25399ebb4caSwyllys NULL, /* ImportCert */ 25499ebb4caSwyllys OpenSSL_ImportCRL, 25599ebb4caSwyllys OpenSSL_DeleteCert, 25699ebb4caSwyllys OpenSSL_DeleteCRL, 25799ebb4caSwyllys OpenSSL_CreateKeypair, 25899ebb4caSwyllys OpenSSL_FindKey, 25999ebb4caSwyllys OpenSSL_EncodePubKeyData, 26099ebb4caSwyllys OpenSSL_SignData, 26199ebb4caSwyllys OpenSSL_DeleteKey, 26299ebb4caSwyllys OpenSSL_ListCRL, 26399ebb4caSwyllys NULL, /* FindCRL */ 26499ebb4caSwyllys OpenSSL_FindCertInCRL, 26599ebb4caSwyllys OpenSSL_GetErrorString, 266*30a5e8faSwyllys OpenSSL_FindPrikeyByCert, 26799ebb4caSwyllys OpenSSL_DecryptData, 268*30a5e8faSwyllys OpenSSL_ExportPK12, 26999ebb4caSwyllys OpenSSL_CreateSymKey, 27099ebb4caSwyllys OpenSSL_GetSymKeyValue, 27199ebb4caSwyllys NULL, /* SetTokenPin */ 27202744e81Swyllys OpenSSL_VerifyDataWithCert, 273*30a5e8faSwyllys OpenSSL_StoreKey, 27499ebb4caSwyllys NULL /* Finalize */ 27599ebb4caSwyllys }; 27699ebb4caSwyllys 27799ebb4caSwyllys static mutex_t *lock_cs; 27899ebb4caSwyllys static long *lock_count; 27999ebb4caSwyllys 28099ebb4caSwyllys static void 28199ebb4caSwyllys /*ARGSUSED*/ 28299ebb4caSwyllys locking_cb(int mode, int type, char *file, int line) 28399ebb4caSwyllys { 28499ebb4caSwyllys if (mode & CRYPTO_LOCK) { 28599ebb4caSwyllys (void) mutex_lock(&(lock_cs[type])); 28699ebb4caSwyllys lock_count[type]++; 28799ebb4caSwyllys } else { 28899ebb4caSwyllys (void) mutex_unlock(&(lock_cs[type])); 28999ebb4caSwyllys } 29099ebb4caSwyllys } 29199ebb4caSwyllys 29299ebb4caSwyllys static unsigned long 29399ebb4caSwyllys thread_id() 29499ebb4caSwyllys { 29599ebb4caSwyllys return ((unsigned long)thr_self()); 29699ebb4caSwyllys } 29799ebb4caSwyllys 29899ebb4caSwyllys KMF_PLUGIN_FUNCLIST * 29999ebb4caSwyllys KMF_Plugin_Initialize() 30099ebb4caSwyllys { 30199ebb4caSwyllys int i; 30299ebb4caSwyllys 30399ebb4caSwyllys (void) mutex_lock(&init_lock); 30499ebb4caSwyllys if (!ssl_initialized) { 30599ebb4caSwyllys OpenSSL_add_all_algorithms(); 30699ebb4caSwyllys 30799ebb4caSwyllys /* Enable error strings for reporting */ 30899ebb4caSwyllys ERR_load_crypto_strings(); 30999ebb4caSwyllys 31099ebb4caSwyllys /* 31199ebb4caSwyllys * Add support for extension OIDs that are not yet in the 31299ebb4caSwyllys * openssl default set. 31399ebb4caSwyllys */ 31499ebb4caSwyllys (void) OBJ_create("2.5.29.30", "nameConstraints", 31599ebb4caSwyllys "X509v3 Name Constraints"); 31699ebb4caSwyllys (void) OBJ_create("2.5.29.33", "policyMappings", 31799ebb4caSwyllys "X509v3 Policy Mappings"); 31899ebb4caSwyllys (void) OBJ_create("2.5.29.36", "policyConstraints", 31999ebb4caSwyllys "X509v3 Policy Constraints"); 32099ebb4caSwyllys (void) OBJ_create("2.5.29.46", "freshestCRL", 32199ebb4caSwyllys "X509v3 Freshest CRL"); 32299ebb4caSwyllys (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy", 32399ebb4caSwyllys "X509v3 Inhibit Any-Policy"); 32499ebb4caSwyllys /* 32599ebb4caSwyllys * Set up for thread-safe operation. 32699ebb4caSwyllys */ 32799ebb4caSwyllys lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t)); 32899ebb4caSwyllys if (lock_cs == NULL) { 32999ebb4caSwyllys (void) mutex_unlock(&init_lock); 33099ebb4caSwyllys return (NULL); 33199ebb4caSwyllys } 33299ebb4caSwyllys 33399ebb4caSwyllys lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long)); 33499ebb4caSwyllys if (lock_count == NULL) { 33599ebb4caSwyllys OPENSSL_free(lock_cs); 33699ebb4caSwyllys (void) mutex_unlock(&init_lock); 33799ebb4caSwyllys return (NULL); 33899ebb4caSwyllys } 33999ebb4caSwyllys 34099ebb4caSwyllys for (i = 0; i < CRYPTO_num_locks(); i++) { 34199ebb4caSwyllys lock_count[i] = 0; 34299ebb4caSwyllys (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL); 34399ebb4caSwyllys } 34499ebb4caSwyllys 34599ebb4caSwyllys CRYPTO_set_id_callback((unsigned long (*)())thread_id); 34699ebb4caSwyllys CRYPTO_set_locking_callback((void (*)())locking_cb); 34799ebb4caSwyllys ssl_initialized = 1; 34899ebb4caSwyllys } 34999ebb4caSwyllys (void) mutex_unlock(&init_lock); 35099ebb4caSwyllys 35199ebb4caSwyllys return (&openssl_plugin_table); 35299ebb4caSwyllys } 35399ebb4caSwyllys /* 35499ebb4caSwyllys * Convert an SSL DN to a KMF DN. 35599ebb4caSwyllys */ 35699ebb4caSwyllys static KMF_RETURN 35799ebb4caSwyllys get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN) 35899ebb4caSwyllys { 35999ebb4caSwyllys KMF_DATA derdata; 36099ebb4caSwyllys KMF_RETURN rv = KMF_OK; 36199ebb4caSwyllys uchar_t *tmp; 36299ebb4caSwyllys 36399ebb4caSwyllys /* Convert to raw DER format */ 36499ebb4caSwyllys derdata.Length = i2d_X509_NAME(sslDN, NULL); 36599ebb4caSwyllys if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length)) 36699ebb4caSwyllys == NULL) { 36799ebb4caSwyllys return (KMF_ERR_MEMORY); 36899ebb4caSwyllys } 36999ebb4caSwyllys (void) i2d_X509_NAME(sslDN, &tmp); 37099ebb4caSwyllys 37199ebb4caSwyllys /* Decode to KMF format */ 37299ebb4caSwyllys rv = DerDecodeName(&derdata, kmfDN); 37399ebb4caSwyllys if (rv != KMF_OK) { 37499ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 37599ebb4caSwyllys } 37699ebb4caSwyllys OPENSSL_free(derdata.Data); 37799ebb4caSwyllys 37899ebb4caSwyllys return (rv); 37999ebb4caSwyllys } 38099ebb4caSwyllys 381*30a5e8faSwyllys int 38299ebb4caSwyllys isdir(char *path) 38399ebb4caSwyllys { 38499ebb4caSwyllys struct stat s; 38599ebb4caSwyllys 38699ebb4caSwyllys if (stat(path, &s) == -1) 38799ebb4caSwyllys return (0); 38899ebb4caSwyllys 389*30a5e8faSwyllys return ((s.st_mode & S_IFMT) == S_IFDIR); 39099ebb4caSwyllys } 39199ebb4caSwyllys 39299ebb4caSwyllys static KMF_RETURN 39399ebb4caSwyllys ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert) 39499ebb4caSwyllys { 39599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 39699ebb4caSwyllys unsigned char *buf = NULL, *p; 39799ebb4caSwyllys int len; 39899ebb4caSwyllys 39999ebb4caSwyllys /* 40099ebb4caSwyllys * Convert the X509 internal struct to DER encoded data 40199ebb4caSwyllys */ 40299ebb4caSwyllys if ((len = i2d_X509(x509cert, NULL)) < 0) { 40399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 40499ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 40599ebb4caSwyllys goto cleanup; 40699ebb4caSwyllys } 40799ebb4caSwyllys if ((buf = malloc(len)) == NULL) { 40899ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 40999ebb4caSwyllys rv = KMF_ERR_MEMORY; 41099ebb4caSwyllys goto cleanup; 41199ebb4caSwyllys } 41299ebb4caSwyllys 41399ebb4caSwyllys /* 41499ebb4caSwyllys * i2d_X509 will increment the buf pointer so that we need to 41599ebb4caSwyllys * save it. 41699ebb4caSwyllys */ 41799ebb4caSwyllys p = buf; 41899ebb4caSwyllys if ((len = i2d_X509(x509cert, &p)) < 0) { 41999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 42099ebb4caSwyllys free(buf); 42199ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 42299ebb4caSwyllys goto cleanup; 42399ebb4caSwyllys } 42499ebb4caSwyllys 42599ebb4caSwyllys /* caller's responsibility to free it */ 42699ebb4caSwyllys cert->Data = buf; 42799ebb4caSwyllys cert->Length = len; 42899ebb4caSwyllys 42999ebb4caSwyllys cleanup: 43099ebb4caSwyllys if (rv != KMF_OK) { 43199ebb4caSwyllys if (buf) 43299ebb4caSwyllys free(buf); 43399ebb4caSwyllys cert->Data = NULL; 43499ebb4caSwyllys cert->Length = 0; 43599ebb4caSwyllys } 43699ebb4caSwyllys 43799ebb4caSwyllys return (rv); 43899ebb4caSwyllys } 43999ebb4caSwyllys 440*30a5e8faSwyllys 44199ebb4caSwyllys static KMF_RETURN 442*30a5e8faSwyllys check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial, 443*30a5e8faSwyllys boolean_t *match) 44499ebb4caSwyllys { 44599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 44699ebb4caSwyllys boolean_t findIssuer = FALSE; 44799ebb4caSwyllys boolean_t findSubject = FALSE; 44899ebb4caSwyllys boolean_t findSerial = FALSE; 44999ebb4caSwyllys KMF_X509_NAME issuerDN, subjectDN; 45099ebb4caSwyllys KMF_X509_NAME certIssuerDN, certSubjectDN; 45199ebb4caSwyllys 45299ebb4caSwyllys *match = FALSE; 45399ebb4caSwyllys if (xcert == NULL) { 45499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 45599ebb4caSwyllys } 45699ebb4caSwyllys 45799ebb4caSwyllys (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME)); 45899ebb4caSwyllys (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME)); 45999ebb4caSwyllys (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME)); 46099ebb4caSwyllys (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME)); 46199ebb4caSwyllys 462*30a5e8faSwyllys if (issuer != NULL && strlen(issuer)) { 463*30a5e8faSwyllys rv = kmf_dn_parser(issuer, &issuerDN); 46499ebb4caSwyllys if (rv != KMF_OK) 46599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 46699ebb4caSwyllys 46799ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); 46899ebb4caSwyllys if (rv != KMF_OK) { 469*30a5e8faSwyllys kmf_free_dn(&issuerDN); 47099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 47199ebb4caSwyllys } 47299ebb4caSwyllys 47399ebb4caSwyllys findIssuer = TRUE; 47499ebb4caSwyllys } 475*30a5e8faSwyllys if (subject != NULL && strlen(subject)) { 476*30a5e8faSwyllys rv = kmf_dn_parser(subject, &subjectDN); 47799ebb4caSwyllys if (rv != KMF_OK) { 47899ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 47999ebb4caSwyllys goto cleanup; 48099ebb4caSwyllys } 48199ebb4caSwyllys 48299ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN); 48399ebb4caSwyllys if (rv != KMF_OK) { 48499ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 48599ebb4caSwyllys goto cleanup; 48699ebb4caSwyllys } 48799ebb4caSwyllys findSubject = TRUE; 48899ebb4caSwyllys } 489*30a5e8faSwyllys if (serial != NULL && serial->val != NULL) 49099ebb4caSwyllys findSerial = TRUE; 49199ebb4caSwyllys 49299ebb4caSwyllys if (findSerial) { 49399ebb4caSwyllys BIGNUM *bn; 49499ebb4caSwyllys 49599ebb4caSwyllys /* Comparing BIGNUMs is a pain! */ 49699ebb4caSwyllys bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL); 49799ebb4caSwyllys if (bn != NULL) { 49899ebb4caSwyllys int bnlen = BN_num_bytes(bn); 49999ebb4caSwyllys 500*30a5e8faSwyllys if (bnlen == serial->len) { 50199ebb4caSwyllys uchar_t *a = malloc(bnlen); 50299ebb4caSwyllys if (a == NULL) { 50399ebb4caSwyllys rv = KMF_ERR_MEMORY; 50499ebb4caSwyllys BN_free(bn); 50599ebb4caSwyllys goto cleanup; 50699ebb4caSwyllys } 50799ebb4caSwyllys bnlen = BN_bn2bin(bn, a); 508*30a5e8faSwyllys *match = (memcmp(a, serial->val, serial->len) == 509*30a5e8faSwyllys 0); 51099ebb4caSwyllys rv = KMF_OK; 51199ebb4caSwyllys free(a); 51299ebb4caSwyllys } 51399ebb4caSwyllys BN_free(bn); 51499ebb4caSwyllys if (!(*match)) 51599ebb4caSwyllys goto cleanup; 51699ebb4caSwyllys } else { 51799ebb4caSwyllys rv = KMF_OK; 51899ebb4caSwyllys goto cleanup; 51999ebb4caSwyllys } 52099ebb4caSwyllys } 52199ebb4caSwyllys if (findIssuer) { 522*30a5e8faSwyllys *match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0); 523*30a5e8faSwyllys if ((*match) == B_FALSE) { 524*30a5e8faSwyllys /* stop checking and bail */ 52599ebb4caSwyllys rv = KMF_OK; 52699ebb4caSwyllys goto cleanup; 52799ebb4caSwyllys } 52899ebb4caSwyllys } 52999ebb4caSwyllys if (findSubject) { 530*30a5e8faSwyllys *match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0); 531*30a5e8faSwyllys if ((*match) == B_FALSE) { 532*30a5e8faSwyllys /* stop checking and bail */ 53399ebb4caSwyllys rv = KMF_OK; 53499ebb4caSwyllys goto cleanup; 53599ebb4caSwyllys } 53699ebb4caSwyllys } 53799ebb4caSwyllys 53899ebb4caSwyllys *match = TRUE; 53999ebb4caSwyllys cleanup: 54099ebb4caSwyllys if (findIssuer) { 541*30a5e8faSwyllys kmf_free_dn(&issuerDN); 542*30a5e8faSwyllys kmf_free_dn(&certIssuerDN); 54399ebb4caSwyllys } 54499ebb4caSwyllys if (findSubject) { 545*30a5e8faSwyllys kmf_free_dn(&subjectDN); 546*30a5e8faSwyllys kmf_free_dn(&certSubjectDN); 54799ebb4caSwyllys } 54899ebb4caSwyllys 54999ebb4caSwyllys return (rv); 55099ebb4caSwyllys } 55199ebb4caSwyllys 552*30a5e8faSwyllys 553*30a5e8faSwyllys /* 554*30a5e8faSwyllys * This function loads a certificate file into an X509 data structure, and 555*30a5e8faSwyllys * checks if its issuer, subject or the serial number matches with those 556*30a5e8faSwyllys * values. If it matches, then return the X509 data structure. 557*30a5e8faSwyllys */ 55899ebb4caSwyllys static KMF_RETURN 55999ebb4caSwyllys load_X509cert(KMF_HANDLE *kmfh, 560*30a5e8faSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 561*30a5e8faSwyllys char *pathname, X509 **outcert) 56299ebb4caSwyllys { 56399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 56499ebb4caSwyllys X509 *xcert = NULL; 56599ebb4caSwyllys BIO *bcert = NULL; 56699ebb4caSwyllys boolean_t match = FALSE; 56799ebb4caSwyllys KMF_ENCODE_FORMAT format; 56899ebb4caSwyllys 56999ebb4caSwyllys /* 57099ebb4caSwyllys * auto-detect the file format, regardless of what 57199ebb4caSwyllys * the 'format' parameters in the params say. 57299ebb4caSwyllys */ 573*30a5e8faSwyllys rv = kmf_get_file_format(pathname, &format); 57499ebb4caSwyllys if (rv != KMF_OK) { 57599ebb4caSwyllys if (rv == KMF_ERR_OPEN_FILE) 57699ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 57799ebb4caSwyllys return (rv); 57899ebb4caSwyllys } 57999ebb4caSwyllys 58099ebb4caSwyllys /* Not ASN1(DER) format */ 58199ebb4caSwyllys if ((bcert = BIO_new_file(pathname, "rb")) == NULL) { 58299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 58399ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 58499ebb4caSwyllys goto cleanup; 58599ebb4caSwyllys } 58699ebb4caSwyllys 58799ebb4caSwyllys if (format == KMF_FORMAT_PEM) 58899ebb4caSwyllys xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL); 58999ebb4caSwyllys else if (format == KMF_FORMAT_ASN1) 59099ebb4caSwyllys xcert = d2i_X509_bio(bcert, NULL); 59199ebb4caSwyllys else if (format == KMF_FORMAT_PKCS12) { 59299ebb4caSwyllys PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL); 59399ebb4caSwyllys if (p12 != NULL) { 59499ebb4caSwyllys (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL); 59599ebb4caSwyllys PKCS12_free(p12); 59699ebb4caSwyllys p12 = NULL; 59799ebb4caSwyllys } else { 59899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 59999ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 60099ebb4caSwyllys } 60199ebb4caSwyllys } else { 60299ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 60399ebb4caSwyllys goto cleanup; 60499ebb4caSwyllys } 60599ebb4caSwyllys 60699ebb4caSwyllys if (xcert == NULL) { 60799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 60899ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 60999ebb4caSwyllys goto cleanup; 61099ebb4caSwyllys } 61199ebb4caSwyllys 612*30a5e8faSwyllys if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK || 613*30a5e8faSwyllys match == FALSE) { 61499ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 61599ebb4caSwyllys goto cleanup; 61699ebb4caSwyllys } 61799ebb4caSwyllys 61899ebb4caSwyllys if (outcert != NULL) { 61999ebb4caSwyllys *outcert = xcert; 62099ebb4caSwyllys } 62199ebb4caSwyllys 62299ebb4caSwyllys cleanup: 62399ebb4caSwyllys if (bcert != NULL) (void) BIO_free(bcert); 62499ebb4caSwyllys if (rv != KMF_OK && xcert != NULL) 62599ebb4caSwyllys X509_free(xcert); 62699ebb4caSwyllys 62799ebb4caSwyllys return (rv); 62899ebb4caSwyllys } 62999ebb4caSwyllys 63071593db2Swyllys static int 63171593db2Swyllys datacmp(const void *a, const void *b) 63271593db2Swyllys { 63371593db2Swyllys KMF_DATA *adata = (KMF_DATA *)a; 63471593db2Swyllys KMF_DATA *bdata = (KMF_DATA *)b; 63571593db2Swyllys if (adata->Length > bdata->Length) 63671593db2Swyllys return (-1); 63771593db2Swyllys if (adata->Length < bdata->Length) 63871593db2Swyllys return (1); 63971593db2Swyllys return (0); 64071593db2Swyllys } 64171593db2Swyllys 64271593db2Swyllys static KMF_RETURN 643*30a5e8faSwyllys load_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial, 644*30a5e8faSwyllys KMF_CERT_VALIDITY validity, char *pathname, 64571593db2Swyllys KMF_DATA **certlist, uint32_t *numcerts) 64671593db2Swyllys { 64771593db2Swyllys KMF_RETURN rv = KMF_OK; 64871593db2Swyllys int i; 64971593db2Swyllys KMF_DATA *certs = NULL; 65071593db2Swyllys int nc = 0; 65171593db2Swyllys int hits = 0; 65271593db2Swyllys KMF_ENCODE_FORMAT format; 65371593db2Swyllys 654*30a5e8faSwyllys rv = kmf_get_file_format(pathname, &format); 65571593db2Swyllys if (rv != KMF_OK) { 65671593db2Swyllys if (rv == KMF_ERR_OPEN_FILE) 65771593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 65871593db2Swyllys return (rv); 65971593db2Swyllys } 66071593db2Swyllys if (format == KMF_FORMAT_ASN1) { 66171593db2Swyllys /* load a single certificate */ 66271593db2Swyllys certs = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 66371593db2Swyllys if (certs == NULL) 66471593db2Swyllys return (KMF_ERR_MEMORY); 66571593db2Swyllys certs->Data = NULL; 66671593db2Swyllys certs->Length = 0; 667*30a5e8faSwyllys rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, 668*30a5e8faSwyllys pathname, certs); 66971593db2Swyllys if (rv == KMF_OK) { 67071593db2Swyllys *certlist = certs; 67171593db2Swyllys *numcerts = 1; 67271593db2Swyllys } 67371593db2Swyllys return (rv); 67471593db2Swyllys } else if (format == KMF_FORMAT_PKCS12) { 67571593db2Swyllys /* We need a credential to access a PKCS#12 file */ 67671593db2Swyllys rv = KMF_ERR_BAD_CERT_FORMAT; 67771593db2Swyllys } else if (format == KMF_FORMAT_PEM || 67871593db2Swyllys format != KMF_FORMAT_PEM_KEYPAIR) { 67971593db2Swyllys 68071593db2Swyllys /* This function only works on PEM files */ 681*30a5e8faSwyllys rv = extract_pem(kmfh, issuer, subject, serial, pathname, 68234acef67Swyllys (uchar_t *)NULL, 0, NULL, &certs, &nc); 68371593db2Swyllys } else { 68471593db2Swyllys return (KMF_ERR_ENCODING); 68571593db2Swyllys } 68671593db2Swyllys 68771593db2Swyllys if (rv != KMF_OK) 68871593db2Swyllys return (rv); 68971593db2Swyllys 69071593db2Swyllys for (i = 0; i < nc; i++) { 691*30a5e8faSwyllys if (validity == KMF_NONEXPIRED_CERTS) { 692*30a5e8faSwyllys rv = kmf_check_cert_date(kmfh, &certs[i]); 693*30a5e8faSwyllys } else if (validity == KMF_EXPIRED_CERTS) { 694*30a5e8faSwyllys rv = kmf_check_cert_date(kmfh, &certs[i]); 69571593db2Swyllys if (rv == KMF_OK) 69671593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 69771593db2Swyllys if (rv == KMF_ERR_VALIDITY_PERIOD) 69871593db2Swyllys rv = KMF_OK; 69971593db2Swyllys } 70071593db2Swyllys if (rv != KMF_OK) { 70171593db2Swyllys /* Remove this cert from the list by clearing it. */ 702*30a5e8faSwyllys kmf_free_data(&certs[i]); 70371593db2Swyllys } else { 70471593db2Swyllys hits++; /* count valid certs found */ 70571593db2Swyllys } 70671593db2Swyllys rv = KMF_OK; 70771593db2Swyllys } 70871593db2Swyllys if (rv == KMF_OK && hits == 0) { 70971593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 71071593db2Swyllys } else if (rv == KMF_OK && hits > 0) { 71171593db2Swyllys /* 71271593db2Swyllys * Sort the list of certs by length to put the cleared ones 71371593db2Swyllys * at the end so they don't get accessed by the caller. 71471593db2Swyllys */ 71571593db2Swyllys qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp); 71671593db2Swyllys *certlist = certs; 71771593db2Swyllys 71871593db2Swyllys /* since we sorted the list, just return the number of hits */ 71971593db2Swyllys *numcerts = hits; 72071593db2Swyllys } 72171593db2Swyllys return (rv); 72271593db2Swyllys } 72371593db2Swyllys 724*30a5e8faSwyllys 72599ebb4caSwyllys static KMF_RETURN 72699ebb4caSwyllys kmf_load_cert(KMF_HANDLE *kmfh, 727*30a5e8faSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 728*30a5e8faSwyllys KMF_CERT_VALIDITY validity, 72999ebb4caSwyllys char *pathname, 73099ebb4caSwyllys KMF_DATA *cert) 73199ebb4caSwyllys { 73299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 73399ebb4caSwyllys X509 *x509cert = NULL; 73499ebb4caSwyllys 735*30a5e8faSwyllys rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert); 73699ebb4caSwyllys if (rv == KMF_OK && x509cert != NULL && cert != NULL) { 73799ebb4caSwyllys rv = ssl_cert2KMFDATA(kmfh, x509cert, cert); 73899ebb4caSwyllys if (rv != KMF_OK) { 73999ebb4caSwyllys goto cleanup; 74099ebb4caSwyllys } 741*30a5e8faSwyllys if (validity == KMF_NONEXPIRED_CERTS) { 742*30a5e8faSwyllys rv = kmf_check_cert_date(kmfh, cert); 743*30a5e8faSwyllys } else if (validity == KMF_EXPIRED_CERTS) { 744*30a5e8faSwyllys rv = kmf_check_cert_date(kmfh, cert); 74599ebb4caSwyllys if (rv == KMF_OK) { 74699ebb4caSwyllys /* 74799ebb4caSwyllys * This is a valid cert so skip it. 74899ebb4caSwyllys */ 74999ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 75099ebb4caSwyllys } 75199ebb4caSwyllys if (rv == KMF_ERR_VALIDITY_PERIOD) { 75299ebb4caSwyllys /* 75399ebb4caSwyllys * We want to return success when we 75499ebb4caSwyllys * find an invalid cert. 75599ebb4caSwyllys */ 75699ebb4caSwyllys rv = KMF_OK; 75799ebb4caSwyllys goto cleanup; 75899ebb4caSwyllys } 75999ebb4caSwyllys } 76099ebb4caSwyllys } 76199ebb4caSwyllys cleanup: 76299ebb4caSwyllys if (x509cert != NULL) 76399ebb4caSwyllys X509_free(x509cert); 76499ebb4caSwyllys 76599ebb4caSwyllys return (rv); 76699ebb4caSwyllys } 76799ebb4caSwyllys 76802744e81Swyllys static KMF_RETURN 76902744e81Swyllys readAltFormatPrivateKey(KMF_DATA *filedata, EVP_PKEY **pkey) 77002744e81Swyllys { 77102744e81Swyllys KMF_RETURN ret = KMF_OK; 77202744e81Swyllys KMF_RAW_RSA_KEY rsa; 77302744e81Swyllys BerElement *asn1 = NULL; 77402744e81Swyllys BerValue filebuf; 77502744e81Swyllys BerValue OID = { NULL, 0 }; 77602744e81Swyllys BerValue *Mod = NULL, *PubExp = NULL; 77702744e81Swyllys BerValue *PriExp = NULL, *Prime1 = NULL, *Prime2 = NULL; 77802744e81Swyllys BerValue *Coef = NULL; 77902744e81Swyllys BIGNUM *D = NULL, *P = NULL, *Q = NULL, *COEF = NULL; 78002744e81Swyllys BIGNUM *Exp1 = NULL, *Exp2 = NULL, *pminus1 = NULL; 78102744e81Swyllys BIGNUM *qminus1 = NULL; 78202744e81Swyllys BN_CTX *ctx = NULL; 78302744e81Swyllys 78402744e81Swyllys *pkey = NULL; 78502744e81Swyllys 78602744e81Swyllys filebuf.bv_val = (char *)filedata->Data; 78702744e81Swyllys filebuf.bv_len = filedata->Length; 78802744e81Swyllys 78902744e81Swyllys asn1 = kmfder_init(&filebuf); 79002744e81Swyllys if (asn1 == NULL) { 79102744e81Swyllys ret = KMF_ERR_MEMORY; 79202744e81Swyllys goto out; 79302744e81Swyllys } 79402744e81Swyllys 79502744e81Swyllys if (kmfber_scanf(asn1, "{{Dn{IIIIII}}}", 79602744e81Swyllys &OID, &Mod, &PubExp, &PriExp, &Prime1, 79702744e81Swyllys &Prime2, &Coef) == -1) { 79802744e81Swyllys ret = KMF_ERR_ENCODING; 79902744e81Swyllys goto out; 80002744e81Swyllys } 80102744e81Swyllys 80202744e81Swyllys /* 80302744e81Swyllys * We have to derive the 2 Exponents using Bignumber math. 80402744e81Swyllys * Exp1 = PriExp mod (Prime1 - 1) 80502744e81Swyllys * Exp2 = PriExp mod (Prime2 - 1) 80602744e81Swyllys */ 80702744e81Swyllys 80802744e81Swyllys /* D = PrivateExponent */ 80902744e81Swyllys D = BN_bin2bn((const uchar_t *)PriExp->bv_val, PriExp->bv_len, D); 81002744e81Swyllys if (D == NULL) { 81102744e81Swyllys ret = KMF_ERR_MEMORY; 81202744e81Swyllys goto out; 81302744e81Swyllys } 81402744e81Swyllys 81502744e81Swyllys /* P = Prime1 (first prime factor of Modulus) */ 81602744e81Swyllys P = BN_bin2bn((const uchar_t *)Prime1->bv_val, Prime1->bv_len, P); 81702744e81Swyllys if (D == NULL) { 81802744e81Swyllys ret = KMF_ERR_MEMORY; 81902744e81Swyllys goto out; 82002744e81Swyllys } 82102744e81Swyllys 82202744e81Swyllys /* Q = Prime2 (second prime factor of Modulus) */ 82302744e81Swyllys Q = BN_bin2bn((const uchar_t *)Prime2->bv_val, Prime2->bv_len, Q); 82402744e81Swyllys 82502744e81Swyllys if ((ctx = BN_CTX_new()) == NULL) { 82602744e81Swyllys ret = KMF_ERR_MEMORY; 82702744e81Swyllys goto out; 82802744e81Swyllys } 82902744e81Swyllys 83002744e81Swyllys /* Compute (P - 1) */ 83102744e81Swyllys pminus1 = BN_new(); 83202744e81Swyllys (void) BN_sub(pminus1, P, BN_value_one()); 83302744e81Swyllys 83402744e81Swyllys /* Exponent1 = D mod (P - 1) */ 83502744e81Swyllys Exp1 = BN_new(); 83602744e81Swyllys (void) BN_mod(Exp1, D, pminus1, ctx); 83702744e81Swyllys 83802744e81Swyllys /* Compute (Q - 1) */ 83902744e81Swyllys qminus1 = BN_new(); 84002744e81Swyllys (void) BN_sub(qminus1, Q, BN_value_one()); 84102744e81Swyllys 84202744e81Swyllys /* Exponent2 = D mod (Q - 1) */ 84302744e81Swyllys Exp2 = BN_new(); 84402744e81Swyllys (void) BN_mod(Exp2, D, qminus1, ctx); 84502744e81Swyllys 84602744e81Swyllys /* Coef = (Inverse Q) mod P */ 84702744e81Swyllys COEF = BN_new(); 84802744e81Swyllys (void) BN_mod_inverse(COEF, Q, P, ctx); 84902744e81Swyllys 85002744e81Swyllys /* Convert back to KMF format */ 85102744e81Swyllys (void) memset(&rsa, 0, sizeof (rsa)); 85202744e81Swyllys 85302744e81Swyllys if ((ret = sslBN2KMFBN(Exp1, &rsa.exp1)) != KMF_OK) 85402744e81Swyllys goto out; 85502744e81Swyllys if ((ret = sslBN2KMFBN(Exp2, &rsa.exp2)) != KMF_OK) 85602744e81Swyllys goto out; 85702744e81Swyllys if ((ret = sslBN2KMFBN(COEF, &rsa.coef)) != KMF_OK) 85802744e81Swyllys goto out; 85902744e81Swyllys 86002744e81Swyllys rsa.mod.val = (uchar_t *)Mod->bv_val; 86102744e81Swyllys rsa.mod.len = Mod->bv_len; 86202744e81Swyllys 86302744e81Swyllys rsa.pubexp.val = (uchar_t *)PubExp->bv_val; 86402744e81Swyllys rsa.pubexp.len = PubExp->bv_len; 86502744e81Swyllys 86602744e81Swyllys rsa.priexp.val = (uchar_t *)PriExp->bv_val; 86702744e81Swyllys rsa.priexp.len = PriExp->bv_len; 86802744e81Swyllys 86902744e81Swyllys rsa.prime1.val = (uchar_t *)Prime1->bv_val; 87002744e81Swyllys rsa.prime1.len = Prime1->bv_len; 87102744e81Swyllys 87202744e81Swyllys rsa.prime2.val = (uchar_t *)Prime2->bv_val; 87302744e81Swyllys rsa.prime2.len = Prime2->bv_len; 87402744e81Swyllys 87502744e81Swyllys *pkey = ImportRawRSAKey(&rsa); 87602744e81Swyllys out: 87702744e81Swyllys if (asn1 != NULL) 87802744e81Swyllys kmfber_free(asn1, 1); 87902744e81Swyllys 88002744e81Swyllys if (OID.bv_val) { 88102744e81Swyllys free(OID.bv_val); 88202744e81Swyllys } 88302744e81Swyllys if (PriExp) 88402744e81Swyllys free(PriExp); 88502744e81Swyllys 88602744e81Swyllys if (Mod) 88702744e81Swyllys free(Mod); 88802744e81Swyllys 88902744e81Swyllys if (PubExp) 89002744e81Swyllys free(PubExp); 89102744e81Swyllys 89202744e81Swyllys if (Coef) { 89302744e81Swyllys (void) memset(Coef->bv_val, 0, Coef->bv_len); 89402744e81Swyllys free(Coef->bv_val); 89502744e81Swyllys free(Coef); 89602744e81Swyllys } 89702744e81Swyllys if (Prime1) 89802744e81Swyllys free(Prime1); 89902744e81Swyllys if (Prime2) 90002744e81Swyllys free(Prime2); 90102744e81Swyllys 90202744e81Swyllys if (ctx != NULL) 90302744e81Swyllys BN_CTX_free(ctx); 90402744e81Swyllys 90502744e81Swyllys if (D) 90602744e81Swyllys BN_clear_free(D); 90702744e81Swyllys if (P) 90802744e81Swyllys BN_clear_free(P); 90902744e81Swyllys if (Q) 91002744e81Swyllys BN_clear_free(Q); 91102744e81Swyllys if (pminus1) 91202744e81Swyllys BN_clear_free(pminus1); 91302744e81Swyllys if (qminus1) 91402744e81Swyllys BN_clear_free(qminus1); 91502744e81Swyllys if (Exp1) 91602744e81Swyllys BN_clear_free(Exp1); 91702744e81Swyllys if (Exp2) 91802744e81Swyllys BN_clear_free(Exp2); 91902744e81Swyllys 92002744e81Swyllys return (ret); 92102744e81Swyllys 92202744e81Swyllys } 92302744e81Swyllys 92499ebb4caSwyllys static EVP_PKEY * 92599ebb4caSwyllys openssl_load_key(KMF_HANDLE_T handle, const char *file) 92699ebb4caSwyllys { 92799ebb4caSwyllys BIO *keyfile = NULL; 92899ebb4caSwyllys EVP_PKEY *pkey = NULL; 92999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 93099ebb4caSwyllys KMF_ENCODE_FORMAT format; 93102744e81Swyllys KMF_RETURN rv; 93202744e81Swyllys KMF_DATA filedata; 93399ebb4caSwyllys 93499ebb4caSwyllys if (file == NULL) { 93599ebb4caSwyllys return (NULL); 93699ebb4caSwyllys } 93799ebb4caSwyllys 938*30a5e8faSwyllys if (kmf_get_file_format((char *)file, &format) != KMF_OK) 93999ebb4caSwyllys return (NULL); 94099ebb4caSwyllys 94199ebb4caSwyllys keyfile = BIO_new_file(file, "rb"); 94299ebb4caSwyllys if (keyfile == NULL) { 94399ebb4caSwyllys goto end; 94499ebb4caSwyllys } 94599ebb4caSwyllys 94602744e81Swyllys if (format == KMF_FORMAT_ASN1) { 94799ebb4caSwyllys pkey = d2i_PrivateKey_bio(keyfile, NULL); 94802744e81Swyllys if (pkey == NULL) { 94902744e81Swyllys 95002744e81Swyllys (void) BIO_free(keyfile); 95102744e81Swyllys keyfile = NULL; 95202744e81Swyllys /* Try odd ASN.1 variations */ 953*30a5e8faSwyllys rv = kmf_read_input_file(kmfh, (char *)file, 95402744e81Swyllys &filedata); 95502744e81Swyllys if (rv == KMF_OK) { 95602744e81Swyllys (void) readAltFormatPrivateKey(&filedata, 95702744e81Swyllys &pkey); 958*30a5e8faSwyllys kmf_free_data(&filedata); 95902744e81Swyllys } 96002744e81Swyllys } 96102744e81Swyllys } else if (format == KMF_FORMAT_PEM || 96202744e81Swyllys format == KMF_FORMAT_PEM_KEYPAIR) { 96399ebb4caSwyllys pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL); 96402744e81Swyllys if (pkey == NULL) { 96502744e81Swyllys KMF_DATA derdata; 96602744e81Swyllys /* 96702744e81Swyllys * Check if this is the alt. format 96802744e81Swyllys * RSA private key file. 96902744e81Swyllys */ 970*30a5e8faSwyllys rv = kmf_read_input_file(kmfh, (char *)file, 97102744e81Swyllys &filedata); 97202744e81Swyllys if (rv == KMF_OK) { 97302744e81Swyllys uchar_t *d = NULL; 97402744e81Swyllys int len; 975*30a5e8faSwyllys rv = kmf_pem_to_der(filedata.Data, 97602744e81Swyllys filedata.Length, &d, &len); 97702744e81Swyllys if (rv == KMF_OK && d != NULL) { 97802744e81Swyllys derdata.Data = d; 97902744e81Swyllys derdata.Length = (size_t)len; 98002744e81Swyllys (void) readAltFormatPrivateKey( 98102744e81Swyllys &derdata, &pkey); 98202744e81Swyllys free(d); 98302744e81Swyllys } 984*30a5e8faSwyllys kmf_free_data(&filedata); 98502744e81Swyllys } 98602744e81Swyllys } 98702744e81Swyllys } 98899ebb4caSwyllys 98999ebb4caSwyllys end: 99099ebb4caSwyllys if (pkey == NULL) 99199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 99299ebb4caSwyllys 99399ebb4caSwyllys if (keyfile != NULL) 99499ebb4caSwyllys (void) BIO_free(keyfile); 99599ebb4caSwyllys 99699ebb4caSwyllys return (pkey); 99799ebb4caSwyllys } 99899ebb4caSwyllys 99999ebb4caSwyllys KMF_RETURN 1000*30a5e8faSwyllys OpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 100199ebb4caSwyllys { 100299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 100399ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1004f482c776Swyllys int i, n; 1005f482c776Swyllys uint32_t maxcerts = 0; 1006*30a5e8faSwyllys uint32_t *num_certs; 1007*30a5e8faSwyllys KMF_X509_DER_CERT *kmf_cert = NULL; 1008*30a5e8faSwyllys char *dirpath = NULL; 1009*30a5e8faSwyllys char *filename = NULL; 1010*30a5e8faSwyllys char *fullpath = NULL; 1011*30a5e8faSwyllys char *issuer = NULL; 1012*30a5e8faSwyllys char *subject = NULL; 1013*30a5e8faSwyllys KMF_BIGINT *serial = NULL; 1014*30a5e8faSwyllys KMF_CERT_VALIDITY validity; 101599ebb4caSwyllys 1016*30a5e8faSwyllys num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 1017*30a5e8faSwyllys if (num_certs == NULL) 101899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 101999ebb4caSwyllys 1020*30a5e8faSwyllys /* num_certs should reference the size of kmf_cert */ 1021f482c776Swyllys maxcerts = *num_certs; 1022f482c776Swyllys if (maxcerts == 0) 1023f482c776Swyllys maxcerts = 0xFFFFFFFF; 102499ebb4caSwyllys *num_certs = 0; 102599ebb4caSwyllys 1026*30a5e8faSwyllys /* Get the optional returned certificate list */ 1027*30a5e8faSwyllys kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, 1028*30a5e8faSwyllys numattr); 102999ebb4caSwyllys 1030*30a5e8faSwyllys /* 1031*30a5e8faSwyllys * The dirpath attribute and the filename attribute can not be NULL 1032*30a5e8faSwyllys * at the same time. 1033*30a5e8faSwyllys */ 1034*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 1035*30a5e8faSwyllys filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 1036*30a5e8faSwyllys numattr); 1037*30a5e8faSwyllys 1038*30a5e8faSwyllys fullpath = get_fullpath(dirpath, filename); 103999ebb4caSwyllys if (fullpath == NULL) 104099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 104199ebb4caSwyllys 1042*30a5e8faSwyllys /* Get optional search criteria attributes */ 1043*30a5e8faSwyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 1044*30a5e8faSwyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 1045*30a5e8faSwyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 1046*30a5e8faSwyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, 1047*30a5e8faSwyllys &validity, NULL); 1048*30a5e8faSwyllys if (rv != KMF_OK) { 1049*30a5e8faSwyllys validity = KMF_ALL_CERTS; 1050*30a5e8faSwyllys rv = KMF_OK; 1051*30a5e8faSwyllys } 1052*30a5e8faSwyllys 105399ebb4caSwyllys if (isdir(fullpath)) { 105499ebb4caSwyllys DIR *dirp; 105599ebb4caSwyllys struct dirent *dp; 105699ebb4caSwyllys 1057f482c776Swyllys n = 0; 105899ebb4caSwyllys /* open all files in the directory and attempt to read them */ 105999ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 106099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 106199ebb4caSwyllys } 106299ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 106399ebb4caSwyllys char *fname; 106471593db2Swyllys KMF_DATA *certlist = NULL; 1065f482c776Swyllys uint32_t loaded_certs = 0; 106671593db2Swyllys 106799ebb4caSwyllys if (strcmp(dp->d_name, ".") == 0 || 106899ebb4caSwyllys strcmp(dp->d_name, "..") == 0) 106999ebb4caSwyllys continue; 107099ebb4caSwyllys 107134acef67Swyllys fname = get_fullpath(fullpath, (char *)&dp->d_name); 107299ebb4caSwyllys 1073*30a5e8faSwyllys rv = load_certs(kmfh, issuer, subject, serial, 1074*30a5e8faSwyllys validity, fname, &certlist, &loaded_certs); 107599ebb4caSwyllys 107699ebb4caSwyllys if (rv != KMF_OK) { 107799ebb4caSwyllys free(fname); 107871593db2Swyllys if (certlist != NULL) { 1079f482c776Swyllys for (i = 0; i < loaded_certs; i++) 1080*30a5e8faSwyllys kmf_free_data(&certlist[i]); 108171593db2Swyllys free(certlist); 108271593db2Swyllys } 108399ebb4caSwyllys continue; 108499ebb4caSwyllys } 108599ebb4caSwyllys 108699ebb4caSwyllys /* If load succeeds, add certdata to the list */ 108799ebb4caSwyllys if (kmf_cert != NULL) { 1088f482c776Swyllys for (i = 0; i < loaded_certs && 1089b4058258Swyllys n < maxcerts; i++) { 109071593db2Swyllys kmf_cert[n].certificate.Data = 109171593db2Swyllys certlist[i].Data; 109299ebb4caSwyllys kmf_cert[n].certificate.Length = 109371593db2Swyllys certlist[i].Length; 109499ebb4caSwyllys 109599ebb4caSwyllys kmf_cert[n].kmf_private.keystore_type = 109699ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 109799ebb4caSwyllys kmf_cert[n].kmf_private.flags = 109899ebb4caSwyllys KMF_FLAG_CERT_VALID; 109971593db2Swyllys kmf_cert[n].kmf_private.label = 110071593db2Swyllys strdup(fname); 110199ebb4caSwyllys n++; 110299ebb4caSwyllys } 1103b4058258Swyllys /* 1104b4058258Swyllys * If maxcerts < loaded_certs, clean up the 1105b4058258Swyllys * certs that were not used. 1106b4058258Swyllys */ 1107f482c776Swyllys for (; i < loaded_certs; i++) 1108*30a5e8faSwyllys kmf_free_data(&certlist[i]); 1109f482c776Swyllys } else { 1110f482c776Swyllys for (i = 0; i < loaded_certs; i++) 1111*30a5e8faSwyllys kmf_free_data(&certlist[i]); 1112f482c776Swyllys n += loaded_certs; 111371593db2Swyllys } 1114f482c776Swyllys free(certlist); 111571593db2Swyllys free(fname); 111671593db2Swyllys } 111799ebb4caSwyllys (*num_certs) = n; 111899ebb4caSwyllys if (*num_certs == 0) 111999ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 1120*30a5e8faSwyllys if (*num_certs > 0) 112199ebb4caSwyllys rv = KMF_OK; 112299ebb4caSwyllys exit: 112399ebb4caSwyllys (void) closedir(dirp); 112499ebb4caSwyllys } else { 112571593db2Swyllys KMF_DATA *certlist = NULL; 1126f482c776Swyllys uint32_t loaded_certs = 0; 112771593db2Swyllys 1128*30a5e8faSwyllys rv = load_certs(kmfh, issuer, subject, serial, validity, 1129*30a5e8faSwyllys fullpath, &certlist, &loaded_certs); 113099ebb4caSwyllys if (rv != KMF_OK) { 113199ebb4caSwyllys free(fullpath); 113299ebb4caSwyllys return (rv); 113399ebb4caSwyllys } 113499ebb4caSwyllys 1135f482c776Swyllys n = 0; 113671593db2Swyllys if (kmf_cert != NULL && certlist != NULL) { 1137f482c776Swyllys for (i = 0; i < loaded_certs && i < maxcerts; i++) { 1138f482c776Swyllys kmf_cert[n].certificate.Data = 113971593db2Swyllys certlist[i].Data; 1140f482c776Swyllys kmf_cert[n].certificate.Length = 114171593db2Swyllys certlist[i].Length; 1142f482c776Swyllys kmf_cert[n].kmf_private.keystore_type = 114399ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 1144f482c776Swyllys kmf_cert[n].kmf_private.flags = 114571593db2Swyllys KMF_FLAG_CERT_VALID; 1146f482c776Swyllys kmf_cert[n].kmf_private.label = 114771593db2Swyllys strdup(fullpath); 1148f482c776Swyllys n++; 114971593db2Swyllys } 1150f482c776Swyllys /* If maxcerts < loaded_certs, clean up */ 1151f482c776Swyllys for (; i < loaded_certs; i++) 1152*30a5e8faSwyllys kmf_free_data(&certlist[i]); 1153f482c776Swyllys } else if (certlist != NULL) { 1154f482c776Swyllys for (i = 0; i < loaded_certs; i++) 1155*30a5e8faSwyllys kmf_free_data(&certlist[i]); 1156f482c776Swyllys n = loaded_certs; 1157f482c776Swyllys } 1158*30a5e8faSwyllys if (certlist != NULL) 115971593db2Swyllys free(certlist); 1160f482c776Swyllys *num_certs = n; 116199ebb4caSwyllys } 116299ebb4caSwyllys 116399ebb4caSwyllys free(fullpath); 116499ebb4caSwyllys 116599ebb4caSwyllys return (rv); 116699ebb4caSwyllys } 116799ebb4caSwyllys 116899ebb4caSwyllys void 116999ebb4caSwyllys /*ARGSUSED*/ 117099ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, 117199ebb4caSwyllys KMF_X509_DER_CERT *kmf_cert) 117299ebb4caSwyllys { 117399ebb4caSwyllys if (kmf_cert != NULL) { 117499ebb4caSwyllys if (kmf_cert->certificate.Data != NULL) { 117599ebb4caSwyllys free(kmf_cert->certificate.Data); 117699ebb4caSwyllys kmf_cert->certificate.Data = NULL; 117799ebb4caSwyllys kmf_cert->certificate.Length = 0; 117899ebb4caSwyllys } 117999ebb4caSwyllys if (kmf_cert->kmf_private.label) 118099ebb4caSwyllys free(kmf_cert->kmf_private.label); 118199ebb4caSwyllys } 118299ebb4caSwyllys } 118399ebb4caSwyllys 1184*30a5e8faSwyllys /*ARGSUSED*/ 118599ebb4caSwyllys KMF_RETURN 1186*30a5e8faSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 118799ebb4caSwyllys { 118899ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1189*30a5e8faSwyllys KMF_DATA *cert = NULL; 1190*30a5e8faSwyllys char *outfilename = NULL; 1191*30a5e8faSwyllys char *dirpath = NULL; 1192*30a5e8faSwyllys char *fullpath = NULL; 119399ebb4caSwyllys KMF_ENCODE_FORMAT format; 119499ebb4caSwyllys 1195*30a5e8faSwyllys /* Get the cert data */ 1196*30a5e8faSwyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 1197*30a5e8faSwyllys if (cert == NULL || cert->Data == NULL) 119899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 119999ebb4caSwyllys 1200*30a5e8faSwyllys /* Check the output filename and directory attributes. */ 1201*30a5e8faSwyllys outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 1202*30a5e8faSwyllys numattr); 1203*30a5e8faSwyllys if (outfilename == NULL) 1204*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 120599ebb4caSwyllys 1206*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 1207*30a5e8faSwyllys fullpath = get_fullpath(dirpath, outfilename); 120899ebb4caSwyllys if (fullpath == NULL) 1209*30a5e8faSwyllys return (KMF_ERR_BAD_CERTFILE); 121099ebb4caSwyllys 1211*30a5e8faSwyllys /* Check the optional format attribute */ 1212*30a5e8faSwyllys ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 1213*30a5e8faSwyllys &format, NULL); 1214*30a5e8faSwyllys if (ret != KMF_OK) { 1215*30a5e8faSwyllys /* If there is no format attribute, then default to PEM */ 1216*30a5e8faSwyllys format = KMF_FORMAT_PEM; 121799ebb4caSwyllys ret = KMF_OK; 1218*30a5e8faSwyllys } else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) { 1219*30a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 122099ebb4caSwyllys goto out; 122199ebb4caSwyllys } 122299ebb4caSwyllys 1223*30a5e8faSwyllys /* Store the certificate in the file with the specified format */ 1224*30a5e8faSwyllys ret = kmf_create_cert_file(cert, format, fullpath); 122599ebb4caSwyllys 122699ebb4caSwyllys out: 122799ebb4caSwyllys if (fullpath != NULL) 122899ebb4caSwyllys free(fullpath); 122999ebb4caSwyllys 123099ebb4caSwyllys return (ret); 123199ebb4caSwyllys } 123299ebb4caSwyllys 1233*30a5e8faSwyllys 123499ebb4caSwyllys KMF_RETURN 1235*30a5e8faSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 123699ebb4caSwyllys { 123799ebb4caSwyllys KMF_RETURN rv; 123899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 123999ebb4caSwyllys KMF_DATA certdata = {NULL, 0}; 1240*30a5e8faSwyllys char *dirpath = NULL; 1241*30a5e8faSwyllys char *filename = NULL; 1242*30a5e8faSwyllys char *fullpath = NULL; 1243*30a5e8faSwyllys char *issuer = NULL; 1244*30a5e8faSwyllys char *subject = NULL; 1245*30a5e8faSwyllys KMF_BIGINT *serial = NULL; 1246*30a5e8faSwyllys KMF_CERT_VALIDITY validity; 124799ebb4caSwyllys 1248*30a5e8faSwyllys /* 1249*30a5e8faSwyllys * Get the DIRPATH and CERT_FILENAME attributes. They can not be 1250*30a5e8faSwyllys * NULL at the same time. 1251*30a5e8faSwyllys */ 1252*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 1253*30a5e8faSwyllys filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 1254*30a5e8faSwyllys numattr); 1255*30a5e8faSwyllys fullpath = get_fullpath(dirpath, filename); 125699ebb4caSwyllys if (fullpath == NULL) 125799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 125899ebb4caSwyllys 1259*30a5e8faSwyllys /* Get optional search criteria attributes */ 1260*30a5e8faSwyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 1261*30a5e8faSwyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 1262*30a5e8faSwyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 1263*30a5e8faSwyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, 1264*30a5e8faSwyllys &validity, NULL); 1265*30a5e8faSwyllys if (rv != KMF_OK) { 1266*30a5e8faSwyllys validity = KMF_ALL_CERTS; 1267*30a5e8faSwyllys rv = KMF_OK; 1268*30a5e8faSwyllys } 1269*30a5e8faSwyllys 127099ebb4caSwyllys if (isdir(fullpath)) { 127199ebb4caSwyllys DIR *dirp; 127299ebb4caSwyllys struct dirent *dp; 127399ebb4caSwyllys 127499ebb4caSwyllys /* open all files in the directory and attempt to read them */ 127599ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 127699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 127799ebb4caSwyllys } 127899ebb4caSwyllys 127999ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 128099ebb4caSwyllys if (strcmp(dp->d_name, ".") != 0 && 128199ebb4caSwyllys strcmp(dp->d_name, "..") != 0) { 128299ebb4caSwyllys char *fname; 128399ebb4caSwyllys 128499ebb4caSwyllys fname = get_fullpath(fullpath, 128599ebb4caSwyllys (char *)&dp->d_name); 128699ebb4caSwyllys 128799ebb4caSwyllys if (fname == NULL) { 128899ebb4caSwyllys rv = KMF_ERR_MEMORY; 128999ebb4caSwyllys break; 129099ebb4caSwyllys } 129199ebb4caSwyllys 1292*30a5e8faSwyllys rv = kmf_load_cert(kmfh, issuer, subject, 1293*30a5e8faSwyllys serial, validity, fname, &certdata); 129499ebb4caSwyllys 129599ebb4caSwyllys if (rv == KMF_ERR_CERT_NOT_FOUND) { 129699ebb4caSwyllys free(fname); 129799ebb4caSwyllys if (certdata.Data) 129899ebb4caSwyllys free(certdata.Data); 129999ebb4caSwyllys rv = KMF_OK; 130099ebb4caSwyllys continue; 130199ebb4caSwyllys } else if (rv != KMF_OK) { 130299ebb4caSwyllys free(fname); 130399ebb4caSwyllys break; 130499ebb4caSwyllys } 130599ebb4caSwyllys 130699ebb4caSwyllys if (unlink(fname) != 0) { 130799ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 130899ebb4caSwyllys rv = KMF_ERR_INTERNAL; 130999ebb4caSwyllys free(fname); 131099ebb4caSwyllys break; 131199ebb4caSwyllys } 131299ebb4caSwyllys free(fname); 131399ebb4caSwyllys if (certdata.Data) 131499ebb4caSwyllys free(certdata.Data); 131599ebb4caSwyllys } 131699ebb4caSwyllys } 131799ebb4caSwyllys (void) closedir(dirp); 131899ebb4caSwyllys } else { 131999ebb4caSwyllys /* Just try to load a single certificate */ 1320*30a5e8faSwyllys rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, 1321*30a5e8faSwyllys fullpath, &certdata); 132299ebb4caSwyllys if (rv == KMF_OK) { 132399ebb4caSwyllys if (unlink(fullpath) != 0) { 132499ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 132599ebb4caSwyllys rv = KMF_ERR_INTERNAL; 132699ebb4caSwyllys } 132799ebb4caSwyllys } 132899ebb4caSwyllys } 132999ebb4caSwyllys 133099ebb4caSwyllys out: 133199ebb4caSwyllys if (fullpath != NULL) 133299ebb4caSwyllys free(fullpath); 133399ebb4caSwyllys 133499ebb4caSwyllys if (certdata.Data) 133599ebb4caSwyllys free(certdata.Data); 133699ebb4caSwyllys 133799ebb4caSwyllys return (rv); 133899ebb4caSwyllys } 133999ebb4caSwyllys 134099ebb4caSwyllys KMF_RETURN 134199ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 134299ebb4caSwyllys KMF_DATA *keydata) 134399ebb4caSwyllys { 134499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 134599ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 134699ebb4caSwyllys int n; 134799ebb4caSwyllys 134899ebb4caSwyllys if (key == NULL || keydata == NULL || 134999ebb4caSwyllys key->keyp == NULL) 135099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 135199ebb4caSwyllys 135299ebb4caSwyllys if (key->keyalg == KMF_RSA) { 135399ebb4caSwyllys RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp); 135499ebb4caSwyllys 135599ebb4caSwyllys if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) { 135699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 135799ebb4caSwyllys return (KMF_ERR_ENCODING); 135899ebb4caSwyllys } 135999ebb4caSwyllys RSA_free(pubkey); 136099ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 136199ebb4caSwyllys DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp); 136299ebb4caSwyllys 136399ebb4caSwyllys if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) { 136499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 136599ebb4caSwyllys return (KMF_ERR_ENCODING); 136699ebb4caSwyllys } 136799ebb4caSwyllys DSA_free(pubkey); 136899ebb4caSwyllys } else { 136999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 137099ebb4caSwyllys } 137199ebb4caSwyllys keydata->Length = n; 137299ebb4caSwyllys 137399ebb4caSwyllys cleanup: 137499ebb4caSwyllys if (rv != KMF_OK) { 137599ebb4caSwyllys if (keydata->Data) 137699ebb4caSwyllys free(keydata->Data); 137799ebb4caSwyllys keydata->Data = NULL; 137899ebb4caSwyllys keydata->Length = 0; 137999ebb4caSwyllys } 138099ebb4caSwyllys 138199ebb4caSwyllys return (rv); 138299ebb4caSwyllys } 138399ebb4caSwyllys 138499ebb4caSwyllys static KMF_RETURN 1385*30a5e8faSwyllys ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, 1386*30a5e8faSwyllys KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private) 138799ebb4caSwyllys { 138899ebb4caSwyllys int rv = 0; 138999ebb4caSwyllys RSA *rsa; 139099ebb4caSwyllys DSA *dsa; 139199ebb4caSwyllys 139299ebb4caSwyllys switch (format) { 139399ebb4caSwyllys case KMF_FORMAT_ASN1: 139499ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 139599ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 1396*30a5e8faSwyllys if (private) 139799ebb4caSwyllys rv = i2d_RSAPrivateKey_bio(out, rsa); 1398*30a5e8faSwyllys else 1399*30a5e8faSwyllys rv = i2d_RSAPublicKey_bio(out, rsa); 140099ebb4caSwyllys RSA_free(rsa); 140199ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 140299ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 140399ebb4caSwyllys rv = i2d_DSAPrivateKey_bio(out, dsa); 140499ebb4caSwyllys DSA_free(dsa); 140599ebb4caSwyllys } 140699ebb4caSwyllys if (rv == 1) { 140799ebb4caSwyllys rv = KMF_OK; 140899ebb4caSwyllys } else { 140999ebb4caSwyllys SET_ERROR(kmfh, rv); 141099ebb4caSwyllys } 141199ebb4caSwyllys break; 141299ebb4caSwyllys case KMF_FORMAT_PEM: 141399ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 141499ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 1415*30a5e8faSwyllys if (private) 141699ebb4caSwyllys rv = PEM_write_bio_RSAPrivateKey(out, 1417*30a5e8faSwyllys rsa, NULL, NULL, 0, NULL, 1418*30a5e8faSwyllys (cred != NULL ? cred->cred : NULL)); 1419*30a5e8faSwyllys else 1420*30a5e8faSwyllys rv = PEM_write_bio_RSAPublicKey(out, 1421*30a5e8faSwyllys rsa); 142299ebb4caSwyllys RSA_free(rsa); 142399ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 142499ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 142599ebb4caSwyllys rv = PEM_write_bio_DSAPrivateKey(out, 1426*30a5e8faSwyllys dsa, NULL, NULL, 0, NULL, 1427*30a5e8faSwyllys (cred != NULL ? cred->cred : NULL)); 142899ebb4caSwyllys DSA_free(dsa); 142999ebb4caSwyllys } 143099ebb4caSwyllys 143199ebb4caSwyllys if (rv == 1) { 143299ebb4caSwyllys rv = KMF_OK; 143399ebb4caSwyllys } else { 143499ebb4caSwyllys SET_ERROR(kmfh, rv); 143599ebb4caSwyllys } 143699ebb4caSwyllys break; 143799ebb4caSwyllys 143899ebb4caSwyllys default: 143999ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 144099ebb4caSwyllys } 144199ebb4caSwyllys 144299ebb4caSwyllys return (rv); 144399ebb4caSwyllys } 144499ebb4caSwyllys 144599ebb4caSwyllys KMF_RETURN 1446*30a5e8faSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, 1447*30a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 144899ebb4caSwyllys { 144999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 145099ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 145199ebb4caSwyllys uint32_t eValue = 0x010001; 145299ebb4caSwyllys RSA *sslPrivKey = NULL; 145399ebb4caSwyllys DSA *sslDSAKey = NULL; 145499ebb4caSwyllys EVP_PKEY *eprikey = NULL; 145599ebb4caSwyllys EVP_PKEY *epubkey = NULL; 145699ebb4caSwyllys BIO *out = NULL; 1457*30a5e8faSwyllys KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL; 1458*30a5e8faSwyllys uint32_t keylen = 1024; 1459*30a5e8faSwyllys uint32_t keylen_size = sizeof (uint32_t); 1460*30a5e8faSwyllys boolean_t storekey = TRUE; 1461*30a5e8faSwyllys KMF_KEY_ALG keytype = KMF_RSA; 146299ebb4caSwyllys 1463*30a5e8faSwyllys rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr, 1464*30a5e8faSwyllys &storekey, NULL); 1465*30a5e8faSwyllys if (rv != KMF_OK) { 1466*30a5e8faSwyllys /* "storekey" is optional. Default is TRUE */ 1467*30a5e8faSwyllys rv = KMF_OK; 146899ebb4caSwyllys } 146999ebb4caSwyllys 1470*30a5e8faSwyllys rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 1471*30a5e8faSwyllys (void *)&keytype, NULL); 1472*30a5e8faSwyllys if (rv != KMF_OK) 1473*30a5e8faSwyllys /* keytype is optional. KMF_RSA is default */ 1474*30a5e8faSwyllys rv = KMF_OK; 147599ebb4caSwyllys 1476*30a5e8faSwyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); 1477*30a5e8faSwyllys if (pubkey == NULL) 147899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 147999ebb4caSwyllys 1480*30a5e8faSwyllys privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); 1481*30a5e8faSwyllys if (privkey == NULL) 1482*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 1483*30a5e8faSwyllys 1484*30a5e8faSwyllys (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); 1485*30a5e8faSwyllys (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); 148699ebb4caSwyllys 148799ebb4caSwyllys eprikey = EVP_PKEY_new(); 148899ebb4caSwyllys if (eprikey == NULL) { 148999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 149099ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 149199ebb4caSwyllys goto cleanup; 149299ebb4caSwyllys } 149399ebb4caSwyllys epubkey = EVP_PKEY_new(); 149499ebb4caSwyllys if (epubkey == NULL) { 149599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 149699ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 149799ebb4caSwyllys goto cleanup; 149899ebb4caSwyllys } 1499*30a5e8faSwyllys if (keytype == KMF_RSA) { 1500*30a5e8faSwyllys KMF_BIGINT *rsaexp = NULL; 150199ebb4caSwyllys 1502*30a5e8faSwyllys rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr); 1503*30a5e8faSwyllys if (rsaexp != NULL) { 1504*30a5e8faSwyllys if (rsaexp->len > 0 && 1505*30a5e8faSwyllys rsaexp->len <= sizeof (eValue) && 1506*30a5e8faSwyllys rsaexp->val != NULL) { 1507*30a5e8faSwyllys /*LINTED*/ 1508*30a5e8faSwyllys eValue = *(uint32_t *)rsaexp->val; 1509*30a5e8faSwyllys } else { 1510*30a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 1511*30a5e8faSwyllys goto cleanup; 1512*30a5e8faSwyllys } 1513*30a5e8faSwyllys } else { 1514*30a5e8faSwyllys /* RSA Exponent is optional. Default is 0x10001 */ 1515*30a5e8faSwyllys rv = KMF_OK; 1516*30a5e8faSwyllys } 1517*30a5e8faSwyllys 1518*30a5e8faSwyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 1519*30a5e8faSwyllys &keylen, &keylen_size); 1520*30a5e8faSwyllys if (rv == KMF_ERR_ATTR_NOT_FOUND) 1521*30a5e8faSwyllys /* keylen is optional, default is 1024 */ 1522*30a5e8faSwyllys rv = KMF_OK; 1523*30a5e8faSwyllys if (rv != KMF_OK) { 1524*30a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 1525*30a5e8faSwyllys goto cleanup; 1526*30a5e8faSwyllys } 1527*30a5e8faSwyllys 1528*30a5e8faSwyllys sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL); 152999ebb4caSwyllys if (sslPrivKey == NULL) { 153099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 153199ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 153299ebb4caSwyllys } else { 1533*30a5e8faSwyllys (void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey); 153499ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 153599ebb4caSwyllys privkey->keyalg = KMF_RSA; 153699ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 153799ebb4caSwyllys privkey->israw = FALSE; 153899ebb4caSwyllys privkey->keyp = (void *)eprikey; 1539*30a5e8faSwyllys 154099ebb4caSwyllys /* OpenSSL derives the public key from the private */ 1541*30a5e8faSwyllys (void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey); 154299ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 154399ebb4caSwyllys pubkey->keyalg = KMF_RSA; 154499ebb4caSwyllys pubkey->israw = FALSE; 154599ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 154699ebb4caSwyllys pubkey->keyp = (void *)epubkey; 154799ebb4caSwyllys } 1548*30a5e8faSwyllys } else if (keytype == KMF_DSA) { 1549*30a5e8faSwyllys DSA *dp; 155099ebb4caSwyllys sslDSAKey = DSA_new(); 155199ebb4caSwyllys if (sslDSAKey == NULL) { 155299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 155399ebb4caSwyllys return (KMF_ERR_MEMORY); 155499ebb4caSwyllys } 155599ebb4caSwyllys 155699ebb4caSwyllys if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) == 155799ebb4caSwyllys NULL) { 155899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 155999ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 156099ebb4caSwyllys goto cleanup; 156199ebb4caSwyllys } 156299ebb4caSwyllys if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) == 156399ebb4caSwyllys NULL) { 156499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 156599ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 156699ebb4caSwyllys goto cleanup; 156799ebb4caSwyllys } 156899ebb4caSwyllys if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) == 156999ebb4caSwyllys NULL) { 157099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 157199ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 157299ebb4caSwyllys goto cleanup; 157399ebb4caSwyllys } 157499ebb4caSwyllys 157599ebb4caSwyllys if (!DSA_generate_key(sslDSAKey)) { 157699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 157799ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 157899ebb4caSwyllys goto cleanup; 157999ebb4caSwyllys } 158099ebb4caSwyllys 158199ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 158299ebb4caSwyllys privkey->keyalg = KMF_DSA; 158399ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 158499ebb4caSwyllys privkey->israw = FALSE; 158599ebb4caSwyllys if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { 158699ebb4caSwyllys privkey->keyp = (void *)eprikey; 158799ebb4caSwyllys } else { 158899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 158999ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 159099ebb4caSwyllys goto cleanup; 159199ebb4caSwyllys } 1592*30a5e8faSwyllys dp = DSA_new(); 159399ebb4caSwyllys /* Make a copy for the public key */ 159499ebb4caSwyllys if (dp != NULL) { 159599ebb4caSwyllys if ((dp->p = BN_new()) == NULL) { 159699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 159799ebb4caSwyllys rv = KMF_ERR_MEMORY; 159899ebb4caSwyllys DSA_free(dp); 159999ebb4caSwyllys goto cleanup; 160099ebb4caSwyllys } 160199ebb4caSwyllys if ((dp->q = BN_new()) == NULL) { 160299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 160399ebb4caSwyllys rv = KMF_ERR_MEMORY; 160499ebb4caSwyllys BN_free(dp->p); 160599ebb4caSwyllys DSA_free(dp); 160699ebb4caSwyllys goto cleanup; 160799ebb4caSwyllys } 160899ebb4caSwyllys if ((dp->g = BN_new()) == NULL) { 160999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 161099ebb4caSwyllys rv = KMF_ERR_MEMORY; 161199ebb4caSwyllys BN_free(dp->q); 161299ebb4caSwyllys BN_free(dp->p); 161399ebb4caSwyllys DSA_free(dp); 161499ebb4caSwyllys goto cleanup; 161599ebb4caSwyllys } 161699ebb4caSwyllys if ((dp->pub_key = BN_new()) == NULL) { 161799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 161899ebb4caSwyllys rv = KMF_ERR_MEMORY; 161999ebb4caSwyllys BN_free(dp->q); 162099ebb4caSwyllys BN_free(dp->p); 162199ebb4caSwyllys BN_free(dp->g); 162299ebb4caSwyllys DSA_free(dp); 162399ebb4caSwyllys goto cleanup; 162499ebb4caSwyllys } 162599ebb4caSwyllys (void) BN_copy(dp->p, sslDSAKey->p); 162699ebb4caSwyllys (void) BN_copy(dp->q, sslDSAKey->q); 162799ebb4caSwyllys (void) BN_copy(dp->g, sslDSAKey->g); 162899ebb4caSwyllys (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); 162999ebb4caSwyllys 163099ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 163199ebb4caSwyllys pubkey->keyalg = KMF_DSA; 163299ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 163399ebb4caSwyllys pubkey->israw = FALSE; 163499ebb4caSwyllys 163599ebb4caSwyllys if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { 163699ebb4caSwyllys pubkey->keyp = (void *)epubkey; 163799ebb4caSwyllys } else { 163899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 163999ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 164099ebb4caSwyllys goto cleanup; 164199ebb4caSwyllys } 164299ebb4caSwyllys } 164399ebb4caSwyllys } 164499ebb4caSwyllys 164599ebb4caSwyllys if (rv != KMF_OK) { 164699ebb4caSwyllys goto cleanup; 164799ebb4caSwyllys } 164899ebb4caSwyllys 1649*30a5e8faSwyllys if (storekey) { 1650*30a5e8faSwyllys KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */ 1651*30a5e8faSwyllys int i = 0; 1652*30a5e8faSwyllys char *keyfile = NULL, *dirpath = NULL; 1653*30a5e8faSwyllys KMF_ENCODE_FORMAT format; 1654*30a5e8faSwyllys /* 1655*30a5e8faSwyllys * Construct a new attribute arrray and call openssl_store_key 1656*30a5e8faSwyllys */ 1657*30a5e8faSwyllys kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR, 1658*30a5e8faSwyllys privkey, sizeof (privkey)); 1659*30a5e8faSwyllys i++; 1660*30a5e8faSwyllys 1661*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 1662*30a5e8faSwyllys if (dirpath != NULL) { 1663*30a5e8faSwyllys storeattrs[i].type = KMF_DIRPATH_ATTR; 1664*30a5e8faSwyllys storeattrs[i].pValue = dirpath; 1665*30a5e8faSwyllys storeattrs[i].valueLen = strlen(dirpath); 1666*30a5e8faSwyllys i++; 1667*30a5e8faSwyllys } else { 1668*30a5e8faSwyllys rv = KMF_OK; /* DIRPATH is optional */ 166999ebb4caSwyllys } 1670*30a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, 1671*30a5e8faSwyllys attrlist, numattr); 1672*30a5e8faSwyllys if (keyfile != NULL) { 1673*30a5e8faSwyllys storeattrs[i].type = KMF_KEY_FILENAME_ATTR; 1674*30a5e8faSwyllys storeattrs[i].pValue = keyfile; 1675*30a5e8faSwyllys storeattrs[i].valueLen = strlen(keyfile); 1676*30a5e8faSwyllys i++; 1677*30a5e8faSwyllys } else { 1678*30a5e8faSwyllys goto cleanup; /* KEYFILE is required */ 1679*30a5e8faSwyllys } 1680*30a5e8faSwyllys rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 1681*30a5e8faSwyllys (void *)&format, NULL); 1682*30a5e8faSwyllys if (rv == KMF_OK) { 1683*30a5e8faSwyllys storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR; 1684*30a5e8faSwyllys storeattrs[i].pValue = &format; 1685*30a5e8faSwyllys storeattrs[i].valueLen = sizeof (format); 1686*30a5e8faSwyllys i++; 1687*30a5e8faSwyllys } 1688*30a5e8faSwyllys 1689*30a5e8faSwyllys rv = OpenSSL_StoreKey(handle, i, storeattrs); 1690*30a5e8faSwyllys } 169199ebb4caSwyllys 169299ebb4caSwyllys cleanup: 169399ebb4caSwyllys if (rv != KMF_OK) { 169499ebb4caSwyllys if (eprikey != NULL) 169599ebb4caSwyllys EVP_PKEY_free(eprikey); 169699ebb4caSwyllys 169799ebb4caSwyllys if (epubkey != NULL) 169899ebb4caSwyllys EVP_PKEY_free(epubkey); 169999ebb4caSwyllys 170099ebb4caSwyllys if (pubkey->keylabel) { 170199ebb4caSwyllys free(pubkey->keylabel); 170299ebb4caSwyllys pubkey->keylabel = NULL; 170399ebb4caSwyllys } 170499ebb4caSwyllys 170599ebb4caSwyllys if (privkey->keylabel) { 170699ebb4caSwyllys free(privkey->keylabel); 170799ebb4caSwyllys privkey->keylabel = NULL; 170899ebb4caSwyllys } 170999ebb4caSwyllys 171099ebb4caSwyllys pubkey->keyp = NULL; 171199ebb4caSwyllys privkey->keyp = NULL; 171299ebb4caSwyllys } 171399ebb4caSwyllys 171499ebb4caSwyllys if (sslPrivKey) 171599ebb4caSwyllys RSA_free(sslPrivKey); 171699ebb4caSwyllys 171799ebb4caSwyllys if (sslDSAKey) 171899ebb4caSwyllys DSA_free(sslDSAKey); 171999ebb4caSwyllys 172099ebb4caSwyllys if (out != NULL) 172199ebb4caSwyllys (void) BIO_free(out); 172299ebb4caSwyllys 172399ebb4caSwyllys return (rv); 172499ebb4caSwyllys } 172599ebb4caSwyllys 172699ebb4caSwyllys KMF_RETURN 172799ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 172899ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output) 172999ebb4caSwyllys { 173099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 173199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 173299ebb4caSwyllys KMF_ALGORITHM_INDEX AlgId; 173399ebb4caSwyllys EVP_MD_CTX ctx; 173499ebb4caSwyllys const EVP_MD *md; 173502744e81Swyllys 173699ebb4caSwyllys if (key == NULL || AlgOID == NULL || 173799ebb4caSwyllys tobesigned == NULL || output == NULL || 173899ebb4caSwyllys tobesigned->Data == NULL || 173999ebb4caSwyllys output->Data == NULL) 174099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 174199ebb4caSwyllys 174299ebb4caSwyllys /* Map the OID to an OpenSSL algorithm */ 1743*30a5e8faSwyllys AlgId = x509_algoid_to_algid(AlgOID); 174499ebb4caSwyllys if (AlgId == KMF_ALGID_NONE) 174599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 174699ebb4caSwyllys 174799ebb4caSwyllys if (key->keyalg == KMF_RSA) { 174899ebb4caSwyllys EVP_PKEY *pkey = (EVP_PKEY *)key->keyp; 174999ebb4caSwyllys uchar_t *p; 175002744e81Swyllys int len; 175199ebb4caSwyllys if (AlgId == KMF_ALGID_MD5WithRSA) 175299ebb4caSwyllys md = EVP_md5(); 175399ebb4caSwyllys else if (AlgId == KMF_ALGID_MD2WithRSA) 175499ebb4caSwyllys md = EVP_md2(); 175599ebb4caSwyllys else if (AlgId == KMF_ALGID_SHA1WithRSA) 175699ebb4caSwyllys md = EVP_sha1(); 175702744e81Swyllys else if (AlgId == KMF_ALGID_RSA) 175802744e81Swyllys md = NULL; 175999ebb4caSwyllys else 176099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 176199ebb4caSwyllys 176202744e81Swyllys if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) { 176302744e81Swyllys RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey); 176499ebb4caSwyllys 176502744e81Swyllys p = output->Data; 176602744e81Swyllys if ((len = RSA_private_encrypt(tobesigned->Length, 176702744e81Swyllys tobesigned->Data, p, rsa, 176802744e81Swyllys RSA_PKCS1_PADDING)) <= 0) { 176902744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 177002744e81Swyllys ret = KMF_ERR_INTERNAL; 177102744e81Swyllys } 177202744e81Swyllys output->Length = len; 177302744e81Swyllys } else { 177499ebb4caSwyllys (void) EVP_MD_CTX_init(&ctx); 177599ebb4caSwyllys (void) EVP_SignInit_ex(&ctx, md, NULL); 177699ebb4caSwyllys (void) EVP_SignUpdate(&ctx, tobesigned->Data, 177799ebb4caSwyllys (uint32_t)tobesigned->Length); 177899ebb4caSwyllys len = (uint32_t)output->Length; 177999ebb4caSwyllys p = output->Data; 178002744e81Swyllys if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) { 178199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 178202744e81Swyllys len = 0; 178302744e81Swyllys ret = KMF_ERR_INTERNAL; 178499ebb4caSwyllys } 178599ebb4caSwyllys output->Length = len; 178699ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 178702744e81Swyllys } 178899ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 178999ebb4caSwyllys DSA *dsa = EVP_PKEY_get1_DSA(key->keyp); 179099ebb4caSwyllys 179199ebb4caSwyllys uchar_t hash[EVP_MAX_MD_SIZE]; 179299ebb4caSwyllys uint32_t hashlen; 179399ebb4caSwyllys DSA_SIG *dsasig; 179499ebb4caSwyllys 179599ebb4caSwyllys /* 179699ebb4caSwyllys * OpenSSL EVP_Sign operation automatically converts to 179799ebb4caSwyllys * ASN.1 output so we do the operations separately so we 179899ebb4caSwyllys * are assured of NOT getting ASN.1 output returned. 179999ebb4caSwyllys * KMF does not want ASN.1 encoded results because 180099ebb4caSwyllys * not all mechanisms return ASN.1 encodings (PKCS#11 180199ebb4caSwyllys * and NSS return raw signature data). 180299ebb4caSwyllys */ 180399ebb4caSwyllys md = EVP_sha1(); 180499ebb4caSwyllys EVP_MD_CTX_init(&ctx); 180599ebb4caSwyllys (void) EVP_DigestInit_ex(&ctx, md, NULL); 180699ebb4caSwyllys (void) EVP_DigestUpdate(&ctx, tobesigned->Data, 180799ebb4caSwyllys tobesigned->Length); 180899ebb4caSwyllys (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen); 180999ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 181099ebb4caSwyllys 181199ebb4caSwyllys dsasig = DSA_do_sign(hash, hashlen, dsa); 181299ebb4caSwyllys if (dsasig != NULL) { 181399ebb4caSwyllys int i; 181499ebb4caSwyllys output->Length = i = BN_bn2bin(dsasig->r, output->Data); 181599ebb4caSwyllys output->Length += BN_bn2bin(dsasig->s, 181699ebb4caSwyllys &output->Data[i]); 181799ebb4caSwyllys DSA_SIG_free(dsasig); 181899ebb4caSwyllys } else { 181999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 182099ebb4caSwyllys } 182199ebb4caSwyllys } else { 182299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 182399ebb4caSwyllys } 182499ebb4caSwyllys cleanup: 182599ebb4caSwyllys return (ret); 182699ebb4caSwyllys } 182799ebb4caSwyllys 182899ebb4caSwyllys KMF_RETURN 182999ebb4caSwyllys /*ARGSUSED*/ 1830*30a5e8faSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T handle, 1831*30a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 183299ebb4caSwyllys { 183399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 1834*30a5e8faSwyllys KMF_KEY_HANDLE *key; 1835*30a5e8faSwyllys boolean_t destroy = B_TRUE; 1836*30a5e8faSwyllys 1837*30a5e8faSwyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 183899ebb4caSwyllys if (key == NULL || key->keyp == NULL) 183999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 184099ebb4caSwyllys 1841*30a5e8faSwyllys rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, 1842*30a5e8faSwyllys (void *)&destroy, NULL); 1843*30a5e8faSwyllys if (rv != KMF_OK) { 1844*30a5e8faSwyllys /* "destroy" is optional. Default is TRUE */ 1845*30a5e8faSwyllys rv = KMF_OK; 1846*30a5e8faSwyllys } 1847*30a5e8faSwyllys 184899ebb4caSwyllys if (key->keyclass != KMF_ASYM_PUB && 184999ebb4caSwyllys key->keyclass != KMF_ASYM_PRI && 185099ebb4caSwyllys key->keyclass != KMF_SYMMETRIC) 185199ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 185299ebb4caSwyllys 185399ebb4caSwyllys if (key->keyclass == KMF_SYMMETRIC) { 1854*30a5e8faSwyllys kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp); 185599ebb4caSwyllys key->keyp = NULL; 185699ebb4caSwyllys } else { 185799ebb4caSwyllys if (key->keyp != NULL) { 185899ebb4caSwyllys EVP_PKEY_free(key->keyp); 185999ebb4caSwyllys key->keyp = NULL; 186099ebb4caSwyllys } 186199ebb4caSwyllys } 186299ebb4caSwyllys 186399ebb4caSwyllys if (key->keylabel != NULL) { 186499ebb4caSwyllys EVP_PKEY *pkey = NULL; 186599ebb4caSwyllys /* If the file exists, make sure it is a proper key. */ 186699ebb4caSwyllys pkey = openssl_load_key(handle, key->keylabel); 186799ebb4caSwyllys if (pkey == NULL) { 186899ebb4caSwyllys free(key->keylabel); 186999ebb4caSwyllys key->keylabel = NULL; 187099ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 187199ebb4caSwyllys } 187299ebb4caSwyllys EVP_PKEY_free(pkey); 187399ebb4caSwyllys 187499ebb4caSwyllys if (destroy) { 187599ebb4caSwyllys if (unlink(key->keylabel) != 0) { 187699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 187799ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 187899ebb4caSwyllys rv = KMF_ERR_INTERNAL; 187999ebb4caSwyllys } 188099ebb4caSwyllys } 188199ebb4caSwyllys if (key->keylabel != NULL) { 188299ebb4caSwyllys free(key->keylabel); 188399ebb4caSwyllys key->keylabel = NULL; 188499ebb4caSwyllys } 188599ebb4caSwyllys } 188699ebb4caSwyllys return (rv); 188799ebb4caSwyllys } 188899ebb4caSwyllys 188999ebb4caSwyllys KMF_RETURN 189099ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 189199ebb4caSwyllys { 189299ebb4caSwyllys KMF_RETURN ret = KMF_OK; 189399ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 189499ebb4caSwyllys char str[256]; /* OpenSSL needs at least 120 byte buffer */ 189599ebb4caSwyllys 189699ebb4caSwyllys ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str)); 189799ebb4caSwyllys if (strlen(str)) { 189899ebb4caSwyllys *msgstr = (char *)strdup(str); 189999ebb4caSwyllys if ((*msgstr) == NULL) 190099ebb4caSwyllys ret = KMF_ERR_MEMORY; 190199ebb4caSwyllys } else { 190299ebb4caSwyllys *msgstr = NULL; 190399ebb4caSwyllys } 190499ebb4caSwyllys 190599ebb4caSwyllys return (ret); 190699ebb4caSwyllys } 190799ebb4caSwyllys 190899ebb4caSwyllys static int 190999ebb4caSwyllys ext2NID(int kmfext) 191099ebb4caSwyllys { 191199ebb4caSwyllys switch (kmfext) { 191299ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 191399ebb4caSwyllys return (NID_key_usage); 191499ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 191599ebb4caSwyllys return (NID_private_key_usage_period); 191699ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 191799ebb4caSwyllys return (NID_certificate_policies); 191899ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 191999ebb4caSwyllys return (NID_subject_alt_name); 192099ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 192199ebb4caSwyllys return (NID_issuer_alt_name); 192299ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 192399ebb4caSwyllys return (NID_basic_constraints); 192499ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 192599ebb4caSwyllys return (NID_ext_key_usage); 192699ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 192799ebb4caSwyllys return (NID_authority_key_identifier); 192899ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 192999ebb4caSwyllys return (NID_crl_distribution_points); 193099ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 193199ebb4caSwyllys return (NID_subject_key_identifier); 193299ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 193399ebb4caSwyllys return (OBJ_sn2nid("policyMappings")); 193499ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 193599ebb4caSwyllys return (OBJ_sn2nid("nameConstraints")); 193699ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 193799ebb4caSwyllys return (OBJ_sn2nid("policyConstraints")); 193899ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 193999ebb4caSwyllys return (OBJ_sn2nid("inhibitAnyPolicy")); 194099ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 194199ebb4caSwyllys return (OBJ_sn2nid("freshestCRL")); 194299ebb4caSwyllys default: 194399ebb4caSwyllys return (NID_undef); 194499ebb4caSwyllys } 194599ebb4caSwyllys } 194699ebb4caSwyllys 194799ebb4caSwyllys KMF_RETURN 194899ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, 194999ebb4caSwyllys KMF_PRINTABLE_ITEM flag, char *resultStr) 195099ebb4caSwyllys { 195199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 195299ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 195399ebb4caSwyllys X509 *xcert = NULL; 195499ebb4caSwyllys unsigned char *outbuf = NULL; 195599ebb4caSwyllys unsigned char *outbuf_p; 195699ebb4caSwyllys char *tmpstr = NULL; 195799ebb4caSwyllys int j; 195899ebb4caSwyllys int ext_index, nid, len; 195999ebb4caSwyllys BIO *mem = NULL; 196099ebb4caSwyllys STACK *emlst = NULL; 196199ebb4caSwyllys X509_EXTENSION *ex; 196299ebb4caSwyllys X509_CINF *ci; 196399ebb4caSwyllys 196499ebb4caSwyllys if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) { 196599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 196699ebb4caSwyllys } 196799ebb4caSwyllys 196899ebb4caSwyllys /* copy cert data to outbuf */ 196999ebb4caSwyllys outbuf = malloc(pcert->Length); 197099ebb4caSwyllys if (outbuf == NULL) { 197199ebb4caSwyllys return (KMF_ERR_MEMORY); 197299ebb4caSwyllys } 197399ebb4caSwyllys (void) memcpy(outbuf, pcert->Data, pcert->Length); 197499ebb4caSwyllys 197599ebb4caSwyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 197699ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length); 197799ebb4caSwyllys if (xcert == NULL) { 197899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 197999ebb4caSwyllys ret = KMF_ERR_ENCODING; 198099ebb4caSwyllys goto out; 198199ebb4caSwyllys } 198299ebb4caSwyllys 198399ebb4caSwyllys mem = BIO_new(BIO_s_mem()); 198499ebb4caSwyllys if (mem == NULL) { 198599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 198699ebb4caSwyllys ret = KMF_ERR_MEMORY; 198799ebb4caSwyllys goto out; 198899ebb4caSwyllys } 198999ebb4caSwyllys 199099ebb4caSwyllys switch (flag) { 199199ebb4caSwyllys case KMF_CERT_ISSUER: 199299ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0, 199399ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 199499ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 199599ebb4caSwyllys break; 199699ebb4caSwyllys 199799ebb4caSwyllys case KMF_CERT_SUBJECT: 199899ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0, 199999ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 200099ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 200199ebb4caSwyllys break; 200299ebb4caSwyllys 200399ebb4caSwyllys case KMF_CERT_VERSION: 200499ebb4caSwyllys tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version); 200599ebb4caSwyllys (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN); 200699ebb4caSwyllys OPENSSL_free(tmpstr); 200799ebb4caSwyllys len = strlen(resultStr); 200899ebb4caSwyllys break; 200999ebb4caSwyllys 201099ebb4caSwyllys case KMF_CERT_SERIALNUM: 201199ebb4caSwyllys if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) { 201299ebb4caSwyllys (void) strcpy(resultStr, "0x"); 201399ebb4caSwyllys len = BIO_gets(mem, &resultStr[2], 201499ebb4caSwyllys KMF_CERT_PRINTABLE_LEN - 2); 201599ebb4caSwyllys } 201699ebb4caSwyllys break; 201799ebb4caSwyllys 201899ebb4caSwyllys case KMF_CERT_NOTBEFORE: 201999ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert)); 202099ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 202199ebb4caSwyllys break; 202299ebb4caSwyllys 202399ebb4caSwyllys case KMF_CERT_NOTAFTER: 202499ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert)); 202599ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 202699ebb4caSwyllys break; 202799ebb4caSwyllys 202899ebb4caSwyllys case KMF_CERT_PUBKEY_DATA: 202999ebb4caSwyllys { 203099ebb4caSwyllys EVP_PKEY *pkey = X509_get_pubkey(xcert); 203199ebb4caSwyllys if (pkey == NULL) { 203299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 203399ebb4caSwyllys ret = KMF_ERR_ENCODING; 203499ebb4caSwyllys goto out; 203599ebb4caSwyllys } 203699ebb4caSwyllys 203799ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 203899ebb4caSwyllys (void) BIO_printf(mem, 203999ebb4caSwyllys "RSA Public Key: (%d bit)\n", 204099ebb4caSwyllys BN_num_bits(pkey->pkey.rsa->n)); 204199ebb4caSwyllys (void) RSA_print(mem, pkey->pkey.rsa, 0); 204299ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 204399ebb4caSwyllys (void) BIO_printf(mem, 204499ebb4caSwyllys "%12sDSA Public Key:\n", ""); 204599ebb4caSwyllys (void) DSA_print(mem, pkey->pkey.dsa, 0); 204699ebb4caSwyllys } else { 204799ebb4caSwyllys (void) BIO_printf(mem, 204899ebb4caSwyllys "%12sUnknown Public Key:\n", ""); 204999ebb4caSwyllys } 205099ebb4caSwyllys (void) BIO_printf(mem, "\n"); 205199ebb4caSwyllys EVP_PKEY_free(pkey); 205299ebb4caSwyllys } 205399ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 205499ebb4caSwyllys break; 205599ebb4caSwyllys case KMF_CERT_SIGNATURE_ALG: 205699ebb4caSwyllys case KMF_CERT_PUBKEY_ALG: 205799ebb4caSwyllys if (flag == KMF_CERT_SIGNATURE_ALG) { 205899ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 205999ebb4caSwyllys xcert->sig_alg->algorithm); 206099ebb4caSwyllys } else { 206199ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 206299ebb4caSwyllys xcert->cert_info->key->algor->algorithm); 206399ebb4caSwyllys } 206499ebb4caSwyllys 206599ebb4caSwyllys if (len > 0) { 206699ebb4caSwyllys len = BIO_read(mem, resultStr, 206799ebb4caSwyllys KMF_CERT_PRINTABLE_LEN); 206899ebb4caSwyllys } 206999ebb4caSwyllys break; 207099ebb4caSwyllys 207199ebb4caSwyllys case KMF_CERT_EMAIL: 207299ebb4caSwyllys emlst = X509_get1_email(xcert); 207399ebb4caSwyllys for (j = 0; j < sk_num(emlst); j++) 207499ebb4caSwyllys (void) BIO_printf(mem, "%s\n", sk_value(emlst, j)); 207599ebb4caSwyllys 207699ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 207799ebb4caSwyllys X509_email_free(emlst); 207899ebb4caSwyllys break; 207999ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 208099ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 208199ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 208299ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 208399ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 208499ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 208599ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 208699ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 208799ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 208899ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 208999ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 209099ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 209199ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 209299ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 209399ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 209499ebb4caSwyllys nid = ext2NID(flag); 209599ebb4caSwyllys if (nid == NID_undef) { 209699ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 209799ebb4caSwyllys goto out; 209899ebb4caSwyllys } 209999ebb4caSwyllys ci = xcert->cert_info; 210099ebb4caSwyllys 210199ebb4caSwyllys ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1); 210299ebb4caSwyllys if (ext_index == -1) { 210399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 210499ebb4caSwyllys 210599ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 210699ebb4caSwyllys goto out; 210799ebb4caSwyllys } 210899ebb4caSwyllys ex = X509v3_get_ext(ci->extensions, ext_index); 210999ebb4caSwyllys 211099ebb4caSwyllys (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); 211199ebb4caSwyllys 211299ebb4caSwyllys if (BIO_printf(mem, ": %s\n", 2113*30a5e8faSwyllys X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) { 211499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 211599ebb4caSwyllys ret = KMF_ERR_ENCODING; 211699ebb4caSwyllys goto out; 211799ebb4caSwyllys } 211899ebb4caSwyllys if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) { 211999ebb4caSwyllys (void) BIO_printf(mem, "%*s", 4, ""); 212099ebb4caSwyllys (void) M_ASN1_OCTET_STRING_print(mem, ex->value); 212199ebb4caSwyllys } 212299ebb4caSwyllys if (BIO_write(mem, "\n", 1) <= 0) { 212399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 212499ebb4caSwyllys ret = KMF_ERR_ENCODING; 212599ebb4caSwyllys goto out; 212699ebb4caSwyllys } 212799ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 212899ebb4caSwyllys } 212999ebb4caSwyllys if (len <= 0) { 213099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 213199ebb4caSwyllys ret = KMF_ERR_ENCODING; 213299ebb4caSwyllys } 213399ebb4caSwyllys 213499ebb4caSwyllys out: 213599ebb4caSwyllys if (outbuf != NULL) { 213699ebb4caSwyllys free(outbuf); 213799ebb4caSwyllys } 213899ebb4caSwyllys 213999ebb4caSwyllys if (xcert != NULL) { 214099ebb4caSwyllys X509_free(xcert); 214199ebb4caSwyllys } 214299ebb4caSwyllys 214399ebb4caSwyllys if (mem != NULL) { 214499ebb4caSwyllys (void) BIO_free(mem); 214599ebb4caSwyllys } 214699ebb4caSwyllys 214799ebb4caSwyllys return (ret); 214899ebb4caSwyllys } 2149*30a5e8faSwyllys 215099ebb4caSwyllys KMF_RETURN 215199ebb4caSwyllys /*ARGSUSED*/ 2152*30a5e8faSwyllys OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, 2153*30a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 215499ebb4caSwyllys { 215599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 2156*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 2157*30a5e8faSwyllys KMF_KEY_CLASS keyclass = KMF_ASYM_PRI; 2158*30a5e8faSwyllys KMF_KEY_HANDLE *key = NULL; 2159*30a5e8faSwyllys uint32_t numkeys = 1; /* 1 key only */ 2160*30a5e8faSwyllys char *dirpath = NULL; 2161*30a5e8faSwyllys char *keyfile = NULL; 2162*30a5e8faSwyllys KMF_ATTRIBUTE new_attrlist[16]; 2163*30a5e8faSwyllys int i = 0; 216499ebb4caSwyllys 216599ebb4caSwyllys /* 216699ebb4caSwyllys * This is really just a FindKey operation, reuse the 216799ebb4caSwyllys * FindKey function. 216899ebb4caSwyllys */ 2169*30a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 2170*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 2171*30a5e8faSwyllys i++; 217299ebb4caSwyllys 2173*30a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 2174*30a5e8faSwyllys KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t)); 2175*30a5e8faSwyllys i++; 217699ebb4caSwyllys 2177*30a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 2178*30a5e8faSwyllys KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); 2179*30a5e8faSwyllys i++; 2180*30a5e8faSwyllys 2181*30a5e8faSwyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 2182*30a5e8faSwyllys if (key == NULL) { 2183*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2184*30a5e8faSwyllys } else { 2185*30a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 2186*30a5e8faSwyllys KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); 2187*30a5e8faSwyllys i++; 2188*30a5e8faSwyllys } 2189*30a5e8faSwyllys 2190*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 2191*30a5e8faSwyllys if (dirpath != NULL) { 2192*30a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 2193*30a5e8faSwyllys KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); 2194*30a5e8faSwyllys i++; 2195*30a5e8faSwyllys } 2196*30a5e8faSwyllys 2197*30a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 2198*30a5e8faSwyllys if (keyfile == NULL) 2199*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2200*30a5e8faSwyllys else { 2201*30a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 2202*30a5e8faSwyllys KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); 2203*30a5e8faSwyllys i++; 2204*30a5e8faSwyllys } 2205*30a5e8faSwyllys 2206*30a5e8faSwyllys rv = OpenSSL_FindKey(handle, i, new_attrlist); 220799ebb4caSwyllys return (rv); 220899ebb4caSwyllys } 220999ebb4caSwyllys 221099ebb4caSwyllys KMF_RETURN 221199ebb4caSwyllys /*ARGSUSED*/ 221299ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 221399ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *ciphertext, 221499ebb4caSwyllys KMF_DATA *output) 221599ebb4caSwyllys { 221699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 221799ebb4caSwyllys RSA *rsa = NULL; 221899ebb4caSwyllys unsigned int in_len = 0, out_len = 0; 221999ebb4caSwyllys unsigned int total_decrypted = 0, modulus_len = 0; 222099ebb4caSwyllys uint8_t *in_data, *out_data; 222199ebb4caSwyllys int i, blocks; 222299ebb4caSwyllys 222399ebb4caSwyllys if (key == NULL || AlgOID == NULL || 222499ebb4caSwyllys ciphertext == NULL || output == NULL || 222599ebb4caSwyllys ciphertext->Data == NULL || 222699ebb4caSwyllys output->Data == NULL) 222799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 222899ebb4caSwyllys 222999ebb4caSwyllys if (key->keyalg == KMF_RSA) { 223099ebb4caSwyllys rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp); 223199ebb4caSwyllys modulus_len = RSA_size(rsa); 223299ebb4caSwyllys } else { 223399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 223499ebb4caSwyllys } 223599ebb4caSwyllys 223699ebb4caSwyllys blocks = ciphertext->Length/modulus_len; 223799ebb4caSwyllys out_data = output->Data; 223899ebb4caSwyllys in_data = ciphertext->Data; 223999ebb4caSwyllys out_len = modulus_len - 11; 224099ebb4caSwyllys in_len = modulus_len; 224199ebb4caSwyllys 224299ebb4caSwyllys for (i = 0; i < blocks; i++) { 224399ebb4caSwyllys out_len = RSA_private_decrypt(in_len, 224499ebb4caSwyllys in_data, out_data, rsa, RSA_PKCS1_PADDING); 224599ebb4caSwyllys 224699ebb4caSwyllys if (out_len == 0) { 224799ebb4caSwyllys ret = KMF_ERR_INTERNAL; 224899ebb4caSwyllys goto cleanup; 224999ebb4caSwyllys } 225099ebb4caSwyllys 225199ebb4caSwyllys out_data += out_len; 225299ebb4caSwyllys total_decrypted += out_len; 225399ebb4caSwyllys in_data += in_len; 225499ebb4caSwyllys } 225599ebb4caSwyllys 225699ebb4caSwyllys output->Length = total_decrypted; 225799ebb4caSwyllys 225899ebb4caSwyllys cleanup: 225999ebb4caSwyllys RSA_free(rsa); 226099ebb4caSwyllys if (ret != KMF_OK) 226199ebb4caSwyllys output->Length = 0; 226299ebb4caSwyllys 226399ebb4caSwyllys return (ret); 226499ebb4caSwyllys 226599ebb4caSwyllys } 226699ebb4caSwyllys 226799ebb4caSwyllys /* 226899ebb4caSwyllys * This function will create a certid from issuer_cert and user_cert. 226999ebb4caSwyllys * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate 227099ebb4caSwyllys * certid memory after use. 227199ebb4caSwyllys */ 227299ebb4caSwyllys static KMF_RETURN 227399ebb4caSwyllys create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert, 227499ebb4caSwyllys const KMF_DATA *user_cert, OCSP_CERTID **certid) 227599ebb4caSwyllys { 227699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 227799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 227899ebb4caSwyllys X509 *issuer = NULL; 227999ebb4caSwyllys X509 *cert = NULL; 228099ebb4caSwyllys unsigned char *ptmp; 228199ebb4caSwyllys 228299ebb4caSwyllys if (issuer_cert == NULL || user_cert == NULL) { 228399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 228499ebb4caSwyllys } 228599ebb4caSwyllys 228699ebb4caSwyllys /* convert the DER-encoded issuer cert to an internal X509 */ 228799ebb4caSwyllys ptmp = issuer_cert->Data; 228899ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 228999ebb4caSwyllys issuer_cert->Length); 229099ebb4caSwyllys if (issuer == NULL) { 229199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 229299ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 229399ebb4caSwyllys goto end; 229499ebb4caSwyllys } 229599ebb4caSwyllys 229699ebb4caSwyllys /* convert the DER-encoded user cert to an internal X509 */ 229799ebb4caSwyllys ptmp = user_cert->Data; 229899ebb4caSwyllys cert = d2i_X509(NULL, (const uchar_t **)&ptmp, 229999ebb4caSwyllys user_cert->Length); 230099ebb4caSwyllys if (cert == NULL) { 230199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 230299ebb4caSwyllys 230399ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_CERT; 230499ebb4caSwyllys goto end; 230599ebb4caSwyllys } 230699ebb4caSwyllys 230799ebb4caSwyllys /* create a CERTID */ 230899ebb4caSwyllys *certid = OCSP_cert_to_id(NULL, cert, issuer); 230999ebb4caSwyllys if (*certid == NULL) { 231099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 231199ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 231299ebb4caSwyllys goto end; 231399ebb4caSwyllys } 231499ebb4caSwyllys 231599ebb4caSwyllys end: 231699ebb4caSwyllys if (issuer != NULL) { 231799ebb4caSwyllys X509_free(issuer); 231899ebb4caSwyllys } 231999ebb4caSwyllys 232099ebb4caSwyllys if (cert != NULL) { 232199ebb4caSwyllys X509_free(cert); 232299ebb4caSwyllys } 232399ebb4caSwyllys 232499ebb4caSwyllys return (ret); 232599ebb4caSwyllys } 232699ebb4caSwyllys 232799ebb4caSwyllys KMF_RETURN 2328*30a5e8faSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, 2329*30a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 233099ebb4caSwyllys { 233199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 233299ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 233399ebb4caSwyllys OCSP_CERTID *id = NULL; 233499ebb4caSwyllys OCSP_REQUEST *req = NULL; 233599ebb4caSwyllys BIO *derbio = NULL; 2336*30a5e8faSwyllys char *reqfile; 2337*30a5e8faSwyllys KMF_DATA *issuer_cert; 2338*30a5e8faSwyllys KMF_DATA *user_cert; 233999ebb4caSwyllys 2340*30a5e8faSwyllys user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, 2341*30a5e8faSwyllys attrlist, numattr); 2342*30a5e8faSwyllys if (user_cert == NULL) 234399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 234499ebb4caSwyllys 2345*30a5e8faSwyllys issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, 2346*30a5e8faSwyllys attrlist, numattr); 2347*30a5e8faSwyllys if (issuer_cert == NULL) 2348*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2349*30a5e8faSwyllys 2350*30a5e8faSwyllys reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR, 2351*30a5e8faSwyllys attrlist, numattr); 2352*30a5e8faSwyllys if (reqfile == NULL) 2353*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2354*30a5e8faSwyllys 2355*30a5e8faSwyllys ret = create_certid(handle, issuer_cert, user_cert, &id); 235699ebb4caSwyllys if (ret != KMF_OK) { 235799ebb4caSwyllys return (ret); 235899ebb4caSwyllys } 235999ebb4caSwyllys 236099ebb4caSwyllys /* Create an OCSP request */ 236199ebb4caSwyllys req = OCSP_REQUEST_new(); 236299ebb4caSwyllys if (req == NULL) { 236399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 236499ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 236599ebb4caSwyllys goto end; 236699ebb4caSwyllys } 236799ebb4caSwyllys 236899ebb4caSwyllys if (!OCSP_request_add0_id(req, id)) { 236999ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 237099ebb4caSwyllys goto end; 237199ebb4caSwyllys } 237299ebb4caSwyllys 237399ebb4caSwyllys /* Write the request to the output file with DER encoding */ 237499ebb4caSwyllys derbio = BIO_new_file(reqfile, "wb"); 237599ebb4caSwyllys if (!derbio) { 237699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 237799ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 237899ebb4caSwyllys goto end; 237999ebb4caSwyllys } 238099ebb4caSwyllys if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) { 238199ebb4caSwyllys ret = KMF_ERR_ENCODING; 238299ebb4caSwyllys } 238399ebb4caSwyllys 238499ebb4caSwyllys end: 238599ebb4caSwyllys /* 238699ebb4caSwyllys * We don't need to free "id" explicitely, because OCSP_REQUEST_free() 238799ebb4caSwyllys * will deallocate certid's space also. 238899ebb4caSwyllys */ 238999ebb4caSwyllys if (req != NULL) { 239099ebb4caSwyllys OCSP_REQUEST_free(req); 239199ebb4caSwyllys } 239299ebb4caSwyllys 239399ebb4caSwyllys if (derbio != NULL) { 239499ebb4caSwyllys (void) BIO_free(derbio); 239599ebb4caSwyllys } 239699ebb4caSwyllys 239799ebb4caSwyllys return (ret); 239899ebb4caSwyllys } 239999ebb4caSwyllys 240099ebb4caSwyllys /* ocsp_find_signer_sk() is copied from openssl source */ 240199ebb4caSwyllys static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 240299ebb4caSwyllys { 240399ebb4caSwyllys int i; 240499ebb4caSwyllys unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 240599ebb4caSwyllys 240699ebb4caSwyllys /* Easy if lookup by name */ 240799ebb4caSwyllys if (id->type == V_OCSP_RESPID_NAME) 240899ebb4caSwyllys return (X509_find_by_subject(certs, id->value.byName)); 240999ebb4caSwyllys 241099ebb4caSwyllys /* Lookup by key hash */ 241199ebb4caSwyllys 241299ebb4caSwyllys /* If key hash isn't SHA1 length then forget it */ 241399ebb4caSwyllys if (id->value.byKey->length != SHA_DIGEST_LENGTH) 241499ebb4caSwyllys return (NULL); 241599ebb4caSwyllys 241699ebb4caSwyllys keyhash = id->value.byKey->data; 241799ebb4caSwyllys /* Calculate hash of each key and compare */ 241899ebb4caSwyllys for (i = 0; i < sk_X509_num(certs); i++) { 241999ebb4caSwyllys /*LINTED*/ 242099ebb4caSwyllys X509 *x = sk_X509_value(certs, i); 242199ebb4caSwyllys (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 242299ebb4caSwyllys if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 242399ebb4caSwyllys return (x); 242499ebb4caSwyllys } 242599ebb4caSwyllys return (NULL); 242699ebb4caSwyllys } 242799ebb4caSwyllys 242899ebb4caSwyllys /* ocsp_find_signer() is copied from openssl source */ 242999ebb4caSwyllys /*ARGSUSED*/ 243099ebb4caSwyllys static int 243199ebb4caSwyllys ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, 243299ebb4caSwyllys X509_STORE *st, unsigned long flags) 243399ebb4caSwyllys { 243499ebb4caSwyllys X509 *signer; 243599ebb4caSwyllys OCSP_RESPID *rid = bs->tbsResponseData->responderId; 243699ebb4caSwyllys if ((signer = ocsp_find_signer_sk(certs, rid))) { 243799ebb4caSwyllys *psigner = signer; 243899ebb4caSwyllys return (2); 243999ebb4caSwyllys } 244099ebb4caSwyllys if (!(flags & OCSP_NOINTERN) && 244199ebb4caSwyllys (signer = ocsp_find_signer_sk(bs->certs, rid))) { 244299ebb4caSwyllys *psigner = signer; 244399ebb4caSwyllys return (1); 244499ebb4caSwyllys } 244599ebb4caSwyllys /* Maybe lookup from store if by subject name */ 244699ebb4caSwyllys 244799ebb4caSwyllys *psigner = NULL; 244899ebb4caSwyllys return (0); 244999ebb4caSwyllys } 245099ebb4caSwyllys 245199ebb4caSwyllys /* 245299ebb4caSwyllys * This function will verify the signature of a basic response, using 245399ebb4caSwyllys * the public key from the OCSP responder certificate. 245499ebb4caSwyllys */ 245599ebb4caSwyllys static KMF_RETURN 245699ebb4caSwyllys check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, 245799ebb4caSwyllys KMF_DATA *signer_cert, KMF_DATA *issuer_cert) 245899ebb4caSwyllys { 245999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 246099ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 246199ebb4caSwyllys STACK_OF(X509) *cert_stack = NULL; 246299ebb4caSwyllys X509 *signer = NULL; 246399ebb4caSwyllys X509 *issuer = NULL; 246499ebb4caSwyllys EVP_PKEY *skey = NULL; 246599ebb4caSwyllys unsigned char *ptmp; 246699ebb4caSwyllys 246799ebb4caSwyllys 246899ebb4caSwyllys if (bs == NULL || issuer_cert == NULL) 246999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 247099ebb4caSwyllys 247199ebb4caSwyllys /* 247299ebb4caSwyllys * Find the certificate that signed the basic response. 247399ebb4caSwyllys * 247499ebb4caSwyllys * If signer_cert is not NULL, we will use that as the signer cert. 247599ebb4caSwyllys * Otherwise, we will check if the issuer cert is actually the signer. 247699ebb4caSwyllys * If we still do not find a signer, we will look for it from the 247799ebb4caSwyllys * certificate list came with the response file. 247899ebb4caSwyllys */ 247999ebb4caSwyllys if (signer_cert != NULL) { 248099ebb4caSwyllys ptmp = signer_cert->Data; 248199ebb4caSwyllys signer = d2i_X509(NULL, (const uchar_t **)&ptmp, 248299ebb4caSwyllys signer_cert->Length); 248399ebb4caSwyllys if (signer == NULL) { 248499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 248599ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 248699ebb4caSwyllys goto end; 248799ebb4caSwyllys } 248899ebb4caSwyllys } else { 248999ebb4caSwyllys /* 249099ebb4caSwyllys * Convert the issuer cert into X509 and push it into a 249199ebb4caSwyllys * stack to be used by ocsp_find_signer(). 249299ebb4caSwyllys */ 249399ebb4caSwyllys ptmp = issuer_cert->Data; 249499ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 249599ebb4caSwyllys issuer_cert->Length); 249699ebb4caSwyllys if (issuer == NULL) { 249799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 249899ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 249999ebb4caSwyllys goto end; 250099ebb4caSwyllys } 250199ebb4caSwyllys 250299ebb4caSwyllys if ((cert_stack = sk_X509_new_null()) == NULL) { 250399ebb4caSwyllys ret = KMF_ERR_INTERNAL; 250499ebb4caSwyllys goto end; 250599ebb4caSwyllys } 250699ebb4caSwyllys 250799ebb4caSwyllys if (sk_X509_push(cert_stack, issuer) == NULL) { 250899ebb4caSwyllys ret = KMF_ERR_INTERNAL; 250999ebb4caSwyllys goto end; 251099ebb4caSwyllys } 251199ebb4caSwyllys 251299ebb4caSwyllys ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0); 251399ebb4caSwyllys if (!ret) { 251499ebb4caSwyllys /* can not find the signer */ 251599ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 251699ebb4caSwyllys goto end; 251799ebb4caSwyllys } 251899ebb4caSwyllys } 251999ebb4caSwyllys 252099ebb4caSwyllys /* Verify the signature of the response */ 252199ebb4caSwyllys skey = X509_get_pubkey(signer); 252299ebb4caSwyllys if (skey == NULL) { 252399ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 252499ebb4caSwyllys goto end; 252599ebb4caSwyllys } 252699ebb4caSwyllys 252799ebb4caSwyllys ret = OCSP_BASICRESP_verify(bs, skey, 0); 252899ebb4caSwyllys if (ret == 0) { 252999ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE; 253099ebb4caSwyllys goto end; 253199ebb4caSwyllys } 253299ebb4caSwyllys 253399ebb4caSwyllys end: 253499ebb4caSwyllys if (issuer != NULL) { 253599ebb4caSwyllys X509_free(issuer); 253699ebb4caSwyllys } 253799ebb4caSwyllys 253899ebb4caSwyllys if (signer != NULL) { 253999ebb4caSwyllys X509_free(signer); 254099ebb4caSwyllys } 254199ebb4caSwyllys 254299ebb4caSwyllys if (skey != NULL) { 254399ebb4caSwyllys EVP_PKEY_free(skey); 254499ebb4caSwyllys } 254599ebb4caSwyllys 254699ebb4caSwyllys if (cert_stack != NULL) { 254799ebb4caSwyllys sk_X509_free(cert_stack); 254899ebb4caSwyllys } 254999ebb4caSwyllys 255099ebb4caSwyllys return (ret); 255199ebb4caSwyllys } 255299ebb4caSwyllys 255399ebb4caSwyllys 255499ebb4caSwyllys 255599ebb4caSwyllys KMF_RETURN 255699ebb4caSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, 2557*30a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 255899ebb4caSwyllys { 255999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 256099ebb4caSwyllys BIO *derbio = NULL; 256199ebb4caSwyllys OCSP_RESPONSE *resp = NULL; 256299ebb4caSwyllys OCSP_BASICRESP *bs = NULL; 256399ebb4caSwyllys OCSP_CERTID *id = NULL; 256499ebb4caSwyllys OCSP_SINGLERESP *single = NULL; 256599ebb4caSwyllys ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 256699ebb4caSwyllys int index, status, reason; 2567*30a5e8faSwyllys KMF_DATA *issuer_cert; 2568*30a5e8faSwyllys KMF_DATA *user_cert; 2569*30a5e8faSwyllys KMF_DATA *signer_cert; 2570*30a5e8faSwyllys KMF_DATA *response; 2571*30a5e8faSwyllys int *response_reason, *response_status, *cert_status; 2572*30a5e8faSwyllys boolean_t ignore_response_sign = B_FALSE; /* default is FALSE */ 2573*30a5e8faSwyllys uint32_t response_lifetime; 257499ebb4caSwyllys 2575*30a5e8faSwyllys issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, 2576*30a5e8faSwyllys attrlist, numattr); 2577*30a5e8faSwyllys if (issuer_cert == NULL) 257899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 257999ebb4caSwyllys 2580*30a5e8faSwyllys user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, 2581*30a5e8faSwyllys attrlist, numattr); 2582*30a5e8faSwyllys if (user_cert == NULL) 258399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2584*30a5e8faSwyllys 2585*30a5e8faSwyllys response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, 2586*30a5e8faSwyllys attrlist, numattr); 2587*30a5e8faSwyllys if (response == NULL) 2588*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2589*30a5e8faSwyllys 2590*30a5e8faSwyllys response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR, 2591*30a5e8faSwyllys attrlist, numattr); 2592*30a5e8faSwyllys if (response_status == NULL) 2593*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2594*30a5e8faSwyllys 2595*30a5e8faSwyllys response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR, 2596*30a5e8faSwyllys attrlist, numattr); 2597*30a5e8faSwyllys if (response_reason == NULL) 2598*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2599*30a5e8faSwyllys 2600*30a5e8faSwyllys cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, 2601*30a5e8faSwyllys attrlist, numattr); 2602*30a5e8faSwyllys if (cert_status == NULL) 2603*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 260499ebb4caSwyllys 260599ebb4caSwyllys /* Read in the response */ 2606*30a5e8faSwyllys derbio = BIO_new_mem_buf(response->Data, response->Length); 260799ebb4caSwyllys if (!derbio) { 260899ebb4caSwyllys ret = KMF_ERR_MEMORY; 260999ebb4caSwyllys return (ret); 261099ebb4caSwyllys } 261199ebb4caSwyllys 261299ebb4caSwyllys resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 261399ebb4caSwyllys if (resp == NULL) { 261499ebb4caSwyllys ret = KMF_ERR_OCSP_MALFORMED_RESPONSE; 261599ebb4caSwyllys goto end; 261699ebb4caSwyllys } 261799ebb4caSwyllys 261899ebb4caSwyllys /* Check the response status */ 261999ebb4caSwyllys status = OCSP_response_status(resp); 2620*30a5e8faSwyllys *response_status = status; 262199ebb4caSwyllys if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 262299ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_STATUS; 262399ebb4caSwyllys goto end; 262499ebb4caSwyllys } 262599ebb4caSwyllys 262699ebb4caSwyllys #ifdef DEBUG 262799ebb4caSwyllys printf("Successfully checked the response file status.\n"); 262899ebb4caSwyllys #endif /* DEBUG */ 262999ebb4caSwyllys 263099ebb4caSwyllys /* Extract basic response */ 263199ebb4caSwyllys bs = OCSP_response_get1_basic(resp); 263299ebb4caSwyllys if (bs == NULL) { 263399ebb4caSwyllys ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE; 263499ebb4caSwyllys goto end; 263599ebb4caSwyllys } 263699ebb4caSwyllys 263799ebb4caSwyllys #ifdef DEBUG 263899ebb4caSwyllys printf("Successfully retrieved the basic response.\n"); 263999ebb4caSwyllys #endif /* DEBUG */ 264099ebb4caSwyllys 264199ebb4caSwyllys /* Check the basic response signature if required */ 2642*30a5e8faSwyllys ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr, 2643*30a5e8faSwyllys (void *)&ignore_response_sign, NULL); 2644*30a5e8faSwyllys if (ret != KMF_OK) 2645*30a5e8faSwyllys ret = KMF_OK; 2646*30a5e8faSwyllys 2647*30a5e8faSwyllys signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, 2648*30a5e8faSwyllys attrlist, numattr); 2649*30a5e8faSwyllys 2650*30a5e8faSwyllys if (ignore_response_sign == B_FALSE) { 265199ebb4caSwyllys ret = check_response_signature(handle, bs, 2652*30a5e8faSwyllys signer_cert, issuer_cert); 265399ebb4caSwyllys if (ret != KMF_OK) 265499ebb4caSwyllys goto end; 265599ebb4caSwyllys } 265699ebb4caSwyllys 265799ebb4caSwyllys #ifdef DEBUG 265899ebb4caSwyllys printf("Successfully verified the response signature.\n"); 265999ebb4caSwyllys #endif /* DEBUG */ 266099ebb4caSwyllys 266199ebb4caSwyllys /* Create a certid for the certificate in question */ 2662*30a5e8faSwyllys ret = create_certid(handle, issuer_cert, user_cert, &id); 266399ebb4caSwyllys if (ret != KMF_OK) { 266499ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 266599ebb4caSwyllys goto end; 266699ebb4caSwyllys } 266799ebb4caSwyllys 266899ebb4caSwyllys #ifdef DEBUG 266999ebb4caSwyllys printf("successfully created a certid for the cert.\n"); 267099ebb4caSwyllys #endif /* DEBUG */ 267199ebb4caSwyllys 267299ebb4caSwyllys /* Find the index of the single response for the certid */ 267399ebb4caSwyllys index = OCSP_resp_find(bs, id, -1); 267499ebb4caSwyllys if (index < 0) { 267599ebb4caSwyllys /* cound not find this certificate in the response */ 267699ebb4caSwyllys ret = KMF_ERR_OCSP_UNKNOWN_CERT; 267799ebb4caSwyllys goto end; 267899ebb4caSwyllys } 267999ebb4caSwyllys 268099ebb4caSwyllys #ifdef DEBUG 268199ebb4caSwyllys printf("Successfully found the single response index for the cert.\n"); 268299ebb4caSwyllys #endif /* DEBUG */ 268399ebb4caSwyllys 268499ebb4caSwyllys /* Retrieve the single response and get the cert status */ 268599ebb4caSwyllys single = OCSP_resp_get0(bs, index); 268699ebb4caSwyllys status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, 268799ebb4caSwyllys &nextupd); 268899ebb4caSwyllys if (status == V_OCSP_CERTSTATUS_GOOD) { 2689*30a5e8faSwyllys *cert_status = OCSP_GOOD; 269099ebb4caSwyllys } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { 2691*30a5e8faSwyllys *cert_status = OCSP_UNKNOWN; 269299ebb4caSwyllys } else { /* revoked */ 2693*30a5e8faSwyllys *cert_status = OCSP_REVOKED; 2694*30a5e8faSwyllys *response_reason = reason; 269599ebb4caSwyllys } 269699ebb4caSwyllys ret = KMF_OK; 269799ebb4caSwyllys 2698*30a5e8faSwyllys /* resp. time is optional, so we don't care about the return code. */ 2699*30a5e8faSwyllys (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr, 2700*30a5e8faSwyllys (void *)&response_lifetime, NULL); 2701*30a5e8faSwyllys 270299ebb4caSwyllys if (!OCSP_check_validity(thisupd, nextupd, 300, 2703*30a5e8faSwyllys response_lifetime)) { 270499ebb4caSwyllys ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; 270599ebb4caSwyllys goto end; 270699ebb4caSwyllys } 270799ebb4caSwyllys 270899ebb4caSwyllys #ifdef DEBUG 270999ebb4caSwyllys printf("Successfully verify the time.\n"); 271099ebb4caSwyllys #endif /* DEBUG */ 271199ebb4caSwyllys 271299ebb4caSwyllys end: 271399ebb4caSwyllys if (derbio != NULL) 271499ebb4caSwyllys (void) BIO_free(derbio); 271599ebb4caSwyllys 271699ebb4caSwyllys if (resp != NULL) 271799ebb4caSwyllys OCSP_RESPONSE_free(resp); 271899ebb4caSwyllys 271999ebb4caSwyllys if (bs != NULL) 272099ebb4caSwyllys OCSP_BASICRESP_free(bs); 272199ebb4caSwyllys 272299ebb4caSwyllys if (id != NULL) 272399ebb4caSwyllys OCSP_CERTID_free(id); 272499ebb4caSwyllys 272599ebb4caSwyllys return (ret); 272699ebb4caSwyllys } 272799ebb4caSwyllys 272899ebb4caSwyllys static KMF_RETURN 272999ebb4caSwyllys fetch_key(KMF_HANDLE_T handle, char *path, 273099ebb4caSwyllys KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) 273199ebb4caSwyllys { 273299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 2733*30a5e8faSwyllys EVP_PKEY *pkey = NULL; 273499ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 273599ebb4caSwyllys 273699ebb4caSwyllys if (keyclass == KMF_ASYM_PRI || 273799ebb4caSwyllys keyclass == KMF_ASYM_PUB) { 273899ebb4caSwyllys pkey = openssl_load_key(handle, path); 273999ebb4caSwyllys if (pkey == NULL) { 274099ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 274199ebb4caSwyllys } 274299ebb4caSwyllys if (key != NULL) { 274399ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) 274499ebb4caSwyllys key->keyalg = KMF_RSA; 274599ebb4caSwyllys else if (pkey->type == EVP_PKEY_DSA) 274699ebb4caSwyllys key->keyalg = KMF_DSA; 274799ebb4caSwyllys 274899ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 274999ebb4caSwyllys key->keyclass = keyclass; 275099ebb4caSwyllys key->keyp = (void *)pkey; 275199ebb4caSwyllys key->israw = FALSE; 275299ebb4caSwyllys key->keylabel = path; 275399ebb4caSwyllys } else { 275499ebb4caSwyllys EVP_PKEY_free(pkey); 275599ebb4caSwyllys pkey = NULL; 275699ebb4caSwyllys } 275799ebb4caSwyllys } else if (keyclass == KMF_SYMMETRIC) { 275899ebb4caSwyllys KMF_ENCODE_FORMAT fmt; 275999ebb4caSwyllys /* 276099ebb4caSwyllys * If the file is a recognized format, 276199ebb4caSwyllys * then it is NOT a symmetric key. 276299ebb4caSwyllys */ 2763*30a5e8faSwyllys rv = kmf_get_file_format(path, &fmt); 276499ebb4caSwyllys if (rv == KMF_OK || fmt != 0) { 276599ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 276699ebb4caSwyllys } else if (rv == KMF_ERR_ENCODING) { 276799ebb4caSwyllys /* 276899ebb4caSwyllys * If we don't know the encoding, 276999ebb4caSwyllys * it is probably a symmetric key. 277099ebb4caSwyllys */ 277199ebb4caSwyllys rv = KMF_OK; 2772*30a5e8faSwyllys } else if (rv == KMF_ERR_OPEN_FILE) { 2773*30a5e8faSwyllys return (KMF_ERR_KEY_NOT_FOUND); 277499ebb4caSwyllys } 277599ebb4caSwyllys 277699ebb4caSwyllys if (key != NULL) { 277799ebb4caSwyllys KMF_DATA keyvalue; 277899ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 277999ebb4caSwyllys if (rkey == NULL) { 278099ebb4caSwyllys rv = KMF_ERR_MEMORY; 278199ebb4caSwyllys goto out; 278299ebb4caSwyllys } 278399ebb4caSwyllys 278499ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 2785*30a5e8faSwyllys rv = kmf_read_input_file(handle, path, &keyvalue); 278699ebb4caSwyllys if (rv != KMF_OK) 278799ebb4caSwyllys goto out; 278899ebb4caSwyllys 278999ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 279099ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 279199ebb4caSwyllys 279299ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 279399ebb4caSwyllys key->keyclass = keyclass; 279499ebb4caSwyllys key->israw = TRUE; 279599ebb4caSwyllys key->keylabel = path; 279699ebb4caSwyllys key->keyp = (void *)rkey; 279799ebb4caSwyllys } 279899ebb4caSwyllys } 279999ebb4caSwyllys out: 280099ebb4caSwyllys if (rv != KMF_OK) { 280199ebb4caSwyllys if (rkey != NULL) { 2802*30a5e8faSwyllys kmf_free_raw_sym_key(rkey); 280399ebb4caSwyllys } 280499ebb4caSwyllys if (pkey != NULL) 280599ebb4caSwyllys EVP_PKEY_free(pkey); 280699ebb4caSwyllys 280799ebb4caSwyllys if (key != NULL) { 280899ebb4caSwyllys key->keyalg = KMF_KEYALG_NONE; 280999ebb4caSwyllys key->keyclass = KMF_KEYCLASS_NONE; 281099ebb4caSwyllys key->keyp = NULL; 281199ebb4caSwyllys } 281299ebb4caSwyllys } 281399ebb4caSwyllys 281499ebb4caSwyllys return (rv); 281599ebb4caSwyllys } 281699ebb4caSwyllys 281799ebb4caSwyllys KMF_RETURN 2818*30a5e8faSwyllys OpenSSL_FindKey(KMF_HANDLE_T handle, 2819*30a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 282099ebb4caSwyllys { 282199ebb4caSwyllys KMF_RETURN rv = KMF_OK; 282299ebb4caSwyllys char *fullpath = NULL; 2823f482c776Swyllys uint32_t maxkeys; 2824*30a5e8faSwyllys KMF_KEY_HANDLE *key; 2825*30a5e8faSwyllys uint32_t *numkeys; 2826*30a5e8faSwyllys KMF_KEY_CLASS keyclass; 2827*30a5e8faSwyllys KMF_RAW_KEY_DATA *rawkey; 2828*30a5e8faSwyllys char *dirpath; 2829*30a5e8faSwyllys char *keyfile; 283099ebb4caSwyllys 2831*30a5e8faSwyllys if (handle == NULL) 283299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 283399ebb4caSwyllys 2834*30a5e8faSwyllys numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 2835*30a5e8faSwyllys if (numkeys == NULL) 2836*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2837*30a5e8faSwyllys 2838*30a5e8faSwyllys rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, 2839*30a5e8faSwyllys (void *)&keyclass, NULL); 2840*30a5e8faSwyllys if (rv != KMF_OK) 2841*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2842*30a5e8faSwyllys 2843*30a5e8faSwyllys if (keyclass != KMF_ASYM_PUB && 2844*30a5e8faSwyllys keyclass != KMF_ASYM_PRI && 2845*30a5e8faSwyllys keyclass != KMF_SYMMETRIC) 284699ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 284799ebb4caSwyllys 2848*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 2849*30a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 2850*30a5e8faSwyllys 2851*30a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 285299ebb4caSwyllys 285399ebb4caSwyllys if (fullpath == NULL) 285499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 285599ebb4caSwyllys 2856f482c776Swyllys maxkeys = *numkeys; 2857f482c776Swyllys if (maxkeys == 0) 2858f482c776Swyllys maxkeys = 0xFFFFFFFF; 285999ebb4caSwyllys *numkeys = 0; 286099ebb4caSwyllys 2861*30a5e8faSwyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 2862*30a5e8faSwyllys /* it is okay to have "keys" contains NULL */ 2863*30a5e8faSwyllys 2864*30a5e8faSwyllys /* 2865*30a5e8faSwyllys * The caller may want a list of the raw key data as well. 2866*30a5e8faSwyllys * Useful for importing keys from a file into other keystores. 2867*30a5e8faSwyllys */ 2868*30a5e8faSwyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); 2869*30a5e8faSwyllys 287099ebb4caSwyllys if (isdir(fullpath)) { 287199ebb4caSwyllys DIR *dirp; 287299ebb4caSwyllys struct dirent *dp; 287399ebb4caSwyllys int n = 0; 287499ebb4caSwyllys 287599ebb4caSwyllys /* open all files in the directory and attempt to read them */ 287699ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 287799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 287899ebb4caSwyllys } 287999ebb4caSwyllys rewinddir(dirp); 2880f482c776Swyllys while ((dp = readdir(dirp)) != NULL && n < maxkeys) { 288199ebb4caSwyllys if (strcmp(dp->d_name, ".") && 288299ebb4caSwyllys strcmp(dp->d_name, "..")) { 288399ebb4caSwyllys char *fname; 288499ebb4caSwyllys 288599ebb4caSwyllys fname = get_fullpath(fullpath, 288699ebb4caSwyllys (char *)&dp->d_name); 288799ebb4caSwyllys 288899ebb4caSwyllys rv = fetch_key(handle, fname, 2889*30a5e8faSwyllys keyclass, key ? &key[n] : NULL); 289099ebb4caSwyllys 2891*30a5e8faSwyllys if (rv == KMF_OK) { 2892*30a5e8faSwyllys if (key != NULL && rawkey != NULL) 2893*30a5e8faSwyllys rv = convertToRawKey( 2894*30a5e8faSwyllys key[n].keyp, &rawkey[n]); 289599ebb4caSwyllys n++; 2896*30a5e8faSwyllys } 289799ebb4caSwyllys 289899ebb4caSwyllys if (rv != KMF_OK || key == NULL) 289999ebb4caSwyllys free(fname); 290099ebb4caSwyllys } 290199ebb4caSwyllys } 290299ebb4caSwyllys (void) closedir(dirp); 290399ebb4caSwyllys free(fullpath); 290499ebb4caSwyllys (*numkeys) = n; 290599ebb4caSwyllys } else { 2906*30a5e8faSwyllys rv = fetch_key(handle, fullpath, keyclass, key); 290799ebb4caSwyllys if (rv == KMF_OK) 290899ebb4caSwyllys (*numkeys) = 1; 290999ebb4caSwyllys 291099ebb4caSwyllys if (rv != KMF_OK || key == NULL) 291199ebb4caSwyllys free(fullpath); 2912*30a5e8faSwyllys 2913*30a5e8faSwyllys if (rv == KMF_OK && key != NULL && rawkey != NULL) { 2914*30a5e8faSwyllys rv = convertToRawKey(key->keyp, rawkey); 2915*30a5e8faSwyllys } 291699ebb4caSwyllys } 291799ebb4caSwyllys 2918f482c776Swyllys if (rv == KMF_OK && (*numkeys) == 0) 291999ebb4caSwyllys rv = KMF_ERR_KEY_NOT_FOUND; 292099ebb4caSwyllys 292199ebb4caSwyllys return (rv); 292299ebb4caSwyllys } 292399ebb4caSwyllys 292499ebb4caSwyllys #define HANDLE_PK12_ERROR { \ 292599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); \ 292699ebb4caSwyllys rv = KMF_ERR_ENCODING; \ 292799ebb4caSwyllys goto out; \ 292899ebb4caSwyllys } 292999ebb4caSwyllys 293099ebb4caSwyllys static KMF_RETURN 293199ebb4caSwyllys write_pkcs12(KMF_HANDLE *kmfh, 293299ebb4caSwyllys BIO *bio, 293399ebb4caSwyllys KMF_CREDENTIAL *cred, 293499ebb4caSwyllys EVP_PKEY *pkey, 293599ebb4caSwyllys X509 *sslcert) 293699ebb4caSwyllys { 293799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 293899ebb4caSwyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 293999ebb4caSwyllys PKCS12_SAFEBAG *bag = NULL; 294099ebb4caSwyllys PKCS7 *cert_authsafe = NULL; 294199ebb4caSwyllys PKCS8_PRIV_KEY_INFO *p8 = NULL; 294299ebb4caSwyllys PKCS7 *key_authsafe = NULL; 294399ebb4caSwyllys STACK_OF(PKCS7) *authsafe_stack = NULL; 294499ebb4caSwyllys PKCS12 *p12_elem = NULL; 294599ebb4caSwyllys char *lab = NULL; 294699ebb4caSwyllys int lab_len = 0; 294799ebb4caSwyllys unsigned char keyid[EVP_MAX_MD_SIZE]; 294899ebb4caSwyllys unsigned int keyidlen = 0; 294999ebb4caSwyllys 295099ebb4caSwyllys /* Must have at least a cert OR a key */ 295199ebb4caSwyllys if (sslcert == NULL && pkey == NULL) 295299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 295399ebb4caSwyllys 295499ebb4caSwyllys (void) memset(keyid, 0, sizeof (keyid)); 295599ebb4caSwyllys /* 295699ebb4caSwyllys * Section 1: 295799ebb4caSwyllys * 295899ebb4caSwyllys * The first PKCS#12 container (safebag) will hold the certificates 295999ebb4caSwyllys * associated with this key. The result of this section is a 296099ebb4caSwyllys * PIN-encrypted PKCS#7 container (authsafe). If there are no 296199ebb4caSwyllys * certificates, there is no point in creating the "safebag" or the 296299ebb4caSwyllys * "authsafe" so we go to the next section. 296399ebb4caSwyllys */ 296499ebb4caSwyllys if (sslcert != NULL && pkey != NULL) { 296599ebb4caSwyllys if (X509_check_private_key(sslcert, pkey)) { 296699ebb4caSwyllys (void) X509_digest(sslcert, EVP_sha1(), keyid, 296799ebb4caSwyllys &keyidlen); 296899ebb4caSwyllys } else { 296999ebb4caSwyllys /* The key doesn't match the cert */ 297099ebb4caSwyllys HANDLE_PK12_ERROR 297199ebb4caSwyllys } 297299ebb4caSwyllys } 297399ebb4caSwyllys 297499ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 297599ebb4caSwyllys if (bag_stack == NULL) 297699ebb4caSwyllys return (KMF_ERR_MEMORY); 297799ebb4caSwyllys 297899ebb4caSwyllys if (sslcert != NULL) { 297999ebb4caSwyllys /* Convert cert from X509 struct to PKCS#12 bag */ 298099ebb4caSwyllys bag = PKCS12_x5092certbag(sslcert); 298199ebb4caSwyllys if (bag == NULL) { 298299ebb4caSwyllys HANDLE_PK12_ERROR 298399ebb4caSwyllys } 298499ebb4caSwyllys 298599ebb4caSwyllys /* Add the key id to the certificate bag. */ 298699ebb4caSwyllys if (keyidlen > 0 && 298799ebb4caSwyllys !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 298899ebb4caSwyllys HANDLE_PK12_ERROR 298999ebb4caSwyllys } 299099ebb4caSwyllys 299199ebb4caSwyllys /* Pile it on the bag_stack. */ 299299ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 299399ebb4caSwyllys HANDLE_PK12_ERROR 299499ebb4caSwyllys } 299599ebb4caSwyllys #if 0 299699ebb4caSwyllys /* No support for CA certs yet */ 299799ebb4caSwyllys if (cacerts != NULL && ncacerts > 0) { 299899ebb4caSwyllys int i; 299999ebb4caSwyllys for (i = 0; i < ncacerts; i++) { 300099ebb4caSwyllys KMF_X509_DER_CERT *c = &cacerts[i]; 300199ebb4caSwyllys X509 *ca = NULL; 300299ebb4caSwyllys 300399ebb4caSwyllys uchar_t *p = (uchar_t *)c->certificate.Data; 3004*30a5e8faSwyllys ca = d2i_X509(NULL, &p, c->certificate.Length); 300599ebb4caSwyllys if (ca == NULL) { 300699ebb4caSwyllys HANDLE_PK12_ERROR 300799ebb4caSwyllys } 300899ebb4caSwyllys /* Convert CA cert to PKCS#12 bag. */ 300999ebb4caSwyllys bag = PKCS12_x5092certbag(ca); 301099ebb4caSwyllys if (bag == NULL) { 301199ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, 301299ebb4caSwyllys PKCS12_SAFEBAG_free); 301399ebb4caSwyllys HANDLE_PK12_ERROR 301499ebb4caSwyllys } 301599ebb4caSwyllys /* Pile it onto the bag_stack. */ 301699ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 301799ebb4caSwyllys HANDLE_PK12_ERROR 301899ebb4caSwyllys } 301999ebb4caSwyllys } 302099ebb4caSwyllys } 302199ebb4caSwyllys #endif 302299ebb4caSwyllys /* Turn bag_stack of certs into encrypted authsafe. */ 302399ebb4caSwyllys cert_authsafe = PKCS12_pack_p7encdata( 302499ebb4caSwyllys NID_pbe_WithSHA1And40BitRC2_CBC, 302534acef67Swyllys cred->cred, cred->credlen, NULL, 0, 302634acef67Swyllys PKCS12_DEFAULT_ITER, bag_stack); 302799ebb4caSwyllys 302899ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 302999ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 303099ebb4caSwyllys bag_stack = NULL; 303199ebb4caSwyllys 303299ebb4caSwyllys if (cert_authsafe == NULL) { 303399ebb4caSwyllys HANDLE_PK12_ERROR 303499ebb4caSwyllys } 303599ebb4caSwyllys } 303699ebb4caSwyllys /* 303799ebb4caSwyllys * Section 2: 303899ebb4caSwyllys * 303999ebb4caSwyllys * The second PKCS#12 container (safebag) will hold the private key 304099ebb4caSwyllys * that goes with the certificates above. The results of this section 304199ebb4caSwyllys * is an unencrypted PKCS#7 container (authsafe). If there is no 304299ebb4caSwyllys * private key, there is no point in creating the "safebag" or the 304399ebb4caSwyllys * "authsafe" so we go to the next section. 304499ebb4caSwyllys */ 304599ebb4caSwyllys if (pkey != NULL) { 304699ebb4caSwyllys p8 = EVP_PKEY2PKCS8(pkey); 304799ebb4caSwyllys if (p8 == NULL) { 304899ebb4caSwyllys HANDLE_PK12_ERROR 304999ebb4caSwyllys } 305099ebb4caSwyllys /* Put the shrouded key into a PKCS#12 bag. */ 305199ebb4caSwyllys bag = PKCS12_MAKE_SHKEYBAG( 305299ebb4caSwyllys NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 305399ebb4caSwyllys cred->cred, cred->credlen, 305499ebb4caSwyllys NULL, 0, PKCS12_DEFAULT_ITER, p8); 305599ebb4caSwyllys 305699ebb4caSwyllys /* Clean up the PKCS#8 shrouded key, don't need it now. */ 305799ebb4caSwyllys PKCS8_PRIV_KEY_INFO_free(p8); 305899ebb4caSwyllys p8 = NULL; 305999ebb4caSwyllys 306099ebb4caSwyllys if (bag == NULL) { 306199ebb4caSwyllys HANDLE_PK12_ERROR 306299ebb4caSwyllys } 306399ebb4caSwyllys if (keyidlen && 306499ebb4caSwyllys !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 306599ebb4caSwyllys HANDLE_PK12_ERROR 306699ebb4caSwyllys } 306799ebb4caSwyllys if (lab != NULL) { 306899ebb4caSwyllys if (!PKCS12_add_friendlyname(bag, 306999ebb4caSwyllys (char *)lab, lab_len)) { 307099ebb4caSwyllys HANDLE_PK12_ERROR 307199ebb4caSwyllys } 307299ebb4caSwyllys } 307399ebb4caSwyllys /* Start a PKCS#12 safebag container for the private key. */ 307499ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 307599ebb4caSwyllys if (bag_stack == NULL) { 307699ebb4caSwyllys HANDLE_PK12_ERROR 307799ebb4caSwyllys } 307899ebb4caSwyllys 307999ebb4caSwyllys /* Pile on the private key on the bag_stack. */ 308099ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 308199ebb4caSwyllys HANDLE_PK12_ERROR 308299ebb4caSwyllys } 308399ebb4caSwyllys key_authsafe = PKCS12_pack_p7data(bag_stack); 308499ebb4caSwyllys 308599ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 308699ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 308799ebb4caSwyllys bag_stack = NULL; 308899ebb4caSwyllys 308999ebb4caSwyllys if (key_authsafe == NULL) { 309099ebb4caSwyllys HANDLE_PK12_ERROR 309199ebb4caSwyllys } 309299ebb4caSwyllys } 309399ebb4caSwyllys /* 309499ebb4caSwyllys * Section 3: 309599ebb4caSwyllys * 309699ebb4caSwyllys * This is where the two PKCS#7 containers, one for the certificates 309799ebb4caSwyllys * and one for the private key, are put together into a PKCS#12 309899ebb4caSwyllys * element. This final PKCS#12 element is written to the export file. 309999ebb4caSwyllys */ 310099ebb4caSwyllys 310199ebb4caSwyllys /* Start a PKCS#7 stack. */ 310299ebb4caSwyllys authsafe_stack = sk_PKCS7_new_null(); 310399ebb4caSwyllys if (authsafe_stack == NULL) { 310499ebb4caSwyllys HANDLE_PK12_ERROR 310599ebb4caSwyllys } 310699ebb4caSwyllys if (key_authsafe != NULL) { 310799ebb4caSwyllys if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) { 310899ebb4caSwyllys HANDLE_PK12_ERROR 310999ebb4caSwyllys } 311099ebb4caSwyllys } 311199ebb4caSwyllys if (cert_authsafe != NULL) { 311299ebb4caSwyllys if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) { 311399ebb4caSwyllys HANDLE_PK12_ERROR 311499ebb4caSwyllys } 311599ebb4caSwyllys } 311699ebb4caSwyllys p12_elem = PKCS12_init(NID_pkcs7_data); 311799ebb4caSwyllys if (p12_elem == NULL) { 311899ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 311999ebb4caSwyllys HANDLE_PK12_ERROR 312099ebb4caSwyllys } 312199ebb4caSwyllys 312299ebb4caSwyllys /* Put the PKCS#7 stack into the PKCS#12 element. */ 312399ebb4caSwyllys if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) { 312499ebb4caSwyllys HANDLE_PK12_ERROR 312599ebb4caSwyllys } 312699ebb4caSwyllys /* Clear away the PKCS#7 stack, we're done with it. */ 312799ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 312899ebb4caSwyllys authsafe_stack = NULL; 312999ebb4caSwyllys 313099ebb4caSwyllys /* Set the integrity MAC on the PKCS#12 element. */ 313199ebb4caSwyllys if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen, 313299ebb4caSwyllys NULL, 0, PKCS12_DEFAULT_ITER, NULL)) { 313399ebb4caSwyllys HANDLE_PK12_ERROR 313499ebb4caSwyllys } 313599ebb4caSwyllys 313699ebb4caSwyllys /* Write the PKCS#12 element to the export file. */ 313799ebb4caSwyllys if (!i2d_PKCS12_bio(bio, p12_elem)) { 313899ebb4caSwyllys HANDLE_PK12_ERROR 313999ebb4caSwyllys } 314099ebb4caSwyllys 314199ebb4caSwyllys PKCS12_free(p12_elem); 314299ebb4caSwyllys out: 314399ebb4caSwyllys if (rv != KMF_OK) { 314499ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 314599ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 314699ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 314799ebb4caSwyllys } 314899ebb4caSwyllys return (rv); 314999ebb4caSwyllys } 315099ebb4caSwyllys 315199ebb4caSwyllys static EVP_PKEY * 315299ebb4caSwyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *key) 315399ebb4caSwyllys { 315499ebb4caSwyllys RSA *rsa = NULL; 315599ebb4caSwyllys EVP_PKEY *newkey = NULL; 315699ebb4caSwyllys 315799ebb4caSwyllys if ((rsa = RSA_new()) == NULL) 315899ebb4caSwyllys return (NULL); 315999ebb4caSwyllys 316099ebb4caSwyllys if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL) 316199ebb4caSwyllys return (NULL); 316299ebb4caSwyllys 316399ebb4caSwyllys if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) == 316499ebb4caSwyllys NULL) 316599ebb4caSwyllys return (NULL); 316699ebb4caSwyllys 316799ebb4caSwyllys if (key->priexp.val != NULL) 316899ebb4caSwyllys if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len, 316999ebb4caSwyllys rsa->d)) == NULL) 317099ebb4caSwyllys return (NULL); 317199ebb4caSwyllys 317299ebb4caSwyllys if (key->prime1.val != NULL) 317399ebb4caSwyllys if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len, 317499ebb4caSwyllys rsa->p)) == NULL) 317599ebb4caSwyllys return (NULL); 317699ebb4caSwyllys 317799ebb4caSwyllys if (key->prime2.val != NULL) 317899ebb4caSwyllys if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len, 317999ebb4caSwyllys rsa->q)) == NULL) 318099ebb4caSwyllys return (NULL); 318199ebb4caSwyllys 318299ebb4caSwyllys if (key->exp1.val != NULL) 318399ebb4caSwyllys if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, 318499ebb4caSwyllys rsa->dmp1)) == NULL) 318599ebb4caSwyllys return (NULL); 318699ebb4caSwyllys 318799ebb4caSwyllys if (key->exp2.val != NULL) 318899ebb4caSwyllys if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, 318999ebb4caSwyllys rsa->dmq1)) == NULL) 319099ebb4caSwyllys return (NULL); 319199ebb4caSwyllys 319299ebb4caSwyllys if (key->coef.val != NULL) 319399ebb4caSwyllys if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len, 319499ebb4caSwyllys rsa->iqmp)) == NULL) 319599ebb4caSwyllys return (NULL); 319699ebb4caSwyllys 319799ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 319899ebb4caSwyllys return (NULL); 319999ebb4caSwyllys 320099ebb4caSwyllys (void) EVP_PKEY_set1_RSA(newkey, rsa); 320199ebb4caSwyllys 320299ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 320399ebb4caSwyllys RSA_free(rsa); 320499ebb4caSwyllys 320599ebb4caSwyllys return (newkey); 320699ebb4caSwyllys } 320799ebb4caSwyllys 320899ebb4caSwyllys static EVP_PKEY * 320999ebb4caSwyllys ImportRawDSAKey(KMF_RAW_DSA_KEY *key) 321099ebb4caSwyllys { 321199ebb4caSwyllys DSA *dsa = NULL; 321299ebb4caSwyllys EVP_PKEY *newkey = NULL; 321399ebb4caSwyllys 321499ebb4caSwyllys if ((dsa = DSA_new()) == NULL) 321599ebb4caSwyllys return (NULL); 321699ebb4caSwyllys 321799ebb4caSwyllys if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len, 321899ebb4caSwyllys dsa->p)) == NULL) 321999ebb4caSwyllys return (NULL); 322099ebb4caSwyllys 322199ebb4caSwyllys if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len, 322299ebb4caSwyllys dsa->q)) == NULL) 322399ebb4caSwyllys return (NULL); 322499ebb4caSwyllys 322599ebb4caSwyllys if ((dsa->g = BN_bin2bn(key->base.val, key->base.len, 322699ebb4caSwyllys dsa->g)) == NULL) 322799ebb4caSwyllys return (NULL); 322899ebb4caSwyllys 322999ebb4caSwyllys if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len, 323099ebb4caSwyllys dsa->priv_key)) == NULL) 323199ebb4caSwyllys return (NULL); 323299ebb4caSwyllys 3233*30a5e8faSwyllys if (key->pubvalue.val != NULL) { 3234*30a5e8faSwyllys if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val, 3235*30a5e8faSwyllys key->pubvalue.len, dsa->pub_key)) == NULL) 3236*30a5e8faSwyllys return (NULL); 3237*30a5e8faSwyllys } 3238*30a5e8faSwyllys 323999ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 324099ebb4caSwyllys return (NULL); 324199ebb4caSwyllys 324299ebb4caSwyllys (void) EVP_PKEY_set1_DSA(newkey, dsa); 324399ebb4caSwyllys 324499ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 324599ebb4caSwyllys DSA_free(dsa); 324699ebb4caSwyllys return (newkey); 324799ebb4caSwyllys } 324899ebb4caSwyllys 324999ebb4caSwyllys static KMF_RETURN 325099ebb4caSwyllys ExportPK12FromRawData(KMF_HANDLE_T handle, 325199ebb4caSwyllys KMF_CREDENTIAL *cred, 325299ebb4caSwyllys int numcerts, KMF_X509_DER_CERT *certlist, 325399ebb4caSwyllys int numkeys, KMF_KEY_HANDLE *keylist, 325499ebb4caSwyllys char *filename) 325599ebb4caSwyllys { 325699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 325799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 325899ebb4caSwyllys BIO *bio = NULL; 325999ebb4caSwyllys X509 *xcert = NULL; 326099ebb4caSwyllys EVP_PKEY *pkey = NULL; 326199ebb4caSwyllys int i; 326299ebb4caSwyllys 326399ebb4caSwyllys /* 326499ebb4caSwyllys * Open the output file. 326599ebb4caSwyllys */ 326699ebb4caSwyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) { 326799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 326899ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 326999ebb4caSwyllys goto cleanup; 327099ebb4caSwyllys } 327199ebb4caSwyllys 327299ebb4caSwyllys if (numcerts > 0 && numkeys > 0) { 327399ebb4caSwyllys for (i = 0; rv == KMF_OK && i < numcerts; i++) { 327499ebb4caSwyllys KMF_RAW_KEY_DATA *key = NULL; 327599ebb4caSwyllys const uchar_t *p = certlist[i].certificate.Data; 327699ebb4caSwyllys long len = certlist[i].certificate.Length; 327799ebb4caSwyllys 327899ebb4caSwyllys if (i < numkeys) { 327999ebb4caSwyllys key = (KMF_RAW_KEY_DATA *)keylist[i].keyp; 328099ebb4caSwyllys 328199ebb4caSwyllys if (key->keytype == KMF_RSA) { 328299ebb4caSwyllys pkey = ImportRawRSAKey( 328399ebb4caSwyllys &key->rawdata.rsa); 328499ebb4caSwyllys } else if (key->keytype == KMF_DSA) { 328599ebb4caSwyllys pkey = ImportRawDSAKey( 328699ebb4caSwyllys &key->rawdata.dsa); 328799ebb4caSwyllys } else { 328899ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 328999ebb4caSwyllys } 329099ebb4caSwyllys } 329199ebb4caSwyllys 329299ebb4caSwyllys xcert = d2i_X509(NULL, &p, len); 329399ebb4caSwyllys if (xcert == NULL) { 329499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 329599ebb4caSwyllys rv = KMF_ERR_ENCODING; 329699ebb4caSwyllys } 329799ebb4caSwyllys /* Stick the key and the cert into a PKCS#12 file */ 329899ebb4caSwyllys rv = write_pkcs12(kmfh, bio, cred, pkey, xcert); 329999ebb4caSwyllys if (xcert) 330099ebb4caSwyllys X509_free(xcert); 330199ebb4caSwyllys if (pkey) 330299ebb4caSwyllys EVP_PKEY_free(pkey); 330399ebb4caSwyllys } 330499ebb4caSwyllys } 330599ebb4caSwyllys 330699ebb4caSwyllys cleanup: 330799ebb4caSwyllys 330899ebb4caSwyllys if (bio != NULL) 330999ebb4caSwyllys (void) BIO_free_all(bio); 331099ebb4caSwyllys 331199ebb4caSwyllys return (rv); 331299ebb4caSwyllys } 331399ebb4caSwyllys 3314*30a5e8faSwyllys 331599ebb4caSwyllys KMF_RETURN 3316*30a5e8faSwyllys openssl_build_pk12(KMF_HANDLE_T handle, int numcerts, 3317*30a5e8faSwyllys KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist, 3318*30a5e8faSwyllys KMF_CREDENTIAL *p12cred, char *filename) 3319*30a5e8faSwyllys { 3320*30a5e8faSwyllys KMF_RETURN rv; 3321*30a5e8faSwyllys 3322*30a5e8faSwyllys if (certlist == NULL && keylist == NULL) 3323*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 3324*30a5e8faSwyllys 3325*30a5e8faSwyllys rv = ExportPK12FromRawData(handle, p12cred, numcerts, certlist, 3326*30a5e8faSwyllys numkeys, keylist, filename); 3327*30a5e8faSwyllys 3328*30a5e8faSwyllys return (rv); 3329*30a5e8faSwyllys } 3330*30a5e8faSwyllys 3331*30a5e8faSwyllys 3332*30a5e8faSwyllys KMF_RETURN 3333*30a5e8faSwyllys OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 333499ebb4caSwyllys { 333599ebb4caSwyllys KMF_RETURN rv; 333699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 333799ebb4caSwyllys BIO *bio = NULL; 333899ebb4caSwyllys X509 *xcert = NULL; 333999ebb4caSwyllys char *fullpath = NULL; 334099ebb4caSwyllys EVP_PKEY *pkey = NULL; 3341*30a5e8faSwyllys char *dirpath = NULL; 3342*30a5e8faSwyllys char *certfile = NULL; 3343*30a5e8faSwyllys char *keyfile = NULL; 3344*30a5e8faSwyllys char *filename = NULL; 3345*30a5e8faSwyllys KMF_CREDENTIAL *p12cred = NULL; 3346*30a5e8faSwyllys 3347*30a5e8faSwyllys if (handle == NULL) 3348*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 334999ebb4caSwyllys 335099ebb4caSwyllys /* 335199ebb4caSwyllys * First, find the certificate. 335299ebb4caSwyllys */ 3353*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 3354*30a5e8faSwyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 3355*30a5e8faSwyllys if (certfile != NULL) { 3356*30a5e8faSwyllys fullpath = get_fullpath(dirpath, certfile); 335799ebb4caSwyllys if (fullpath == NULL) 335899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 335999ebb4caSwyllys 336099ebb4caSwyllys if (isdir(fullpath)) { 336199ebb4caSwyllys free(fullpath); 336299ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 336399ebb4caSwyllys } 336499ebb4caSwyllys 3365*30a5e8faSwyllys rv = load_X509cert(kmfh, NULL, NULL, NULL, fullpath, &xcert); 336699ebb4caSwyllys if (rv != KMF_OK) 336799ebb4caSwyllys goto end; 3368*30a5e8faSwyllys 3369*30a5e8faSwyllys free(fullpath); 337099ebb4caSwyllys } 337199ebb4caSwyllys 337299ebb4caSwyllys /* 337399ebb4caSwyllys * Now find the private key. 337499ebb4caSwyllys */ 3375*30a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 3376*30a5e8faSwyllys if (keyfile != NULL) { 3377*30a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 337899ebb4caSwyllys if (fullpath == NULL) 337999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 338099ebb4caSwyllys 338199ebb4caSwyllys if (isdir(fullpath)) { 338299ebb4caSwyllys free(fullpath); 338399ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 338499ebb4caSwyllys } 338599ebb4caSwyllys 338699ebb4caSwyllys pkey = openssl_load_key(handle, fullpath); 338799ebb4caSwyllys if (pkey == NULL) { 338899ebb4caSwyllys rv = KMF_ERR_KEY_NOT_FOUND; 338999ebb4caSwyllys goto end; 339099ebb4caSwyllys } 339199ebb4caSwyllys } 339299ebb4caSwyllys 339399ebb4caSwyllys /* 339499ebb4caSwyllys * Open the output file. 339599ebb4caSwyllys */ 3396*30a5e8faSwyllys filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, 3397*30a5e8faSwyllys numattr); 3398*30a5e8faSwyllys if (filename == NULL) { 3399*30a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 3400*30a5e8faSwyllys goto end; 3401*30a5e8faSwyllys } 3402*30a5e8faSwyllys 340399ebb4caSwyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) { 340499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 340599ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 340699ebb4caSwyllys goto end; 340799ebb4caSwyllys } 340899ebb4caSwyllys 340999ebb4caSwyllys /* Stick the key and the cert into a PKCS#12 file */ 3410*30a5e8faSwyllys p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); 3411*30a5e8faSwyllys if (p12cred == NULL) { 3412*30a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 3413*30a5e8faSwyllys goto end; 3414*30a5e8faSwyllys } 3415*30a5e8faSwyllys 3416*30a5e8faSwyllys rv = write_pkcs12(kmfh, bio, p12cred, pkey, xcert); 341799ebb4caSwyllys 341899ebb4caSwyllys end: 341999ebb4caSwyllys if (fullpath) 342099ebb4caSwyllys free(fullpath); 342199ebb4caSwyllys if (xcert) 342299ebb4caSwyllys X509_free(xcert); 342399ebb4caSwyllys if (pkey) 342499ebb4caSwyllys EVP_PKEY_free(pkey); 342599ebb4caSwyllys if (bio) 342699ebb4caSwyllys (void) BIO_free(bio); 342799ebb4caSwyllys 342899ebb4caSwyllys return (rv); 342999ebb4caSwyllys } 343099ebb4caSwyllys 3431*30a5e8faSwyllys 343271593db2Swyllys #define MAX_CHAIN_LENGTH 100 343371593db2Swyllys /* 343471593db2Swyllys * Helper function to extract keys and certificates from 343571593db2Swyllys * a single PEM file. Typically the file should contain a 343671593db2Swyllys * private key and an associated public key wrapped in an x509 cert. 343771593db2Swyllys * However, the file may be just a list of X509 certs with no keys. 343871593db2Swyllys */ 343971593db2Swyllys static KMF_RETURN 3440*30a5e8faSwyllys extract_pem(KMF_HANDLE *kmfh, 3441*30a5e8faSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 344202744e81Swyllys char *filename, CK_UTF8CHAR *pin, 344371593db2Swyllys CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs, 344471593db2Swyllys int *numcerts) 344571593db2Swyllys /* ARGSUSED */ 344671593db2Swyllys { 344771593db2Swyllys KMF_RETURN rv = KMF_OK; 344871593db2Swyllys FILE *fp; 344934acef67Swyllys STACK_OF(X509_INFO) *x509_info_stack = NULL; 345002744e81Swyllys int i, ncerts = 0, matchcerts = 0; 345171593db2Swyllys EVP_PKEY *pkey = NULL; 345271593db2Swyllys X509_INFO *info; 345371593db2Swyllys X509 *x; 345471593db2Swyllys X509_INFO *cert_infos[MAX_CHAIN_LENGTH]; 345571593db2Swyllys KMF_DATA *certlist = NULL; 345671593db2Swyllys 345771593db2Swyllys if (priv_key) 345871593db2Swyllys *priv_key = NULL; 345971593db2Swyllys if (certs) 346071593db2Swyllys *certs = NULL; 346171593db2Swyllys fp = fopen(filename, "r"); 346271593db2Swyllys if (fp == NULL) { 346371593db2Swyllys return (KMF_ERR_OPEN_FILE); 346471593db2Swyllys } 346571593db2Swyllys x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin); 346671593db2Swyllys if (x509_info_stack == NULL) { 346771593db2Swyllys (void) fclose(fp); 346871593db2Swyllys return (KMF_ERR_ENCODING); 346971593db2Swyllys } 347071593db2Swyllys 3471*30a5e8faSwyllys 347234acef67Swyllys for (i = 0; 347334acef67Swyllys i < sk_X509_INFO_num(x509_info_stack) && i < MAX_CHAIN_LENGTH; 347434acef67Swyllys i++) { 347571593db2Swyllys /* LINTED */ 347634acef67Swyllys cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i); 347771593db2Swyllys ncerts++; 347871593db2Swyllys } 347971593db2Swyllys 348071593db2Swyllys if (ncerts == 0) { 348171593db2Swyllys (void) fclose(fp); 348234acef67Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 348334acef67Swyllys goto err; 348471593db2Swyllys } 348571593db2Swyllys 348671593db2Swyllys if (priv_key != NULL) { 348771593db2Swyllys rewind(fp); 348871593db2Swyllys pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin); 348971593db2Swyllys } 349071593db2Swyllys (void) fclose(fp); 349171593db2Swyllys 349271593db2Swyllys x = cert_infos[ncerts - 1]->x509; 349371593db2Swyllys /* 349471593db2Swyllys * Make sure the private key matchs the last cert in the file. 349571593db2Swyllys */ 349671593db2Swyllys if (pkey != NULL && !X509_check_private_key(x, pkey)) { 349771593db2Swyllys EVP_PKEY_free(pkey); 349834acef67Swyllys rv = KMF_ERR_KEY_MISMATCH; 349934acef67Swyllys goto err; 350071593db2Swyllys } 350171593db2Swyllys 350271593db2Swyllys certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA)); 350371593db2Swyllys if (certlist == NULL) { 350471593db2Swyllys if (pkey != NULL) 350571593db2Swyllys EVP_PKEY_free(pkey); 350634acef67Swyllys rv = KMF_ERR_MEMORY; 350734acef67Swyllys goto err; 350871593db2Swyllys } 350971593db2Swyllys 351071593db2Swyllys /* 351171593db2Swyllys * Convert all of the certs to DER format. 351271593db2Swyllys */ 351302744e81Swyllys matchcerts = 0; 351471593db2Swyllys for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) { 351502744e81Swyllys boolean_t match = FALSE; 351671593db2Swyllys info = cert_infos[ncerts - 1 - i]; 351771593db2Swyllys 3518*30a5e8faSwyllys rv = check_cert(info->x509, issuer, subject, serial, &match); 351902744e81Swyllys if (rv != KMF_OK || match != TRUE) { 352002744e81Swyllys rv = KMF_OK; 352102744e81Swyllys continue; 352202744e81Swyllys } 352302744e81Swyllys 352402744e81Swyllys rv = ssl_cert2KMFDATA(kmfh, info->x509, 352502744e81Swyllys &certlist[matchcerts++]); 352671593db2Swyllys 352771593db2Swyllys if (rv != KMF_OK) { 352871593db2Swyllys free(certlist); 352971593db2Swyllys certlist = NULL; 353002744e81Swyllys ncerts = matchcerts = 0; 353171593db2Swyllys } 353271593db2Swyllys } 353371593db2Swyllys 353471593db2Swyllys if (numcerts != NULL) 353502744e81Swyllys *numcerts = matchcerts; 353671593db2Swyllys if (certs != NULL) 353771593db2Swyllys *certs = certlist; 353871593db2Swyllys 353971593db2Swyllys if (priv_key == NULL && pkey != NULL) 354071593db2Swyllys EVP_PKEY_free(pkey); 354171593db2Swyllys else if (priv_key != NULL && pkey != NULL) 354271593db2Swyllys *priv_key = pkey; 354371593db2Swyllys 354434acef67Swyllys err: 354534acef67Swyllys /* Cleanup the stack of X509 info records */ 354634acef67Swyllys for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) { 354734acef67Swyllys /*LINTED*/ 354834acef67Swyllys info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i); 354934acef67Swyllys X509_INFO_free(info); 355034acef67Swyllys } 355134acef67Swyllys if (x509_info_stack) 355234acef67Swyllys sk_X509_INFO_free(x509_info_stack); 355334acef67Swyllys 355471593db2Swyllys return (rv); 355571593db2Swyllys } 355671593db2Swyllys 355799ebb4caSwyllys /* 355899ebb4caSwyllys * Helper function to decrypt and parse PKCS#12 import file. 355999ebb4caSwyllys */ 356099ebb4caSwyllys static KMF_RETURN 356199ebb4caSwyllys extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 356299ebb4caSwyllys EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca) 356399ebb4caSwyllys /* ARGSUSED */ 356499ebb4caSwyllys { 356599ebb4caSwyllys PKCS12 *pk12, *pk12_tmp; 356699ebb4caSwyllys EVP_PKEY *temp_pkey = NULL; 356799ebb4caSwyllys X509 *temp_cert = NULL; 356899ebb4caSwyllys STACK_OF(X509) *temp_ca = NULL; 356999ebb4caSwyllys 357099ebb4caSwyllys if ((pk12 = PKCS12_new()) == NULL) { 357199ebb4caSwyllys return (KMF_ERR_MEMORY); 357299ebb4caSwyllys } 357399ebb4caSwyllys 357499ebb4caSwyllys if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) { 357599ebb4caSwyllys /* This is ok; it seems to mean there is no more to read. */ 357699ebb4caSwyllys if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 && 357799ebb4caSwyllys ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG) 357899ebb4caSwyllys goto end_extract_pkcs12; 357999ebb4caSwyllys 358099ebb4caSwyllys PKCS12_free(pk12); 358199ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 358299ebb4caSwyllys } 358399ebb4caSwyllys pk12 = pk12_tmp; 358499ebb4caSwyllys 358599ebb4caSwyllys if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert, 358699ebb4caSwyllys &temp_ca) <= 0) { 358799ebb4caSwyllys PKCS12_free(pk12); 358899ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 358999ebb4caSwyllys } 359099ebb4caSwyllys 359199ebb4caSwyllys end_extract_pkcs12: 359299ebb4caSwyllys 359399ebb4caSwyllys *priv_key = temp_pkey; 359499ebb4caSwyllys *cert = temp_cert; 359599ebb4caSwyllys *ca = temp_ca; 359699ebb4caSwyllys 359799ebb4caSwyllys PKCS12_free(pk12); 359899ebb4caSwyllys return (KMF_OK); 359999ebb4caSwyllys } 360099ebb4caSwyllys 360199ebb4caSwyllys static KMF_RETURN 360299ebb4caSwyllys sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to) 360399ebb4caSwyllys { 360499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 360599ebb4caSwyllys uint32_t sz; 360699ebb4caSwyllys 360799ebb4caSwyllys sz = BN_num_bytes(from); 360899ebb4caSwyllys to->val = (uchar_t *)malloc(sz); 360999ebb4caSwyllys if (to->val == NULL) 361099ebb4caSwyllys return (KMF_ERR_MEMORY); 361199ebb4caSwyllys 361299ebb4caSwyllys if ((to->len = BN_bn2bin(from, to->val)) != sz) { 361399ebb4caSwyllys free(to->val); 361499ebb4caSwyllys to->val = NULL; 361599ebb4caSwyllys to->len = 0; 361699ebb4caSwyllys rv = KMF_ERR_MEMORY; 361799ebb4caSwyllys } 361899ebb4caSwyllys 361999ebb4caSwyllys return (rv); 362099ebb4caSwyllys } 362199ebb4caSwyllys 362299ebb4caSwyllys static KMF_RETURN 362399ebb4caSwyllys exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) 362499ebb4caSwyllys { 362599ebb4caSwyllys KMF_RETURN rv; 362699ebb4caSwyllys KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa; 362799ebb4caSwyllys 362899ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY)); 362999ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK) 363099ebb4caSwyllys goto cleanup; 363199ebb4caSwyllys 363299ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK) 363399ebb4caSwyllys goto cleanup; 363499ebb4caSwyllys 363599ebb4caSwyllys if (rsa->d != NULL) 363699ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK) 363799ebb4caSwyllys goto cleanup; 363899ebb4caSwyllys 363999ebb4caSwyllys if (rsa->p != NULL) 364099ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK) 364199ebb4caSwyllys goto cleanup; 364299ebb4caSwyllys 364399ebb4caSwyllys if (rsa->q != NULL) 364499ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK) 364599ebb4caSwyllys goto cleanup; 364699ebb4caSwyllys 364799ebb4caSwyllys if (rsa->dmp1 != NULL) 364899ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK) 364999ebb4caSwyllys goto cleanup; 365099ebb4caSwyllys 365199ebb4caSwyllys if (rsa->dmq1 != NULL) 365299ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK) 365399ebb4caSwyllys goto cleanup; 365499ebb4caSwyllys 365599ebb4caSwyllys if (rsa->iqmp != NULL) 365699ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK) 365799ebb4caSwyllys goto cleanup; 365899ebb4caSwyllys cleanup: 365999ebb4caSwyllys if (rv != KMF_OK) 3660*30a5e8faSwyllys kmf_free_raw_key(key); 366199ebb4caSwyllys else 366299ebb4caSwyllys key->keytype = KMF_RSA; 366399ebb4caSwyllys 366499ebb4caSwyllys /* 366599ebb4caSwyllys * Free the reference to this key, SSL will not actually free 366699ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 366799ebb4caSwyllys */ 366899ebb4caSwyllys RSA_free(rsa); 366999ebb4caSwyllys 367099ebb4caSwyllys return (rv); 367199ebb4caSwyllys } 367299ebb4caSwyllys 367399ebb4caSwyllys static KMF_RETURN 367499ebb4caSwyllys exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) 367599ebb4caSwyllys { 367699ebb4caSwyllys KMF_RETURN rv; 367799ebb4caSwyllys KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa; 367899ebb4caSwyllys 367999ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY)); 368099ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK) 368199ebb4caSwyllys goto cleanup; 368299ebb4caSwyllys 368399ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK) 368499ebb4caSwyllys goto cleanup; 368599ebb4caSwyllys 368699ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK) 368799ebb4caSwyllys goto cleanup; 368899ebb4caSwyllys 368999ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK) 369099ebb4caSwyllys goto cleanup; 369199ebb4caSwyllys 369299ebb4caSwyllys cleanup: 369399ebb4caSwyllys if (rv != KMF_OK) 3694*30a5e8faSwyllys kmf_free_raw_key(key); 369599ebb4caSwyllys else 369699ebb4caSwyllys key->keytype = KMF_DSA; 369799ebb4caSwyllys 369899ebb4caSwyllys /* 369999ebb4caSwyllys * Free the reference to this key, SSL will not actually free 370099ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 370199ebb4caSwyllys */ 370299ebb4caSwyllys DSA_free(dsa); 370399ebb4caSwyllys 370499ebb4caSwyllys return (rv); 370599ebb4caSwyllys } 370699ebb4caSwyllys 370799ebb4caSwyllys static KMF_RETURN 370899ebb4caSwyllys add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert, 370999ebb4caSwyllys KMF_DATA **certlist, int *ncerts) 371099ebb4caSwyllys { 371199ebb4caSwyllys KMF_RETURN rv = KMF_OK; 371299ebb4caSwyllys KMF_DATA *list = (*certlist); 371399ebb4caSwyllys KMF_DATA cert; 371499ebb4caSwyllys int n = (*ncerts); 371599ebb4caSwyllys 371699ebb4caSwyllys if (list == NULL) { 371799ebb4caSwyllys list = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 371899ebb4caSwyllys } else { 371999ebb4caSwyllys list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1)); 372099ebb4caSwyllys } 372199ebb4caSwyllys 372299ebb4caSwyllys if (list == NULL) 372399ebb4caSwyllys return (KMF_ERR_MEMORY); 372499ebb4caSwyllys 372599ebb4caSwyllys rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert); 372699ebb4caSwyllys if (rv == KMF_OK) { 372799ebb4caSwyllys list[n] = cert; 372899ebb4caSwyllys (*ncerts) = n + 1; 372999ebb4caSwyllys 373099ebb4caSwyllys *certlist = list; 373199ebb4caSwyllys } else { 373299ebb4caSwyllys free(list); 373399ebb4caSwyllys } 373499ebb4caSwyllys 373599ebb4caSwyllys return (rv); 373699ebb4caSwyllys } 373799ebb4caSwyllys 373899ebb4caSwyllys static KMF_RETURN 373999ebb4caSwyllys add_key_to_list(KMF_RAW_KEY_DATA **keylist, 374099ebb4caSwyllys KMF_RAW_KEY_DATA *newkey, int *nkeys) 374199ebb4caSwyllys { 374299ebb4caSwyllys KMF_RAW_KEY_DATA *list = (*keylist); 374399ebb4caSwyllys int n = (*nkeys); 374499ebb4caSwyllys 374599ebb4caSwyllys if (list == NULL) { 374699ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA)); 374799ebb4caSwyllys } else { 374899ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)realloc(list, 374999ebb4caSwyllys sizeof (KMF_RAW_KEY_DATA) * (n + 1)); 375099ebb4caSwyllys } 375199ebb4caSwyllys 375299ebb4caSwyllys if (list == NULL) 375399ebb4caSwyllys return (KMF_ERR_MEMORY); 375499ebb4caSwyllys 375599ebb4caSwyllys list[n] = *newkey; 375699ebb4caSwyllys (*nkeys) = n + 1; 375799ebb4caSwyllys 375899ebb4caSwyllys *keylist = list; 375999ebb4caSwyllys 376099ebb4caSwyllys return (KMF_OK); 376199ebb4caSwyllys } 376299ebb4caSwyllys 3763*30a5e8faSwyllys static KMF_RETURN 3764*30a5e8faSwyllys convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key) 3765*30a5e8faSwyllys { 3766*30a5e8faSwyllys KMF_RETURN rv = KMF_OK; 3767*30a5e8faSwyllys 3768*30a5e8faSwyllys if (pkey == NULL || key == NULL) 3769*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 3770*30a5e8faSwyllys /* Convert SSL key to raw key */ 3771*30a5e8faSwyllys switch (pkey->type) { 3772*30a5e8faSwyllys case EVP_PKEY_RSA: 3773*30a5e8faSwyllys rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey), 3774*30a5e8faSwyllys key); 3775*30a5e8faSwyllys if (rv != KMF_OK) 3776*30a5e8faSwyllys return (rv); 3777*30a5e8faSwyllys break; 3778*30a5e8faSwyllys case EVP_PKEY_DSA: 3779*30a5e8faSwyllys rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey), 3780*30a5e8faSwyllys key); 3781*30a5e8faSwyllys if (rv != KMF_OK) 3782*30a5e8faSwyllys return (rv); 3783*30a5e8faSwyllys break; 3784*30a5e8faSwyllys default: 3785*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 3786*30a5e8faSwyllys } 3787*30a5e8faSwyllys 3788*30a5e8faSwyllys return (rv); 3789*30a5e8faSwyllys } 379099ebb4caSwyllys 379199ebb4caSwyllys static KMF_RETURN 379299ebb4caSwyllys convertPK12Objects( 379399ebb4caSwyllys KMF_HANDLE *kmfh, 379499ebb4caSwyllys EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts, 379599ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys, 379699ebb4caSwyllys KMF_DATA **certlist, int *ncerts) 379799ebb4caSwyllys { 379899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 379999ebb4caSwyllys KMF_RAW_KEY_DATA key; 380099ebb4caSwyllys int i; 380199ebb4caSwyllys 380299ebb4caSwyllys if (sslkey != NULL) { 3803*30a5e8faSwyllys rv = convertToRawKey(sslkey, &key); 3804*30a5e8faSwyllys if (rv == KMF_OK) 380599ebb4caSwyllys rv = add_key_to_list(keylist, &key, nkeys); 3806*30a5e8faSwyllys 380799ebb4caSwyllys if (rv != KMF_OK) 380899ebb4caSwyllys return (rv); 380999ebb4caSwyllys } 381099ebb4caSwyllys 381199ebb4caSwyllys /* Now add the certificate to the certlist */ 381299ebb4caSwyllys if (sslcert != NULL) { 381399ebb4caSwyllys rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts); 381499ebb4caSwyllys if (rv != KMF_OK) 381599ebb4caSwyllys return (rv); 381699ebb4caSwyllys } 381799ebb4caSwyllys 381899ebb4caSwyllys /* Also add any included CA certs to the list */ 381971593db2Swyllys for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) { 382099ebb4caSwyllys X509 *c; 382199ebb4caSwyllys /* 382299ebb4caSwyllys * sk_X509_value() is macro that embeds a cast to (X509 *). 382399ebb4caSwyllys * Here it translates into ((X509 *)sk_value((ca), (i))). 382499ebb4caSwyllys * Lint is complaining about the embedded casting, and 382599ebb4caSwyllys * to fix it, you need to fix openssl header files. 382699ebb4caSwyllys */ 382799ebb4caSwyllys /* LINTED E_BAD_PTR_CAST_ALIGN */ 382899ebb4caSwyllys c = sk_X509_value(sslcacerts, i); 382999ebb4caSwyllys 383099ebb4caSwyllys /* Now add the ca cert to the certlist */ 383199ebb4caSwyllys rv = add_cert_to_list(kmfh, c, certlist, ncerts); 383299ebb4caSwyllys if (rv != KMF_OK) 383399ebb4caSwyllys return (rv); 383499ebb4caSwyllys } 383599ebb4caSwyllys return (rv); 383699ebb4caSwyllys } 383799ebb4caSwyllys 383899ebb4caSwyllys KMF_RETURN 3839*30a5e8faSwyllys openssl_import_objects(KMF_HANDLE *kmfh, 384099ebb4caSwyllys char *filename, KMF_CREDENTIAL *cred, 384199ebb4caSwyllys KMF_DATA **certlist, int *ncerts, 384299ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys) 384399ebb4caSwyllys { 384499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 384599ebb4caSwyllys EVP_PKEY *privkey = NULL; 3846*30a5e8faSwyllys KMF_ENCODE_FORMAT format; 3847*30a5e8faSwyllys BIO *bio = NULL; 384899ebb4caSwyllys X509 *cert = NULL; 384999ebb4caSwyllys STACK_OF(X509) *cacerts = NULL; 385099ebb4caSwyllys 3851*30a5e8faSwyllys /* 3852*30a5e8faSwyllys * auto-detect the file format, regardless of what 3853*30a5e8faSwyllys * the 'format' parameters in the params say. 3854*30a5e8faSwyllys */ 3855*30a5e8faSwyllys rv = kmf_get_file_format(filename, &format); 3856*30a5e8faSwyllys if (rv != KMF_OK) { 3857*30a5e8faSwyllys return (rv); 3858*30a5e8faSwyllys } 3859*30a5e8faSwyllys 3860*30a5e8faSwyllys /* This function only works for PEM or PKCS#12 files */ 3861*30a5e8faSwyllys if (format != KMF_FORMAT_PEM && 3862*30a5e8faSwyllys format != KMF_FORMAT_PEM_KEYPAIR && 3863*30a5e8faSwyllys format != KMF_FORMAT_PKCS12) 3864*30a5e8faSwyllys return (KMF_ERR_ENCODING); 3865*30a5e8faSwyllys 3866*30a5e8faSwyllys *certlist = NULL; 3867*30a5e8faSwyllys *keylist = NULL; 3868*30a5e8faSwyllys *ncerts = 0; 3869*30a5e8faSwyllys *nkeys = 0; 3870*30a5e8faSwyllys 3871*30a5e8faSwyllys if (format == KMF_FORMAT_PKCS12) { 387299ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 387399ebb4caSwyllys if (bio == NULL) { 387499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 387599ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 387699ebb4caSwyllys goto end; 387799ebb4caSwyllys } 387899ebb4caSwyllys 387934acef67Swyllys rv = extract_pkcs12(bio, (uchar_t *)cred->cred, 388034acef67Swyllys (uint32_t)cred->credlen, &privkey, &cert, &cacerts); 388199ebb4caSwyllys 388299ebb4caSwyllys if (rv == KMF_OK) 388399ebb4caSwyllys /* Convert keys and certs to exportable format */ 388499ebb4caSwyllys rv = convertPK12Objects(kmfh, privkey, cert, cacerts, 388599ebb4caSwyllys keylist, nkeys, certlist, ncerts); 388699ebb4caSwyllys 3887*30a5e8faSwyllys } else { 3888*30a5e8faSwyllys rv = extract_pem(kmfh, NULL, NULL, NULL, filename, 388934acef67Swyllys (uchar_t *)cred->cred, (uint32_t)cred->credlen, 389071593db2Swyllys &privkey, certlist, ncerts); 389171593db2Swyllys 389271593db2Swyllys /* Reached end of import file? */ 389371593db2Swyllys if (rv == KMF_OK) 389471593db2Swyllys /* Convert keys and certs to exportable format */ 389571593db2Swyllys rv = convertPK12Objects(kmfh, privkey, NULL, NULL, 389671593db2Swyllys keylist, nkeys, NULL, NULL); 3897*30a5e8faSwyllys } 389871593db2Swyllys 389971593db2Swyllys end: 390071593db2Swyllys if (privkey) 390171593db2Swyllys EVP_PKEY_free(privkey); 390271593db2Swyllys 3903*30a5e8faSwyllys if (bio != NULL) 390499ebb4caSwyllys (void) BIO_free(bio); 390599ebb4caSwyllys 3906*30a5e8faSwyllys if (cert) 3907*30a5e8faSwyllys X509_free(cert); 3908*30a5e8faSwyllys 3909*30a5e8faSwyllys if (cacerts) 3910*30a5e8faSwyllys sk_X509_free(cacerts); 3911*30a5e8faSwyllys 391299ebb4caSwyllys return (rv); 391399ebb4caSwyllys } 391499ebb4caSwyllys 391599ebb4caSwyllys static KMF_RETURN 391699ebb4caSwyllys create_deskey(DES_cblock **deskey) 391799ebb4caSwyllys { 391899ebb4caSwyllys DES_cblock *key; 391999ebb4caSwyllys 392099ebb4caSwyllys key = (DES_cblock *) malloc(sizeof (DES_cblock)); 392199ebb4caSwyllys if (key == NULL) { 392299ebb4caSwyllys return (KMF_ERR_MEMORY); 392399ebb4caSwyllys } 392499ebb4caSwyllys 392599ebb4caSwyllys if (DES_random_key(key) == 0) { 392699ebb4caSwyllys free(key); 392799ebb4caSwyllys return (KMF_ERR_KEYGEN_FAILED); 392899ebb4caSwyllys } 392999ebb4caSwyllys 393099ebb4caSwyllys *deskey = key; 393199ebb4caSwyllys return (KMF_OK); 393299ebb4caSwyllys } 393399ebb4caSwyllys 393499ebb4caSwyllys #define KEYGEN_RETRY 3 393599ebb4caSwyllys #define DES3_KEY_SIZE 24 393699ebb4caSwyllys 393799ebb4caSwyllys static KMF_RETURN 393899ebb4caSwyllys create_des3key(unsigned char **des3key) 393999ebb4caSwyllys { 394099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 394199ebb4caSwyllys DES_cblock *deskey1 = NULL; 394299ebb4caSwyllys DES_cblock *deskey2 = NULL; 394399ebb4caSwyllys DES_cblock *deskey3 = NULL; 394499ebb4caSwyllys unsigned char *newkey = NULL; 394599ebb4caSwyllys int retry; 394699ebb4caSwyllys 394799ebb4caSwyllys if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) { 394899ebb4caSwyllys return (KMF_ERR_MEMORY); 394999ebb4caSwyllys } 395099ebb4caSwyllys 395199ebb4caSwyllys /* create the 1st DES key */ 395299ebb4caSwyllys if ((ret = create_deskey(&deskey1)) != KMF_OK) { 395399ebb4caSwyllys goto out; 395499ebb4caSwyllys } 395599ebb4caSwyllys 395699ebb4caSwyllys /* 395799ebb4caSwyllys * Create the 2nd DES key and make sure its value is different 395899ebb4caSwyllys * from the 1st DES key. 395999ebb4caSwyllys */ 396099ebb4caSwyllys retry = 0; 396199ebb4caSwyllys do { 396299ebb4caSwyllys if (deskey2 != NULL) { 396399ebb4caSwyllys free(deskey2); 396499ebb4caSwyllys deskey2 = NULL; 396599ebb4caSwyllys } 396699ebb4caSwyllys 396799ebb4caSwyllys if ((ret = create_deskey(&deskey2)) != KMF_OK) { 396899ebb4caSwyllys goto out; 396999ebb4caSwyllys } 397099ebb4caSwyllys 397199ebb4caSwyllys if (memcmp((const void *) deskey1, (const void *) deskey2, 8) 397299ebb4caSwyllys == 0) { 397399ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 397499ebb4caSwyllys retry++; 397599ebb4caSwyllys } 397699ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 397799ebb4caSwyllys 397899ebb4caSwyllys if (ret != KMF_OK) { 397999ebb4caSwyllys goto out; 398099ebb4caSwyllys } 398199ebb4caSwyllys 398299ebb4caSwyllys /* 398399ebb4caSwyllys * Create the 3rd DES key and make sure its value is different 398499ebb4caSwyllys * from the 2nd DES key. 398599ebb4caSwyllys */ 398699ebb4caSwyllys retry = 0; 398799ebb4caSwyllys do { 398899ebb4caSwyllys if (deskey3 != NULL) { 398999ebb4caSwyllys free(deskey3); 399099ebb4caSwyllys deskey3 = NULL; 399199ebb4caSwyllys } 399299ebb4caSwyllys 399399ebb4caSwyllys if ((ret = create_deskey(&deskey3)) != KMF_OK) { 399499ebb4caSwyllys goto out; 399599ebb4caSwyllys } 399699ebb4caSwyllys 399799ebb4caSwyllys if (memcmp((const void *)deskey2, (const void *)deskey3, 8) 399899ebb4caSwyllys == 0) { 399999ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 400099ebb4caSwyllys retry++; 400199ebb4caSwyllys } 400299ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 400399ebb4caSwyllys 400499ebb4caSwyllys if (ret != KMF_OK) { 400599ebb4caSwyllys goto out; 400699ebb4caSwyllys } 400799ebb4caSwyllys 400899ebb4caSwyllys /* Concatenate 3 DES keys into a DES3 key */ 400999ebb4caSwyllys (void) memcpy((void *)newkey, (const void *)deskey1, 8); 401099ebb4caSwyllys (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8); 401199ebb4caSwyllys (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8); 401299ebb4caSwyllys *des3key = newkey; 401399ebb4caSwyllys 401499ebb4caSwyllys out: 401599ebb4caSwyllys if (deskey1 != NULL) 401699ebb4caSwyllys free(deskey1); 401799ebb4caSwyllys 401899ebb4caSwyllys if (deskey2 != NULL) 401999ebb4caSwyllys free(deskey2); 402099ebb4caSwyllys 402199ebb4caSwyllys if (deskey3 != NULL) 402299ebb4caSwyllys free(deskey3); 402399ebb4caSwyllys 402499ebb4caSwyllys if (ret != KMF_OK && newkey != NULL) 402599ebb4caSwyllys free(newkey); 402699ebb4caSwyllys 402799ebb4caSwyllys return (ret); 402899ebb4caSwyllys } 402999ebb4caSwyllys 403099ebb4caSwyllys KMF_RETURN 4031*30a5e8faSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T handle, 4032*30a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 403399ebb4caSwyllys { 403499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 403599ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 403699ebb4caSwyllys char *fullpath = NULL; 403799ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 403899ebb4caSwyllys DES_cblock *deskey = NULL; 403999ebb4caSwyllys unsigned char *des3key = NULL; 404099ebb4caSwyllys unsigned char *random = NULL; 404199ebb4caSwyllys int fd = -1; 4042*30a5e8faSwyllys KMF_KEY_HANDLE *symkey; 4043*30a5e8faSwyllys KMF_KEY_ALG keytype; 4044*30a5e8faSwyllys uint32_t keylen; 4045*30a5e8faSwyllys uint32_t keylen_size = sizeof (keylen); 4046*30a5e8faSwyllys char *dirpath; 4047*30a5e8faSwyllys char *keyfile; 404899ebb4caSwyllys 404999ebb4caSwyllys if (kmfh == NULL) 405099ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 405199ebb4caSwyllys 4052*30a5e8faSwyllys symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 4053*30a5e8faSwyllys if (symkey == NULL) 405499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 405599ebb4caSwyllys 4056*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 4057*30a5e8faSwyllys 4058*30a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 4059*30a5e8faSwyllys if (keyfile == NULL) 4060*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 4061*30a5e8faSwyllys 4062*30a5e8faSwyllys ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 4063*30a5e8faSwyllys (void *)&keytype, NULL); 4064*30a5e8faSwyllys if (ret != KMF_OK) 4065*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 4066*30a5e8faSwyllys 4067*30a5e8faSwyllys ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 4068*30a5e8faSwyllys &keylen, &keylen_size); 4069*30a5e8faSwyllys if (ret == KMF_ERR_ATTR_NOT_FOUND && 4070*30a5e8faSwyllys (keytype == KMF_DES || keytype == KMF_DES3)) 4071*30a5e8faSwyllys /* keylength is not required for DES and 3DES */ 4072*30a5e8faSwyllys ret = KMF_OK; 4073*30a5e8faSwyllys if (ret != KMF_OK) 4074*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 4075*30a5e8faSwyllys 4076*30a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 407799ebb4caSwyllys if (fullpath == NULL) 407899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 407999ebb4caSwyllys 408099ebb4caSwyllys /* If the requested file exists, return an error */ 4081*30a5e8faSwyllys if (test_for_file(fullpath, 0400) == 1) { 408299ebb4caSwyllys free(fullpath); 408399ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 408499ebb4caSwyllys } 408599ebb4caSwyllys 408699ebb4caSwyllys fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400); 408799ebb4caSwyllys if (fd == -1) { 408899ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 408999ebb4caSwyllys goto out; 409099ebb4caSwyllys } 409199ebb4caSwyllys 409299ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 409399ebb4caSwyllys if (rkey == NULL) { 409499ebb4caSwyllys ret = KMF_ERR_MEMORY; 409599ebb4caSwyllys goto out; 409699ebb4caSwyllys } 409799ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 409899ebb4caSwyllys 4099*30a5e8faSwyllys if (keytype == KMF_DES) { 410099ebb4caSwyllys if ((ret = create_deskey(&deskey)) != KMF_OK) { 410199ebb4caSwyllys goto out; 410299ebb4caSwyllys } 410399ebb4caSwyllys rkey->keydata.val = (uchar_t *)deskey; 410499ebb4caSwyllys rkey->keydata.len = 8; 410599ebb4caSwyllys 410699ebb4caSwyllys symkey->keyalg = KMF_DES; 410799ebb4caSwyllys 4108*30a5e8faSwyllys } else if (keytype == KMF_DES3) { 410999ebb4caSwyllys if ((ret = create_des3key(&des3key)) != KMF_OK) { 411099ebb4caSwyllys goto out; 411199ebb4caSwyllys } 411299ebb4caSwyllys rkey->keydata.val = (uchar_t *)des3key; 411399ebb4caSwyllys rkey->keydata.len = DES3_KEY_SIZE; 411499ebb4caSwyllys symkey->keyalg = KMF_DES3; 41159b37d296Swyllys 4116*30a5e8faSwyllys } else if (keytype == KMF_AES || keytype == KMF_RC4 || 4117*30a5e8faSwyllys keytype == KMF_GENERIC_SECRET) { 411899ebb4caSwyllys int bytes; 411999ebb4caSwyllys 4120*30a5e8faSwyllys if (keylen % 8 != 0) { 412199ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 412299ebb4caSwyllys goto out; 412399ebb4caSwyllys } 412499ebb4caSwyllys 4125*30a5e8faSwyllys if (keytype == KMF_AES) { 4126*30a5e8faSwyllys if (keylen != 128 && 4127*30a5e8faSwyllys keylen != 192 && 4128*30a5e8faSwyllys keylen != 256) { 412999ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 413099ebb4caSwyllys goto out; 413199ebb4caSwyllys } 413299ebb4caSwyllys } 413399ebb4caSwyllys 4134*30a5e8faSwyllys bytes = keylen/8; 413599ebb4caSwyllys random = malloc(bytes); 413699ebb4caSwyllys if (random == NULL) { 413799ebb4caSwyllys ret = KMF_ERR_MEMORY; 413899ebb4caSwyllys goto out; 413999ebb4caSwyllys } 414099ebb4caSwyllys if (RAND_bytes(random, bytes) != 1) { 414199ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 414299ebb4caSwyllys goto out; 414399ebb4caSwyllys } 414499ebb4caSwyllys 414599ebb4caSwyllys rkey->keydata.val = (uchar_t *)random; 414699ebb4caSwyllys rkey->keydata.len = bytes; 4147*30a5e8faSwyllys symkey->keyalg = keytype; 414899ebb4caSwyllys 414999ebb4caSwyllys } else { 415099ebb4caSwyllys ret = KMF_ERR_BAD_KEY_TYPE; 415199ebb4caSwyllys goto out; 415299ebb4caSwyllys } 415399ebb4caSwyllys 415499ebb4caSwyllys (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len); 415599ebb4caSwyllys 415699ebb4caSwyllys symkey->kstype = KMF_KEYSTORE_OPENSSL; 415799ebb4caSwyllys symkey->keyclass = KMF_SYMMETRIC; 415899ebb4caSwyllys symkey->keylabel = (char *)fullpath; 415999ebb4caSwyllys symkey->israw = TRUE; 416099ebb4caSwyllys symkey->keyp = rkey; 416199ebb4caSwyllys 416299ebb4caSwyllys out: 416399ebb4caSwyllys if (fd != -1) 416499ebb4caSwyllys (void) close(fd); 416599ebb4caSwyllys 416699ebb4caSwyllys if (ret != KMF_OK && fullpath != NULL) { 416799ebb4caSwyllys free(fullpath); 416899ebb4caSwyllys } 416999ebb4caSwyllys if (ret != KMF_OK) { 4170*30a5e8faSwyllys kmf_free_raw_sym_key(rkey); 417199ebb4caSwyllys symkey->keyp = NULL; 417299ebb4caSwyllys symkey->keyalg = KMF_KEYALG_NONE; 417399ebb4caSwyllys } 417499ebb4caSwyllys 417599ebb4caSwyllys return (ret); 417699ebb4caSwyllys } 417799ebb4caSwyllys 417899ebb4caSwyllys /* 417999ebb4caSwyllys * Check a file to see if it is a CRL file with PEM or DER format. 418099ebb4caSwyllys * If success, return its format in the "pformat" argument. 418199ebb4caSwyllys */ 418299ebb4caSwyllys KMF_RETURN 418399ebb4caSwyllys OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat) 418499ebb4caSwyllys { 418599ebb4caSwyllys KMF_RETURN ret = KMF_OK; 418699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 418799ebb4caSwyllys BIO *bio = NULL; 418899ebb4caSwyllys X509_CRL *xcrl = NULL; 418999ebb4caSwyllys 419099ebb4caSwyllys if (filename == NULL) { 419199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 419299ebb4caSwyllys } 419399ebb4caSwyllys 419499ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 419599ebb4caSwyllys if (bio == NULL) { 419699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 419799ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 419899ebb4caSwyllys goto out; 419999ebb4caSwyllys } 420099ebb4caSwyllys 420199ebb4caSwyllys if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) { 420299ebb4caSwyllys *pformat = KMF_FORMAT_PEM; 420399ebb4caSwyllys goto out; 420499ebb4caSwyllys } 420599ebb4caSwyllys (void) BIO_free(bio); 420699ebb4caSwyllys 420799ebb4caSwyllys /* 420899ebb4caSwyllys * Now try to read it as raw DER data. 420999ebb4caSwyllys */ 421099ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 421199ebb4caSwyllys if (bio == NULL) { 421299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 421399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 421499ebb4caSwyllys goto out; 421599ebb4caSwyllys } 421699ebb4caSwyllys 421799ebb4caSwyllys if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) { 421899ebb4caSwyllys *pformat = KMF_FORMAT_ASN1; 421999ebb4caSwyllys } else { 422099ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 422199ebb4caSwyllys } 422299ebb4caSwyllys 422399ebb4caSwyllys out: 422499ebb4caSwyllys if (bio != NULL) 422599ebb4caSwyllys (void) BIO_free(bio); 422699ebb4caSwyllys 422799ebb4caSwyllys if (xcrl != NULL) 422899ebb4caSwyllys X509_CRL_free(xcrl); 422999ebb4caSwyllys 423099ebb4caSwyllys return (ret); 423199ebb4caSwyllys } 423299ebb4caSwyllys 423399ebb4caSwyllys /* 423499ebb4caSwyllys * Check a file to see if it is a certficate file with PEM or DER format. 423599ebb4caSwyllys * If success, return its format in the pformat argument. 423699ebb4caSwyllys */ 423799ebb4caSwyllys KMF_RETURN 423899ebb4caSwyllys OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, 423999ebb4caSwyllys KMF_ENCODE_FORMAT *pformat) 424099ebb4caSwyllys { 424199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 424299ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 424399ebb4caSwyllys BIO *bio = NULL; 424499ebb4caSwyllys X509 *xcert = NULL; 424599ebb4caSwyllys 424699ebb4caSwyllys if (filename == NULL) { 424799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 424899ebb4caSwyllys } 424999ebb4caSwyllys 4250*30a5e8faSwyllys ret = kmf_get_file_format(filename, pformat); 425199ebb4caSwyllys if (ret != KMF_OK) 425299ebb4caSwyllys return (ret); 425399ebb4caSwyllys 425499ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 425599ebb4caSwyllys if (bio == NULL) { 425699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 425799ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 425899ebb4caSwyllys goto out; 425999ebb4caSwyllys } 426099ebb4caSwyllys 426199ebb4caSwyllys if ((*pformat) == KMF_FORMAT_PEM) { 426299ebb4caSwyllys if ((xcert = PEM_read_bio_X509(bio, NULL, 426399ebb4caSwyllys NULL, NULL)) == NULL) { 426499ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 426599ebb4caSwyllys } 426699ebb4caSwyllys } else if ((*pformat) == KMF_FORMAT_ASN1) { 426799ebb4caSwyllys if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) { 426899ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 426999ebb4caSwyllys } 427099ebb4caSwyllys } else { 427199ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 427299ebb4caSwyllys } 427399ebb4caSwyllys 427499ebb4caSwyllys out: 427599ebb4caSwyllys if (bio != NULL) 427699ebb4caSwyllys (void) BIO_free(bio); 427799ebb4caSwyllys 427899ebb4caSwyllys if (xcert != NULL) 427999ebb4caSwyllys X509_free(xcert); 428099ebb4caSwyllys 428199ebb4caSwyllys return (ret); 428299ebb4caSwyllys } 428399ebb4caSwyllys 428499ebb4caSwyllys KMF_RETURN 428599ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 428699ebb4caSwyllys KMF_RAW_SYM_KEY *rkey) 428799ebb4caSwyllys { 428899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 428999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 429099ebb4caSwyllys KMF_DATA keyvalue; 429199ebb4caSwyllys 429299ebb4caSwyllys if (kmfh == NULL) 429399ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 429499ebb4caSwyllys 429599ebb4caSwyllys if (symkey == NULL || rkey == NULL) 429699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 429799ebb4caSwyllys else if (symkey->keyclass != KMF_SYMMETRIC) 429899ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 429999ebb4caSwyllys 430099ebb4caSwyllys if (symkey->israw) { 430199ebb4caSwyllys KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp; 430299ebb4caSwyllys 430399ebb4caSwyllys if (rawkey == NULL || 430499ebb4caSwyllys rawkey->keydata.val == NULL || 430599ebb4caSwyllys rawkey->keydata.len == 0) 430699ebb4caSwyllys return (KMF_ERR_BAD_KEYHANDLE); 430799ebb4caSwyllys 430899ebb4caSwyllys rkey->keydata.len = rawkey->keydata.len; 430999ebb4caSwyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 431099ebb4caSwyllys return (KMF_ERR_MEMORY); 431199ebb4caSwyllys (void) memcpy(rkey->keydata.val, rawkey->keydata.val, 431299ebb4caSwyllys rkey->keydata.len); 431399ebb4caSwyllys } else { 4314*30a5e8faSwyllys rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue); 431599ebb4caSwyllys if (rv != KMF_OK) 431699ebb4caSwyllys return (rv); 431799ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 431899ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 431999ebb4caSwyllys } 432099ebb4caSwyllys 432199ebb4caSwyllys return (rv); 432299ebb4caSwyllys } 432302744e81Swyllys 432402744e81Swyllys /* 432502744e81Swyllys * id-sha1 OBJECT IDENTIFIER ::= { 432602744e81Swyllys * iso(1) identified-organization(3) oiw(14) secsig(3) 432702744e81Swyllys * algorithms(2) 26 432802744e81Swyllys * } 432902744e81Swyllys */ 433002744e81Swyllys #define ASN1_SHA1_OID_PREFIX_LEN 15 433102744e81Swyllys static uchar_t SHA1_DER_PREFIX[ASN1_SHA1_OID_PREFIX_LEN] = { 433202744e81Swyllys 0x30, 0x21, 0x30, 0x09, 433302744e81Swyllys 0x06, 0x05, 0x2b, 0x0e, 433402744e81Swyllys 0x03, 0x02, 0x1a, 0x05, 433502744e81Swyllys 0x00, 0x04, 0x14 433602744e81Swyllys }; 433702744e81Swyllys 433802744e81Swyllys /* 433902744e81Swyllys * id-md2 OBJECT IDENTIFIER ::= { 434002744e81Swyllys * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 434102744e81Swyllys * } 434202744e81Swyllys */ 434302744e81Swyllys #define ASN1_MD2_OID_PREFIX_LEN 18 434402744e81Swyllys static uchar_t MD2_DER_PREFIX[ASN1_MD2_OID_PREFIX_LEN] = { 434502744e81Swyllys 0x30, 0x20, 0x30, 0x0c, 434602744e81Swyllys 0x06, 0x08, 0x2a, 0x86, 434702744e81Swyllys 0x48, 0x86, 0xf7, 0x0d, 434802744e81Swyllys 0x02, 0x02, 0x05, 0x00, 434902744e81Swyllys 0x04, 0x10 435002744e81Swyllys }; 435102744e81Swyllys 435202744e81Swyllys /* 435302744e81Swyllys * id-md5 OBJECT IDENTIFIER ::= { 435402744e81Swyllys * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 435502744e81Swyllys * } 435602744e81Swyllys */ 435702744e81Swyllys #define ASN1_MD5_OID_PREFIX_LEN 18 435802744e81Swyllys static uchar_t MD5_DER_PREFIX[ASN1_MD5_OID_PREFIX_LEN] = { 435902744e81Swyllys 0x30, 0x20, 0x30, 0x0c, 436002744e81Swyllys 0x06, 0x08, 0x2a, 0x86, 436102744e81Swyllys 0x48, 0x86, 0xf7, 0x0d, 436202744e81Swyllys 0x02, 0x05, 0x05, 0x00, 436302744e81Swyllys 0x04, 0x10 436402744e81Swyllys }; 436502744e81Swyllys 436602744e81Swyllys KMF_RETURN 436702744e81Swyllys OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle, 436802744e81Swyllys KMF_ALGORITHM_INDEX algid, KMF_DATA *indata, 436902744e81Swyllys KMF_DATA *insig, KMF_DATA *cert) 437002744e81Swyllys { 437102744e81Swyllys KMF_RETURN ret = KMF_OK; 437202744e81Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 437302744e81Swyllys X509 *xcert = NULL; 437402744e81Swyllys EVP_PKEY *pkey = NULL; 437502744e81Swyllys uchar_t *p; 437602744e81Swyllys uchar_t *rsaout = NULL; 437702744e81Swyllys uchar_t *pfx = NULL; 437802744e81Swyllys const EVP_MD *md; 437902744e81Swyllys int pfxlen = 0, len; 438002744e81Swyllys 438102744e81Swyllys if (handle == NULL || indata == NULL || 438202744e81Swyllys indata->Data == NULL || indata->Length == 0 || 438302744e81Swyllys insig == NULL|| insig->Data == NULL || insig->Length == 0 || 438402744e81Swyllys cert == NULL || cert->Data == NULL || cert->Length == 0) 438502744e81Swyllys return (KMF_ERR_BAD_PARAMETER); 438602744e81Swyllys 438702744e81Swyllys p = cert->Data; 438802744e81Swyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, cert->Length); 438902744e81Swyllys if (xcert == NULL) { 439002744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 439102744e81Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 439202744e81Swyllys goto cleanup; 439302744e81Swyllys } 439402744e81Swyllys 439502744e81Swyllys pkey = X509_get_pubkey(xcert); 4396*30a5e8faSwyllys if (pkey == NULL) { 439702744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 439802744e81Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 439902744e81Swyllys goto cleanup; 440002744e81Swyllys } 440102744e81Swyllys 440202744e81Swyllys if (algid != KMF_ALGID_NONE) { 440302744e81Swyllys switch (algid) { 440402744e81Swyllys case KMF_ALGID_MD5WithRSA: 440502744e81Swyllys md = EVP_md5(); 440602744e81Swyllys break; 440702744e81Swyllys case KMF_ALGID_MD2WithRSA: 440802744e81Swyllys md = EVP_md2(); 440902744e81Swyllys break; 441002744e81Swyllys case KMF_ALGID_SHA1WithRSA: 441102744e81Swyllys md = EVP_sha1(); 441202744e81Swyllys break; 441302744e81Swyllys case KMF_ALGID_RSA: 441402744e81Swyllys md = NULL; 441502744e81Swyllys break; 441602744e81Swyllys default: 441702744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 441802744e81Swyllys goto cleanup; 441902744e81Swyllys } 442002744e81Swyllys } else { 442102744e81Swyllys /* Get the hash type from the cert signature */ 442202744e81Swyllys md = EVP_get_digestbyobj(xcert->sig_alg->algorithm); 442302744e81Swyllys if (md == NULL) { 442402744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 442502744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 442602744e81Swyllys goto cleanup; 442702744e81Swyllys } 442802744e81Swyllys } 44299b37d296Swyllys if (md != NULL) { 443002744e81Swyllys switch (EVP_MD_type(md)) { 443102744e81Swyllys case NID_md2: 443202744e81Swyllys case NID_md2WithRSAEncryption: 443302744e81Swyllys pfxlen = ASN1_MD2_OID_PREFIX_LEN; 443402744e81Swyllys pfx = MD2_DER_PREFIX; 443502744e81Swyllys break; 443602744e81Swyllys case NID_md5: 443702744e81Swyllys case NID_md5WithRSAEncryption: 443802744e81Swyllys pfxlen = ASN1_MD5_OID_PREFIX_LEN; 443902744e81Swyllys pfx = MD5_DER_PREFIX; 444002744e81Swyllys break; 444102744e81Swyllys case NID_sha1: 444202744e81Swyllys case NID_sha1WithRSAEncryption: 444302744e81Swyllys pfxlen = ASN1_SHA1_OID_PREFIX_LEN; 444402744e81Swyllys pfx = SHA1_DER_PREFIX; 444502744e81Swyllys break; 444602744e81Swyllys default: /* Unsupported */ 444702744e81Swyllys pfxlen = 0; 444802744e81Swyllys pfx = NULL; 444902744e81Swyllys break; 445002744e81Swyllys } 44519b37d296Swyllys } 445202744e81Swyllys 445302744e81Swyllys /* RSA with no hash is a special case */ 445402744e81Swyllys rsaout = malloc(RSA_size(pkey->pkey.rsa)); 445502744e81Swyllys if (rsaout == NULL) 445602744e81Swyllys return (KMF_ERR_MEMORY); 445702744e81Swyllys 445802744e81Swyllys /* Decrypt the input signature */ 445902744e81Swyllys len = RSA_public_decrypt(insig->Length, 446002744e81Swyllys insig->Data, rsaout, pkey->pkey.rsa, RSA_PKCS1_PADDING); 446102744e81Swyllys if (len < 1) { 446202744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 446302744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 446402744e81Swyllys } else { 446502744e81Swyllys size_t hashlen = 0; 446602744e81Swyllys uint32_t dlen; 446702744e81Swyllys char *digest = NULL; 446802744e81Swyllys 446902744e81Swyllys /* 447002744e81Swyllys * If the AlgId requires it, hash the input data before 447102744e81Swyllys * comparing it to the decrypted signature. 447202744e81Swyllys */ 447302744e81Swyllys if (md) { 447402744e81Swyllys EVP_MD_CTX ctx; 447502744e81Swyllys 447602744e81Swyllys hashlen = md->md_size; 447702744e81Swyllys 447802744e81Swyllys digest = malloc(hashlen + pfxlen); 447902744e81Swyllys if (digest == NULL) 448002744e81Swyllys return (KMF_ERR_MEMORY); 448102744e81Swyllys /* Add the prefix to the comparison buffer. */ 448202744e81Swyllys if (pfx && pfxlen > 0) { 448302744e81Swyllys (void) memcpy(digest, pfx, pfxlen); 448402744e81Swyllys } 448502744e81Swyllys (void) EVP_DigestInit(&ctx, md); 448602744e81Swyllys (void) EVP_DigestUpdate(&ctx, indata->Data, 448702744e81Swyllys indata->Length); 448802744e81Swyllys 448902744e81Swyllys /* Add the digest AFTER the ASN1 prefix */ 449002744e81Swyllys (void) EVP_DigestFinal(&ctx, 449102744e81Swyllys (uchar_t *)digest + pfxlen, &dlen); 449202744e81Swyllys 449302744e81Swyllys dlen += pfxlen; 449402744e81Swyllys } else { 449502744e81Swyllys digest = (char *)indata->Data; 449602744e81Swyllys dlen = indata->Length; 449702744e81Swyllys } 449802744e81Swyllys 449902744e81Swyllys /* 450002744e81Swyllys * The result of the RSA decryption should be ASN1(OID | Hash). 450102744e81Swyllys * Compare the output hash to the input data for the final 450202744e81Swyllys * result. 450302744e81Swyllys */ 450402744e81Swyllys if (memcmp(rsaout, digest, dlen)) 450502744e81Swyllys ret = KMF_ERR_INTERNAL; 450602744e81Swyllys else 450702744e81Swyllys ret = KMF_OK; 450802744e81Swyllys 450902744e81Swyllys /* If we had to allocate space for the digest, free it now */ 451002744e81Swyllys if (hashlen) 451102744e81Swyllys free(digest); 451202744e81Swyllys } 451302744e81Swyllys cleanup: 451402744e81Swyllys if (pkey) 451502744e81Swyllys EVP_PKEY_free(pkey); 451602744e81Swyllys 451702744e81Swyllys if (xcert) 451802744e81Swyllys X509_free(xcert); 451902744e81Swyllys 452002744e81Swyllys if (rsaout) 452102744e81Swyllys free(rsaout); 452202744e81Swyllys 452302744e81Swyllys return (ret); 452402744e81Swyllys } 4525*30a5e8faSwyllys 4526*30a5e8faSwyllys /* 4527*30a5e8faSwyllys * substitute for the unsafe access(2) function. 4528*30a5e8faSwyllys * If the file in question already exists, return 1. 4529*30a5e8faSwyllys * else 0. If an error occurs during testing (other 4530*30a5e8faSwyllys * than EEXIST), return -1. 4531*30a5e8faSwyllys */ 4532*30a5e8faSwyllys static int 4533*30a5e8faSwyllys test_for_file(char *filename, mode_t mode) 4534*30a5e8faSwyllys { 4535*30a5e8faSwyllys int fd; 4536*30a5e8faSwyllys 4537*30a5e8faSwyllys /* 4538*30a5e8faSwyllys * Try to create the file with the EXCL flag. 4539*30a5e8faSwyllys * The call should fail if the file exists. 4540*30a5e8faSwyllys */ 4541*30a5e8faSwyllys fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode); 4542*30a5e8faSwyllys if (fd == -1 && errno == EEXIST) 4543*30a5e8faSwyllys return (1); 4544*30a5e8faSwyllys else if (fd == -1) /* some other error */ 4545*30a5e8faSwyllys return (-1); 4546*30a5e8faSwyllys 4547*30a5e8faSwyllys /* The file did NOT exist. Delete the testcase. */ 4548*30a5e8faSwyllys (void) close(fd); 4549*30a5e8faSwyllys (void) unlink(filename); 4550*30a5e8faSwyllys return (0); 4551*30a5e8faSwyllys } 4552*30a5e8faSwyllys 4553*30a5e8faSwyllys KMF_RETURN 4554*30a5e8faSwyllys OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr, 4555*30a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 4556*30a5e8faSwyllys { 4557*30a5e8faSwyllys KMF_RETURN rv = KMF_OK; 4558*30a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4559*30a5e8faSwyllys KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL; 4560*30a5e8faSwyllys KMF_RAW_KEY_DATA *rawkey; 4561*30a5e8faSwyllys EVP_PKEY *pkey = NULL; 4562*30a5e8faSwyllys KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM; 4563*30a5e8faSwyllys KMF_CREDENTIAL cred = {NULL, 0}; 4564*30a5e8faSwyllys BIO *out = NULL; 4565*30a5e8faSwyllys int keys = 0; 4566*30a5e8faSwyllys char *fullpath = NULL; 4567*30a5e8faSwyllys char *keyfile = NULL; 4568*30a5e8faSwyllys char *dirpath = NULL; 4569*30a5e8faSwyllys 4570*30a5e8faSwyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); 4571*30a5e8faSwyllys if (pubkey != NULL) 4572*30a5e8faSwyllys keys++; 4573*30a5e8faSwyllys 4574*30a5e8faSwyllys prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); 4575*30a5e8faSwyllys if (prikey != NULL) 4576*30a5e8faSwyllys keys++; 4577*30a5e8faSwyllys 4578*30a5e8faSwyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); 4579*30a5e8faSwyllys if (rawkey != NULL) 4580*30a5e8faSwyllys keys++; 4581*30a5e8faSwyllys 4582*30a5e8faSwyllys /* 4583*30a5e8faSwyllys * Exactly 1 type of key must be passed to this function. 4584*30a5e8faSwyllys */ 4585*30a5e8faSwyllys if (keys != 1) 4586*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 4587*30a5e8faSwyllys 4588*30a5e8faSwyllys keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, 4589*30a5e8faSwyllys numattr); 4590*30a5e8faSwyllys if (keyfile == NULL) 4591*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 4592*30a5e8faSwyllys 4593*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 4594*30a5e8faSwyllys 4595*30a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 4596*30a5e8faSwyllys 4597*30a5e8faSwyllys /* Once we have the full path, we don't need the pieces */ 4598*30a5e8faSwyllys if (fullpath == NULL) 4599*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 4600*30a5e8faSwyllys 4601*30a5e8faSwyllys /* If the requested file exists, return an error */ 4602*30a5e8faSwyllys if (test_for_file(fullpath, 0400) == 1) { 4603*30a5e8faSwyllys free(fullpath); 4604*30a5e8faSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 4605*30a5e8faSwyllys } 4606*30a5e8faSwyllys 4607*30a5e8faSwyllys rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 4608*30a5e8faSwyllys &format, NULL); 4609*30a5e8faSwyllys if (rv != KMF_OK) 4610*30a5e8faSwyllys /* format is optional. */ 4611*30a5e8faSwyllys rv = KMF_OK; 4612*30a5e8faSwyllys 4613*30a5e8faSwyllys /* CRED is not required for OpenSSL files */ 4614*30a5e8faSwyllys (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, 4615*30a5e8faSwyllys &cred, NULL); 4616*30a5e8faSwyllys 4617*30a5e8faSwyllys /* Store the private key to the keyfile */ 4618*30a5e8faSwyllys out = BIO_new_file(fullpath, "wb"); 4619*30a5e8faSwyllys if (out == NULL) { 4620*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4621*30a5e8faSwyllys rv = KMF_ERR_OPEN_FILE; 4622*30a5e8faSwyllys goto end; 4623*30a5e8faSwyllys } 4624*30a5e8faSwyllys 4625*30a5e8faSwyllys if (prikey != NULL && prikey->keyp != NULL) { 4626*30a5e8faSwyllys if (prikey->keyalg == KMF_RSA || 4627*30a5e8faSwyllys prikey->keyalg == KMF_DSA) { 4628*30a5e8faSwyllys pkey = (EVP_PKEY *)prikey->keyp; 4629*30a5e8faSwyllys 4630*30a5e8faSwyllys rv = ssl_write_key(kmfh, format, 4631*30a5e8faSwyllys out, &cred, pkey, TRUE); 4632*30a5e8faSwyllys 4633*30a5e8faSwyllys if (rv == KMF_OK && prikey->keylabel == NULL) { 4634*30a5e8faSwyllys prikey->keylabel = strdup(fullpath); 4635*30a5e8faSwyllys if (prikey->keylabel == NULL) 4636*30a5e8faSwyllys rv = KMF_ERR_MEMORY; 4637*30a5e8faSwyllys } 4638*30a5e8faSwyllys } 4639*30a5e8faSwyllys } else if (pubkey != NULL && pubkey->keyp != NULL) { 4640*30a5e8faSwyllys if (pubkey->keyalg == KMF_RSA || 4641*30a5e8faSwyllys pubkey->keyalg == KMF_DSA) { 4642*30a5e8faSwyllys pkey = (EVP_PKEY *)pubkey->keyp; 4643*30a5e8faSwyllys 4644*30a5e8faSwyllys rv = ssl_write_key(kmfh, format, 4645*30a5e8faSwyllys out, &cred, pkey, FALSE); 4646*30a5e8faSwyllys 4647*30a5e8faSwyllys if (rv == KMF_OK && pubkey->keylabel == NULL) { 4648*30a5e8faSwyllys pubkey->keylabel = strdup(fullpath); 4649*30a5e8faSwyllys if (pubkey->keylabel == NULL) 4650*30a5e8faSwyllys rv = KMF_ERR_MEMORY; 4651*30a5e8faSwyllys } 4652*30a5e8faSwyllys } 4653*30a5e8faSwyllys } else if (rawkey != NULL) { 4654*30a5e8faSwyllys /* RAW keys are always private */ 4655*30a5e8faSwyllys if (rawkey->keytype == KMF_RSA) { 4656*30a5e8faSwyllys pkey = ImportRawRSAKey(&rawkey->rawdata.rsa); 4657*30a5e8faSwyllys } else if (rawkey->keytype == KMF_DSA) { 4658*30a5e8faSwyllys pkey = ImportRawDSAKey(&rawkey->rawdata.dsa); 4659*30a5e8faSwyllys } else { 4660*30a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 4661*30a5e8faSwyllys } 4662*30a5e8faSwyllys rv = ssl_write_key(kmfh, format, out, &cred, pkey, TRUE); 4663*30a5e8faSwyllys } 4664*30a5e8faSwyllys 4665*30a5e8faSwyllys end: 4666*30a5e8faSwyllys 4667*30a5e8faSwyllys if (out) 4668*30a5e8faSwyllys (void) BIO_free(out); 4669*30a5e8faSwyllys 4670*30a5e8faSwyllys if (rv == KMF_OK) 4671*30a5e8faSwyllys (void) chmod(fullpath, 0400); 4672*30a5e8faSwyllys 4673*30a5e8faSwyllys free(fullpath); 4674*30a5e8faSwyllys return (rv); 4675*30a5e8faSwyllys } 4676*30a5e8faSwyllys 4677*30a5e8faSwyllys KMF_RETURN 4678*30a5e8faSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 4679*30a5e8faSwyllys { 4680*30a5e8faSwyllys KMF_RETURN ret = KMF_OK; 4681*30a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4682*30a5e8faSwyllys X509_CRL *xcrl = NULL; 4683*30a5e8faSwyllys X509 *xcert = NULL; 4684*30a5e8faSwyllys EVP_PKEY *pkey; 4685*30a5e8faSwyllys KMF_ENCODE_FORMAT format; 4686*30a5e8faSwyllys BIO *in = NULL, *out = NULL; 4687*30a5e8faSwyllys int openssl_ret = 0; 4688*30a5e8faSwyllys KMF_ENCODE_FORMAT outformat; 4689*30a5e8faSwyllys boolean_t crlcheck = FALSE; 4690*30a5e8faSwyllys char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile; 4691*30a5e8faSwyllys 4692*30a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 4693*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 4694*30a5e8faSwyllys } 4695*30a5e8faSwyllys 4696*30a5e8faSwyllys /* CRL check is optional */ 4697*30a5e8faSwyllys (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr, 4698*30a5e8faSwyllys &crlcheck, NULL); 4699*30a5e8faSwyllys 4700*30a5e8faSwyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 4701*30a5e8faSwyllys if (crlcheck == B_TRUE && certfile == NULL) { 4702*30a5e8faSwyllys return (KMF_ERR_BAD_CERTFILE); 4703*30a5e8faSwyllys } 4704*30a5e8faSwyllys 4705*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 4706*30a5e8faSwyllys incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr); 4707*30a5e8faSwyllys outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr); 4708*30a5e8faSwyllys 4709*30a5e8faSwyllys crlfile = get_fullpath(dirpath, incrl); 4710*30a5e8faSwyllys 4711*30a5e8faSwyllys if (crlfile == NULL) 4712*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 4713*30a5e8faSwyllys 4714*30a5e8faSwyllys outcrlfile = get_fullpath(dirpath, outcrl); 4715*30a5e8faSwyllys if (outcrlfile == NULL) 4716*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 4717*30a5e8faSwyllys 4718*30a5e8faSwyllys if (isdir(outcrlfile)) { 4719*30a5e8faSwyllys free(outcrlfile); 4720*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 4721*30a5e8faSwyllys } 4722*30a5e8faSwyllys 4723*30a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 4724*30a5e8faSwyllys if (ret != KMF_OK) { 4725*30a5e8faSwyllys free(outcrlfile); 4726*30a5e8faSwyllys return (ret); 4727*30a5e8faSwyllys } 4728*30a5e8faSwyllys 4729*30a5e8faSwyllys in = BIO_new_file(crlfile, "rb"); 4730*30a5e8faSwyllys if (in == NULL) { 4731*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4732*30a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 4733*30a5e8faSwyllys goto end; 4734*30a5e8faSwyllys } 4735*30a5e8faSwyllys 4736*30a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 4737*30a5e8faSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 4738*30a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 4739*30a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 4740*30a5e8faSwyllys } 4741*30a5e8faSwyllys 4742*30a5e8faSwyllys if (xcrl == NULL) { 4743*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4744*30a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 4745*30a5e8faSwyllys goto end; 4746*30a5e8faSwyllys } 4747*30a5e8faSwyllys 4748*30a5e8faSwyllys /* If bypasscheck is specified, no need to verify. */ 4749*30a5e8faSwyllys if (crlcheck == B_FALSE) 4750*30a5e8faSwyllys goto output; 4751*30a5e8faSwyllys 4752*30a5e8faSwyllys ret = kmf_is_cert_file(handle, certfile, &format); 4753*30a5e8faSwyllys if (ret != KMF_OK) 4754*30a5e8faSwyllys goto end; 4755*30a5e8faSwyllys 4756*30a5e8faSwyllys /* Read in the CA cert file and convert to X509 */ 4757*30a5e8faSwyllys if (BIO_read_filename(in, certfile) <= 0) { 4758*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4759*30a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 4760*30a5e8faSwyllys goto end; 4761*30a5e8faSwyllys } 4762*30a5e8faSwyllys 4763*30a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 4764*30a5e8faSwyllys xcert = d2i_X509_bio(in, NULL); 4765*30a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 4766*30a5e8faSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 4767*30a5e8faSwyllys } else { 4768*30a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 4769*30a5e8faSwyllys goto end; 4770*30a5e8faSwyllys } 4771*30a5e8faSwyllys 4772*30a5e8faSwyllys if (xcert == NULL) { 4773*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4774*30a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 4775*30a5e8faSwyllys goto end; 4776*30a5e8faSwyllys } 4777*30a5e8faSwyllys /* Now get the public key from the CA cert */ 4778*30a5e8faSwyllys pkey = X509_get_pubkey(xcert); 4779*30a5e8faSwyllys if (pkey == NULL) { 4780*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4781*30a5e8faSwyllys ret = KMF_ERR_BAD_CERTFILE; 4782*30a5e8faSwyllys goto end; 4783*30a5e8faSwyllys } 4784*30a5e8faSwyllys 4785*30a5e8faSwyllys /* Verify the CRL with the CA's public key */ 4786*30a5e8faSwyllys openssl_ret = X509_CRL_verify(xcrl, pkey); 4787*30a5e8faSwyllys EVP_PKEY_free(pkey); 4788*30a5e8faSwyllys if (openssl_ret > 0) { 4789*30a5e8faSwyllys ret = KMF_OK; /* verify succeed */ 4790*30a5e8faSwyllys } else { 4791*30a5e8faSwyllys SET_ERROR(kmfh, openssl_ret); 4792*30a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 4793*30a5e8faSwyllys } 4794*30a5e8faSwyllys 4795*30a5e8faSwyllys output: 4796*30a5e8faSwyllys ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 4797*30a5e8faSwyllys &outformat, NULL); 4798*30a5e8faSwyllys if (ret != KMF_OK) { 4799*30a5e8faSwyllys ret = KMF_OK; 4800*30a5e8faSwyllys outformat = KMF_FORMAT_PEM; 4801*30a5e8faSwyllys } 4802*30a5e8faSwyllys 4803*30a5e8faSwyllys out = BIO_new_file(outcrlfile, "wb"); 4804*30a5e8faSwyllys if (out == NULL) { 4805*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4806*30a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 4807*30a5e8faSwyllys goto end; 4808*30a5e8faSwyllys } 4809*30a5e8faSwyllys 4810*30a5e8faSwyllys if (outformat == KMF_FORMAT_ASN1) { 4811*30a5e8faSwyllys openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); 4812*30a5e8faSwyllys } else if (outformat == KMF_FORMAT_PEM) { 4813*30a5e8faSwyllys openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); 4814*30a5e8faSwyllys } else { 4815*30a5e8faSwyllys ret = KMF_ERR_BAD_PARAMETER; 4816*30a5e8faSwyllys goto end; 4817*30a5e8faSwyllys } 4818*30a5e8faSwyllys 4819*30a5e8faSwyllys if (openssl_ret <= 0) { 4820*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4821*30a5e8faSwyllys ret = KMF_ERR_WRITE_FILE; 4822*30a5e8faSwyllys } else { 4823*30a5e8faSwyllys ret = KMF_OK; 4824*30a5e8faSwyllys } 4825*30a5e8faSwyllys 4826*30a5e8faSwyllys end: 4827*30a5e8faSwyllys if (xcrl != NULL) 4828*30a5e8faSwyllys X509_CRL_free(xcrl); 4829*30a5e8faSwyllys 4830*30a5e8faSwyllys if (xcert != NULL) 4831*30a5e8faSwyllys X509_free(xcert); 4832*30a5e8faSwyllys 4833*30a5e8faSwyllys if (in != NULL) 4834*30a5e8faSwyllys (void) BIO_free(in); 4835*30a5e8faSwyllys 4836*30a5e8faSwyllys if (out != NULL) 4837*30a5e8faSwyllys (void) BIO_free(out); 4838*30a5e8faSwyllys 4839*30a5e8faSwyllys if (outcrlfile != NULL) 4840*30a5e8faSwyllys free(outcrlfile); 4841*30a5e8faSwyllys 4842*30a5e8faSwyllys return (ret); 4843*30a5e8faSwyllys } 4844*30a5e8faSwyllys 4845*30a5e8faSwyllys KMF_RETURN 4846*30a5e8faSwyllys OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 4847*30a5e8faSwyllys { 4848*30a5e8faSwyllys KMF_RETURN ret = KMF_OK; 4849*30a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4850*30a5e8faSwyllys X509_CRL *x = NULL; 4851*30a5e8faSwyllys KMF_ENCODE_FORMAT format; 4852*30a5e8faSwyllys char *crlfile = NULL; 4853*30a5e8faSwyllys BIO *in = NULL; 4854*30a5e8faSwyllys BIO *mem = NULL; 4855*30a5e8faSwyllys long len; 4856*30a5e8faSwyllys char *memptr; 4857*30a5e8faSwyllys char *data = NULL; 4858*30a5e8faSwyllys char **crldata; 4859*30a5e8faSwyllys char *crlfilename, *dirpath; 4860*30a5e8faSwyllys 4861*30a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 4862*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 4863*30a5e8faSwyllys } 4864*30a5e8faSwyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 4865*30a5e8faSwyllys attrlist, numattr); 4866*30a5e8faSwyllys if (crlfilename == NULL) 4867*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 4868*30a5e8faSwyllys 4869*30a5e8faSwyllys crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR, 4870*30a5e8faSwyllys attrlist, numattr); 4871*30a5e8faSwyllys 4872*30a5e8faSwyllys if (crldata == NULL) 4873*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 4874*30a5e8faSwyllys 4875*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 4876*30a5e8faSwyllys 4877*30a5e8faSwyllys crlfile = get_fullpath(dirpath, crlfilename); 4878*30a5e8faSwyllys 4879*30a5e8faSwyllys if (crlfile == NULL) 4880*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 4881*30a5e8faSwyllys 4882*30a5e8faSwyllys if (isdir(crlfile)) { 4883*30a5e8faSwyllys free(crlfile); 4884*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 4885*30a5e8faSwyllys } 4886*30a5e8faSwyllys 4887*30a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 4888*30a5e8faSwyllys if (ret != KMF_OK) { 4889*30a5e8faSwyllys free(crlfile); 4890*30a5e8faSwyllys return (ret); 4891*30a5e8faSwyllys } 4892*30a5e8faSwyllys 4893*30a5e8faSwyllys if (bio_err == NULL) 4894*30a5e8faSwyllys bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 4895*30a5e8faSwyllys 4896*30a5e8faSwyllys in = BIO_new_file(crlfile, "rb"); 4897*30a5e8faSwyllys if (in == NULL) { 4898*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4899*30a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 4900*30a5e8faSwyllys goto end; 4901*30a5e8faSwyllys } 4902*30a5e8faSwyllys 4903*30a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 4904*30a5e8faSwyllys x = d2i_X509_CRL_bio(in, NULL); 4905*30a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 4906*30a5e8faSwyllys x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 4907*30a5e8faSwyllys } 4908*30a5e8faSwyllys 4909*30a5e8faSwyllys if (x == NULL) { /* should not happen */ 4910*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4911*30a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 4912*30a5e8faSwyllys goto end; 4913*30a5e8faSwyllys } 4914*30a5e8faSwyllys 4915*30a5e8faSwyllys mem = BIO_new(BIO_s_mem()); 4916*30a5e8faSwyllys if (mem == NULL) { 4917*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4918*30a5e8faSwyllys ret = KMF_ERR_MEMORY; 4919*30a5e8faSwyllys goto end; 4920*30a5e8faSwyllys } 4921*30a5e8faSwyllys 4922*30a5e8faSwyllys (void) X509_CRL_print(mem, x); 4923*30a5e8faSwyllys len = BIO_get_mem_data(mem, &memptr); 4924*30a5e8faSwyllys if (len <= 0) { 4925*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 4926*30a5e8faSwyllys ret = KMF_ERR_MEMORY; 4927*30a5e8faSwyllys goto end; 4928*30a5e8faSwyllys } 4929*30a5e8faSwyllys 4930*30a5e8faSwyllys data = malloc(len + 1); 4931*30a5e8faSwyllys if (data == NULL) { 4932*30a5e8faSwyllys ret = KMF_ERR_MEMORY; 4933*30a5e8faSwyllys goto end; 4934*30a5e8faSwyllys } 4935*30a5e8faSwyllys 4936*30a5e8faSwyllys (void) memcpy(data, memptr, len); 4937*30a5e8faSwyllys data[len] = '\0'; 4938*30a5e8faSwyllys *crldata = data; 4939*30a5e8faSwyllys 4940*30a5e8faSwyllys end: 4941*30a5e8faSwyllys if (x != NULL) 4942*30a5e8faSwyllys X509_CRL_free(x); 4943*30a5e8faSwyllys 4944*30a5e8faSwyllys if (crlfile != NULL) 4945*30a5e8faSwyllys free(crlfile); 4946*30a5e8faSwyllys 4947*30a5e8faSwyllys if (in != NULL) 4948*30a5e8faSwyllys (void) BIO_free(in); 4949*30a5e8faSwyllys 4950*30a5e8faSwyllys if (mem != NULL) 4951*30a5e8faSwyllys (void) BIO_free(mem); 4952*30a5e8faSwyllys 4953*30a5e8faSwyllys return (ret); 4954*30a5e8faSwyllys } 4955*30a5e8faSwyllys 4956*30a5e8faSwyllys KMF_RETURN 4957*30a5e8faSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 4958*30a5e8faSwyllys { 4959*30a5e8faSwyllys KMF_RETURN ret = KMF_OK; 4960*30a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4961*30a5e8faSwyllys KMF_ENCODE_FORMAT format; 4962*30a5e8faSwyllys char *crlfile = NULL; 4963*30a5e8faSwyllys BIO *in = NULL; 4964*30a5e8faSwyllys char *crlfilename, *dirpath; 4965*30a5e8faSwyllys 4966*30a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 4967*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 4968*30a5e8faSwyllys } 4969*30a5e8faSwyllys 4970*30a5e8faSwyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 4971*30a5e8faSwyllys attrlist, numattr); 4972*30a5e8faSwyllys 4973*30a5e8faSwyllys if (crlfilename == NULL) 4974*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 4975*30a5e8faSwyllys 4976*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 4977*30a5e8faSwyllys 4978*30a5e8faSwyllys crlfile = get_fullpath(dirpath, crlfilename); 4979*30a5e8faSwyllys 4980*30a5e8faSwyllys if (crlfile == NULL) 4981*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 4982*30a5e8faSwyllys 4983*30a5e8faSwyllys if (isdir(crlfile)) { 4984*30a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 4985*30a5e8faSwyllys goto end; 4986*30a5e8faSwyllys } 4987*30a5e8faSwyllys 4988*30a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 4989*30a5e8faSwyllys if (ret != KMF_OK) 4990*30a5e8faSwyllys goto end; 4991*30a5e8faSwyllys 4992*30a5e8faSwyllys if (unlink(crlfile) != 0) { 4993*30a5e8faSwyllys SET_SYS_ERROR(kmfh, errno); 4994*30a5e8faSwyllys ret = KMF_ERR_INTERNAL; 4995*30a5e8faSwyllys goto end; 4996*30a5e8faSwyllys } 4997*30a5e8faSwyllys 4998*30a5e8faSwyllys end: 4999*30a5e8faSwyllys if (in != NULL) 5000*30a5e8faSwyllys (void) BIO_free(in); 5001*30a5e8faSwyllys if (crlfile != NULL) 5002*30a5e8faSwyllys free(crlfile); 5003*30a5e8faSwyllys 5004*30a5e8faSwyllys return (ret); 5005*30a5e8faSwyllys } 5006*30a5e8faSwyllys 5007*30a5e8faSwyllys KMF_RETURN 5008*30a5e8faSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 5009*30a5e8faSwyllys { 5010*30a5e8faSwyllys KMF_RETURN ret = KMF_OK; 5011*30a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 5012*30a5e8faSwyllys KMF_ENCODE_FORMAT format; 5013*30a5e8faSwyllys BIO *in = NULL; 5014*30a5e8faSwyllys X509 *xcert = NULL; 5015*30a5e8faSwyllys X509_CRL *xcrl = NULL; 5016*30a5e8faSwyllys STACK_OF(X509_REVOKED) *revoke_stack = NULL; 5017*30a5e8faSwyllys X509_REVOKED *revoke; 5018*30a5e8faSwyllys int i; 5019*30a5e8faSwyllys char *crlfilename, *crlfile, *dirpath, *certfile; 5020*30a5e8faSwyllys 5021*30a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 5022*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 5023*30a5e8faSwyllys } 5024*30a5e8faSwyllys 5025*30a5e8faSwyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 5026*30a5e8faSwyllys attrlist, numattr); 5027*30a5e8faSwyllys 5028*30a5e8faSwyllys if (crlfilename == NULL) 5029*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 5030*30a5e8faSwyllys 5031*30a5e8faSwyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 5032*30a5e8faSwyllys if (certfile == NULL) 5033*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 5034*30a5e8faSwyllys 5035*30a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 5036*30a5e8faSwyllys 5037*30a5e8faSwyllys crlfile = get_fullpath(dirpath, crlfilename); 5038*30a5e8faSwyllys 5039*30a5e8faSwyllys if (crlfile == NULL) 5040*30a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 5041*30a5e8faSwyllys 5042*30a5e8faSwyllys if (isdir(crlfile)) { 5043*30a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 5044*30a5e8faSwyllys goto end; 5045*30a5e8faSwyllys } 5046*30a5e8faSwyllys 5047*30a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 5048*30a5e8faSwyllys if (ret != KMF_OK) 5049*30a5e8faSwyllys goto end; 5050*30a5e8faSwyllys 5051*30a5e8faSwyllys /* Read the CRL file and load it into a X509_CRL structure */ 5052*30a5e8faSwyllys in = BIO_new_file(crlfilename, "rb"); 5053*30a5e8faSwyllys if (in == NULL) { 5054*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5055*30a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 5056*30a5e8faSwyllys goto end; 5057*30a5e8faSwyllys } 5058*30a5e8faSwyllys 5059*30a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 5060*30a5e8faSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 5061*30a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 5062*30a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 5063*30a5e8faSwyllys } 5064*30a5e8faSwyllys 5065*30a5e8faSwyllys if (xcrl == NULL) { 5066*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5067*30a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 5068*30a5e8faSwyllys goto end; 5069*30a5e8faSwyllys } 5070*30a5e8faSwyllys (void) BIO_free(in); 5071*30a5e8faSwyllys 5072*30a5e8faSwyllys /* Read the Certificate file and load it into a X509 structure */ 5073*30a5e8faSwyllys ret = kmf_is_cert_file(handle, certfile, &format); 5074*30a5e8faSwyllys if (ret != KMF_OK) 5075*30a5e8faSwyllys goto end; 5076*30a5e8faSwyllys 5077*30a5e8faSwyllys in = BIO_new_file(certfile, "rb"); 5078*30a5e8faSwyllys if (in == NULL) { 5079*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5080*30a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 5081*30a5e8faSwyllys goto end; 5082*30a5e8faSwyllys } 5083*30a5e8faSwyllys 5084*30a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 5085*30a5e8faSwyllys xcert = d2i_X509_bio(in, NULL); 5086*30a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 5087*30a5e8faSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 5088*30a5e8faSwyllys } 5089*30a5e8faSwyllys 5090*30a5e8faSwyllys if (xcert == NULL) { 5091*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5092*30a5e8faSwyllys ret = KMF_ERR_BAD_CERTFILE; 5093*30a5e8faSwyllys goto end; 5094*30a5e8faSwyllys } 5095*30a5e8faSwyllys 5096*30a5e8faSwyllys /* Check if the certificate and the CRL have same issuer */ 5097*30a5e8faSwyllys if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { 5098*30a5e8faSwyllys ret = KMF_ERR_ISSUER; 5099*30a5e8faSwyllys goto end; 5100*30a5e8faSwyllys } 5101*30a5e8faSwyllys 5102*30a5e8faSwyllys /* Check to see if the certificate serial number is revoked */ 5103*30a5e8faSwyllys revoke_stack = X509_CRL_get_REVOKED(xcrl); 5104*30a5e8faSwyllys if (sk_X509_REVOKED_num(revoke_stack) <= 0) { 5105*30a5e8faSwyllys /* No revoked certificates in the CRL file */ 5106*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5107*30a5e8faSwyllys ret = KMF_ERR_EMPTY_CRL; 5108*30a5e8faSwyllys goto end; 5109*30a5e8faSwyllys } 5110*30a5e8faSwyllys 5111*30a5e8faSwyllys for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { 5112*30a5e8faSwyllys /*LINTED*/ 5113*30a5e8faSwyllys revoke = sk_X509_REVOKED_value(revoke_stack, i); 5114*30a5e8faSwyllys if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, 5115*30a5e8faSwyllys revoke->serialNumber) == 0) { 5116*30a5e8faSwyllys break; 5117*30a5e8faSwyllys } 5118*30a5e8faSwyllys } 5119*30a5e8faSwyllys 5120*30a5e8faSwyllys if (i < sk_X509_REVOKED_num(revoke_stack)) { 5121*30a5e8faSwyllys ret = KMF_OK; 5122*30a5e8faSwyllys } else { 5123*30a5e8faSwyllys ret = KMF_ERR_NOT_REVOKED; 5124*30a5e8faSwyllys } 5125*30a5e8faSwyllys 5126*30a5e8faSwyllys end: 5127*30a5e8faSwyllys if (in != NULL) 5128*30a5e8faSwyllys (void) BIO_free(in); 5129*30a5e8faSwyllys if (xcrl != NULL) 5130*30a5e8faSwyllys X509_CRL_free(xcrl); 5131*30a5e8faSwyllys if (xcert != NULL) 5132*30a5e8faSwyllys X509_free(xcert); 5133*30a5e8faSwyllys 5134*30a5e8faSwyllys return (ret); 5135*30a5e8faSwyllys } 5136*30a5e8faSwyllys 5137*30a5e8faSwyllys KMF_RETURN 5138*30a5e8faSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert) 5139*30a5e8faSwyllys { 5140*30a5e8faSwyllys KMF_RETURN ret = KMF_OK; 5141*30a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 5142*30a5e8faSwyllys BIO *bcrl = NULL; 5143*30a5e8faSwyllys X509_CRL *xcrl = NULL; 5144*30a5e8faSwyllys X509 *xcert = NULL; 5145*30a5e8faSwyllys EVP_PKEY *pkey; 5146*30a5e8faSwyllys int sslret; 5147*30a5e8faSwyllys KMF_ENCODE_FORMAT crl_format; 5148*30a5e8faSwyllys unsigned char *p; 5149*30a5e8faSwyllys long len; 5150*30a5e8faSwyllys 5151*30a5e8faSwyllys if (handle == NULL || crlname == NULL || tacert == NULL) { 5152*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 5153*30a5e8faSwyllys } 5154*30a5e8faSwyllys 5155*30a5e8faSwyllys ret = kmf_get_file_format(crlname, &crl_format); 5156*30a5e8faSwyllys if (ret != KMF_OK) 5157*30a5e8faSwyllys return (ret); 5158*30a5e8faSwyllys 5159*30a5e8faSwyllys bcrl = BIO_new_file(crlname, "rb"); 5160*30a5e8faSwyllys if (bcrl == NULL) { 5161*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5162*30a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 5163*30a5e8faSwyllys goto cleanup; 5164*30a5e8faSwyllys } 5165*30a5e8faSwyllys 5166*30a5e8faSwyllys if (crl_format == KMF_FORMAT_ASN1) { 5167*30a5e8faSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 5168*30a5e8faSwyllys } else if (crl_format == KMF_FORMAT_PEM) { 5169*30a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 5170*30a5e8faSwyllys } else { 5171*30a5e8faSwyllys ret = KMF_ERR_BAD_PARAMETER; 5172*30a5e8faSwyllys goto cleanup; 5173*30a5e8faSwyllys } 5174*30a5e8faSwyllys 5175*30a5e8faSwyllys if (xcrl == NULL) { 5176*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5177*30a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 5178*30a5e8faSwyllys goto cleanup; 5179*30a5e8faSwyllys } 5180*30a5e8faSwyllys 5181*30a5e8faSwyllys p = tacert->Data; 5182*30a5e8faSwyllys len = tacert->Length; 5183*30a5e8faSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, len); 5184*30a5e8faSwyllys 5185*30a5e8faSwyllys if (xcert == NULL) { 5186*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5187*30a5e8faSwyllys ret = KMF_ERR_BAD_CERTFILE; 5188*30a5e8faSwyllys goto cleanup; 5189*30a5e8faSwyllys } 5190*30a5e8faSwyllys 5191*30a5e8faSwyllys /* Get issuer certificate public key */ 5192*30a5e8faSwyllys pkey = X509_get_pubkey(xcert); 5193*30a5e8faSwyllys if (pkey == NULL) { 5194*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5195*30a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 5196*30a5e8faSwyllys goto cleanup; 5197*30a5e8faSwyllys } 5198*30a5e8faSwyllys 5199*30a5e8faSwyllys /* Verify CRL signature */ 5200*30a5e8faSwyllys sslret = X509_CRL_verify(xcrl, pkey); 5201*30a5e8faSwyllys EVP_PKEY_free(pkey); 5202*30a5e8faSwyllys if (sslret > 0) { 5203*30a5e8faSwyllys ret = KMF_OK; 5204*30a5e8faSwyllys } else { 5205*30a5e8faSwyllys SET_ERROR(kmfh, sslret); 5206*30a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 5207*30a5e8faSwyllys } 5208*30a5e8faSwyllys 5209*30a5e8faSwyllys cleanup: 5210*30a5e8faSwyllys if (bcrl != NULL) 5211*30a5e8faSwyllys (void) BIO_free(bcrl); 5212*30a5e8faSwyllys 5213*30a5e8faSwyllys if (xcrl != NULL) 5214*30a5e8faSwyllys X509_CRL_free(xcrl); 5215*30a5e8faSwyllys 5216*30a5e8faSwyllys if (xcert != NULL) 5217*30a5e8faSwyllys X509_free(xcert); 5218*30a5e8faSwyllys 5219*30a5e8faSwyllys return (ret); 5220*30a5e8faSwyllys 5221*30a5e8faSwyllys } 5222*30a5e8faSwyllys 5223*30a5e8faSwyllys KMF_RETURN 5224*30a5e8faSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname) 5225*30a5e8faSwyllys { 5226*30a5e8faSwyllys KMF_RETURN ret = KMF_OK; 5227*30a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 5228*30a5e8faSwyllys KMF_ENCODE_FORMAT crl_format; 5229*30a5e8faSwyllys BIO *bcrl = NULL; 5230*30a5e8faSwyllys X509_CRL *xcrl = NULL; 5231*30a5e8faSwyllys int i; 5232*30a5e8faSwyllys 5233*30a5e8faSwyllys if (handle == NULL || crlname == NULL) { 5234*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 5235*30a5e8faSwyllys } 5236*30a5e8faSwyllys 5237*30a5e8faSwyllys ret = kmf_is_crl_file(handle, crlname, &crl_format); 5238*30a5e8faSwyllys if (ret != KMF_OK) 5239*30a5e8faSwyllys return (ret); 5240*30a5e8faSwyllys 5241*30a5e8faSwyllys bcrl = BIO_new_file(crlname, "rb"); 5242*30a5e8faSwyllys if (bcrl == NULL) { 5243*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5244*30a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 5245*30a5e8faSwyllys goto cleanup; 5246*30a5e8faSwyllys } 5247*30a5e8faSwyllys 5248*30a5e8faSwyllys if (crl_format == KMF_FORMAT_ASN1) { 5249*30a5e8faSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 5250*30a5e8faSwyllys } else if (crl_format == KMF_FORMAT_PEM) { 5251*30a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 5252*30a5e8faSwyllys } 5253*30a5e8faSwyllys 5254*30a5e8faSwyllys if (xcrl == NULL) { 5255*30a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 5256*30a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 5257*30a5e8faSwyllys goto cleanup; 5258*30a5e8faSwyllys } 5259*30a5e8faSwyllys 5260*30a5e8faSwyllys i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); 5261*30a5e8faSwyllys if (i >= 0) { 5262*30a5e8faSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 5263*30a5e8faSwyllys goto cleanup; 5264*30a5e8faSwyllys } 5265*30a5e8faSwyllys 5266*30a5e8faSwyllys if (X509_CRL_get_nextUpdate(xcrl)) { 5267*30a5e8faSwyllys i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); 5268*30a5e8faSwyllys 5269*30a5e8faSwyllys if (i <= 0) { 5270*30a5e8faSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 5271*30a5e8faSwyllys goto cleanup; 5272*30a5e8faSwyllys } 5273*30a5e8faSwyllys } 5274*30a5e8faSwyllys 5275*30a5e8faSwyllys ret = KMF_OK; 5276*30a5e8faSwyllys 5277*30a5e8faSwyllys cleanup: 5278*30a5e8faSwyllys if (bcrl != NULL) 5279*30a5e8faSwyllys (void) BIO_free(bcrl); 5280*30a5e8faSwyllys 5281*30a5e8faSwyllys if (xcrl != NULL) 5282*30a5e8faSwyllys X509_CRL_free(xcrl); 5283*30a5e8faSwyllys 5284*30a5e8faSwyllys return (ret); 5285*30a5e8faSwyllys } 5286