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 1355b3e1433Swyllys /* 1365b3e1433Swyllys * Declare some new macros for managing stacks of EVP_PKEYS, similar to 1375b3e1433Swyllys * what wanboot did. 1385b3e1433Swyllys */ 1395b3e1433Swyllys DECLARE_STACK_OF(EVP_PKEY) 1405b3e1433Swyllys 1415b3e1433Swyllys #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY) 1425b3e1433Swyllys #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st)) 1435b3e1433Swyllys #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st)) 1445b3e1433Swyllys #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i)) 1455b3e1433Swyllys #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val)) 1465b3e1433Swyllys #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \ 1475b3e1433Swyllys (free_func)) 1485b3e1433Swyllys 14999ebb4caSwyllys mutex_t init_lock = DEFAULTMUTEX; 15099ebb4caSwyllys static int ssl_initialized = 0; 15130a5e8faSwyllys static BIO *bio_err = NULL; 15230a5e8faSwyllys 15330a5e8faSwyllys static int 15430a5e8faSwyllys test_for_file(char *, mode_t); 1555b3e1433Swyllys static KMF_RETURN 1565b3e1433Swyllys openssl_parse_bag(PKCS12_SAFEBAG *, char *, int, 1575b3e1433Swyllys STACK_OF(EVP_PKEY) *, STACK_OF(X509) *); 1585b3e1433Swyllys 1595b3e1433Swyllys static KMF_RETURN 1605b3e1433Swyllys local_export_pk12(KMF_HANDLE_T, KMF_CREDENTIAL *, int, KMF_X509_DER_CERT *, 1615b3e1433Swyllys int, KMF_KEY_HANDLE *, char *); 1625b3e1433Swyllys 1635b3e1433Swyllys static KMF_RETURN set_pkey_attrib(EVP_PKEY *, ASN1_TYPE *, int); 16499ebb4caSwyllys 16571593db2Swyllys static KMF_RETURN 16630a5e8faSwyllys extract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *, 16702744e81Swyllys CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *); 16871593db2Swyllys 16971593db2Swyllys static KMF_RETURN 17030a5e8faSwyllys kmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, 17130a5e8faSwyllys char *, KMF_DATA *); 17230a5e8faSwyllys 17330a5e8faSwyllys static KMF_RETURN 17430a5e8faSwyllys load_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, 17530a5e8faSwyllys char *, KMF_DATA **, uint32_t *); 17671593db2Swyllys 17702744e81Swyllys static KMF_RETURN 17802744e81Swyllys sslBN2KMFBN(BIGNUM *, KMF_BIGINT *); 17902744e81Swyllys 18002744e81Swyllys static EVP_PKEY * 18102744e81Swyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *); 18202744e81Swyllys 18330a5e8faSwyllys static KMF_RETURN 18430a5e8faSwyllys convertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *); 18530a5e8faSwyllys 18699ebb4caSwyllys KMF_RETURN 18730a5e8faSwyllys OpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 18899ebb4caSwyllys 18999ebb4caSwyllys void 19099ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); 19199ebb4caSwyllys 19299ebb4caSwyllys KMF_RETURN 19330a5e8faSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); 19499ebb4caSwyllys 19599ebb4caSwyllys KMF_RETURN 19630a5e8faSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); 19799ebb4caSwyllys 19899ebb4caSwyllys KMF_RETURN 19930a5e8faSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 20030a5e8faSwyllys 20130a5e8faSwyllys KMF_RETURN 20230a5e8faSwyllys OpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 20399ebb4caSwyllys 20499ebb4caSwyllys KMF_RETURN 20599ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 20699ebb4caSwyllys 20799ebb4caSwyllys KMF_RETURN 20899ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 20999ebb4caSwyllys KMF_DATA *, KMF_DATA *); 21099ebb4caSwyllys 21199ebb4caSwyllys KMF_RETURN 21230a5e8faSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 21399ebb4caSwyllys 21499ebb4caSwyllys KMF_RETURN 21530a5e8faSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 21699ebb4caSwyllys 21799ebb4caSwyllys KMF_RETURN 21830a5e8faSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 21999ebb4caSwyllys 22099ebb4caSwyllys KMF_RETURN 22130a5e8faSwyllys OpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 22299ebb4caSwyllys 22399ebb4caSwyllys KMF_RETURN 22430a5e8faSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 22599ebb4caSwyllys 22699ebb4caSwyllys KMF_RETURN 22799ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *, 22899ebb4caSwyllys KMF_PRINTABLE_ITEM, char *); 22999ebb4caSwyllys 23099ebb4caSwyllys KMF_RETURN 23199ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T, char **); 23299ebb4caSwyllys 23399ebb4caSwyllys KMF_RETURN 23430a5e8faSwyllys OpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 23599ebb4caSwyllys 23699ebb4caSwyllys KMF_RETURN 23799ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 23899ebb4caSwyllys KMF_DATA *, KMF_DATA *); 23999ebb4caSwyllys 24099ebb4caSwyllys KMF_RETURN 24130a5e8faSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 24299ebb4caSwyllys 24399ebb4caSwyllys KMF_RETURN 24430a5e8faSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 24599ebb4caSwyllys 24699ebb4caSwyllys KMF_RETURN 24730a5e8faSwyllys OpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 24899ebb4caSwyllys 24999ebb4caSwyllys KMF_RETURN 25030a5e8faSwyllys OpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 25199ebb4caSwyllys 25299ebb4caSwyllys KMF_RETURN 25330a5e8faSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 25499ebb4caSwyllys 25599ebb4caSwyllys KMF_RETURN 25699ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 25799ebb4caSwyllys 25899ebb4caSwyllys KMF_RETURN 25930a5e8faSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *); 26099ebb4caSwyllys 26199ebb4caSwyllys KMF_RETURN 26230a5e8faSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T, char *); 26399ebb4caSwyllys 26402744e81Swyllys KMF_RETURN 26502744e81Swyllys OpenSSL_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, 26602744e81Swyllys KMF_DATA *, KMF_DATA *, KMF_DATA *); 26702744e81Swyllys 26899ebb4caSwyllys static 26999ebb4caSwyllys KMF_PLUGIN_FUNCLIST openssl_plugin_table = 27099ebb4caSwyllys { 27199ebb4caSwyllys 1, /* Version */ 27299ebb4caSwyllys NULL, /* ConfigureKeystore */ 27399ebb4caSwyllys OpenSSL_FindCert, 27499ebb4caSwyllys OpenSSL_FreeKMFCert, 27599ebb4caSwyllys OpenSSL_StoreCert, 27699ebb4caSwyllys NULL, /* ImportCert */ 27799ebb4caSwyllys OpenSSL_ImportCRL, 27899ebb4caSwyllys OpenSSL_DeleteCert, 27999ebb4caSwyllys OpenSSL_DeleteCRL, 28099ebb4caSwyllys OpenSSL_CreateKeypair, 28199ebb4caSwyllys OpenSSL_FindKey, 28299ebb4caSwyllys OpenSSL_EncodePubKeyData, 28399ebb4caSwyllys OpenSSL_SignData, 28499ebb4caSwyllys OpenSSL_DeleteKey, 28599ebb4caSwyllys OpenSSL_ListCRL, 28699ebb4caSwyllys NULL, /* FindCRL */ 28799ebb4caSwyllys OpenSSL_FindCertInCRL, 28899ebb4caSwyllys OpenSSL_GetErrorString, 28930a5e8faSwyllys OpenSSL_FindPrikeyByCert, 29099ebb4caSwyllys OpenSSL_DecryptData, 29130a5e8faSwyllys OpenSSL_ExportPK12, 29299ebb4caSwyllys OpenSSL_CreateSymKey, 29399ebb4caSwyllys OpenSSL_GetSymKeyValue, 29499ebb4caSwyllys NULL, /* SetTokenPin */ 29502744e81Swyllys OpenSSL_VerifyDataWithCert, 29630a5e8faSwyllys OpenSSL_StoreKey, 29799ebb4caSwyllys NULL /* Finalize */ 29899ebb4caSwyllys }; 29999ebb4caSwyllys 30099ebb4caSwyllys static mutex_t *lock_cs; 30199ebb4caSwyllys static long *lock_count; 30299ebb4caSwyllys 30399ebb4caSwyllys static void 30499ebb4caSwyllys /*ARGSUSED*/ 30599ebb4caSwyllys locking_cb(int mode, int type, char *file, int line) 30699ebb4caSwyllys { 30799ebb4caSwyllys if (mode & CRYPTO_LOCK) { 30899ebb4caSwyllys (void) mutex_lock(&(lock_cs[type])); 30999ebb4caSwyllys lock_count[type]++; 31099ebb4caSwyllys } else { 31199ebb4caSwyllys (void) mutex_unlock(&(lock_cs[type])); 31299ebb4caSwyllys } 31399ebb4caSwyllys } 31499ebb4caSwyllys 31599ebb4caSwyllys static unsigned long 31699ebb4caSwyllys thread_id() 31799ebb4caSwyllys { 31899ebb4caSwyllys return ((unsigned long)thr_self()); 31999ebb4caSwyllys } 32099ebb4caSwyllys 32199ebb4caSwyllys KMF_PLUGIN_FUNCLIST * 32299ebb4caSwyllys KMF_Plugin_Initialize() 32399ebb4caSwyllys { 32499ebb4caSwyllys int i; 32599ebb4caSwyllys 32699ebb4caSwyllys (void) mutex_lock(&init_lock); 32799ebb4caSwyllys if (!ssl_initialized) { 32899ebb4caSwyllys OpenSSL_add_all_algorithms(); 32999ebb4caSwyllys 33099ebb4caSwyllys /* Enable error strings for reporting */ 33199ebb4caSwyllys ERR_load_crypto_strings(); 33299ebb4caSwyllys 33399ebb4caSwyllys /* 33499ebb4caSwyllys * Add support for extension OIDs that are not yet in the 33599ebb4caSwyllys * openssl default set. 33699ebb4caSwyllys */ 33799ebb4caSwyllys (void) OBJ_create("2.5.29.30", "nameConstraints", 33899ebb4caSwyllys "X509v3 Name Constraints"); 33999ebb4caSwyllys (void) OBJ_create("2.5.29.33", "policyMappings", 34099ebb4caSwyllys "X509v3 Policy Mappings"); 34199ebb4caSwyllys (void) OBJ_create("2.5.29.36", "policyConstraints", 34299ebb4caSwyllys "X509v3 Policy Constraints"); 34399ebb4caSwyllys (void) OBJ_create("2.5.29.46", "freshestCRL", 34499ebb4caSwyllys "X509v3 Freshest CRL"); 34599ebb4caSwyllys (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy", 34699ebb4caSwyllys "X509v3 Inhibit Any-Policy"); 34799ebb4caSwyllys /* 34899ebb4caSwyllys * Set up for thread-safe operation. 34999ebb4caSwyllys */ 35099ebb4caSwyllys lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t)); 35199ebb4caSwyllys if (lock_cs == NULL) { 35299ebb4caSwyllys (void) mutex_unlock(&init_lock); 35399ebb4caSwyllys return (NULL); 35499ebb4caSwyllys } 35599ebb4caSwyllys 35699ebb4caSwyllys lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long)); 35799ebb4caSwyllys if (lock_count == NULL) { 35899ebb4caSwyllys OPENSSL_free(lock_cs); 35999ebb4caSwyllys (void) mutex_unlock(&init_lock); 36099ebb4caSwyllys return (NULL); 36199ebb4caSwyllys } 36299ebb4caSwyllys 36399ebb4caSwyllys for (i = 0; i < CRYPTO_num_locks(); i++) { 36499ebb4caSwyllys lock_count[i] = 0; 36599ebb4caSwyllys (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL); 36699ebb4caSwyllys } 36799ebb4caSwyllys 36899ebb4caSwyllys CRYPTO_set_id_callback((unsigned long (*)())thread_id); 36999ebb4caSwyllys CRYPTO_set_locking_callback((void (*)())locking_cb); 37099ebb4caSwyllys ssl_initialized = 1; 37199ebb4caSwyllys } 37299ebb4caSwyllys (void) mutex_unlock(&init_lock); 37399ebb4caSwyllys 37499ebb4caSwyllys return (&openssl_plugin_table); 37599ebb4caSwyllys } 37699ebb4caSwyllys /* 37799ebb4caSwyllys * Convert an SSL DN to a KMF DN. 37899ebb4caSwyllys */ 37999ebb4caSwyllys static KMF_RETURN 38099ebb4caSwyllys get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN) 38199ebb4caSwyllys { 38299ebb4caSwyllys KMF_DATA derdata; 38399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 38499ebb4caSwyllys uchar_t *tmp; 38599ebb4caSwyllys 38699ebb4caSwyllys /* Convert to raw DER format */ 38799ebb4caSwyllys derdata.Length = i2d_X509_NAME(sslDN, NULL); 38899ebb4caSwyllys if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length)) 38999ebb4caSwyllys == NULL) { 39099ebb4caSwyllys return (KMF_ERR_MEMORY); 39199ebb4caSwyllys } 39299ebb4caSwyllys (void) i2d_X509_NAME(sslDN, &tmp); 39399ebb4caSwyllys 39499ebb4caSwyllys /* Decode to KMF format */ 39599ebb4caSwyllys rv = DerDecodeName(&derdata, kmfDN); 39699ebb4caSwyllys if (rv != KMF_OK) { 39799ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 39899ebb4caSwyllys } 39999ebb4caSwyllys OPENSSL_free(derdata.Data); 40099ebb4caSwyllys 40199ebb4caSwyllys return (rv); 40299ebb4caSwyllys } 40399ebb4caSwyllys 40430a5e8faSwyllys int 40599ebb4caSwyllys isdir(char *path) 40699ebb4caSwyllys { 40799ebb4caSwyllys struct stat s; 40899ebb4caSwyllys 40999ebb4caSwyllys if (stat(path, &s) == -1) 41099ebb4caSwyllys return (0); 41199ebb4caSwyllys 41230a5e8faSwyllys return ((s.st_mode & S_IFMT) == S_IFDIR); 41399ebb4caSwyllys } 41499ebb4caSwyllys 41599ebb4caSwyllys static KMF_RETURN 41699ebb4caSwyllys ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert) 41799ebb4caSwyllys { 41899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 41999ebb4caSwyllys unsigned char *buf = NULL, *p; 42099ebb4caSwyllys int len; 42199ebb4caSwyllys 42299ebb4caSwyllys /* 42399ebb4caSwyllys * Convert the X509 internal struct to DER encoded data 42499ebb4caSwyllys */ 42599ebb4caSwyllys if ((len = i2d_X509(x509cert, NULL)) < 0) { 42699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 42799ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 42899ebb4caSwyllys goto cleanup; 42999ebb4caSwyllys } 43099ebb4caSwyllys if ((buf = malloc(len)) == NULL) { 43199ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 43299ebb4caSwyllys rv = KMF_ERR_MEMORY; 43399ebb4caSwyllys goto cleanup; 43499ebb4caSwyllys } 43599ebb4caSwyllys 43699ebb4caSwyllys /* 43799ebb4caSwyllys * i2d_X509 will increment the buf pointer so that we need to 43899ebb4caSwyllys * save it. 43999ebb4caSwyllys */ 44099ebb4caSwyllys p = buf; 44199ebb4caSwyllys if ((len = i2d_X509(x509cert, &p)) < 0) { 44299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 44399ebb4caSwyllys free(buf); 44499ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 44599ebb4caSwyllys goto cleanup; 44699ebb4caSwyllys } 44799ebb4caSwyllys 44899ebb4caSwyllys /* caller's responsibility to free it */ 44999ebb4caSwyllys cert->Data = buf; 45099ebb4caSwyllys cert->Length = len; 45199ebb4caSwyllys 45299ebb4caSwyllys cleanup: 45399ebb4caSwyllys if (rv != KMF_OK) { 45499ebb4caSwyllys if (buf) 45599ebb4caSwyllys free(buf); 45699ebb4caSwyllys cert->Data = NULL; 45799ebb4caSwyllys cert->Length = 0; 45899ebb4caSwyllys } 45999ebb4caSwyllys 46099ebb4caSwyllys return (rv); 46199ebb4caSwyllys } 46299ebb4caSwyllys 46330a5e8faSwyllys 46499ebb4caSwyllys static KMF_RETURN 46530a5e8faSwyllys check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial, 46630a5e8faSwyllys boolean_t *match) 46799ebb4caSwyllys { 46899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 46999ebb4caSwyllys boolean_t findIssuer = FALSE; 47099ebb4caSwyllys boolean_t findSubject = FALSE; 47199ebb4caSwyllys boolean_t findSerial = FALSE; 47299ebb4caSwyllys KMF_X509_NAME issuerDN, subjectDN; 47399ebb4caSwyllys KMF_X509_NAME certIssuerDN, certSubjectDN; 47499ebb4caSwyllys 47599ebb4caSwyllys *match = FALSE; 47699ebb4caSwyllys if (xcert == NULL) { 47799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 47899ebb4caSwyllys } 47999ebb4caSwyllys 48099ebb4caSwyllys (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME)); 48199ebb4caSwyllys (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME)); 48299ebb4caSwyllys (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME)); 48399ebb4caSwyllys (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME)); 48499ebb4caSwyllys 48530a5e8faSwyllys if (issuer != NULL && strlen(issuer)) { 48630a5e8faSwyllys rv = kmf_dn_parser(issuer, &issuerDN); 48799ebb4caSwyllys if (rv != KMF_OK) 48899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 48999ebb4caSwyllys 49099ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); 49199ebb4caSwyllys if (rv != KMF_OK) { 49230a5e8faSwyllys kmf_free_dn(&issuerDN); 49399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 49499ebb4caSwyllys } 49599ebb4caSwyllys 49699ebb4caSwyllys findIssuer = TRUE; 49799ebb4caSwyllys } 49830a5e8faSwyllys if (subject != NULL && strlen(subject)) { 49930a5e8faSwyllys rv = kmf_dn_parser(subject, &subjectDN); 50099ebb4caSwyllys if (rv != KMF_OK) { 50199ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 50299ebb4caSwyllys goto cleanup; 50399ebb4caSwyllys } 50499ebb4caSwyllys 50599ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN); 50699ebb4caSwyllys if (rv != KMF_OK) { 50799ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 50899ebb4caSwyllys goto cleanup; 50999ebb4caSwyllys } 51099ebb4caSwyllys findSubject = TRUE; 51199ebb4caSwyllys } 51230a5e8faSwyllys if (serial != NULL && serial->val != NULL) 51399ebb4caSwyllys findSerial = TRUE; 51499ebb4caSwyllys 51599ebb4caSwyllys if (findSerial) { 51699ebb4caSwyllys BIGNUM *bn; 51799ebb4caSwyllys 51899ebb4caSwyllys /* Comparing BIGNUMs is a pain! */ 51999ebb4caSwyllys bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL); 52099ebb4caSwyllys if (bn != NULL) { 52199ebb4caSwyllys int bnlen = BN_num_bytes(bn); 52299ebb4caSwyllys 52330a5e8faSwyllys if (bnlen == serial->len) { 52499ebb4caSwyllys uchar_t *a = malloc(bnlen); 52599ebb4caSwyllys if (a == NULL) { 52699ebb4caSwyllys rv = KMF_ERR_MEMORY; 52799ebb4caSwyllys BN_free(bn); 52899ebb4caSwyllys goto cleanup; 52999ebb4caSwyllys } 53099ebb4caSwyllys bnlen = BN_bn2bin(bn, a); 53130a5e8faSwyllys *match = (memcmp(a, serial->val, serial->len) == 53230a5e8faSwyllys 0); 53399ebb4caSwyllys rv = KMF_OK; 53499ebb4caSwyllys free(a); 53599ebb4caSwyllys } 53699ebb4caSwyllys BN_free(bn); 53799ebb4caSwyllys if (!(*match)) 53899ebb4caSwyllys goto cleanup; 53999ebb4caSwyllys } else { 54099ebb4caSwyllys rv = KMF_OK; 54199ebb4caSwyllys goto cleanup; 54299ebb4caSwyllys } 54399ebb4caSwyllys } 54499ebb4caSwyllys if (findIssuer) { 54530a5e8faSwyllys *match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0); 54630a5e8faSwyllys if ((*match) == B_FALSE) { 54730a5e8faSwyllys /* stop checking and bail */ 54899ebb4caSwyllys rv = KMF_OK; 54999ebb4caSwyllys goto cleanup; 55099ebb4caSwyllys } 55199ebb4caSwyllys } 55299ebb4caSwyllys if (findSubject) { 55330a5e8faSwyllys *match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0); 55430a5e8faSwyllys if ((*match) == B_FALSE) { 55530a5e8faSwyllys /* stop checking and bail */ 55699ebb4caSwyllys rv = KMF_OK; 55799ebb4caSwyllys goto cleanup; 55899ebb4caSwyllys } 55999ebb4caSwyllys } 56099ebb4caSwyllys 56199ebb4caSwyllys *match = TRUE; 56299ebb4caSwyllys cleanup: 56399ebb4caSwyllys if (findIssuer) { 56430a5e8faSwyllys kmf_free_dn(&issuerDN); 56530a5e8faSwyllys kmf_free_dn(&certIssuerDN); 56699ebb4caSwyllys } 56799ebb4caSwyllys if (findSubject) { 56830a5e8faSwyllys kmf_free_dn(&subjectDN); 56930a5e8faSwyllys kmf_free_dn(&certSubjectDN); 57099ebb4caSwyllys } 57199ebb4caSwyllys 57299ebb4caSwyllys return (rv); 57399ebb4caSwyllys } 57499ebb4caSwyllys 57530a5e8faSwyllys 57630a5e8faSwyllys /* 57730a5e8faSwyllys * This function loads a certificate file into an X509 data structure, and 57830a5e8faSwyllys * checks if its issuer, subject or the serial number matches with those 57930a5e8faSwyllys * values. If it matches, then return the X509 data structure. 58030a5e8faSwyllys */ 58199ebb4caSwyllys static KMF_RETURN 58299ebb4caSwyllys load_X509cert(KMF_HANDLE *kmfh, 58330a5e8faSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 58430a5e8faSwyllys char *pathname, X509 **outcert) 58599ebb4caSwyllys { 58699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 58799ebb4caSwyllys X509 *xcert = NULL; 58899ebb4caSwyllys BIO *bcert = NULL; 58999ebb4caSwyllys boolean_t match = FALSE; 59099ebb4caSwyllys KMF_ENCODE_FORMAT format; 59199ebb4caSwyllys 59299ebb4caSwyllys /* 59399ebb4caSwyllys * auto-detect the file format, regardless of what 59499ebb4caSwyllys * the 'format' parameters in the params say. 59599ebb4caSwyllys */ 59630a5e8faSwyllys rv = kmf_get_file_format(pathname, &format); 59799ebb4caSwyllys if (rv != KMF_OK) { 59899ebb4caSwyllys if (rv == KMF_ERR_OPEN_FILE) 59999ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 60099ebb4caSwyllys return (rv); 60199ebb4caSwyllys } 60299ebb4caSwyllys 60399ebb4caSwyllys /* Not ASN1(DER) format */ 60499ebb4caSwyllys if ((bcert = BIO_new_file(pathname, "rb")) == NULL) { 60599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 60699ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 60799ebb4caSwyllys goto cleanup; 60899ebb4caSwyllys } 60999ebb4caSwyllys 61099ebb4caSwyllys if (format == KMF_FORMAT_PEM) 61199ebb4caSwyllys xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL); 61299ebb4caSwyllys else if (format == KMF_FORMAT_ASN1) 61399ebb4caSwyllys xcert = d2i_X509_bio(bcert, NULL); 61499ebb4caSwyllys else if (format == KMF_FORMAT_PKCS12) { 61599ebb4caSwyllys PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL); 61699ebb4caSwyllys if (p12 != NULL) { 61799ebb4caSwyllys (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL); 61899ebb4caSwyllys PKCS12_free(p12); 61999ebb4caSwyllys p12 = NULL; 62099ebb4caSwyllys } else { 62199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 62299ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 62399ebb4caSwyllys } 62499ebb4caSwyllys } else { 62599ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 62699ebb4caSwyllys goto cleanup; 62799ebb4caSwyllys } 62899ebb4caSwyllys 62999ebb4caSwyllys if (xcert == NULL) { 63099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 63199ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 63299ebb4caSwyllys goto cleanup; 63399ebb4caSwyllys } 63499ebb4caSwyllys 63530a5e8faSwyllys if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK || 63630a5e8faSwyllys match == FALSE) { 63799ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 63899ebb4caSwyllys goto cleanup; 63999ebb4caSwyllys } 64099ebb4caSwyllys 64199ebb4caSwyllys if (outcert != NULL) { 64299ebb4caSwyllys *outcert = xcert; 64399ebb4caSwyllys } 64499ebb4caSwyllys 64599ebb4caSwyllys cleanup: 64699ebb4caSwyllys if (bcert != NULL) (void) BIO_free(bcert); 64799ebb4caSwyllys if (rv != KMF_OK && xcert != NULL) 64899ebb4caSwyllys X509_free(xcert); 64999ebb4caSwyllys 65099ebb4caSwyllys return (rv); 65199ebb4caSwyllys } 65299ebb4caSwyllys 65371593db2Swyllys static int 65471593db2Swyllys datacmp(const void *a, const void *b) 65571593db2Swyllys { 65671593db2Swyllys KMF_DATA *adata = (KMF_DATA *)a; 65771593db2Swyllys KMF_DATA *bdata = (KMF_DATA *)b; 65871593db2Swyllys if (adata->Length > bdata->Length) 65971593db2Swyllys return (-1); 66071593db2Swyllys if (adata->Length < bdata->Length) 66171593db2Swyllys return (1); 66271593db2Swyllys return (0); 66371593db2Swyllys } 66471593db2Swyllys 66571593db2Swyllys static KMF_RETURN 66630a5e8faSwyllys load_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial, 66730a5e8faSwyllys KMF_CERT_VALIDITY validity, char *pathname, 66871593db2Swyllys KMF_DATA **certlist, uint32_t *numcerts) 66971593db2Swyllys { 67071593db2Swyllys KMF_RETURN rv = KMF_OK; 67171593db2Swyllys int i; 67271593db2Swyllys KMF_DATA *certs = NULL; 67371593db2Swyllys int nc = 0; 67471593db2Swyllys int hits = 0; 67571593db2Swyllys KMF_ENCODE_FORMAT format; 67671593db2Swyllys 67730a5e8faSwyllys rv = kmf_get_file_format(pathname, &format); 67871593db2Swyllys if (rv != KMF_OK) { 67971593db2Swyllys if (rv == KMF_ERR_OPEN_FILE) 68071593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 68171593db2Swyllys return (rv); 68271593db2Swyllys } 68371593db2Swyllys if (format == KMF_FORMAT_ASN1) { 68471593db2Swyllys /* load a single certificate */ 68571593db2Swyllys certs = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 68671593db2Swyllys if (certs == NULL) 68771593db2Swyllys return (KMF_ERR_MEMORY); 68871593db2Swyllys certs->Data = NULL; 68971593db2Swyllys certs->Length = 0; 69030a5e8faSwyllys rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, 69130a5e8faSwyllys pathname, certs); 69271593db2Swyllys if (rv == KMF_OK) { 69371593db2Swyllys *certlist = certs; 69471593db2Swyllys *numcerts = 1; 69571593db2Swyllys } 69671593db2Swyllys return (rv); 69771593db2Swyllys } else if (format == KMF_FORMAT_PKCS12) { 69871593db2Swyllys /* We need a credential to access a PKCS#12 file */ 69971593db2Swyllys rv = KMF_ERR_BAD_CERT_FORMAT; 70071593db2Swyllys } else if (format == KMF_FORMAT_PEM || 70171593db2Swyllys format != KMF_FORMAT_PEM_KEYPAIR) { 70271593db2Swyllys 70371593db2Swyllys /* This function only works on PEM files */ 70430a5e8faSwyllys rv = extract_pem(kmfh, issuer, subject, serial, pathname, 70534acef67Swyllys (uchar_t *)NULL, 0, NULL, &certs, &nc); 70671593db2Swyllys } else { 70771593db2Swyllys return (KMF_ERR_ENCODING); 70871593db2Swyllys } 70971593db2Swyllys 71071593db2Swyllys if (rv != KMF_OK) 71171593db2Swyllys return (rv); 71271593db2Swyllys 71371593db2Swyllys for (i = 0; i < nc; i++) { 71430a5e8faSwyllys if (validity == KMF_NONEXPIRED_CERTS) { 71530a5e8faSwyllys rv = kmf_check_cert_date(kmfh, &certs[i]); 71630a5e8faSwyllys } else if (validity == KMF_EXPIRED_CERTS) { 71730a5e8faSwyllys rv = kmf_check_cert_date(kmfh, &certs[i]); 71871593db2Swyllys if (rv == KMF_OK) 71971593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 72071593db2Swyllys if (rv == KMF_ERR_VALIDITY_PERIOD) 72171593db2Swyllys rv = KMF_OK; 72271593db2Swyllys } 72371593db2Swyllys if (rv != KMF_OK) { 72471593db2Swyllys /* Remove this cert from the list by clearing it. */ 72530a5e8faSwyllys kmf_free_data(&certs[i]); 72671593db2Swyllys } else { 72771593db2Swyllys hits++; /* count valid certs found */ 72871593db2Swyllys } 72971593db2Swyllys rv = KMF_OK; 73071593db2Swyllys } 73171593db2Swyllys if (rv == KMF_OK && hits == 0) { 73271593db2Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 73371593db2Swyllys } else if (rv == KMF_OK && hits > 0) { 73471593db2Swyllys /* 73571593db2Swyllys * Sort the list of certs by length to put the cleared ones 73671593db2Swyllys * at the end so they don't get accessed by the caller. 73771593db2Swyllys */ 73871593db2Swyllys qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp); 73971593db2Swyllys *certlist = certs; 74071593db2Swyllys 74171593db2Swyllys /* since we sorted the list, just return the number of hits */ 74271593db2Swyllys *numcerts = hits; 74371593db2Swyllys } 74471593db2Swyllys return (rv); 74571593db2Swyllys } 74671593db2Swyllys 74730a5e8faSwyllys 74899ebb4caSwyllys static KMF_RETURN 74999ebb4caSwyllys kmf_load_cert(KMF_HANDLE *kmfh, 75030a5e8faSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 75130a5e8faSwyllys KMF_CERT_VALIDITY validity, 75299ebb4caSwyllys char *pathname, 75399ebb4caSwyllys KMF_DATA *cert) 75499ebb4caSwyllys { 75599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 75699ebb4caSwyllys X509 *x509cert = NULL; 75799ebb4caSwyllys 75830a5e8faSwyllys rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert); 75999ebb4caSwyllys if (rv == KMF_OK && x509cert != NULL && cert != NULL) { 76099ebb4caSwyllys rv = ssl_cert2KMFDATA(kmfh, x509cert, cert); 76199ebb4caSwyllys if (rv != KMF_OK) { 76299ebb4caSwyllys goto cleanup; 76399ebb4caSwyllys } 76430a5e8faSwyllys if (validity == KMF_NONEXPIRED_CERTS) { 76530a5e8faSwyllys rv = kmf_check_cert_date(kmfh, cert); 76630a5e8faSwyllys } else if (validity == KMF_EXPIRED_CERTS) { 76730a5e8faSwyllys rv = kmf_check_cert_date(kmfh, cert); 76899ebb4caSwyllys if (rv == KMF_OK) { 76999ebb4caSwyllys /* 77099ebb4caSwyllys * This is a valid cert so skip it. 77199ebb4caSwyllys */ 77299ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 77399ebb4caSwyllys } 77499ebb4caSwyllys if (rv == KMF_ERR_VALIDITY_PERIOD) { 77599ebb4caSwyllys /* 77699ebb4caSwyllys * We want to return success when we 77799ebb4caSwyllys * find an invalid cert. 77899ebb4caSwyllys */ 77999ebb4caSwyllys rv = KMF_OK; 78099ebb4caSwyllys goto cleanup; 78199ebb4caSwyllys } 78299ebb4caSwyllys } 78399ebb4caSwyllys } 78499ebb4caSwyllys cleanup: 78599ebb4caSwyllys if (x509cert != NULL) 78699ebb4caSwyllys X509_free(x509cert); 78799ebb4caSwyllys 78899ebb4caSwyllys return (rv); 78999ebb4caSwyllys } 79099ebb4caSwyllys 79102744e81Swyllys static KMF_RETURN 79202744e81Swyllys readAltFormatPrivateKey(KMF_DATA *filedata, EVP_PKEY **pkey) 79302744e81Swyllys { 79402744e81Swyllys KMF_RETURN ret = KMF_OK; 79502744e81Swyllys KMF_RAW_RSA_KEY rsa; 79602744e81Swyllys BerElement *asn1 = NULL; 79702744e81Swyllys BerValue filebuf; 79802744e81Swyllys BerValue OID = { NULL, 0 }; 79902744e81Swyllys BerValue *Mod = NULL, *PubExp = NULL; 80002744e81Swyllys BerValue *PriExp = NULL, *Prime1 = NULL, *Prime2 = NULL; 80102744e81Swyllys BerValue *Coef = NULL; 80202744e81Swyllys BIGNUM *D = NULL, *P = NULL, *Q = NULL, *COEF = NULL; 80302744e81Swyllys BIGNUM *Exp1 = NULL, *Exp2 = NULL, *pminus1 = NULL; 80402744e81Swyllys BIGNUM *qminus1 = NULL; 80502744e81Swyllys BN_CTX *ctx = NULL; 80602744e81Swyllys 80702744e81Swyllys *pkey = NULL; 80802744e81Swyllys 80902744e81Swyllys filebuf.bv_val = (char *)filedata->Data; 81002744e81Swyllys filebuf.bv_len = filedata->Length; 81102744e81Swyllys 81202744e81Swyllys asn1 = kmfder_init(&filebuf); 81302744e81Swyllys if (asn1 == NULL) { 81402744e81Swyllys ret = KMF_ERR_MEMORY; 81502744e81Swyllys goto out; 81602744e81Swyllys } 81702744e81Swyllys 81802744e81Swyllys if (kmfber_scanf(asn1, "{{Dn{IIIIII}}}", 81902744e81Swyllys &OID, &Mod, &PubExp, &PriExp, &Prime1, 82002744e81Swyllys &Prime2, &Coef) == -1) { 82102744e81Swyllys ret = KMF_ERR_ENCODING; 82202744e81Swyllys goto out; 82302744e81Swyllys } 82402744e81Swyllys 82502744e81Swyllys /* 82602744e81Swyllys * We have to derive the 2 Exponents using Bignumber math. 82702744e81Swyllys * Exp1 = PriExp mod (Prime1 - 1) 82802744e81Swyllys * Exp2 = PriExp mod (Prime2 - 1) 82902744e81Swyllys */ 83002744e81Swyllys 83102744e81Swyllys /* D = PrivateExponent */ 83202744e81Swyllys D = BN_bin2bn((const uchar_t *)PriExp->bv_val, PriExp->bv_len, D); 83302744e81Swyllys if (D == NULL) { 83402744e81Swyllys ret = KMF_ERR_MEMORY; 83502744e81Swyllys goto out; 83602744e81Swyllys } 83702744e81Swyllys 83802744e81Swyllys /* P = Prime1 (first prime factor of Modulus) */ 83902744e81Swyllys P = BN_bin2bn((const uchar_t *)Prime1->bv_val, Prime1->bv_len, P); 84002744e81Swyllys if (D == NULL) { 84102744e81Swyllys ret = KMF_ERR_MEMORY; 84202744e81Swyllys goto out; 84302744e81Swyllys } 84402744e81Swyllys 84502744e81Swyllys /* Q = Prime2 (second prime factor of Modulus) */ 84602744e81Swyllys Q = BN_bin2bn((const uchar_t *)Prime2->bv_val, Prime2->bv_len, Q); 84702744e81Swyllys 84802744e81Swyllys if ((ctx = BN_CTX_new()) == NULL) { 84902744e81Swyllys ret = KMF_ERR_MEMORY; 85002744e81Swyllys goto out; 85102744e81Swyllys } 85202744e81Swyllys 85302744e81Swyllys /* Compute (P - 1) */ 85402744e81Swyllys pminus1 = BN_new(); 85502744e81Swyllys (void) BN_sub(pminus1, P, BN_value_one()); 85602744e81Swyllys 85702744e81Swyllys /* Exponent1 = D mod (P - 1) */ 85802744e81Swyllys Exp1 = BN_new(); 85902744e81Swyllys (void) BN_mod(Exp1, D, pminus1, ctx); 86002744e81Swyllys 86102744e81Swyllys /* Compute (Q - 1) */ 86202744e81Swyllys qminus1 = BN_new(); 86302744e81Swyllys (void) BN_sub(qminus1, Q, BN_value_one()); 86402744e81Swyllys 86502744e81Swyllys /* Exponent2 = D mod (Q - 1) */ 86602744e81Swyllys Exp2 = BN_new(); 86702744e81Swyllys (void) BN_mod(Exp2, D, qminus1, ctx); 86802744e81Swyllys 86902744e81Swyllys /* Coef = (Inverse Q) mod P */ 87002744e81Swyllys COEF = BN_new(); 87102744e81Swyllys (void) BN_mod_inverse(COEF, Q, P, ctx); 87202744e81Swyllys 87302744e81Swyllys /* Convert back to KMF format */ 87402744e81Swyllys (void) memset(&rsa, 0, sizeof (rsa)); 87502744e81Swyllys 87602744e81Swyllys if ((ret = sslBN2KMFBN(Exp1, &rsa.exp1)) != KMF_OK) 87702744e81Swyllys goto out; 87802744e81Swyllys if ((ret = sslBN2KMFBN(Exp2, &rsa.exp2)) != KMF_OK) 87902744e81Swyllys goto out; 88002744e81Swyllys if ((ret = sslBN2KMFBN(COEF, &rsa.coef)) != KMF_OK) 88102744e81Swyllys goto out; 88202744e81Swyllys 88302744e81Swyllys rsa.mod.val = (uchar_t *)Mod->bv_val; 88402744e81Swyllys rsa.mod.len = Mod->bv_len; 88502744e81Swyllys 88602744e81Swyllys rsa.pubexp.val = (uchar_t *)PubExp->bv_val; 88702744e81Swyllys rsa.pubexp.len = PubExp->bv_len; 88802744e81Swyllys 88902744e81Swyllys rsa.priexp.val = (uchar_t *)PriExp->bv_val; 89002744e81Swyllys rsa.priexp.len = PriExp->bv_len; 89102744e81Swyllys 89202744e81Swyllys rsa.prime1.val = (uchar_t *)Prime1->bv_val; 89302744e81Swyllys rsa.prime1.len = Prime1->bv_len; 89402744e81Swyllys 89502744e81Swyllys rsa.prime2.val = (uchar_t *)Prime2->bv_val; 89602744e81Swyllys rsa.prime2.len = Prime2->bv_len; 89702744e81Swyllys 89802744e81Swyllys *pkey = ImportRawRSAKey(&rsa); 89902744e81Swyllys out: 90002744e81Swyllys if (asn1 != NULL) 90102744e81Swyllys kmfber_free(asn1, 1); 90202744e81Swyllys 90302744e81Swyllys if (OID.bv_val) { 90402744e81Swyllys free(OID.bv_val); 90502744e81Swyllys } 90602744e81Swyllys if (PriExp) 90702744e81Swyllys free(PriExp); 90802744e81Swyllys 90902744e81Swyllys if (Mod) 91002744e81Swyllys free(Mod); 91102744e81Swyllys 91202744e81Swyllys if (PubExp) 91302744e81Swyllys free(PubExp); 91402744e81Swyllys 91502744e81Swyllys if (Coef) { 91602744e81Swyllys (void) memset(Coef->bv_val, 0, Coef->bv_len); 91702744e81Swyllys free(Coef->bv_val); 91802744e81Swyllys free(Coef); 91902744e81Swyllys } 92002744e81Swyllys if (Prime1) 92102744e81Swyllys free(Prime1); 92202744e81Swyllys if (Prime2) 92302744e81Swyllys free(Prime2); 92402744e81Swyllys 92502744e81Swyllys if (ctx != NULL) 92602744e81Swyllys BN_CTX_free(ctx); 92702744e81Swyllys 92802744e81Swyllys if (D) 92902744e81Swyllys BN_clear_free(D); 93002744e81Swyllys if (P) 93102744e81Swyllys BN_clear_free(P); 93202744e81Swyllys if (Q) 93302744e81Swyllys BN_clear_free(Q); 93402744e81Swyllys if (pminus1) 93502744e81Swyllys BN_clear_free(pminus1); 93602744e81Swyllys if (qminus1) 93702744e81Swyllys BN_clear_free(qminus1); 93802744e81Swyllys if (Exp1) 93902744e81Swyllys BN_clear_free(Exp1); 94002744e81Swyllys if (Exp2) 94102744e81Swyllys BN_clear_free(Exp2); 94202744e81Swyllys 94302744e81Swyllys return (ret); 94402744e81Swyllys 94502744e81Swyllys } 94602744e81Swyllys 94799ebb4caSwyllys static EVP_PKEY * 94899ebb4caSwyllys openssl_load_key(KMF_HANDLE_T handle, const char *file) 94999ebb4caSwyllys { 95099ebb4caSwyllys BIO *keyfile = NULL; 95199ebb4caSwyllys EVP_PKEY *pkey = NULL; 95299ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 95399ebb4caSwyllys KMF_ENCODE_FORMAT format; 95402744e81Swyllys KMF_RETURN rv; 95502744e81Swyllys KMF_DATA filedata; 95699ebb4caSwyllys 95799ebb4caSwyllys if (file == NULL) { 95899ebb4caSwyllys return (NULL); 95999ebb4caSwyllys } 96099ebb4caSwyllys 96130a5e8faSwyllys if (kmf_get_file_format((char *)file, &format) != KMF_OK) 96299ebb4caSwyllys return (NULL); 96399ebb4caSwyllys 96499ebb4caSwyllys keyfile = BIO_new_file(file, "rb"); 96599ebb4caSwyllys if (keyfile == NULL) { 96699ebb4caSwyllys goto end; 96799ebb4caSwyllys } 96899ebb4caSwyllys 96902744e81Swyllys if (format == KMF_FORMAT_ASN1) { 97099ebb4caSwyllys pkey = d2i_PrivateKey_bio(keyfile, NULL); 97102744e81Swyllys if (pkey == NULL) { 97202744e81Swyllys 97302744e81Swyllys (void) BIO_free(keyfile); 97402744e81Swyllys keyfile = NULL; 97502744e81Swyllys /* Try odd ASN.1 variations */ 97630a5e8faSwyllys rv = kmf_read_input_file(kmfh, (char *)file, 97702744e81Swyllys &filedata); 97802744e81Swyllys if (rv == KMF_OK) { 97902744e81Swyllys (void) readAltFormatPrivateKey(&filedata, 98002744e81Swyllys &pkey); 98130a5e8faSwyllys kmf_free_data(&filedata); 98202744e81Swyllys } 98302744e81Swyllys } 98402744e81Swyllys } else if (format == KMF_FORMAT_PEM || 98502744e81Swyllys format == KMF_FORMAT_PEM_KEYPAIR) { 98699ebb4caSwyllys pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL); 98702744e81Swyllys if (pkey == NULL) { 98802744e81Swyllys KMF_DATA derdata; 98902744e81Swyllys /* 99002744e81Swyllys * Check if this is the alt. format 99102744e81Swyllys * RSA private key file. 99202744e81Swyllys */ 99330a5e8faSwyllys rv = kmf_read_input_file(kmfh, (char *)file, 99402744e81Swyllys &filedata); 99502744e81Swyllys if (rv == KMF_OK) { 99602744e81Swyllys uchar_t *d = NULL; 99702744e81Swyllys int len; 99830a5e8faSwyllys rv = kmf_pem_to_der(filedata.Data, 99902744e81Swyllys filedata.Length, &d, &len); 100002744e81Swyllys if (rv == KMF_OK && d != NULL) { 100102744e81Swyllys derdata.Data = d; 100202744e81Swyllys derdata.Length = (size_t)len; 100302744e81Swyllys (void) readAltFormatPrivateKey( 100402744e81Swyllys &derdata, &pkey); 100502744e81Swyllys free(d); 100602744e81Swyllys } 100730a5e8faSwyllys kmf_free_data(&filedata); 100802744e81Swyllys } 100902744e81Swyllys } 101002744e81Swyllys } 101199ebb4caSwyllys 101299ebb4caSwyllys end: 101399ebb4caSwyllys if (pkey == NULL) 101499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 101599ebb4caSwyllys 101699ebb4caSwyllys if (keyfile != NULL) 101799ebb4caSwyllys (void) BIO_free(keyfile); 101899ebb4caSwyllys 101999ebb4caSwyllys return (pkey); 102099ebb4caSwyllys } 102199ebb4caSwyllys 102299ebb4caSwyllys KMF_RETURN 102330a5e8faSwyllys OpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 102499ebb4caSwyllys { 102599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 102699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1027f482c776Swyllys int i, n; 1028f482c776Swyllys uint32_t maxcerts = 0; 102930a5e8faSwyllys uint32_t *num_certs; 103030a5e8faSwyllys KMF_X509_DER_CERT *kmf_cert = NULL; 103130a5e8faSwyllys char *dirpath = NULL; 103230a5e8faSwyllys char *filename = NULL; 103330a5e8faSwyllys char *fullpath = NULL; 103430a5e8faSwyllys char *issuer = NULL; 103530a5e8faSwyllys char *subject = NULL; 103630a5e8faSwyllys KMF_BIGINT *serial = NULL; 103730a5e8faSwyllys KMF_CERT_VALIDITY validity; 103899ebb4caSwyllys 103930a5e8faSwyllys num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 104030a5e8faSwyllys if (num_certs == NULL) 104199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 104299ebb4caSwyllys 104330a5e8faSwyllys /* num_certs should reference the size of kmf_cert */ 1044f482c776Swyllys maxcerts = *num_certs; 1045f482c776Swyllys if (maxcerts == 0) 1046f482c776Swyllys maxcerts = 0xFFFFFFFF; 104799ebb4caSwyllys *num_certs = 0; 104899ebb4caSwyllys 104930a5e8faSwyllys /* Get the optional returned certificate list */ 105030a5e8faSwyllys kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, 105130a5e8faSwyllys numattr); 105299ebb4caSwyllys 105330a5e8faSwyllys /* 105430a5e8faSwyllys * The dirpath attribute and the filename attribute can not be NULL 105530a5e8faSwyllys * at the same time. 105630a5e8faSwyllys */ 105730a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 105830a5e8faSwyllys filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 105930a5e8faSwyllys numattr); 106030a5e8faSwyllys 106130a5e8faSwyllys fullpath = get_fullpath(dirpath, filename); 106299ebb4caSwyllys if (fullpath == NULL) 106399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 106499ebb4caSwyllys 106530a5e8faSwyllys /* Get optional search criteria attributes */ 106630a5e8faSwyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 106730a5e8faSwyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 106830a5e8faSwyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 106930a5e8faSwyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, 107030a5e8faSwyllys &validity, NULL); 107130a5e8faSwyllys if (rv != KMF_OK) { 107230a5e8faSwyllys validity = KMF_ALL_CERTS; 107330a5e8faSwyllys rv = KMF_OK; 107430a5e8faSwyllys } 107530a5e8faSwyllys 107699ebb4caSwyllys if (isdir(fullpath)) { 107799ebb4caSwyllys DIR *dirp; 107899ebb4caSwyllys struct dirent *dp; 107999ebb4caSwyllys 1080f482c776Swyllys n = 0; 108199ebb4caSwyllys /* open all files in the directory and attempt to read them */ 108299ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 108399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 108499ebb4caSwyllys } 108599ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 108699ebb4caSwyllys char *fname; 108771593db2Swyllys KMF_DATA *certlist = NULL; 1088f482c776Swyllys uint32_t loaded_certs = 0; 108971593db2Swyllys 109099ebb4caSwyllys if (strcmp(dp->d_name, ".") == 0 || 109199ebb4caSwyllys strcmp(dp->d_name, "..") == 0) 109299ebb4caSwyllys continue; 109399ebb4caSwyllys 109434acef67Swyllys fname = get_fullpath(fullpath, (char *)&dp->d_name); 109599ebb4caSwyllys 109630a5e8faSwyllys rv = load_certs(kmfh, issuer, subject, serial, 109730a5e8faSwyllys validity, fname, &certlist, &loaded_certs); 109899ebb4caSwyllys 109999ebb4caSwyllys if (rv != KMF_OK) { 110099ebb4caSwyllys free(fname); 110171593db2Swyllys if (certlist != NULL) { 1102f482c776Swyllys for (i = 0; i < loaded_certs; i++) 110330a5e8faSwyllys kmf_free_data(&certlist[i]); 110471593db2Swyllys free(certlist); 110571593db2Swyllys } 110699ebb4caSwyllys continue; 110799ebb4caSwyllys } 110899ebb4caSwyllys 110999ebb4caSwyllys /* If load succeeds, add certdata to the list */ 111099ebb4caSwyllys if (kmf_cert != NULL) { 1111f482c776Swyllys for (i = 0; i < loaded_certs && 1112b4058258Swyllys n < maxcerts; i++) { 111371593db2Swyllys kmf_cert[n].certificate.Data = 111471593db2Swyllys certlist[i].Data; 111599ebb4caSwyllys kmf_cert[n].certificate.Length = 111671593db2Swyllys certlist[i].Length; 111799ebb4caSwyllys 111899ebb4caSwyllys kmf_cert[n].kmf_private.keystore_type = 111999ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 112099ebb4caSwyllys kmf_cert[n].kmf_private.flags = 112199ebb4caSwyllys KMF_FLAG_CERT_VALID; 112271593db2Swyllys kmf_cert[n].kmf_private.label = 112371593db2Swyllys strdup(fname); 112499ebb4caSwyllys n++; 112599ebb4caSwyllys } 1126b4058258Swyllys /* 1127b4058258Swyllys * If maxcerts < loaded_certs, clean up the 1128b4058258Swyllys * certs that were not used. 1129b4058258Swyllys */ 1130f482c776Swyllys for (; i < loaded_certs; i++) 113130a5e8faSwyllys kmf_free_data(&certlist[i]); 1132f482c776Swyllys } else { 1133f482c776Swyllys for (i = 0; i < loaded_certs; i++) 113430a5e8faSwyllys kmf_free_data(&certlist[i]); 1135f482c776Swyllys n += loaded_certs; 113671593db2Swyllys } 1137f482c776Swyllys free(certlist); 113871593db2Swyllys free(fname); 113971593db2Swyllys } 114099ebb4caSwyllys (*num_certs) = n; 114199ebb4caSwyllys if (*num_certs == 0) 114299ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 114330a5e8faSwyllys if (*num_certs > 0) 114499ebb4caSwyllys rv = KMF_OK; 114599ebb4caSwyllys exit: 114699ebb4caSwyllys (void) closedir(dirp); 114799ebb4caSwyllys } else { 114871593db2Swyllys KMF_DATA *certlist = NULL; 1149f482c776Swyllys uint32_t loaded_certs = 0; 115071593db2Swyllys 115130a5e8faSwyllys rv = load_certs(kmfh, issuer, subject, serial, validity, 115230a5e8faSwyllys fullpath, &certlist, &loaded_certs); 115399ebb4caSwyllys if (rv != KMF_OK) { 115499ebb4caSwyllys free(fullpath); 115599ebb4caSwyllys return (rv); 115699ebb4caSwyllys } 115799ebb4caSwyllys 1158f482c776Swyllys n = 0; 115971593db2Swyllys if (kmf_cert != NULL && certlist != NULL) { 1160f482c776Swyllys for (i = 0; i < loaded_certs && i < maxcerts; i++) { 1161f482c776Swyllys kmf_cert[n].certificate.Data = 116271593db2Swyllys certlist[i].Data; 1163f482c776Swyllys kmf_cert[n].certificate.Length = 116471593db2Swyllys certlist[i].Length; 1165f482c776Swyllys kmf_cert[n].kmf_private.keystore_type = 116699ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 1167f482c776Swyllys kmf_cert[n].kmf_private.flags = 116871593db2Swyllys KMF_FLAG_CERT_VALID; 1169f482c776Swyllys kmf_cert[n].kmf_private.label = 117071593db2Swyllys strdup(fullpath); 1171f482c776Swyllys n++; 117271593db2Swyllys } 1173f482c776Swyllys /* If maxcerts < loaded_certs, clean up */ 1174f482c776Swyllys for (; i < loaded_certs; i++) 117530a5e8faSwyllys kmf_free_data(&certlist[i]); 1176f482c776Swyllys } else if (certlist != NULL) { 1177f482c776Swyllys for (i = 0; i < loaded_certs; i++) 117830a5e8faSwyllys kmf_free_data(&certlist[i]); 1179f482c776Swyllys n = loaded_certs; 1180f482c776Swyllys } 118130a5e8faSwyllys if (certlist != NULL) 118271593db2Swyllys free(certlist); 1183f482c776Swyllys *num_certs = n; 118499ebb4caSwyllys } 118599ebb4caSwyllys 118699ebb4caSwyllys free(fullpath); 118799ebb4caSwyllys 118899ebb4caSwyllys return (rv); 118999ebb4caSwyllys } 119099ebb4caSwyllys 119199ebb4caSwyllys void 119299ebb4caSwyllys /*ARGSUSED*/ 119399ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, 119499ebb4caSwyllys KMF_X509_DER_CERT *kmf_cert) 119599ebb4caSwyllys { 119699ebb4caSwyllys if (kmf_cert != NULL) { 119799ebb4caSwyllys if (kmf_cert->certificate.Data != NULL) { 119899ebb4caSwyllys free(kmf_cert->certificate.Data); 119999ebb4caSwyllys kmf_cert->certificate.Data = NULL; 120099ebb4caSwyllys kmf_cert->certificate.Length = 0; 120199ebb4caSwyllys } 120299ebb4caSwyllys if (kmf_cert->kmf_private.label) 120399ebb4caSwyllys free(kmf_cert->kmf_private.label); 120499ebb4caSwyllys } 120599ebb4caSwyllys } 120699ebb4caSwyllys 120730a5e8faSwyllys /*ARGSUSED*/ 120899ebb4caSwyllys KMF_RETURN 120930a5e8faSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 121099ebb4caSwyllys { 121199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 121230a5e8faSwyllys KMF_DATA *cert = NULL; 121330a5e8faSwyllys char *outfilename = NULL; 121430a5e8faSwyllys char *dirpath = NULL; 121530a5e8faSwyllys char *fullpath = NULL; 121699ebb4caSwyllys KMF_ENCODE_FORMAT format; 121799ebb4caSwyllys 121830a5e8faSwyllys /* Get the cert data */ 121930a5e8faSwyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 122030a5e8faSwyllys if (cert == NULL || cert->Data == NULL) 122199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 122299ebb4caSwyllys 122330a5e8faSwyllys /* Check the output filename and directory attributes. */ 122430a5e8faSwyllys outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 122530a5e8faSwyllys numattr); 122630a5e8faSwyllys if (outfilename == NULL) 122730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 122899ebb4caSwyllys 122930a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 123030a5e8faSwyllys fullpath = get_fullpath(dirpath, outfilename); 123199ebb4caSwyllys if (fullpath == NULL) 123230a5e8faSwyllys return (KMF_ERR_BAD_CERTFILE); 123399ebb4caSwyllys 123430a5e8faSwyllys /* Check the optional format attribute */ 123530a5e8faSwyllys ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 123630a5e8faSwyllys &format, NULL); 123730a5e8faSwyllys if (ret != KMF_OK) { 123830a5e8faSwyllys /* If there is no format attribute, then default to PEM */ 123930a5e8faSwyllys format = KMF_FORMAT_PEM; 124099ebb4caSwyllys ret = KMF_OK; 124130a5e8faSwyllys } else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) { 124230a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 124399ebb4caSwyllys goto out; 124499ebb4caSwyllys } 124599ebb4caSwyllys 124630a5e8faSwyllys /* Store the certificate in the file with the specified format */ 124730a5e8faSwyllys ret = kmf_create_cert_file(cert, format, fullpath); 124899ebb4caSwyllys 124999ebb4caSwyllys out: 125099ebb4caSwyllys if (fullpath != NULL) 125199ebb4caSwyllys free(fullpath); 125299ebb4caSwyllys 125399ebb4caSwyllys return (ret); 125499ebb4caSwyllys } 125599ebb4caSwyllys 125630a5e8faSwyllys 125799ebb4caSwyllys KMF_RETURN 125830a5e8faSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 125999ebb4caSwyllys { 126099ebb4caSwyllys KMF_RETURN rv; 126199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 126299ebb4caSwyllys KMF_DATA certdata = {NULL, 0}; 126330a5e8faSwyllys char *dirpath = NULL; 126430a5e8faSwyllys char *filename = NULL; 126530a5e8faSwyllys char *fullpath = NULL; 126630a5e8faSwyllys char *issuer = NULL; 126730a5e8faSwyllys char *subject = NULL; 126830a5e8faSwyllys KMF_BIGINT *serial = NULL; 126930a5e8faSwyllys KMF_CERT_VALIDITY validity; 127099ebb4caSwyllys 127130a5e8faSwyllys /* 127230a5e8faSwyllys * Get the DIRPATH and CERT_FILENAME attributes. They can not be 127330a5e8faSwyllys * NULL at the same time. 127430a5e8faSwyllys */ 127530a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 127630a5e8faSwyllys filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 127730a5e8faSwyllys numattr); 127830a5e8faSwyllys fullpath = get_fullpath(dirpath, filename); 127999ebb4caSwyllys if (fullpath == NULL) 128099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 128199ebb4caSwyllys 128230a5e8faSwyllys /* Get optional search criteria attributes */ 128330a5e8faSwyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 128430a5e8faSwyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 128530a5e8faSwyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 128630a5e8faSwyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, 128730a5e8faSwyllys &validity, NULL); 128830a5e8faSwyllys if (rv != KMF_OK) { 128930a5e8faSwyllys validity = KMF_ALL_CERTS; 129030a5e8faSwyllys rv = KMF_OK; 129130a5e8faSwyllys } 129230a5e8faSwyllys 129399ebb4caSwyllys if (isdir(fullpath)) { 129499ebb4caSwyllys DIR *dirp; 129599ebb4caSwyllys struct dirent *dp; 129699ebb4caSwyllys 129799ebb4caSwyllys /* open all files in the directory and attempt to read them */ 129899ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 129999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 130099ebb4caSwyllys } 130199ebb4caSwyllys 130299ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 130399ebb4caSwyllys if (strcmp(dp->d_name, ".") != 0 && 130499ebb4caSwyllys strcmp(dp->d_name, "..") != 0) { 130599ebb4caSwyllys char *fname; 130699ebb4caSwyllys 130799ebb4caSwyllys fname = get_fullpath(fullpath, 130899ebb4caSwyllys (char *)&dp->d_name); 130999ebb4caSwyllys 131099ebb4caSwyllys if (fname == NULL) { 131199ebb4caSwyllys rv = KMF_ERR_MEMORY; 131299ebb4caSwyllys break; 131399ebb4caSwyllys } 131499ebb4caSwyllys 131530a5e8faSwyllys rv = kmf_load_cert(kmfh, issuer, subject, 131630a5e8faSwyllys serial, validity, fname, &certdata); 131799ebb4caSwyllys 131899ebb4caSwyllys if (rv == KMF_ERR_CERT_NOT_FOUND) { 131999ebb4caSwyllys free(fname); 132099ebb4caSwyllys if (certdata.Data) 132199ebb4caSwyllys free(certdata.Data); 132299ebb4caSwyllys rv = KMF_OK; 132399ebb4caSwyllys continue; 132499ebb4caSwyllys } else if (rv != KMF_OK) { 132599ebb4caSwyllys free(fname); 132699ebb4caSwyllys break; 132799ebb4caSwyllys } 132899ebb4caSwyllys 132999ebb4caSwyllys if (unlink(fname) != 0) { 133099ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 133199ebb4caSwyllys rv = KMF_ERR_INTERNAL; 133299ebb4caSwyllys free(fname); 133399ebb4caSwyllys break; 133499ebb4caSwyllys } 133599ebb4caSwyllys free(fname); 133699ebb4caSwyllys if (certdata.Data) 133799ebb4caSwyllys free(certdata.Data); 133899ebb4caSwyllys } 133999ebb4caSwyllys } 134099ebb4caSwyllys (void) closedir(dirp); 134199ebb4caSwyllys } else { 134299ebb4caSwyllys /* Just try to load a single certificate */ 134330a5e8faSwyllys rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, 134430a5e8faSwyllys fullpath, &certdata); 134599ebb4caSwyllys if (rv == KMF_OK) { 134699ebb4caSwyllys if (unlink(fullpath) != 0) { 134799ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 134899ebb4caSwyllys rv = KMF_ERR_INTERNAL; 134999ebb4caSwyllys } 135099ebb4caSwyllys } 135199ebb4caSwyllys } 135299ebb4caSwyllys 135399ebb4caSwyllys out: 135499ebb4caSwyllys if (fullpath != NULL) 135599ebb4caSwyllys free(fullpath); 135699ebb4caSwyllys 135799ebb4caSwyllys if (certdata.Data) 135899ebb4caSwyllys free(certdata.Data); 135999ebb4caSwyllys 136099ebb4caSwyllys return (rv); 136199ebb4caSwyllys } 136299ebb4caSwyllys 136399ebb4caSwyllys KMF_RETURN 136499ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 136599ebb4caSwyllys KMF_DATA *keydata) 136699ebb4caSwyllys { 136799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 136899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 136999ebb4caSwyllys int n; 137099ebb4caSwyllys 137199ebb4caSwyllys if (key == NULL || keydata == NULL || 137299ebb4caSwyllys key->keyp == NULL) 137399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 137499ebb4caSwyllys 137599ebb4caSwyllys if (key->keyalg == KMF_RSA) { 137699ebb4caSwyllys RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp); 137799ebb4caSwyllys 137899ebb4caSwyllys if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) { 137999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 138099ebb4caSwyllys return (KMF_ERR_ENCODING); 138199ebb4caSwyllys } 138299ebb4caSwyllys RSA_free(pubkey); 138399ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 138499ebb4caSwyllys DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp); 138599ebb4caSwyllys 138699ebb4caSwyllys if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) { 138799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 138899ebb4caSwyllys return (KMF_ERR_ENCODING); 138999ebb4caSwyllys } 139099ebb4caSwyllys DSA_free(pubkey); 139199ebb4caSwyllys } else { 139299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 139399ebb4caSwyllys } 139499ebb4caSwyllys keydata->Length = n; 139599ebb4caSwyllys 139699ebb4caSwyllys cleanup: 139799ebb4caSwyllys if (rv != KMF_OK) { 139899ebb4caSwyllys if (keydata->Data) 139999ebb4caSwyllys free(keydata->Data); 140099ebb4caSwyllys keydata->Data = NULL; 140199ebb4caSwyllys keydata->Length = 0; 140299ebb4caSwyllys } 140399ebb4caSwyllys 140499ebb4caSwyllys return (rv); 140599ebb4caSwyllys } 140699ebb4caSwyllys 140799ebb4caSwyllys static KMF_RETURN 140830a5e8faSwyllys ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, 140930a5e8faSwyllys KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private) 141099ebb4caSwyllys { 141199ebb4caSwyllys int rv = 0; 141299ebb4caSwyllys RSA *rsa; 141399ebb4caSwyllys DSA *dsa; 141499ebb4caSwyllys 14155b3e1433Swyllys if (pkey == NULL || out == NULL) 14165b3e1433Swyllys return (KMF_ERR_BAD_PARAMETER); 14175b3e1433Swyllys 141899ebb4caSwyllys switch (format) { 1419*73cc0e02Swyllys case KMF_FORMAT_RAWKEY: 1420*73cc0e02Swyllys /* same as ASN.1 */ 142199ebb4caSwyllys case KMF_FORMAT_ASN1: 142299ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 142399ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 142430a5e8faSwyllys if (private) 142599ebb4caSwyllys rv = i2d_RSAPrivateKey_bio(out, rsa); 142630a5e8faSwyllys else 142730a5e8faSwyllys rv = i2d_RSAPublicKey_bio(out, rsa); 142899ebb4caSwyllys RSA_free(rsa); 142999ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 143099ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 143199ebb4caSwyllys rv = i2d_DSAPrivateKey_bio(out, dsa); 143299ebb4caSwyllys DSA_free(dsa); 143399ebb4caSwyllys } 143499ebb4caSwyllys if (rv == 1) { 143599ebb4caSwyllys rv = KMF_OK; 143699ebb4caSwyllys } else { 143799ebb4caSwyllys SET_ERROR(kmfh, rv); 143899ebb4caSwyllys } 143999ebb4caSwyllys break; 144099ebb4caSwyllys case KMF_FORMAT_PEM: 144199ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 144299ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 144330a5e8faSwyllys if (private) 144499ebb4caSwyllys rv = PEM_write_bio_RSAPrivateKey(out, 144530a5e8faSwyllys rsa, NULL, NULL, 0, NULL, 144630a5e8faSwyllys (cred != NULL ? cred->cred : NULL)); 144730a5e8faSwyllys else 144830a5e8faSwyllys rv = PEM_write_bio_RSAPublicKey(out, 144930a5e8faSwyllys rsa); 145099ebb4caSwyllys RSA_free(rsa); 145199ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 145299ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 145399ebb4caSwyllys rv = PEM_write_bio_DSAPrivateKey(out, 145430a5e8faSwyllys dsa, NULL, NULL, 0, NULL, 145530a5e8faSwyllys (cred != NULL ? cred->cred : NULL)); 145699ebb4caSwyllys DSA_free(dsa); 145799ebb4caSwyllys } 145899ebb4caSwyllys 145999ebb4caSwyllys if (rv == 1) { 146099ebb4caSwyllys rv = KMF_OK; 146199ebb4caSwyllys } else { 146299ebb4caSwyllys SET_ERROR(kmfh, rv); 146399ebb4caSwyllys } 146499ebb4caSwyllys break; 146599ebb4caSwyllys 146699ebb4caSwyllys default: 146799ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 146899ebb4caSwyllys } 146999ebb4caSwyllys 147099ebb4caSwyllys return (rv); 147199ebb4caSwyllys } 147299ebb4caSwyllys 147399ebb4caSwyllys KMF_RETURN 147430a5e8faSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, 147530a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 147699ebb4caSwyllys { 147799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 147899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 147999ebb4caSwyllys uint32_t eValue = 0x010001; 148099ebb4caSwyllys RSA *sslPrivKey = NULL; 148199ebb4caSwyllys DSA *sslDSAKey = NULL; 148299ebb4caSwyllys EVP_PKEY *eprikey = NULL; 148399ebb4caSwyllys EVP_PKEY *epubkey = NULL; 148499ebb4caSwyllys BIO *out = NULL; 148530a5e8faSwyllys KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL; 148630a5e8faSwyllys uint32_t keylen = 1024; 148730a5e8faSwyllys uint32_t keylen_size = sizeof (uint32_t); 148830a5e8faSwyllys boolean_t storekey = TRUE; 148930a5e8faSwyllys KMF_KEY_ALG keytype = KMF_RSA; 149099ebb4caSwyllys 149130a5e8faSwyllys rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr, 149230a5e8faSwyllys &storekey, NULL); 149330a5e8faSwyllys if (rv != KMF_OK) { 149430a5e8faSwyllys /* "storekey" is optional. Default is TRUE */ 149530a5e8faSwyllys rv = KMF_OK; 149699ebb4caSwyllys } 149799ebb4caSwyllys 149830a5e8faSwyllys rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 149930a5e8faSwyllys (void *)&keytype, NULL); 150030a5e8faSwyllys if (rv != KMF_OK) 150130a5e8faSwyllys /* keytype is optional. KMF_RSA is default */ 150230a5e8faSwyllys rv = KMF_OK; 150399ebb4caSwyllys 150430a5e8faSwyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); 150530a5e8faSwyllys if (pubkey == NULL) 150699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 150799ebb4caSwyllys 150830a5e8faSwyllys privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); 150930a5e8faSwyllys if (privkey == NULL) 151030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 151130a5e8faSwyllys 151230a5e8faSwyllys (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); 151330a5e8faSwyllys (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); 151499ebb4caSwyllys 151599ebb4caSwyllys eprikey = EVP_PKEY_new(); 151699ebb4caSwyllys if (eprikey == NULL) { 151799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 151899ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 151999ebb4caSwyllys goto cleanup; 152099ebb4caSwyllys } 152199ebb4caSwyllys epubkey = EVP_PKEY_new(); 152299ebb4caSwyllys if (epubkey == NULL) { 152399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 152499ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 152599ebb4caSwyllys goto cleanup; 152699ebb4caSwyllys } 152730a5e8faSwyllys if (keytype == KMF_RSA) { 152830a5e8faSwyllys KMF_BIGINT *rsaexp = NULL; 152999ebb4caSwyllys 153030a5e8faSwyllys rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr); 153130a5e8faSwyllys if (rsaexp != NULL) { 153230a5e8faSwyllys if (rsaexp->len > 0 && 153330a5e8faSwyllys rsaexp->len <= sizeof (eValue) && 153430a5e8faSwyllys rsaexp->val != NULL) { 153530a5e8faSwyllys /*LINTED*/ 153630a5e8faSwyllys eValue = *(uint32_t *)rsaexp->val; 153730a5e8faSwyllys } else { 153830a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 153930a5e8faSwyllys goto cleanup; 154030a5e8faSwyllys } 154130a5e8faSwyllys } else { 154230a5e8faSwyllys /* RSA Exponent is optional. Default is 0x10001 */ 154330a5e8faSwyllys rv = KMF_OK; 154430a5e8faSwyllys } 154530a5e8faSwyllys 154630a5e8faSwyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 154730a5e8faSwyllys &keylen, &keylen_size); 154830a5e8faSwyllys if (rv == KMF_ERR_ATTR_NOT_FOUND) 154930a5e8faSwyllys /* keylen is optional, default is 1024 */ 155030a5e8faSwyllys rv = KMF_OK; 155130a5e8faSwyllys if (rv != KMF_OK) { 155230a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 155330a5e8faSwyllys goto cleanup; 155430a5e8faSwyllys } 155530a5e8faSwyllys 155630a5e8faSwyllys sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL); 155799ebb4caSwyllys if (sslPrivKey == NULL) { 155899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 155999ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 156099ebb4caSwyllys } else { 156130a5e8faSwyllys (void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey); 156299ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 156399ebb4caSwyllys privkey->keyalg = KMF_RSA; 156499ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 156599ebb4caSwyllys privkey->israw = FALSE; 156699ebb4caSwyllys privkey->keyp = (void *)eprikey; 156730a5e8faSwyllys 156899ebb4caSwyllys /* OpenSSL derives the public key from the private */ 156930a5e8faSwyllys (void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey); 157099ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 157199ebb4caSwyllys pubkey->keyalg = KMF_RSA; 157299ebb4caSwyllys pubkey->israw = FALSE; 157399ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 157499ebb4caSwyllys pubkey->keyp = (void *)epubkey; 157599ebb4caSwyllys } 157630a5e8faSwyllys } else if (keytype == KMF_DSA) { 157730a5e8faSwyllys DSA *dp; 157899ebb4caSwyllys sslDSAKey = DSA_new(); 157999ebb4caSwyllys if (sslDSAKey == NULL) { 158099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 158199ebb4caSwyllys return (KMF_ERR_MEMORY); 158299ebb4caSwyllys } 158399ebb4caSwyllys 158499ebb4caSwyllys if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) == 158599ebb4caSwyllys NULL) { 158699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 158799ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 158899ebb4caSwyllys goto cleanup; 158999ebb4caSwyllys } 159099ebb4caSwyllys if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) == 159199ebb4caSwyllys NULL) { 159299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 159399ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 159499ebb4caSwyllys goto cleanup; 159599ebb4caSwyllys } 159699ebb4caSwyllys if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) == 159799ebb4caSwyllys NULL) { 159899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 159999ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 160099ebb4caSwyllys goto cleanup; 160199ebb4caSwyllys } 160299ebb4caSwyllys 160399ebb4caSwyllys if (!DSA_generate_key(sslDSAKey)) { 160499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 160599ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 160699ebb4caSwyllys goto cleanup; 160799ebb4caSwyllys } 160899ebb4caSwyllys 160999ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 161099ebb4caSwyllys privkey->keyalg = KMF_DSA; 161199ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 161299ebb4caSwyllys privkey->israw = FALSE; 161399ebb4caSwyllys if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { 161499ebb4caSwyllys privkey->keyp = (void *)eprikey; 161599ebb4caSwyllys } else { 161699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 161799ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 161899ebb4caSwyllys goto cleanup; 161999ebb4caSwyllys } 162030a5e8faSwyllys dp = DSA_new(); 162199ebb4caSwyllys /* Make a copy for the public key */ 162299ebb4caSwyllys if (dp != NULL) { 162399ebb4caSwyllys if ((dp->p = BN_new()) == NULL) { 162499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 162599ebb4caSwyllys rv = KMF_ERR_MEMORY; 162699ebb4caSwyllys DSA_free(dp); 162799ebb4caSwyllys goto cleanup; 162899ebb4caSwyllys } 162999ebb4caSwyllys if ((dp->q = BN_new()) == NULL) { 163099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 163199ebb4caSwyllys rv = KMF_ERR_MEMORY; 163299ebb4caSwyllys BN_free(dp->p); 163399ebb4caSwyllys DSA_free(dp); 163499ebb4caSwyllys goto cleanup; 163599ebb4caSwyllys } 163699ebb4caSwyllys if ((dp->g = BN_new()) == NULL) { 163799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 163899ebb4caSwyllys rv = KMF_ERR_MEMORY; 163999ebb4caSwyllys BN_free(dp->q); 164099ebb4caSwyllys BN_free(dp->p); 164199ebb4caSwyllys DSA_free(dp); 164299ebb4caSwyllys goto cleanup; 164399ebb4caSwyllys } 164499ebb4caSwyllys if ((dp->pub_key = BN_new()) == NULL) { 164599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 164699ebb4caSwyllys rv = KMF_ERR_MEMORY; 164799ebb4caSwyllys BN_free(dp->q); 164899ebb4caSwyllys BN_free(dp->p); 164999ebb4caSwyllys BN_free(dp->g); 165099ebb4caSwyllys DSA_free(dp); 165199ebb4caSwyllys goto cleanup; 165299ebb4caSwyllys } 165399ebb4caSwyllys (void) BN_copy(dp->p, sslDSAKey->p); 165499ebb4caSwyllys (void) BN_copy(dp->q, sslDSAKey->q); 165599ebb4caSwyllys (void) BN_copy(dp->g, sslDSAKey->g); 165699ebb4caSwyllys (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); 165799ebb4caSwyllys 165899ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 165999ebb4caSwyllys pubkey->keyalg = KMF_DSA; 166099ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 166199ebb4caSwyllys pubkey->israw = FALSE; 166299ebb4caSwyllys 166399ebb4caSwyllys if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { 166499ebb4caSwyllys pubkey->keyp = (void *)epubkey; 166599ebb4caSwyllys } else { 166699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 166799ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 166899ebb4caSwyllys goto cleanup; 166999ebb4caSwyllys } 167099ebb4caSwyllys } 167199ebb4caSwyllys } 167299ebb4caSwyllys 167399ebb4caSwyllys if (rv != KMF_OK) { 167499ebb4caSwyllys goto cleanup; 167599ebb4caSwyllys } 167699ebb4caSwyllys 167730a5e8faSwyllys if (storekey) { 167830a5e8faSwyllys KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */ 167930a5e8faSwyllys int i = 0; 168030a5e8faSwyllys char *keyfile = NULL, *dirpath = NULL; 168130a5e8faSwyllys KMF_ENCODE_FORMAT format; 168230a5e8faSwyllys /* 168330a5e8faSwyllys * Construct a new attribute arrray and call openssl_store_key 168430a5e8faSwyllys */ 168530a5e8faSwyllys kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR, 168630a5e8faSwyllys privkey, sizeof (privkey)); 168730a5e8faSwyllys i++; 168830a5e8faSwyllys 168930a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 169030a5e8faSwyllys if (dirpath != NULL) { 169130a5e8faSwyllys storeattrs[i].type = KMF_DIRPATH_ATTR; 169230a5e8faSwyllys storeattrs[i].pValue = dirpath; 169330a5e8faSwyllys storeattrs[i].valueLen = strlen(dirpath); 169430a5e8faSwyllys i++; 169530a5e8faSwyllys } else { 169630a5e8faSwyllys rv = KMF_OK; /* DIRPATH is optional */ 169799ebb4caSwyllys } 169830a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, 169930a5e8faSwyllys attrlist, numattr); 170030a5e8faSwyllys if (keyfile != NULL) { 170130a5e8faSwyllys storeattrs[i].type = KMF_KEY_FILENAME_ATTR; 170230a5e8faSwyllys storeattrs[i].pValue = keyfile; 170330a5e8faSwyllys storeattrs[i].valueLen = strlen(keyfile); 170430a5e8faSwyllys i++; 170530a5e8faSwyllys } else { 170630a5e8faSwyllys goto cleanup; /* KEYFILE is required */ 170730a5e8faSwyllys } 170830a5e8faSwyllys rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 170930a5e8faSwyllys (void *)&format, NULL); 171030a5e8faSwyllys if (rv == KMF_OK) { 171130a5e8faSwyllys storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR; 171230a5e8faSwyllys storeattrs[i].pValue = &format; 171330a5e8faSwyllys storeattrs[i].valueLen = sizeof (format); 171430a5e8faSwyllys i++; 171530a5e8faSwyllys } 171630a5e8faSwyllys 171730a5e8faSwyllys rv = OpenSSL_StoreKey(handle, i, storeattrs); 171830a5e8faSwyllys } 171999ebb4caSwyllys 172099ebb4caSwyllys cleanup: 172199ebb4caSwyllys if (rv != KMF_OK) { 172299ebb4caSwyllys if (eprikey != NULL) 172399ebb4caSwyllys EVP_PKEY_free(eprikey); 172499ebb4caSwyllys 172599ebb4caSwyllys if (epubkey != NULL) 172699ebb4caSwyllys EVP_PKEY_free(epubkey); 172799ebb4caSwyllys 172899ebb4caSwyllys if (pubkey->keylabel) { 172999ebb4caSwyllys free(pubkey->keylabel); 173099ebb4caSwyllys pubkey->keylabel = NULL; 173199ebb4caSwyllys } 173299ebb4caSwyllys 173399ebb4caSwyllys if (privkey->keylabel) { 173499ebb4caSwyllys free(privkey->keylabel); 173599ebb4caSwyllys privkey->keylabel = NULL; 173699ebb4caSwyllys } 173799ebb4caSwyllys 173899ebb4caSwyllys pubkey->keyp = NULL; 173999ebb4caSwyllys privkey->keyp = NULL; 174099ebb4caSwyllys } 174199ebb4caSwyllys 174299ebb4caSwyllys if (sslPrivKey) 174399ebb4caSwyllys RSA_free(sslPrivKey); 174499ebb4caSwyllys 174599ebb4caSwyllys if (sslDSAKey) 174699ebb4caSwyllys DSA_free(sslDSAKey); 174799ebb4caSwyllys 174899ebb4caSwyllys if (out != NULL) 174999ebb4caSwyllys (void) BIO_free(out); 175099ebb4caSwyllys 175199ebb4caSwyllys return (rv); 175299ebb4caSwyllys } 175399ebb4caSwyllys 175499ebb4caSwyllys KMF_RETURN 175599ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 175699ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output) 175799ebb4caSwyllys { 175899ebb4caSwyllys KMF_RETURN ret = KMF_OK; 175999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 176099ebb4caSwyllys KMF_ALGORITHM_INDEX AlgId; 176199ebb4caSwyllys EVP_MD_CTX ctx; 176299ebb4caSwyllys const EVP_MD *md; 176302744e81Swyllys 176499ebb4caSwyllys if (key == NULL || AlgOID == NULL || 176599ebb4caSwyllys tobesigned == NULL || output == NULL || 176699ebb4caSwyllys tobesigned->Data == NULL || 176799ebb4caSwyllys output->Data == NULL) 176899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 176999ebb4caSwyllys 177099ebb4caSwyllys /* Map the OID to an OpenSSL algorithm */ 177130a5e8faSwyllys AlgId = x509_algoid_to_algid(AlgOID); 177299ebb4caSwyllys if (AlgId == KMF_ALGID_NONE) 177399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 177499ebb4caSwyllys 177599ebb4caSwyllys if (key->keyalg == KMF_RSA) { 177699ebb4caSwyllys EVP_PKEY *pkey = (EVP_PKEY *)key->keyp; 177799ebb4caSwyllys uchar_t *p; 177802744e81Swyllys int len; 177999ebb4caSwyllys if (AlgId == KMF_ALGID_MD5WithRSA) 178099ebb4caSwyllys md = EVP_md5(); 178199ebb4caSwyllys else if (AlgId == KMF_ALGID_MD2WithRSA) 178299ebb4caSwyllys md = EVP_md2(); 178399ebb4caSwyllys else if (AlgId == KMF_ALGID_SHA1WithRSA) 178499ebb4caSwyllys md = EVP_sha1(); 178502744e81Swyllys else if (AlgId == KMF_ALGID_RSA) 178602744e81Swyllys md = NULL; 178799ebb4caSwyllys else 178899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 178999ebb4caSwyllys 179002744e81Swyllys if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) { 179102744e81Swyllys RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey); 179299ebb4caSwyllys 179302744e81Swyllys p = output->Data; 179402744e81Swyllys if ((len = RSA_private_encrypt(tobesigned->Length, 179502744e81Swyllys tobesigned->Data, p, rsa, 179602744e81Swyllys RSA_PKCS1_PADDING)) <= 0) { 179702744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 179802744e81Swyllys ret = KMF_ERR_INTERNAL; 179902744e81Swyllys } 180002744e81Swyllys output->Length = len; 180102744e81Swyllys } else { 180299ebb4caSwyllys (void) EVP_MD_CTX_init(&ctx); 180399ebb4caSwyllys (void) EVP_SignInit_ex(&ctx, md, NULL); 180499ebb4caSwyllys (void) EVP_SignUpdate(&ctx, tobesigned->Data, 180599ebb4caSwyllys (uint32_t)tobesigned->Length); 180699ebb4caSwyllys len = (uint32_t)output->Length; 180799ebb4caSwyllys p = output->Data; 180802744e81Swyllys if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) { 180999ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 181002744e81Swyllys len = 0; 181102744e81Swyllys ret = KMF_ERR_INTERNAL; 181299ebb4caSwyllys } 181399ebb4caSwyllys output->Length = len; 181499ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 181502744e81Swyllys } 181699ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 181799ebb4caSwyllys DSA *dsa = EVP_PKEY_get1_DSA(key->keyp); 181899ebb4caSwyllys 181999ebb4caSwyllys uchar_t hash[EVP_MAX_MD_SIZE]; 182099ebb4caSwyllys uint32_t hashlen; 182199ebb4caSwyllys DSA_SIG *dsasig; 182299ebb4caSwyllys 182399ebb4caSwyllys /* 182499ebb4caSwyllys * OpenSSL EVP_Sign operation automatically converts to 182599ebb4caSwyllys * ASN.1 output so we do the operations separately so we 182699ebb4caSwyllys * are assured of NOT getting ASN.1 output returned. 182799ebb4caSwyllys * KMF does not want ASN.1 encoded results because 182899ebb4caSwyllys * not all mechanisms return ASN.1 encodings (PKCS#11 182999ebb4caSwyllys * and NSS return raw signature data). 183099ebb4caSwyllys */ 183199ebb4caSwyllys md = EVP_sha1(); 183299ebb4caSwyllys EVP_MD_CTX_init(&ctx); 183399ebb4caSwyllys (void) EVP_DigestInit_ex(&ctx, md, NULL); 183499ebb4caSwyllys (void) EVP_DigestUpdate(&ctx, tobesigned->Data, 183599ebb4caSwyllys tobesigned->Length); 183699ebb4caSwyllys (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen); 183799ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 183899ebb4caSwyllys 183999ebb4caSwyllys dsasig = DSA_do_sign(hash, hashlen, dsa); 184099ebb4caSwyllys if (dsasig != NULL) { 184199ebb4caSwyllys int i; 184299ebb4caSwyllys output->Length = i = BN_bn2bin(dsasig->r, output->Data); 184399ebb4caSwyllys output->Length += BN_bn2bin(dsasig->s, 184499ebb4caSwyllys &output->Data[i]); 184599ebb4caSwyllys DSA_SIG_free(dsasig); 184699ebb4caSwyllys } else { 184799ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 184899ebb4caSwyllys } 184999ebb4caSwyllys } else { 185099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 185199ebb4caSwyllys } 185299ebb4caSwyllys cleanup: 185399ebb4caSwyllys return (ret); 185499ebb4caSwyllys } 185599ebb4caSwyllys 185699ebb4caSwyllys KMF_RETURN 185799ebb4caSwyllys /*ARGSUSED*/ 185830a5e8faSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T handle, 185930a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 186099ebb4caSwyllys { 186199ebb4caSwyllys KMF_RETURN rv = KMF_OK; 186230a5e8faSwyllys KMF_KEY_HANDLE *key; 186330a5e8faSwyllys boolean_t destroy = B_TRUE; 186430a5e8faSwyllys 186530a5e8faSwyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 186699ebb4caSwyllys if (key == NULL || key->keyp == NULL) 186799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 186899ebb4caSwyllys 186930a5e8faSwyllys rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, 187030a5e8faSwyllys (void *)&destroy, NULL); 187130a5e8faSwyllys if (rv != KMF_OK) { 187230a5e8faSwyllys /* "destroy" is optional. Default is TRUE */ 187330a5e8faSwyllys rv = KMF_OK; 187430a5e8faSwyllys } 187530a5e8faSwyllys 187699ebb4caSwyllys if (key->keyclass != KMF_ASYM_PUB && 187799ebb4caSwyllys key->keyclass != KMF_ASYM_PRI && 187899ebb4caSwyllys key->keyclass != KMF_SYMMETRIC) 187999ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 188099ebb4caSwyllys 188199ebb4caSwyllys if (key->keyclass == KMF_SYMMETRIC) { 188230a5e8faSwyllys kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp); 188399ebb4caSwyllys key->keyp = NULL; 188499ebb4caSwyllys } else { 188599ebb4caSwyllys if (key->keyp != NULL) { 188699ebb4caSwyllys EVP_PKEY_free(key->keyp); 188799ebb4caSwyllys key->keyp = NULL; 188899ebb4caSwyllys } 188999ebb4caSwyllys } 189099ebb4caSwyllys 189199ebb4caSwyllys if (key->keylabel != NULL) { 189299ebb4caSwyllys EVP_PKEY *pkey = NULL; 189399ebb4caSwyllys /* If the file exists, make sure it is a proper key. */ 189499ebb4caSwyllys pkey = openssl_load_key(handle, key->keylabel); 189599ebb4caSwyllys if (pkey == NULL) { 18965b3e1433Swyllys if (key->keylabel != NULL) { 189799ebb4caSwyllys free(key->keylabel); 189899ebb4caSwyllys key->keylabel = NULL; 18995b3e1433Swyllys } 190099ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 190199ebb4caSwyllys } 190299ebb4caSwyllys EVP_PKEY_free(pkey); 190399ebb4caSwyllys 190499ebb4caSwyllys if (destroy) { 190599ebb4caSwyllys if (unlink(key->keylabel) != 0) { 190699ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 190799ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 190899ebb4caSwyllys rv = KMF_ERR_INTERNAL; 190999ebb4caSwyllys } 191099ebb4caSwyllys } 191199ebb4caSwyllys if (key->keylabel != NULL) { 191299ebb4caSwyllys free(key->keylabel); 191399ebb4caSwyllys key->keylabel = NULL; 191499ebb4caSwyllys } 191599ebb4caSwyllys } 191699ebb4caSwyllys return (rv); 191799ebb4caSwyllys } 191899ebb4caSwyllys 191999ebb4caSwyllys KMF_RETURN 192099ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 192199ebb4caSwyllys { 192299ebb4caSwyllys KMF_RETURN ret = KMF_OK; 192399ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 192499ebb4caSwyllys char str[256]; /* OpenSSL needs at least 120 byte buffer */ 192599ebb4caSwyllys 192699ebb4caSwyllys ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str)); 192799ebb4caSwyllys if (strlen(str)) { 192899ebb4caSwyllys *msgstr = (char *)strdup(str); 192999ebb4caSwyllys if ((*msgstr) == NULL) 193099ebb4caSwyllys ret = KMF_ERR_MEMORY; 193199ebb4caSwyllys } else { 193299ebb4caSwyllys *msgstr = NULL; 193399ebb4caSwyllys } 193499ebb4caSwyllys 193599ebb4caSwyllys return (ret); 193699ebb4caSwyllys } 193799ebb4caSwyllys 193899ebb4caSwyllys static int 193999ebb4caSwyllys ext2NID(int kmfext) 194099ebb4caSwyllys { 194199ebb4caSwyllys switch (kmfext) { 194299ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 194399ebb4caSwyllys return (NID_key_usage); 194499ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 194599ebb4caSwyllys return (NID_private_key_usage_period); 194699ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 194799ebb4caSwyllys return (NID_certificate_policies); 194899ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 194999ebb4caSwyllys return (NID_subject_alt_name); 195099ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 195199ebb4caSwyllys return (NID_issuer_alt_name); 195299ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 195399ebb4caSwyllys return (NID_basic_constraints); 195499ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 195599ebb4caSwyllys return (NID_ext_key_usage); 195699ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 195799ebb4caSwyllys return (NID_authority_key_identifier); 195899ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 195999ebb4caSwyllys return (NID_crl_distribution_points); 196099ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 196199ebb4caSwyllys return (NID_subject_key_identifier); 196299ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 196399ebb4caSwyllys return (OBJ_sn2nid("policyMappings")); 196499ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 196599ebb4caSwyllys return (OBJ_sn2nid("nameConstraints")); 196699ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 196799ebb4caSwyllys return (OBJ_sn2nid("policyConstraints")); 196899ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 196999ebb4caSwyllys return (OBJ_sn2nid("inhibitAnyPolicy")); 197099ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 197199ebb4caSwyllys return (OBJ_sn2nid("freshestCRL")); 197299ebb4caSwyllys default: 197399ebb4caSwyllys return (NID_undef); 197499ebb4caSwyllys } 197599ebb4caSwyllys } 197699ebb4caSwyllys 197799ebb4caSwyllys KMF_RETURN 197899ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, 197999ebb4caSwyllys KMF_PRINTABLE_ITEM flag, char *resultStr) 198099ebb4caSwyllys { 198199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 198299ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 198399ebb4caSwyllys X509 *xcert = NULL; 198499ebb4caSwyllys unsigned char *outbuf = NULL; 198599ebb4caSwyllys unsigned char *outbuf_p; 198699ebb4caSwyllys char *tmpstr = NULL; 198799ebb4caSwyllys int j; 198899ebb4caSwyllys int ext_index, nid, len; 198999ebb4caSwyllys BIO *mem = NULL; 199099ebb4caSwyllys STACK *emlst = NULL; 199199ebb4caSwyllys X509_EXTENSION *ex; 199299ebb4caSwyllys X509_CINF *ci; 199399ebb4caSwyllys 199499ebb4caSwyllys if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) { 199599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 199699ebb4caSwyllys } 199799ebb4caSwyllys 199899ebb4caSwyllys /* copy cert data to outbuf */ 199999ebb4caSwyllys outbuf = malloc(pcert->Length); 200099ebb4caSwyllys if (outbuf == NULL) { 200199ebb4caSwyllys return (KMF_ERR_MEMORY); 200299ebb4caSwyllys } 200399ebb4caSwyllys (void) memcpy(outbuf, pcert->Data, pcert->Length); 200499ebb4caSwyllys 200599ebb4caSwyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 200699ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length); 200799ebb4caSwyllys if (xcert == NULL) { 200899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 200999ebb4caSwyllys ret = KMF_ERR_ENCODING; 201099ebb4caSwyllys goto out; 201199ebb4caSwyllys } 201299ebb4caSwyllys 201399ebb4caSwyllys mem = BIO_new(BIO_s_mem()); 201499ebb4caSwyllys if (mem == NULL) { 201599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 201699ebb4caSwyllys ret = KMF_ERR_MEMORY; 201799ebb4caSwyllys goto out; 201899ebb4caSwyllys } 201999ebb4caSwyllys 202099ebb4caSwyllys switch (flag) { 202199ebb4caSwyllys case KMF_CERT_ISSUER: 202299ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0, 202399ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 202499ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 202599ebb4caSwyllys break; 202699ebb4caSwyllys 202799ebb4caSwyllys case KMF_CERT_SUBJECT: 202899ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0, 202999ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 203099ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 203199ebb4caSwyllys break; 203299ebb4caSwyllys 203399ebb4caSwyllys case KMF_CERT_VERSION: 203499ebb4caSwyllys tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version); 203599ebb4caSwyllys (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN); 203699ebb4caSwyllys OPENSSL_free(tmpstr); 203799ebb4caSwyllys len = strlen(resultStr); 203899ebb4caSwyllys break; 203999ebb4caSwyllys 204099ebb4caSwyllys case KMF_CERT_SERIALNUM: 204199ebb4caSwyllys if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) { 204299ebb4caSwyllys (void) strcpy(resultStr, "0x"); 204399ebb4caSwyllys len = BIO_gets(mem, &resultStr[2], 204499ebb4caSwyllys KMF_CERT_PRINTABLE_LEN - 2); 204599ebb4caSwyllys } 204699ebb4caSwyllys break; 204799ebb4caSwyllys 204899ebb4caSwyllys case KMF_CERT_NOTBEFORE: 204999ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert)); 205099ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 205199ebb4caSwyllys break; 205299ebb4caSwyllys 205399ebb4caSwyllys case KMF_CERT_NOTAFTER: 205499ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert)); 205599ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 205699ebb4caSwyllys break; 205799ebb4caSwyllys 205899ebb4caSwyllys case KMF_CERT_PUBKEY_DATA: 205999ebb4caSwyllys { 206099ebb4caSwyllys EVP_PKEY *pkey = X509_get_pubkey(xcert); 206199ebb4caSwyllys if (pkey == NULL) { 206299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 206399ebb4caSwyllys ret = KMF_ERR_ENCODING; 206499ebb4caSwyllys goto out; 206599ebb4caSwyllys } 206699ebb4caSwyllys 206799ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 206899ebb4caSwyllys (void) BIO_printf(mem, 206999ebb4caSwyllys "RSA Public Key: (%d bit)\n", 207099ebb4caSwyllys BN_num_bits(pkey->pkey.rsa->n)); 207199ebb4caSwyllys (void) RSA_print(mem, pkey->pkey.rsa, 0); 207299ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 207399ebb4caSwyllys (void) BIO_printf(mem, 207499ebb4caSwyllys "%12sDSA Public Key:\n", ""); 207599ebb4caSwyllys (void) DSA_print(mem, pkey->pkey.dsa, 0); 207699ebb4caSwyllys } else { 207799ebb4caSwyllys (void) BIO_printf(mem, 207899ebb4caSwyllys "%12sUnknown Public Key:\n", ""); 207999ebb4caSwyllys } 208099ebb4caSwyllys (void) BIO_printf(mem, "\n"); 208199ebb4caSwyllys EVP_PKEY_free(pkey); 208299ebb4caSwyllys } 208399ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 208499ebb4caSwyllys break; 208599ebb4caSwyllys case KMF_CERT_SIGNATURE_ALG: 208699ebb4caSwyllys case KMF_CERT_PUBKEY_ALG: 208799ebb4caSwyllys if (flag == KMF_CERT_SIGNATURE_ALG) { 208899ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 208999ebb4caSwyllys xcert->sig_alg->algorithm); 209099ebb4caSwyllys } else { 209199ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 209299ebb4caSwyllys xcert->cert_info->key->algor->algorithm); 209399ebb4caSwyllys } 209499ebb4caSwyllys 209599ebb4caSwyllys if (len > 0) { 209699ebb4caSwyllys len = BIO_read(mem, resultStr, 209799ebb4caSwyllys KMF_CERT_PRINTABLE_LEN); 209899ebb4caSwyllys } 209999ebb4caSwyllys break; 210099ebb4caSwyllys 210199ebb4caSwyllys case KMF_CERT_EMAIL: 210299ebb4caSwyllys emlst = X509_get1_email(xcert); 210399ebb4caSwyllys for (j = 0; j < sk_num(emlst); j++) 210499ebb4caSwyllys (void) BIO_printf(mem, "%s\n", sk_value(emlst, j)); 210599ebb4caSwyllys 210699ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 210799ebb4caSwyllys X509_email_free(emlst); 210899ebb4caSwyllys break; 210999ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 211099ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 211199ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 211299ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 211399ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 211499ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 211599ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 211699ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 211799ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 211899ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 211999ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 212099ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 212199ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 212299ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 212399ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 212499ebb4caSwyllys nid = ext2NID(flag); 212599ebb4caSwyllys if (nid == NID_undef) { 212699ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 212799ebb4caSwyllys goto out; 212899ebb4caSwyllys } 212999ebb4caSwyllys ci = xcert->cert_info; 213099ebb4caSwyllys 213199ebb4caSwyllys ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1); 213299ebb4caSwyllys if (ext_index == -1) { 213399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 213499ebb4caSwyllys 213599ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 213699ebb4caSwyllys goto out; 213799ebb4caSwyllys } 213899ebb4caSwyllys ex = X509v3_get_ext(ci->extensions, ext_index); 213999ebb4caSwyllys 214099ebb4caSwyllys (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); 214199ebb4caSwyllys 214299ebb4caSwyllys if (BIO_printf(mem, ": %s\n", 214330a5e8faSwyllys X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) { 214499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 214599ebb4caSwyllys ret = KMF_ERR_ENCODING; 214699ebb4caSwyllys goto out; 214799ebb4caSwyllys } 214899ebb4caSwyllys if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) { 214999ebb4caSwyllys (void) BIO_printf(mem, "%*s", 4, ""); 215099ebb4caSwyllys (void) M_ASN1_OCTET_STRING_print(mem, ex->value); 215199ebb4caSwyllys } 215299ebb4caSwyllys if (BIO_write(mem, "\n", 1) <= 0) { 215399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 215499ebb4caSwyllys ret = KMF_ERR_ENCODING; 215599ebb4caSwyllys goto out; 215699ebb4caSwyllys } 215799ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 215899ebb4caSwyllys } 215999ebb4caSwyllys if (len <= 0) { 216099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 216199ebb4caSwyllys ret = KMF_ERR_ENCODING; 216299ebb4caSwyllys } 216399ebb4caSwyllys 216499ebb4caSwyllys out: 216599ebb4caSwyllys if (outbuf != NULL) { 216699ebb4caSwyllys free(outbuf); 216799ebb4caSwyllys } 216899ebb4caSwyllys 216999ebb4caSwyllys if (xcert != NULL) { 217099ebb4caSwyllys X509_free(xcert); 217199ebb4caSwyllys } 217299ebb4caSwyllys 217399ebb4caSwyllys if (mem != NULL) { 217499ebb4caSwyllys (void) BIO_free(mem); 217599ebb4caSwyllys } 217699ebb4caSwyllys 217799ebb4caSwyllys return (ret); 217899ebb4caSwyllys } 217930a5e8faSwyllys 218099ebb4caSwyllys KMF_RETURN 218199ebb4caSwyllys /*ARGSUSED*/ 218230a5e8faSwyllys OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, 218330a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 218499ebb4caSwyllys { 218599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 218630a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 218730a5e8faSwyllys KMF_KEY_CLASS keyclass = KMF_ASYM_PRI; 218830a5e8faSwyllys KMF_KEY_HANDLE *key = NULL; 218930a5e8faSwyllys uint32_t numkeys = 1; /* 1 key only */ 219030a5e8faSwyllys char *dirpath = NULL; 219130a5e8faSwyllys char *keyfile = NULL; 219230a5e8faSwyllys KMF_ATTRIBUTE new_attrlist[16]; 219330a5e8faSwyllys int i = 0; 219499ebb4caSwyllys 219599ebb4caSwyllys /* 219699ebb4caSwyllys * This is really just a FindKey operation, reuse the 219799ebb4caSwyllys * FindKey function. 219899ebb4caSwyllys */ 219930a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 220030a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 220130a5e8faSwyllys i++; 220299ebb4caSwyllys 220330a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 220430a5e8faSwyllys KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t)); 220530a5e8faSwyllys i++; 220699ebb4caSwyllys 220730a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 220830a5e8faSwyllys KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); 220930a5e8faSwyllys i++; 221030a5e8faSwyllys 221130a5e8faSwyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 221230a5e8faSwyllys if (key == NULL) { 221330a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 221430a5e8faSwyllys } else { 221530a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 221630a5e8faSwyllys KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); 221730a5e8faSwyllys i++; 221830a5e8faSwyllys } 221930a5e8faSwyllys 222030a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 222130a5e8faSwyllys if (dirpath != NULL) { 222230a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 222330a5e8faSwyllys KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); 222430a5e8faSwyllys i++; 222530a5e8faSwyllys } 222630a5e8faSwyllys 222730a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 222830a5e8faSwyllys if (keyfile == NULL) 222930a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 223030a5e8faSwyllys else { 223130a5e8faSwyllys kmf_set_attr_at_index(new_attrlist, i, 223230a5e8faSwyllys KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); 223330a5e8faSwyllys i++; 223430a5e8faSwyllys } 223530a5e8faSwyllys 223630a5e8faSwyllys rv = OpenSSL_FindKey(handle, i, new_attrlist); 223799ebb4caSwyllys return (rv); 223899ebb4caSwyllys } 223999ebb4caSwyllys 224099ebb4caSwyllys KMF_RETURN 224199ebb4caSwyllys /*ARGSUSED*/ 224299ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 224399ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *ciphertext, 224499ebb4caSwyllys KMF_DATA *output) 224599ebb4caSwyllys { 224699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 224799ebb4caSwyllys RSA *rsa = NULL; 224899ebb4caSwyllys unsigned int in_len = 0, out_len = 0; 224999ebb4caSwyllys unsigned int total_decrypted = 0, modulus_len = 0; 225099ebb4caSwyllys uint8_t *in_data, *out_data; 225199ebb4caSwyllys int i, blocks; 225299ebb4caSwyllys 225399ebb4caSwyllys if (key == NULL || AlgOID == NULL || 225499ebb4caSwyllys ciphertext == NULL || output == NULL || 225599ebb4caSwyllys ciphertext->Data == NULL || 225699ebb4caSwyllys output->Data == NULL) 225799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 225899ebb4caSwyllys 225999ebb4caSwyllys if (key->keyalg == KMF_RSA) { 226099ebb4caSwyllys rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp); 226199ebb4caSwyllys modulus_len = RSA_size(rsa); 226299ebb4caSwyllys } else { 226399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 226499ebb4caSwyllys } 226599ebb4caSwyllys 226699ebb4caSwyllys blocks = ciphertext->Length/modulus_len; 226799ebb4caSwyllys out_data = output->Data; 226899ebb4caSwyllys in_data = ciphertext->Data; 226999ebb4caSwyllys out_len = modulus_len - 11; 227099ebb4caSwyllys in_len = modulus_len; 227199ebb4caSwyllys 227299ebb4caSwyllys for (i = 0; i < blocks; i++) { 227399ebb4caSwyllys out_len = RSA_private_decrypt(in_len, 227499ebb4caSwyllys in_data, out_data, rsa, RSA_PKCS1_PADDING); 227599ebb4caSwyllys 227699ebb4caSwyllys if (out_len == 0) { 227799ebb4caSwyllys ret = KMF_ERR_INTERNAL; 227899ebb4caSwyllys goto cleanup; 227999ebb4caSwyllys } 228099ebb4caSwyllys 228199ebb4caSwyllys out_data += out_len; 228299ebb4caSwyllys total_decrypted += out_len; 228399ebb4caSwyllys in_data += in_len; 228499ebb4caSwyllys } 228599ebb4caSwyllys 228699ebb4caSwyllys output->Length = total_decrypted; 228799ebb4caSwyllys 228899ebb4caSwyllys cleanup: 228999ebb4caSwyllys RSA_free(rsa); 229099ebb4caSwyllys if (ret != KMF_OK) 229199ebb4caSwyllys output->Length = 0; 229299ebb4caSwyllys 229399ebb4caSwyllys return (ret); 229499ebb4caSwyllys 229599ebb4caSwyllys } 229699ebb4caSwyllys 229799ebb4caSwyllys /* 229899ebb4caSwyllys * This function will create a certid from issuer_cert and user_cert. 229999ebb4caSwyllys * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate 230099ebb4caSwyllys * certid memory after use. 230199ebb4caSwyllys */ 230299ebb4caSwyllys static KMF_RETURN 230399ebb4caSwyllys create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert, 230499ebb4caSwyllys const KMF_DATA *user_cert, OCSP_CERTID **certid) 230599ebb4caSwyllys { 230699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 230799ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 230899ebb4caSwyllys X509 *issuer = NULL; 230999ebb4caSwyllys X509 *cert = NULL; 231099ebb4caSwyllys unsigned char *ptmp; 231199ebb4caSwyllys 231299ebb4caSwyllys if (issuer_cert == NULL || user_cert == NULL) { 231399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 231499ebb4caSwyllys } 231599ebb4caSwyllys 231699ebb4caSwyllys /* convert the DER-encoded issuer cert to an internal X509 */ 231799ebb4caSwyllys ptmp = issuer_cert->Data; 231899ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 231999ebb4caSwyllys issuer_cert->Length); 232099ebb4caSwyllys if (issuer == NULL) { 232199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 232299ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 232399ebb4caSwyllys goto end; 232499ebb4caSwyllys } 232599ebb4caSwyllys 232699ebb4caSwyllys /* convert the DER-encoded user cert to an internal X509 */ 232799ebb4caSwyllys ptmp = user_cert->Data; 232899ebb4caSwyllys cert = d2i_X509(NULL, (const uchar_t **)&ptmp, 232999ebb4caSwyllys user_cert->Length); 233099ebb4caSwyllys if (cert == NULL) { 233199ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 233299ebb4caSwyllys 233399ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_CERT; 233499ebb4caSwyllys goto end; 233599ebb4caSwyllys } 233699ebb4caSwyllys 233799ebb4caSwyllys /* create a CERTID */ 233899ebb4caSwyllys *certid = OCSP_cert_to_id(NULL, cert, issuer); 233999ebb4caSwyllys if (*certid == NULL) { 234099ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 234199ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 234299ebb4caSwyllys goto end; 234399ebb4caSwyllys } 234499ebb4caSwyllys 234599ebb4caSwyllys end: 234699ebb4caSwyllys if (issuer != NULL) { 234799ebb4caSwyllys X509_free(issuer); 234899ebb4caSwyllys } 234999ebb4caSwyllys 235099ebb4caSwyllys if (cert != NULL) { 235199ebb4caSwyllys X509_free(cert); 235299ebb4caSwyllys } 235399ebb4caSwyllys 235499ebb4caSwyllys return (ret); 235599ebb4caSwyllys } 235699ebb4caSwyllys 235799ebb4caSwyllys KMF_RETURN 235830a5e8faSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, 235930a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 236099ebb4caSwyllys { 236199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 236299ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 236399ebb4caSwyllys OCSP_CERTID *id = NULL; 236499ebb4caSwyllys OCSP_REQUEST *req = NULL; 236599ebb4caSwyllys BIO *derbio = NULL; 236630a5e8faSwyllys char *reqfile; 236730a5e8faSwyllys KMF_DATA *issuer_cert; 236830a5e8faSwyllys KMF_DATA *user_cert; 236999ebb4caSwyllys 237030a5e8faSwyllys user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, 237130a5e8faSwyllys attrlist, numattr); 237230a5e8faSwyllys if (user_cert == NULL) 237399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 237499ebb4caSwyllys 237530a5e8faSwyllys issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, 237630a5e8faSwyllys attrlist, numattr); 237730a5e8faSwyllys if (issuer_cert == NULL) 237830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 237930a5e8faSwyllys 238030a5e8faSwyllys reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR, 238130a5e8faSwyllys attrlist, numattr); 238230a5e8faSwyllys if (reqfile == NULL) 238330a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 238430a5e8faSwyllys 238530a5e8faSwyllys ret = create_certid(handle, issuer_cert, user_cert, &id); 238699ebb4caSwyllys if (ret != KMF_OK) { 238799ebb4caSwyllys return (ret); 238899ebb4caSwyllys } 238999ebb4caSwyllys 239099ebb4caSwyllys /* Create an OCSP request */ 239199ebb4caSwyllys req = OCSP_REQUEST_new(); 239299ebb4caSwyllys if (req == NULL) { 239399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 239499ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 239599ebb4caSwyllys goto end; 239699ebb4caSwyllys } 239799ebb4caSwyllys 239899ebb4caSwyllys if (!OCSP_request_add0_id(req, id)) { 239999ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 240099ebb4caSwyllys goto end; 240199ebb4caSwyllys } 240299ebb4caSwyllys 240399ebb4caSwyllys /* Write the request to the output file with DER encoding */ 240499ebb4caSwyllys derbio = BIO_new_file(reqfile, "wb"); 240599ebb4caSwyllys if (!derbio) { 240699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 240799ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 240899ebb4caSwyllys goto end; 240999ebb4caSwyllys } 241099ebb4caSwyllys if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) { 241199ebb4caSwyllys ret = KMF_ERR_ENCODING; 241299ebb4caSwyllys } 241399ebb4caSwyllys 241499ebb4caSwyllys end: 241599ebb4caSwyllys /* 241699ebb4caSwyllys * We don't need to free "id" explicitely, because OCSP_REQUEST_free() 241799ebb4caSwyllys * will deallocate certid's space also. 241899ebb4caSwyllys */ 241999ebb4caSwyllys if (req != NULL) { 242099ebb4caSwyllys OCSP_REQUEST_free(req); 242199ebb4caSwyllys } 242299ebb4caSwyllys 242399ebb4caSwyllys if (derbio != NULL) { 242499ebb4caSwyllys (void) BIO_free(derbio); 242599ebb4caSwyllys } 242699ebb4caSwyllys 242799ebb4caSwyllys return (ret); 242899ebb4caSwyllys } 242999ebb4caSwyllys 243099ebb4caSwyllys /* ocsp_find_signer_sk() is copied from openssl source */ 243199ebb4caSwyllys static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 243299ebb4caSwyllys { 243399ebb4caSwyllys int i; 243499ebb4caSwyllys unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 243599ebb4caSwyllys 243699ebb4caSwyllys /* Easy if lookup by name */ 243799ebb4caSwyllys if (id->type == V_OCSP_RESPID_NAME) 243899ebb4caSwyllys return (X509_find_by_subject(certs, id->value.byName)); 243999ebb4caSwyllys 244099ebb4caSwyllys /* Lookup by key hash */ 244199ebb4caSwyllys 244299ebb4caSwyllys /* If key hash isn't SHA1 length then forget it */ 244399ebb4caSwyllys if (id->value.byKey->length != SHA_DIGEST_LENGTH) 244499ebb4caSwyllys return (NULL); 244599ebb4caSwyllys 244699ebb4caSwyllys keyhash = id->value.byKey->data; 244799ebb4caSwyllys /* Calculate hash of each key and compare */ 244899ebb4caSwyllys for (i = 0; i < sk_X509_num(certs); i++) { 244999ebb4caSwyllys /*LINTED*/ 245099ebb4caSwyllys X509 *x = sk_X509_value(certs, i); 24515b3e1433Swyllys /* Use pubkey_digest to get the key ID value */ 245299ebb4caSwyllys (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 245399ebb4caSwyllys if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 245499ebb4caSwyllys return (x); 245599ebb4caSwyllys } 245699ebb4caSwyllys return (NULL); 245799ebb4caSwyllys } 245899ebb4caSwyllys 245999ebb4caSwyllys /* ocsp_find_signer() is copied from openssl source */ 246099ebb4caSwyllys /*ARGSUSED*/ 246199ebb4caSwyllys static int 246299ebb4caSwyllys ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, 246399ebb4caSwyllys X509_STORE *st, unsigned long flags) 246499ebb4caSwyllys { 246599ebb4caSwyllys X509 *signer; 246699ebb4caSwyllys OCSP_RESPID *rid = bs->tbsResponseData->responderId; 246799ebb4caSwyllys if ((signer = ocsp_find_signer_sk(certs, rid))) { 246899ebb4caSwyllys *psigner = signer; 246999ebb4caSwyllys return (2); 247099ebb4caSwyllys } 247199ebb4caSwyllys if (!(flags & OCSP_NOINTERN) && 247299ebb4caSwyllys (signer = ocsp_find_signer_sk(bs->certs, rid))) { 247399ebb4caSwyllys *psigner = signer; 247499ebb4caSwyllys return (1); 247599ebb4caSwyllys } 247699ebb4caSwyllys /* Maybe lookup from store if by subject name */ 247799ebb4caSwyllys 247899ebb4caSwyllys *psigner = NULL; 247999ebb4caSwyllys return (0); 248099ebb4caSwyllys } 248199ebb4caSwyllys 248299ebb4caSwyllys /* 248399ebb4caSwyllys * This function will verify the signature of a basic response, using 248499ebb4caSwyllys * the public key from the OCSP responder certificate. 248599ebb4caSwyllys */ 248699ebb4caSwyllys static KMF_RETURN 248799ebb4caSwyllys check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, 248899ebb4caSwyllys KMF_DATA *signer_cert, KMF_DATA *issuer_cert) 248999ebb4caSwyllys { 249099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 249199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 249299ebb4caSwyllys STACK_OF(X509) *cert_stack = NULL; 249399ebb4caSwyllys X509 *signer = NULL; 249499ebb4caSwyllys X509 *issuer = NULL; 249599ebb4caSwyllys EVP_PKEY *skey = NULL; 249699ebb4caSwyllys unsigned char *ptmp; 249799ebb4caSwyllys 249899ebb4caSwyllys 249999ebb4caSwyllys if (bs == NULL || issuer_cert == NULL) 250099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 250199ebb4caSwyllys 250299ebb4caSwyllys /* 250399ebb4caSwyllys * Find the certificate that signed the basic response. 250499ebb4caSwyllys * 250599ebb4caSwyllys * If signer_cert is not NULL, we will use that as the signer cert. 250699ebb4caSwyllys * Otherwise, we will check if the issuer cert is actually the signer. 250799ebb4caSwyllys * If we still do not find a signer, we will look for it from the 250899ebb4caSwyllys * certificate list came with the response file. 250999ebb4caSwyllys */ 251099ebb4caSwyllys if (signer_cert != NULL) { 251199ebb4caSwyllys ptmp = signer_cert->Data; 251299ebb4caSwyllys signer = d2i_X509(NULL, (const uchar_t **)&ptmp, 251399ebb4caSwyllys signer_cert->Length); 251499ebb4caSwyllys if (signer == NULL) { 251599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 251699ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 251799ebb4caSwyllys goto end; 251899ebb4caSwyllys } 251999ebb4caSwyllys } else { 252099ebb4caSwyllys /* 252199ebb4caSwyllys * Convert the issuer cert into X509 and push it into a 252299ebb4caSwyllys * stack to be used by ocsp_find_signer(). 252399ebb4caSwyllys */ 252499ebb4caSwyllys ptmp = issuer_cert->Data; 252599ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 252699ebb4caSwyllys issuer_cert->Length); 252799ebb4caSwyllys if (issuer == NULL) { 252899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 252999ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 253099ebb4caSwyllys goto end; 253199ebb4caSwyllys } 253299ebb4caSwyllys 253399ebb4caSwyllys if ((cert_stack = sk_X509_new_null()) == NULL) { 253499ebb4caSwyllys ret = KMF_ERR_INTERNAL; 253599ebb4caSwyllys goto end; 253699ebb4caSwyllys } 253799ebb4caSwyllys 253899ebb4caSwyllys if (sk_X509_push(cert_stack, issuer) == NULL) { 253999ebb4caSwyllys ret = KMF_ERR_INTERNAL; 254099ebb4caSwyllys goto end; 254199ebb4caSwyllys } 254299ebb4caSwyllys 254399ebb4caSwyllys ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0); 254499ebb4caSwyllys if (!ret) { 254599ebb4caSwyllys /* can not find the signer */ 254699ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 254799ebb4caSwyllys goto end; 254899ebb4caSwyllys } 254999ebb4caSwyllys } 255099ebb4caSwyllys 255199ebb4caSwyllys /* Verify the signature of the response */ 255299ebb4caSwyllys skey = X509_get_pubkey(signer); 255399ebb4caSwyllys if (skey == NULL) { 255499ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 255599ebb4caSwyllys goto end; 255699ebb4caSwyllys } 255799ebb4caSwyllys 255899ebb4caSwyllys ret = OCSP_BASICRESP_verify(bs, skey, 0); 255999ebb4caSwyllys if (ret == 0) { 256099ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE; 256199ebb4caSwyllys goto end; 256299ebb4caSwyllys } 256399ebb4caSwyllys 256499ebb4caSwyllys end: 256599ebb4caSwyllys if (issuer != NULL) { 256699ebb4caSwyllys X509_free(issuer); 256799ebb4caSwyllys } 256899ebb4caSwyllys 256999ebb4caSwyllys if (signer != NULL) { 257099ebb4caSwyllys X509_free(signer); 257199ebb4caSwyllys } 257299ebb4caSwyllys 257399ebb4caSwyllys if (skey != NULL) { 257499ebb4caSwyllys EVP_PKEY_free(skey); 257599ebb4caSwyllys } 257699ebb4caSwyllys 257799ebb4caSwyllys if (cert_stack != NULL) { 257899ebb4caSwyllys sk_X509_free(cert_stack); 257999ebb4caSwyllys } 258099ebb4caSwyllys 258199ebb4caSwyllys return (ret); 258299ebb4caSwyllys } 258399ebb4caSwyllys 258499ebb4caSwyllys 258599ebb4caSwyllys 258699ebb4caSwyllys KMF_RETURN 258799ebb4caSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, 258830a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 258999ebb4caSwyllys { 259099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 259199ebb4caSwyllys BIO *derbio = NULL; 259299ebb4caSwyllys OCSP_RESPONSE *resp = NULL; 259399ebb4caSwyllys OCSP_BASICRESP *bs = NULL; 259499ebb4caSwyllys OCSP_CERTID *id = NULL; 259599ebb4caSwyllys OCSP_SINGLERESP *single = NULL; 259699ebb4caSwyllys ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 259799ebb4caSwyllys int index, status, reason; 259830a5e8faSwyllys KMF_DATA *issuer_cert; 259930a5e8faSwyllys KMF_DATA *user_cert; 260030a5e8faSwyllys KMF_DATA *signer_cert; 260130a5e8faSwyllys KMF_DATA *response; 260230a5e8faSwyllys int *response_reason, *response_status, *cert_status; 260330a5e8faSwyllys boolean_t ignore_response_sign = B_FALSE; /* default is FALSE */ 260430a5e8faSwyllys uint32_t response_lifetime; 260599ebb4caSwyllys 260630a5e8faSwyllys issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, 260730a5e8faSwyllys attrlist, numattr); 260830a5e8faSwyllys if (issuer_cert == NULL) 260999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 261099ebb4caSwyllys 261130a5e8faSwyllys user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, 261230a5e8faSwyllys attrlist, numattr); 261330a5e8faSwyllys if (user_cert == NULL) 261499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 261530a5e8faSwyllys 261630a5e8faSwyllys response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, 261730a5e8faSwyllys attrlist, numattr); 261830a5e8faSwyllys if (response == NULL) 261930a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 262030a5e8faSwyllys 262130a5e8faSwyllys response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR, 262230a5e8faSwyllys attrlist, numattr); 262330a5e8faSwyllys if (response_status == NULL) 262430a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 262530a5e8faSwyllys 262630a5e8faSwyllys response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR, 262730a5e8faSwyllys attrlist, numattr); 262830a5e8faSwyllys if (response_reason == NULL) 262930a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 263030a5e8faSwyllys 263130a5e8faSwyllys cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, 263230a5e8faSwyllys attrlist, numattr); 263330a5e8faSwyllys if (cert_status == NULL) 263430a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 263599ebb4caSwyllys 263699ebb4caSwyllys /* Read in the response */ 263730a5e8faSwyllys derbio = BIO_new_mem_buf(response->Data, response->Length); 263899ebb4caSwyllys if (!derbio) { 263999ebb4caSwyllys ret = KMF_ERR_MEMORY; 264099ebb4caSwyllys return (ret); 264199ebb4caSwyllys } 264299ebb4caSwyllys 264399ebb4caSwyllys resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 264499ebb4caSwyllys if (resp == NULL) { 264599ebb4caSwyllys ret = KMF_ERR_OCSP_MALFORMED_RESPONSE; 264699ebb4caSwyllys goto end; 264799ebb4caSwyllys } 264899ebb4caSwyllys 264999ebb4caSwyllys /* Check the response status */ 265099ebb4caSwyllys status = OCSP_response_status(resp); 265130a5e8faSwyllys *response_status = status; 265299ebb4caSwyllys if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 265399ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_STATUS; 265499ebb4caSwyllys goto end; 265599ebb4caSwyllys } 265699ebb4caSwyllys 265799ebb4caSwyllys #ifdef DEBUG 265899ebb4caSwyllys printf("Successfully checked the response file status.\n"); 265999ebb4caSwyllys #endif /* DEBUG */ 266099ebb4caSwyllys 266199ebb4caSwyllys /* Extract basic response */ 266299ebb4caSwyllys bs = OCSP_response_get1_basic(resp); 266399ebb4caSwyllys if (bs == NULL) { 266499ebb4caSwyllys ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE; 266599ebb4caSwyllys goto end; 266699ebb4caSwyllys } 266799ebb4caSwyllys 266899ebb4caSwyllys #ifdef DEBUG 266999ebb4caSwyllys printf("Successfully retrieved the basic response.\n"); 267099ebb4caSwyllys #endif /* DEBUG */ 267199ebb4caSwyllys 267299ebb4caSwyllys /* Check the basic response signature if required */ 267330a5e8faSwyllys ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr, 267430a5e8faSwyllys (void *)&ignore_response_sign, NULL); 267530a5e8faSwyllys if (ret != KMF_OK) 267630a5e8faSwyllys ret = KMF_OK; 267730a5e8faSwyllys 267830a5e8faSwyllys signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, 267930a5e8faSwyllys attrlist, numattr); 268030a5e8faSwyllys 268130a5e8faSwyllys if (ignore_response_sign == B_FALSE) { 268299ebb4caSwyllys ret = check_response_signature(handle, bs, 268330a5e8faSwyllys signer_cert, issuer_cert); 268499ebb4caSwyllys if (ret != KMF_OK) 268599ebb4caSwyllys goto end; 268699ebb4caSwyllys } 268799ebb4caSwyllys 268899ebb4caSwyllys #ifdef DEBUG 268999ebb4caSwyllys printf("Successfully verified the response signature.\n"); 269099ebb4caSwyllys #endif /* DEBUG */ 269199ebb4caSwyllys 269299ebb4caSwyllys /* Create a certid for the certificate in question */ 269330a5e8faSwyllys ret = create_certid(handle, issuer_cert, user_cert, &id); 269499ebb4caSwyllys if (ret != KMF_OK) { 269599ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 269699ebb4caSwyllys goto end; 269799ebb4caSwyllys } 269899ebb4caSwyllys 269999ebb4caSwyllys #ifdef DEBUG 270099ebb4caSwyllys printf("successfully created a certid for the cert.\n"); 270199ebb4caSwyllys #endif /* DEBUG */ 270299ebb4caSwyllys 270399ebb4caSwyllys /* Find the index of the single response for the certid */ 270499ebb4caSwyllys index = OCSP_resp_find(bs, id, -1); 270599ebb4caSwyllys if (index < 0) { 270699ebb4caSwyllys /* cound not find this certificate in the response */ 270799ebb4caSwyllys ret = KMF_ERR_OCSP_UNKNOWN_CERT; 270899ebb4caSwyllys goto end; 270999ebb4caSwyllys } 271099ebb4caSwyllys 271199ebb4caSwyllys #ifdef DEBUG 271299ebb4caSwyllys printf("Successfully found the single response index for the cert.\n"); 271399ebb4caSwyllys #endif /* DEBUG */ 271499ebb4caSwyllys 271599ebb4caSwyllys /* Retrieve the single response and get the cert status */ 271699ebb4caSwyllys single = OCSP_resp_get0(bs, index); 271799ebb4caSwyllys status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, 271899ebb4caSwyllys &nextupd); 271999ebb4caSwyllys if (status == V_OCSP_CERTSTATUS_GOOD) { 272030a5e8faSwyllys *cert_status = OCSP_GOOD; 272199ebb4caSwyllys } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { 272230a5e8faSwyllys *cert_status = OCSP_UNKNOWN; 272399ebb4caSwyllys } else { /* revoked */ 272430a5e8faSwyllys *cert_status = OCSP_REVOKED; 272530a5e8faSwyllys *response_reason = reason; 272699ebb4caSwyllys } 272799ebb4caSwyllys ret = KMF_OK; 272899ebb4caSwyllys 272930a5e8faSwyllys /* resp. time is optional, so we don't care about the return code. */ 273030a5e8faSwyllys (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr, 273130a5e8faSwyllys (void *)&response_lifetime, NULL); 273230a5e8faSwyllys 273399ebb4caSwyllys if (!OCSP_check_validity(thisupd, nextupd, 300, 273430a5e8faSwyllys response_lifetime)) { 273599ebb4caSwyllys ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; 273699ebb4caSwyllys goto end; 273799ebb4caSwyllys } 273899ebb4caSwyllys 273999ebb4caSwyllys #ifdef DEBUG 274099ebb4caSwyllys printf("Successfully verify the time.\n"); 274199ebb4caSwyllys #endif /* DEBUG */ 274299ebb4caSwyllys 274399ebb4caSwyllys end: 274499ebb4caSwyllys if (derbio != NULL) 274599ebb4caSwyllys (void) BIO_free(derbio); 274699ebb4caSwyllys 274799ebb4caSwyllys if (resp != NULL) 274899ebb4caSwyllys OCSP_RESPONSE_free(resp); 274999ebb4caSwyllys 275099ebb4caSwyllys if (bs != NULL) 275199ebb4caSwyllys OCSP_BASICRESP_free(bs); 275299ebb4caSwyllys 275399ebb4caSwyllys if (id != NULL) 275499ebb4caSwyllys OCSP_CERTID_free(id); 275599ebb4caSwyllys 275699ebb4caSwyllys return (ret); 275799ebb4caSwyllys } 275899ebb4caSwyllys 275999ebb4caSwyllys static KMF_RETURN 276099ebb4caSwyllys fetch_key(KMF_HANDLE_T handle, char *path, 276199ebb4caSwyllys KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) 276299ebb4caSwyllys { 276399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 276430a5e8faSwyllys EVP_PKEY *pkey = NULL; 276599ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 276699ebb4caSwyllys 276799ebb4caSwyllys if (keyclass == KMF_ASYM_PRI || 276899ebb4caSwyllys keyclass == KMF_ASYM_PUB) { 276999ebb4caSwyllys pkey = openssl_load_key(handle, path); 277099ebb4caSwyllys if (pkey == NULL) { 277199ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 277299ebb4caSwyllys } 277399ebb4caSwyllys if (key != NULL) { 277499ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) 277599ebb4caSwyllys key->keyalg = KMF_RSA; 277699ebb4caSwyllys else if (pkey->type == EVP_PKEY_DSA) 277799ebb4caSwyllys key->keyalg = KMF_DSA; 277899ebb4caSwyllys 277999ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 278099ebb4caSwyllys key->keyclass = keyclass; 278199ebb4caSwyllys key->keyp = (void *)pkey; 278299ebb4caSwyllys key->israw = FALSE; 27835b3e1433Swyllys if (path != NULL && 27845b3e1433Swyllys ((key->keylabel = strdup(path)) == NULL)) { 27855b3e1433Swyllys EVP_PKEY_free(pkey); 27865b3e1433Swyllys return (KMF_ERR_MEMORY); 27875b3e1433Swyllys } 278899ebb4caSwyllys } else { 278999ebb4caSwyllys EVP_PKEY_free(pkey); 279099ebb4caSwyllys pkey = NULL; 279199ebb4caSwyllys } 279299ebb4caSwyllys } else if (keyclass == KMF_SYMMETRIC) { 279399ebb4caSwyllys KMF_ENCODE_FORMAT fmt; 279499ebb4caSwyllys /* 279599ebb4caSwyllys * If the file is a recognized format, 279699ebb4caSwyllys * then it is NOT a symmetric key. 279799ebb4caSwyllys */ 279830a5e8faSwyllys rv = kmf_get_file_format(path, &fmt); 279999ebb4caSwyllys if (rv == KMF_OK || fmt != 0) { 280099ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 280199ebb4caSwyllys } else if (rv == KMF_ERR_ENCODING) { 280299ebb4caSwyllys /* 280399ebb4caSwyllys * If we don't know the encoding, 280499ebb4caSwyllys * it is probably a symmetric key. 280599ebb4caSwyllys */ 280699ebb4caSwyllys rv = KMF_OK; 280730a5e8faSwyllys } else if (rv == KMF_ERR_OPEN_FILE) { 280830a5e8faSwyllys return (KMF_ERR_KEY_NOT_FOUND); 280999ebb4caSwyllys } 281099ebb4caSwyllys 281199ebb4caSwyllys if (key != NULL) { 281299ebb4caSwyllys KMF_DATA keyvalue; 281399ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 281499ebb4caSwyllys if (rkey == NULL) { 281599ebb4caSwyllys rv = KMF_ERR_MEMORY; 281699ebb4caSwyllys goto out; 281799ebb4caSwyllys } 281899ebb4caSwyllys 281999ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 282030a5e8faSwyllys rv = kmf_read_input_file(handle, path, &keyvalue); 282199ebb4caSwyllys if (rv != KMF_OK) 282299ebb4caSwyllys goto out; 282399ebb4caSwyllys 282499ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 282599ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 282699ebb4caSwyllys 282799ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 282899ebb4caSwyllys key->keyclass = keyclass; 282999ebb4caSwyllys key->israw = TRUE; 283099ebb4caSwyllys key->keyp = (void *)rkey; 28315b3e1433Swyllys if (path != NULL && 28325b3e1433Swyllys ((key->keylabel = strdup(path)) == NULL)) { 28335b3e1433Swyllys rv = KMF_ERR_MEMORY; 28345b3e1433Swyllys } 283599ebb4caSwyllys } 283699ebb4caSwyllys } 283799ebb4caSwyllys out: 283899ebb4caSwyllys if (rv != KMF_OK) { 283999ebb4caSwyllys if (rkey != NULL) { 284030a5e8faSwyllys kmf_free_raw_sym_key(rkey); 284199ebb4caSwyllys } 284299ebb4caSwyllys if (pkey != NULL) 284399ebb4caSwyllys EVP_PKEY_free(pkey); 284499ebb4caSwyllys 284599ebb4caSwyllys if (key != NULL) { 284699ebb4caSwyllys key->keyalg = KMF_KEYALG_NONE; 284799ebb4caSwyllys key->keyclass = KMF_KEYCLASS_NONE; 284899ebb4caSwyllys key->keyp = NULL; 284999ebb4caSwyllys } 285099ebb4caSwyllys } 285199ebb4caSwyllys 285299ebb4caSwyllys return (rv); 285399ebb4caSwyllys } 285499ebb4caSwyllys 285599ebb4caSwyllys KMF_RETURN 285630a5e8faSwyllys OpenSSL_FindKey(KMF_HANDLE_T handle, 285730a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 285899ebb4caSwyllys { 285999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 286099ebb4caSwyllys char *fullpath = NULL; 2861f482c776Swyllys uint32_t maxkeys; 286230a5e8faSwyllys KMF_KEY_HANDLE *key; 286330a5e8faSwyllys uint32_t *numkeys; 286430a5e8faSwyllys KMF_KEY_CLASS keyclass; 286530a5e8faSwyllys KMF_RAW_KEY_DATA *rawkey; 286630a5e8faSwyllys char *dirpath; 286730a5e8faSwyllys char *keyfile; 286899ebb4caSwyllys 286930a5e8faSwyllys if (handle == NULL) 287099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 287199ebb4caSwyllys 287230a5e8faSwyllys numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 287330a5e8faSwyllys if (numkeys == NULL) 287430a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 287530a5e8faSwyllys 287630a5e8faSwyllys rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, 287730a5e8faSwyllys (void *)&keyclass, NULL); 287830a5e8faSwyllys if (rv != KMF_OK) 287930a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 288030a5e8faSwyllys 288130a5e8faSwyllys if (keyclass != KMF_ASYM_PUB && 288230a5e8faSwyllys keyclass != KMF_ASYM_PRI && 288330a5e8faSwyllys keyclass != KMF_SYMMETRIC) 288499ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 288599ebb4caSwyllys 288630a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 288730a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 288830a5e8faSwyllys 288930a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 289099ebb4caSwyllys 289199ebb4caSwyllys if (fullpath == NULL) 289299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 289399ebb4caSwyllys 2894f482c776Swyllys maxkeys = *numkeys; 2895f482c776Swyllys if (maxkeys == 0) 2896f482c776Swyllys maxkeys = 0xFFFFFFFF; 289799ebb4caSwyllys *numkeys = 0; 289899ebb4caSwyllys 289930a5e8faSwyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 290030a5e8faSwyllys /* it is okay to have "keys" contains NULL */ 290130a5e8faSwyllys 290230a5e8faSwyllys /* 290330a5e8faSwyllys * The caller may want a list of the raw key data as well. 290430a5e8faSwyllys * Useful for importing keys from a file into other keystores. 290530a5e8faSwyllys */ 290630a5e8faSwyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); 290730a5e8faSwyllys 290899ebb4caSwyllys if (isdir(fullpath)) { 290999ebb4caSwyllys DIR *dirp; 291099ebb4caSwyllys struct dirent *dp; 291199ebb4caSwyllys int n = 0; 291299ebb4caSwyllys 291399ebb4caSwyllys /* open all files in the directory and attempt to read them */ 291499ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 291599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 291699ebb4caSwyllys } 291799ebb4caSwyllys rewinddir(dirp); 2918f482c776Swyllys while ((dp = readdir(dirp)) != NULL && n < maxkeys) { 291999ebb4caSwyllys if (strcmp(dp->d_name, ".") && 292099ebb4caSwyllys strcmp(dp->d_name, "..")) { 292199ebb4caSwyllys char *fname; 292299ebb4caSwyllys 292399ebb4caSwyllys fname = get_fullpath(fullpath, 292499ebb4caSwyllys (char *)&dp->d_name); 292599ebb4caSwyllys 292699ebb4caSwyllys rv = fetch_key(handle, fname, 292730a5e8faSwyllys keyclass, key ? &key[n] : NULL); 292899ebb4caSwyllys 292930a5e8faSwyllys if (rv == KMF_OK) { 293030a5e8faSwyllys if (key != NULL && rawkey != NULL) 293130a5e8faSwyllys rv = convertToRawKey( 293230a5e8faSwyllys key[n].keyp, &rawkey[n]); 293399ebb4caSwyllys n++; 293430a5e8faSwyllys } 293599ebb4caSwyllys 293699ebb4caSwyllys if (rv != KMF_OK || key == NULL) 293799ebb4caSwyllys free(fname); 293899ebb4caSwyllys } 293999ebb4caSwyllys } 294099ebb4caSwyllys (void) closedir(dirp); 294199ebb4caSwyllys free(fullpath); 294299ebb4caSwyllys (*numkeys) = n; 294399ebb4caSwyllys } else { 294430a5e8faSwyllys rv = fetch_key(handle, fullpath, keyclass, key); 294599ebb4caSwyllys if (rv == KMF_OK) 294699ebb4caSwyllys (*numkeys) = 1; 294799ebb4caSwyllys 294899ebb4caSwyllys if (rv != KMF_OK || key == NULL) 294999ebb4caSwyllys free(fullpath); 295030a5e8faSwyllys 295130a5e8faSwyllys if (rv == KMF_OK && key != NULL && rawkey != NULL) { 295230a5e8faSwyllys rv = convertToRawKey(key->keyp, rawkey); 295330a5e8faSwyllys } 295499ebb4caSwyllys } 295599ebb4caSwyllys 2956f482c776Swyllys if (rv == KMF_OK && (*numkeys) == 0) 295799ebb4caSwyllys rv = KMF_ERR_KEY_NOT_FOUND; 2958*73cc0e02Swyllys else if (rv == KMF_ERR_KEY_NOT_FOUND && (*numkeys) > 0) 2959*73cc0e02Swyllys rv = KMF_OK; 296099ebb4caSwyllys 296199ebb4caSwyllys return (rv); 296299ebb4caSwyllys } 296399ebb4caSwyllys 296499ebb4caSwyllys #define HANDLE_PK12_ERROR { \ 296599ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); \ 296699ebb4caSwyllys rv = KMF_ERR_ENCODING; \ 296799ebb4caSwyllys goto out; \ 296899ebb4caSwyllys } 296999ebb4caSwyllys 29705b3e1433Swyllys static int 29715b3e1433Swyllys add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert) 297299ebb4caSwyllys { 29735b3e1433Swyllys if (xcert != NULL && xcert->aux != NULL && 29745b3e1433Swyllys xcert->aux->alias != NULL) { 29755b3e1433Swyllys if (PKCS12_add_friendlyname_asc(bag, 29765b3e1433Swyllys (const char *)xcert->aux->alias->data, 29775b3e1433Swyllys xcert->aux->alias->length) == 0) 29785b3e1433Swyllys return (0); 29795b3e1433Swyllys } 29805b3e1433Swyllys return (1); 29815b3e1433Swyllys } 29825b3e1433Swyllys 29835b3e1433Swyllys static PKCS7 * 29845b3e1433Swyllys add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred, 29855b3e1433Swyllys uchar_t *keyid, unsigned int keyidlen) 29865b3e1433Swyllys { 298799ebb4caSwyllys PKCS12_SAFEBAG *bag = NULL; 298899ebb4caSwyllys PKCS7 *cert_authsafe = NULL; 29895b3e1433Swyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack; 299099ebb4caSwyllys 299199ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 299299ebb4caSwyllys if (bag_stack == NULL) 29935b3e1433Swyllys return (NULL); 299499ebb4caSwyllys 299599ebb4caSwyllys /* Convert cert from X509 struct to PKCS#12 bag */ 299699ebb4caSwyllys bag = PKCS12_x5092certbag(sslcert); 299799ebb4caSwyllys if (bag == NULL) { 29985b3e1433Swyllys goto out; 299999ebb4caSwyllys } 300099ebb4caSwyllys 300199ebb4caSwyllys /* Add the key id to the certificate bag. */ 30025b3e1433Swyllys if (keyidlen > 0 && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 30035b3e1433Swyllys goto out; 300499ebb4caSwyllys } 300599ebb4caSwyllys 30065b3e1433Swyllys if (!add_alias_to_bag(bag, sslcert)) 30075b3e1433Swyllys goto out; 30085b3e1433Swyllys 300999ebb4caSwyllys /* Pile it on the bag_stack. */ 301099ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 30115b3e1433Swyllys goto out; 301299ebb4caSwyllys } 301399ebb4caSwyllys /* Turn bag_stack of certs into encrypted authsafe. */ 301499ebb4caSwyllys cert_authsafe = PKCS12_pack_p7encdata( 301599ebb4caSwyllys NID_pbe_WithSHA1And40BitRC2_CBC, 301634acef67Swyllys cred->cred, cred->credlen, NULL, 0, 301734acef67Swyllys PKCS12_DEFAULT_ITER, bag_stack); 301899ebb4caSwyllys 30195b3e1433Swyllys out: 30205b3e1433Swyllys if (bag_stack != NULL) 302199ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 302299ebb4caSwyllys 30235b3e1433Swyllys return (cert_authsafe); 302499ebb4caSwyllys } 30255b3e1433Swyllys 30265b3e1433Swyllys static PKCS7 * 30275b3e1433Swyllys add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred, 30285b3e1433Swyllys uchar_t *keyid, unsigned int keyidlen, 30295b3e1433Swyllys char *label, int label_len) 30305b3e1433Swyllys { 30315b3e1433Swyllys PKCS8_PRIV_KEY_INFO *p8 = NULL; 30325b3e1433Swyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 30335b3e1433Swyllys PKCS12_SAFEBAG *bag = NULL; 30345b3e1433Swyllys PKCS7 *key_authsafe = NULL; 30355b3e1433Swyllys 303699ebb4caSwyllys p8 = EVP_PKEY2PKCS8(pkey); 303799ebb4caSwyllys if (p8 == NULL) { 30385b3e1433Swyllys return (NULL); 303999ebb4caSwyllys } 304099ebb4caSwyllys /* Put the shrouded key into a PKCS#12 bag. */ 304199ebb4caSwyllys bag = PKCS12_MAKE_SHKEYBAG( 304299ebb4caSwyllys NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 304399ebb4caSwyllys cred->cred, cred->credlen, 304499ebb4caSwyllys NULL, 0, PKCS12_DEFAULT_ITER, p8); 304599ebb4caSwyllys 304699ebb4caSwyllys /* Clean up the PKCS#8 shrouded key, don't need it now. */ 304799ebb4caSwyllys PKCS8_PRIV_KEY_INFO_free(p8); 304899ebb4caSwyllys p8 = NULL; 304999ebb4caSwyllys 305099ebb4caSwyllys if (bag == NULL) { 30515b3e1433Swyllys return (NULL); 305299ebb4caSwyllys } 30535b3e1433Swyllys if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) 30545b3e1433Swyllys goto out; 30555b3e1433Swyllys if (label != NULL && !PKCS12_add_friendlyname(bag, label, label_len)) 30565b3e1433Swyllys goto out; 30575b3e1433Swyllys 305899ebb4caSwyllys /* Start a PKCS#12 safebag container for the private key. */ 305999ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 30605b3e1433Swyllys if (bag_stack == NULL) 30615b3e1433Swyllys goto out; 306299ebb4caSwyllys 306399ebb4caSwyllys /* Pile on the private key on the bag_stack. */ 30645b3e1433Swyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) 30655b3e1433Swyllys goto out; 30665b3e1433Swyllys 306799ebb4caSwyllys key_authsafe = PKCS12_pack_p7data(bag_stack); 306899ebb4caSwyllys 30695b3e1433Swyllys out: 30705b3e1433Swyllys if (bag_stack != NULL) 307199ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 307299ebb4caSwyllys bag_stack = NULL; 30735b3e1433Swyllys return (key_authsafe); 307499ebb4caSwyllys } 307599ebb4caSwyllys 307699ebb4caSwyllys static EVP_PKEY * 307799ebb4caSwyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *key) 307899ebb4caSwyllys { 307999ebb4caSwyllys RSA *rsa = NULL; 308099ebb4caSwyllys EVP_PKEY *newkey = NULL; 308199ebb4caSwyllys 308299ebb4caSwyllys if ((rsa = RSA_new()) == NULL) 308399ebb4caSwyllys return (NULL); 308499ebb4caSwyllys 308599ebb4caSwyllys if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL) 308699ebb4caSwyllys return (NULL); 308799ebb4caSwyllys 308899ebb4caSwyllys if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) == 308999ebb4caSwyllys NULL) 309099ebb4caSwyllys return (NULL); 309199ebb4caSwyllys 309299ebb4caSwyllys if (key->priexp.val != NULL) 309399ebb4caSwyllys if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len, 309499ebb4caSwyllys rsa->d)) == NULL) 309599ebb4caSwyllys return (NULL); 309699ebb4caSwyllys 309799ebb4caSwyllys if (key->prime1.val != NULL) 309899ebb4caSwyllys if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len, 309999ebb4caSwyllys rsa->p)) == NULL) 310099ebb4caSwyllys return (NULL); 310199ebb4caSwyllys 310299ebb4caSwyllys if (key->prime2.val != NULL) 310399ebb4caSwyllys if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len, 310499ebb4caSwyllys rsa->q)) == NULL) 310599ebb4caSwyllys return (NULL); 310699ebb4caSwyllys 310799ebb4caSwyllys if (key->exp1.val != NULL) 310899ebb4caSwyllys if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, 310999ebb4caSwyllys rsa->dmp1)) == NULL) 311099ebb4caSwyllys return (NULL); 311199ebb4caSwyllys 311299ebb4caSwyllys if (key->exp2.val != NULL) 311399ebb4caSwyllys if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, 311499ebb4caSwyllys rsa->dmq1)) == NULL) 311599ebb4caSwyllys return (NULL); 311699ebb4caSwyllys 311799ebb4caSwyllys if (key->coef.val != NULL) 311899ebb4caSwyllys if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len, 311999ebb4caSwyllys rsa->iqmp)) == NULL) 312099ebb4caSwyllys return (NULL); 312199ebb4caSwyllys 312299ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 312399ebb4caSwyllys return (NULL); 312499ebb4caSwyllys 312599ebb4caSwyllys (void) EVP_PKEY_set1_RSA(newkey, rsa); 312699ebb4caSwyllys 312799ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 312899ebb4caSwyllys RSA_free(rsa); 312999ebb4caSwyllys 313099ebb4caSwyllys return (newkey); 313199ebb4caSwyllys } 313299ebb4caSwyllys 313399ebb4caSwyllys static EVP_PKEY * 313499ebb4caSwyllys ImportRawDSAKey(KMF_RAW_DSA_KEY *key) 313599ebb4caSwyllys { 313699ebb4caSwyllys DSA *dsa = NULL; 313799ebb4caSwyllys EVP_PKEY *newkey = NULL; 313899ebb4caSwyllys 313999ebb4caSwyllys if ((dsa = DSA_new()) == NULL) 314099ebb4caSwyllys return (NULL); 314199ebb4caSwyllys 314299ebb4caSwyllys if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len, 314399ebb4caSwyllys dsa->p)) == NULL) 314499ebb4caSwyllys return (NULL); 314599ebb4caSwyllys 314699ebb4caSwyllys if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len, 314799ebb4caSwyllys dsa->q)) == NULL) 314899ebb4caSwyllys return (NULL); 314999ebb4caSwyllys 315099ebb4caSwyllys if ((dsa->g = BN_bin2bn(key->base.val, key->base.len, 315199ebb4caSwyllys dsa->g)) == NULL) 315299ebb4caSwyllys return (NULL); 315399ebb4caSwyllys 315499ebb4caSwyllys if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len, 315599ebb4caSwyllys dsa->priv_key)) == NULL) 315699ebb4caSwyllys return (NULL); 315799ebb4caSwyllys 315830a5e8faSwyllys if (key->pubvalue.val != NULL) { 315930a5e8faSwyllys if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val, 316030a5e8faSwyllys key->pubvalue.len, dsa->pub_key)) == NULL) 316130a5e8faSwyllys return (NULL); 316230a5e8faSwyllys } 316330a5e8faSwyllys 316499ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 316599ebb4caSwyllys return (NULL); 316699ebb4caSwyllys 316799ebb4caSwyllys (void) EVP_PKEY_set1_DSA(newkey, dsa); 316899ebb4caSwyllys 316999ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 317099ebb4caSwyllys DSA_free(dsa); 317199ebb4caSwyllys return (newkey); 317299ebb4caSwyllys } 317399ebb4caSwyllys 31745b3e1433Swyllys static EVP_PKEY * 31755b3e1433Swyllys raw_key_to_pkey(KMF_KEY_HANDLE *key) 31765b3e1433Swyllys { 31775b3e1433Swyllys EVP_PKEY *pkey = NULL; 31785b3e1433Swyllys KMF_RAW_KEY_DATA *rawkey; 31795b3e1433Swyllys ASN1_TYPE *attr = NULL; 31805b3e1433Swyllys KMF_RETURN ret; 31815b3e1433Swyllys 31825b3e1433Swyllys if (key == NULL || !key->israw) 31835b3e1433Swyllys return (NULL); 31845b3e1433Swyllys 31855b3e1433Swyllys rawkey = (KMF_RAW_KEY_DATA *)key->keyp; 31865b3e1433Swyllys if (rawkey->keytype == KMF_RSA) { 31875b3e1433Swyllys pkey = ImportRawRSAKey(&rawkey->rawdata.rsa); 31885b3e1433Swyllys } else if (rawkey->keytype == KMF_DSA) { 31895b3e1433Swyllys pkey = ImportRawDSAKey(&rawkey->rawdata.dsa); 31905b3e1433Swyllys } else { 31915b3e1433Swyllys /* wrong kind of key */ 31925b3e1433Swyllys return (NULL); 31935b3e1433Swyllys } 31945b3e1433Swyllys 31955b3e1433Swyllys if (rawkey->label != NULL) { 31965b3e1433Swyllys if ((attr = ASN1_TYPE_new()) == NULL) { 31975b3e1433Swyllys EVP_PKEY_free(pkey); 31985b3e1433Swyllys return (NULL); 31995b3e1433Swyllys } 32005b3e1433Swyllys attr->value.bmpstring = ASN1_STRING_type_new(V_ASN1_BMPSTRING); 32015b3e1433Swyllys (void) ASN1_STRING_set(attr->value.bmpstring, rawkey->label, 32025b3e1433Swyllys strlen(rawkey->label)); 32035b3e1433Swyllys attr->type = V_ASN1_BMPSTRING; 32045b3e1433Swyllys attr->value.ptr = (char *)attr->value.bmpstring; 32055b3e1433Swyllys ret = set_pkey_attrib(pkey, attr, NID_friendlyName); 32065b3e1433Swyllys if (ret != KMF_OK) { 32075b3e1433Swyllys EVP_PKEY_free(pkey); 32085b3e1433Swyllys ASN1_TYPE_free(attr); 32095b3e1433Swyllys return (NULL); 32105b3e1433Swyllys } 32115b3e1433Swyllys } 32125b3e1433Swyllys if (rawkey->id.Data != NULL) { 32135b3e1433Swyllys if ((attr = ASN1_TYPE_new()) == NULL) { 32145b3e1433Swyllys EVP_PKEY_free(pkey); 32155b3e1433Swyllys return (NULL); 32165b3e1433Swyllys } 32175b3e1433Swyllys attr->value.octet_string = 32185b3e1433Swyllys ASN1_STRING_type_new(V_ASN1_OCTET_STRING); 32195b3e1433Swyllys attr->type = V_ASN1_OCTET_STRING; 32205b3e1433Swyllys (void) ASN1_STRING_set(attr->value.octet_string, 32215b3e1433Swyllys rawkey->id.Data, rawkey->id.Length); 32225b3e1433Swyllys attr->value.ptr = (char *)attr->value.octet_string; 32235b3e1433Swyllys ret = set_pkey_attrib(pkey, attr, NID_localKeyID); 32245b3e1433Swyllys if (ret != KMF_OK) { 32255b3e1433Swyllys EVP_PKEY_free(pkey); 32265b3e1433Swyllys ASN1_TYPE_free(attr); 32275b3e1433Swyllys return (NULL); 32285b3e1433Swyllys } 32295b3e1433Swyllys } 32305b3e1433Swyllys return (pkey); 32315b3e1433Swyllys } 32325b3e1433Swyllys 32335b3e1433Swyllys /* 32345b3e1433Swyllys * Search a list of private keys to find one that goes with the certificate. 32355b3e1433Swyllys */ 32365b3e1433Swyllys static EVP_PKEY * 32375b3e1433Swyllys find_matching_key(X509 *xcert, int numkeys, KMF_KEY_HANDLE *keylist) 32385b3e1433Swyllys { 32395b3e1433Swyllys int i; 32405b3e1433Swyllys EVP_PKEY *pkey = NULL; 32415b3e1433Swyllys 32425b3e1433Swyllys if (numkeys == 0 || keylist == NULL || xcert == NULL) 32435b3e1433Swyllys return (NULL); 32445b3e1433Swyllys for (i = 0; i < numkeys; i++) { 32455b3e1433Swyllys if (keylist[i].israw) 32465b3e1433Swyllys pkey = raw_key_to_pkey(&keylist[i]); 32475b3e1433Swyllys else 32485b3e1433Swyllys pkey = (EVP_PKEY *)keylist[i].keyp; 32495b3e1433Swyllys if (pkey != NULL) { 32505b3e1433Swyllys if (X509_check_private_key(xcert, pkey)) { 32515b3e1433Swyllys return (pkey); 32525b3e1433Swyllys } else { 32535b3e1433Swyllys EVP_PKEY_free(pkey); 32545b3e1433Swyllys pkey = NULL; 32555b3e1433Swyllys } 32565b3e1433Swyllys } 32575b3e1433Swyllys } 32585b3e1433Swyllys return (pkey); 32595b3e1433Swyllys } 32605b3e1433Swyllys 326199ebb4caSwyllys static KMF_RETURN 32625b3e1433Swyllys local_export_pk12(KMF_HANDLE_T handle, 326399ebb4caSwyllys KMF_CREDENTIAL *cred, 326499ebb4caSwyllys int numcerts, KMF_X509_DER_CERT *certlist, 326599ebb4caSwyllys int numkeys, KMF_KEY_HANDLE *keylist, 326699ebb4caSwyllys char *filename) 326799ebb4caSwyllys { 326899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 326999ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 327099ebb4caSwyllys BIO *bio = NULL; 32715b3e1433Swyllys PKCS7 *cert_authsafe = NULL; 32725b3e1433Swyllys PKCS7 *key_authsafe = NULL; 32735b3e1433Swyllys STACK_OF(PKCS7) *authsafe_stack = NULL; 32745b3e1433Swyllys PKCS12 *p12_elem = NULL; 327599ebb4caSwyllys int i; 327699ebb4caSwyllys 32775b3e1433Swyllys if (numcerts == 0 && numkeys == 0) 32785b3e1433Swyllys return (KMF_ERR_BAD_PARAMETER); 32795b3e1433Swyllys 328099ebb4caSwyllys /* 328199ebb4caSwyllys * Open the output file. 328299ebb4caSwyllys */ 328399ebb4caSwyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) { 328499ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 328599ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 328699ebb4caSwyllys goto cleanup; 328799ebb4caSwyllys } 328899ebb4caSwyllys 32895b3e1433Swyllys /* Start a PKCS#7 stack. */ 32905b3e1433Swyllys authsafe_stack = sk_PKCS7_new_null(); 32915b3e1433Swyllys if (authsafe_stack == NULL) { 32925b3e1433Swyllys rv = KMF_ERR_MEMORY; 32935b3e1433Swyllys goto cleanup; 32945b3e1433Swyllys } 32955b3e1433Swyllys if (numcerts > 0) { 329699ebb4caSwyllys for (i = 0; rv == KMF_OK && i < numcerts; i++) { 329799ebb4caSwyllys const uchar_t *p = certlist[i].certificate.Data; 329899ebb4caSwyllys long len = certlist[i].certificate.Length; 32995b3e1433Swyllys X509 *xcert = NULL; 33005b3e1433Swyllys EVP_PKEY *pkey = NULL; 33015b3e1433Swyllys unsigned char keyid[EVP_MAX_MD_SIZE]; 33025b3e1433Swyllys unsigned int keyidlen = 0; 330399ebb4caSwyllys 330499ebb4caSwyllys xcert = d2i_X509(NULL, &p, len); 330599ebb4caSwyllys if (xcert == NULL) { 330699ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 330799ebb4caSwyllys rv = KMF_ERR_ENCODING; 330899ebb4caSwyllys } 33095b3e1433Swyllys if (certlist[i].kmf_private.label != NULL) { 33105b3e1433Swyllys /* Set alias attribute */ 33115b3e1433Swyllys (void) X509_alias_set1(xcert, 33125b3e1433Swyllys (uchar_t *)certlist[i].kmf_private.label, 33135b3e1433Swyllys strlen(certlist[i].kmf_private.label)); 33145b3e1433Swyllys } 33155b3e1433Swyllys /* Check if there is a key corresponding to this cert */ 33165b3e1433Swyllys pkey = find_matching_key(xcert, numkeys, keylist); 33175b3e1433Swyllys 33185b3e1433Swyllys /* 33195b3e1433Swyllys * If key is found, get fingerprint and create a 33205b3e1433Swyllys * safebag. 33215b3e1433Swyllys */ 33225b3e1433Swyllys if (pkey != NULL) { 33235b3e1433Swyllys (void) X509_digest(xcert, EVP_sha1(), 33245b3e1433Swyllys keyid, &keyidlen); 33255b3e1433Swyllys key_authsafe = add_key_to_safe(pkey, cred, 33265b3e1433Swyllys keyid, keyidlen, 33275b3e1433Swyllys certlist[i].kmf_private.label, 33285b3e1433Swyllys (certlist[i].kmf_private.label ? 33295b3e1433Swyllys strlen(certlist[i].kmf_private.label) : 0)); 33305b3e1433Swyllys 33315b3e1433Swyllys if (key_authsafe == NULL) { 33325b3e1433Swyllys X509_free(xcert); 33335b3e1433Swyllys EVP_PKEY_free(pkey); 33345b3e1433Swyllys goto cleanup; 33355b3e1433Swyllys } 33365b3e1433Swyllys /* Put the key safe into the Auth Safe */ 33375b3e1433Swyllys if (!sk_PKCS7_push(authsafe_stack, 33385b3e1433Swyllys key_authsafe)) { 33395b3e1433Swyllys X509_free(xcert); 33405b3e1433Swyllys EVP_PKEY_free(pkey); 33415b3e1433Swyllys goto cleanup; 33425b3e1433Swyllys } 33435b3e1433Swyllys } 33445b3e1433Swyllys 33455b3e1433Swyllys /* create a certificate safebag */ 33465b3e1433Swyllys cert_authsafe = add_cert_to_safe(xcert, cred, keyid, 33475b3e1433Swyllys keyidlen); 33485b3e1433Swyllys if (cert_authsafe == NULL) { 33495b3e1433Swyllys X509_free(xcert); 33505b3e1433Swyllys EVP_PKEY_free(pkey); 33515b3e1433Swyllys goto cleanup; 33525b3e1433Swyllys } 33535b3e1433Swyllys if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) { 33545b3e1433Swyllys X509_free(xcert); 33555b3e1433Swyllys EVP_PKEY_free(pkey); 33565b3e1433Swyllys goto cleanup; 33575b3e1433Swyllys } 33585b3e1433Swyllys 335999ebb4caSwyllys X509_free(xcert); 336099ebb4caSwyllys if (pkey) 336199ebb4caSwyllys EVP_PKEY_free(pkey); 336299ebb4caSwyllys } 33635b3e1433Swyllys } else if (numcerts == 0 && numkeys > 0) { 33645b3e1433Swyllys /* 33655b3e1433Swyllys * If only adding keys to the file. 33665b3e1433Swyllys */ 33675b3e1433Swyllys for (i = 0; i < numkeys; i++) { 33685b3e1433Swyllys EVP_PKEY *pkey = NULL; 33695b3e1433Swyllys 33705b3e1433Swyllys if (keylist[i].israw) 33715b3e1433Swyllys pkey = raw_key_to_pkey(&keylist[i]); 33725b3e1433Swyllys else 33735b3e1433Swyllys pkey = (EVP_PKEY *)keylist[i].keyp; 33745b3e1433Swyllys 33755b3e1433Swyllys if (pkey == NULL) 33765b3e1433Swyllys continue; 33775b3e1433Swyllys 33785b3e1433Swyllys key_authsafe = add_key_to_safe(pkey, cred, 33795b3e1433Swyllys NULL, 0, NULL, 0); 33805b3e1433Swyllys 33815b3e1433Swyllys if (key_authsafe == NULL) { 33825b3e1433Swyllys EVP_PKEY_free(pkey); 33835b3e1433Swyllys goto cleanup; 33845b3e1433Swyllys } 33855b3e1433Swyllys if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) { 33865b3e1433Swyllys EVP_PKEY_free(pkey); 33875b3e1433Swyllys goto cleanup; 33885b3e1433Swyllys } 33895b3e1433Swyllys } 33905b3e1433Swyllys } 33915b3e1433Swyllys p12_elem = PKCS12_init(NID_pkcs7_data); 33925b3e1433Swyllys if (p12_elem == NULL) { 33935b3e1433Swyllys goto cleanup; 339499ebb4caSwyllys } 339599ebb4caSwyllys 33965b3e1433Swyllys /* Put the PKCS#7 stack into the PKCS#12 element. */ 33975b3e1433Swyllys if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) { 33985b3e1433Swyllys goto cleanup; 33995b3e1433Swyllys } 34005b3e1433Swyllys 34015b3e1433Swyllys /* Set the integrity MAC on the PKCS#12 element. */ 34025b3e1433Swyllys if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen, 34035b3e1433Swyllys NULL, 0, PKCS12_DEFAULT_ITER, NULL)) { 34045b3e1433Swyllys goto cleanup; 34055b3e1433Swyllys } 34065b3e1433Swyllys 34075b3e1433Swyllys /* Write the PKCS#12 element to the export file. */ 34085b3e1433Swyllys if (!i2d_PKCS12_bio(bio, p12_elem)) { 34095b3e1433Swyllys goto cleanup; 34105b3e1433Swyllys } 34115b3e1433Swyllys PKCS12_free(p12_elem); 34125b3e1433Swyllys 341399ebb4caSwyllys cleanup: 34145b3e1433Swyllys /* Clear away the PKCS#7 stack, we're done with it. */ 34155b3e1433Swyllys if (authsafe_stack) 34165b3e1433Swyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 341799ebb4caSwyllys 341899ebb4caSwyllys if (bio != NULL) 341999ebb4caSwyllys (void) BIO_free_all(bio); 342099ebb4caSwyllys 342199ebb4caSwyllys return (rv); 342299ebb4caSwyllys } 342399ebb4caSwyllys 342499ebb4caSwyllys KMF_RETURN 342530a5e8faSwyllys openssl_build_pk12(KMF_HANDLE_T handle, int numcerts, 342630a5e8faSwyllys KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist, 342730a5e8faSwyllys KMF_CREDENTIAL *p12cred, char *filename) 342830a5e8faSwyllys { 342930a5e8faSwyllys KMF_RETURN rv; 343030a5e8faSwyllys 343130a5e8faSwyllys if (certlist == NULL && keylist == NULL) 343230a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 343330a5e8faSwyllys 34345b3e1433Swyllys rv = local_export_pk12(handle, p12cred, numcerts, certlist, 343530a5e8faSwyllys numkeys, keylist, filename); 343630a5e8faSwyllys 343730a5e8faSwyllys return (rv); 343830a5e8faSwyllys } 343930a5e8faSwyllys 344030a5e8faSwyllys KMF_RETURN 344130a5e8faSwyllys OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 344299ebb4caSwyllys { 344399ebb4caSwyllys KMF_RETURN rv; 344499ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 344599ebb4caSwyllys char *fullpath = NULL; 344630a5e8faSwyllys char *dirpath = NULL; 344730a5e8faSwyllys char *certfile = NULL; 344830a5e8faSwyllys char *keyfile = NULL; 344930a5e8faSwyllys char *filename = NULL; 345030a5e8faSwyllys KMF_CREDENTIAL *p12cred = NULL; 34515b3e1433Swyllys KMF_X509_DER_CERT certdata; 34525b3e1433Swyllys KMF_KEY_HANDLE key; 34535b3e1433Swyllys int gotkey = 0; 34545b3e1433Swyllys int gotcert = 0; 345530a5e8faSwyllys 345630a5e8faSwyllys if (handle == NULL) 345730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 345899ebb4caSwyllys 345999ebb4caSwyllys /* 346099ebb4caSwyllys * First, find the certificate. 346199ebb4caSwyllys */ 346230a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 346330a5e8faSwyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 346430a5e8faSwyllys if (certfile != NULL) { 346530a5e8faSwyllys fullpath = get_fullpath(dirpath, certfile); 346699ebb4caSwyllys if (fullpath == NULL) 346799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 346899ebb4caSwyllys 346999ebb4caSwyllys if (isdir(fullpath)) { 347099ebb4caSwyllys free(fullpath); 347199ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 347299ebb4caSwyllys } 347399ebb4caSwyllys 34745b3e1433Swyllys (void) memset(&certdata, 0, sizeof (certdata)); 34755b3e1433Swyllys rv = kmf_load_cert(kmfh, NULL, NULL, NULL, NULL, 34765b3e1433Swyllys fullpath, &certdata.certificate); 347799ebb4caSwyllys if (rv != KMF_OK) 347899ebb4caSwyllys goto end; 347930a5e8faSwyllys 34805b3e1433Swyllys gotcert++; 34815b3e1433Swyllys certdata.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL; 348230a5e8faSwyllys free(fullpath); 348399ebb4caSwyllys } 348499ebb4caSwyllys 348599ebb4caSwyllys /* 348699ebb4caSwyllys * Now find the private key. 348799ebb4caSwyllys */ 348830a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 348930a5e8faSwyllys if (keyfile != NULL) { 349030a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 349199ebb4caSwyllys if (fullpath == NULL) 349299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 349399ebb4caSwyllys 349499ebb4caSwyllys if (isdir(fullpath)) { 349599ebb4caSwyllys free(fullpath); 349699ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 349799ebb4caSwyllys } 349899ebb4caSwyllys 34995b3e1433Swyllys (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE)); 35005b3e1433Swyllys rv = fetch_key(handle, fullpath, KMF_ASYM_PRI, &key); 35015b3e1433Swyllys if (rv != KMF_OK) 350299ebb4caSwyllys goto end; 35035b3e1433Swyllys gotkey++; 350499ebb4caSwyllys } 350599ebb4caSwyllys 350699ebb4caSwyllys /* 350799ebb4caSwyllys * Open the output file. 350899ebb4caSwyllys */ 350930a5e8faSwyllys filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, 351030a5e8faSwyllys numattr); 351130a5e8faSwyllys if (filename == NULL) { 351230a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 351330a5e8faSwyllys goto end; 351430a5e8faSwyllys } 351530a5e8faSwyllys 351699ebb4caSwyllys /* Stick the key and the cert into a PKCS#12 file */ 351730a5e8faSwyllys p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); 351830a5e8faSwyllys if (p12cred == NULL) { 351930a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 352030a5e8faSwyllys goto end; 352130a5e8faSwyllys } 352230a5e8faSwyllys 35235b3e1433Swyllys rv = local_export_pk12(handle, p12cred, 1, &certdata, 35245b3e1433Swyllys 1, &key, filename); 352599ebb4caSwyllys 352699ebb4caSwyllys end: 352799ebb4caSwyllys if (fullpath) 352899ebb4caSwyllys free(fullpath); 352999ebb4caSwyllys 35305b3e1433Swyllys if (gotcert) 35315b3e1433Swyllys kmf_free_kmf_cert(handle, &certdata); 35325b3e1433Swyllys if (gotkey) 35335b3e1433Swyllys kmf_free_kmf_key(handle, &key); 353499ebb4caSwyllys return (rv); 353599ebb4caSwyllys } 353699ebb4caSwyllys 353771593db2Swyllys /* 353871593db2Swyllys * Helper function to extract keys and certificates from 353971593db2Swyllys * a single PEM file. Typically the file should contain a 354071593db2Swyllys * private key and an associated public key wrapped in an x509 cert. 354171593db2Swyllys * However, the file may be just a list of X509 certs with no keys. 354271593db2Swyllys */ 354371593db2Swyllys static KMF_RETURN 354430a5e8faSwyllys extract_pem(KMF_HANDLE *kmfh, 354530a5e8faSwyllys char *issuer, char *subject, KMF_BIGINT *serial, 354602744e81Swyllys char *filename, CK_UTF8CHAR *pin, 354771593db2Swyllys CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs, 354871593db2Swyllys int *numcerts) 354971593db2Swyllys /* ARGSUSED */ 355071593db2Swyllys { 355171593db2Swyllys KMF_RETURN rv = KMF_OK; 355271593db2Swyllys FILE *fp; 355334acef67Swyllys STACK_OF(X509_INFO) *x509_info_stack = NULL; 355402744e81Swyllys int i, ncerts = 0, matchcerts = 0; 355571593db2Swyllys EVP_PKEY *pkey = NULL; 355671593db2Swyllys X509_INFO *info; 355771593db2Swyllys X509 *x; 35585b3e1433Swyllys X509_INFO **cert_infos = NULL; 355971593db2Swyllys KMF_DATA *certlist = NULL; 356071593db2Swyllys 356171593db2Swyllys if (priv_key) 356271593db2Swyllys *priv_key = NULL; 356371593db2Swyllys if (certs) 356471593db2Swyllys *certs = NULL; 356571593db2Swyllys fp = fopen(filename, "r"); 35665b3e1433Swyllys if (fp == NULL) 356771593db2Swyllys return (KMF_ERR_OPEN_FILE); 35685b3e1433Swyllys 356971593db2Swyllys x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin); 357071593db2Swyllys if (x509_info_stack == NULL) { 357171593db2Swyllys (void) fclose(fp); 357271593db2Swyllys return (KMF_ERR_ENCODING); 357371593db2Swyllys } 35745b3e1433Swyllys cert_infos = (X509_INFO **)malloc(sk_X509_INFO_num(x509_info_stack) * 35755b3e1433Swyllys sizeof (X509_INFO *)); 35765b3e1433Swyllys if (cert_infos == NULL) { 35775b3e1433Swyllys (void) fclose(fp); 35785b3e1433Swyllys rv = KMF_ERR_MEMORY; 35795b3e1433Swyllys goto err; 35805b3e1433Swyllys } 358171593db2Swyllys 35825b3e1433Swyllys for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) { 358371593db2Swyllys /* LINTED */ 358434acef67Swyllys cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i); 358571593db2Swyllys ncerts++; 358671593db2Swyllys } 358771593db2Swyllys 358871593db2Swyllys if (ncerts == 0) { 358971593db2Swyllys (void) fclose(fp); 359034acef67Swyllys rv = KMF_ERR_CERT_NOT_FOUND; 359134acef67Swyllys goto err; 359271593db2Swyllys } 359371593db2Swyllys 359471593db2Swyllys if (priv_key != NULL) { 359571593db2Swyllys rewind(fp); 359671593db2Swyllys pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin); 359771593db2Swyllys } 359871593db2Swyllys (void) fclose(fp); 359971593db2Swyllys 360071593db2Swyllys x = cert_infos[ncerts - 1]->x509; 360171593db2Swyllys /* 360271593db2Swyllys * Make sure the private key matchs the last cert in the file. 360371593db2Swyllys */ 360471593db2Swyllys if (pkey != NULL && !X509_check_private_key(x, pkey)) { 360571593db2Swyllys EVP_PKEY_free(pkey); 360634acef67Swyllys rv = KMF_ERR_KEY_MISMATCH; 360734acef67Swyllys goto err; 360871593db2Swyllys } 360971593db2Swyllys 361071593db2Swyllys certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA)); 361171593db2Swyllys if (certlist == NULL) { 361271593db2Swyllys if (pkey != NULL) 361371593db2Swyllys EVP_PKEY_free(pkey); 361434acef67Swyllys rv = KMF_ERR_MEMORY; 361534acef67Swyllys goto err; 361671593db2Swyllys } 361771593db2Swyllys 361871593db2Swyllys /* 361971593db2Swyllys * Convert all of the certs to DER format. 362071593db2Swyllys */ 362102744e81Swyllys matchcerts = 0; 362271593db2Swyllys for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) { 362302744e81Swyllys boolean_t match = FALSE; 362471593db2Swyllys info = cert_infos[ncerts - 1 - i]; 362571593db2Swyllys 362630a5e8faSwyllys rv = check_cert(info->x509, issuer, subject, serial, &match); 362702744e81Swyllys if (rv != KMF_OK || match != TRUE) { 362802744e81Swyllys rv = KMF_OK; 362902744e81Swyllys continue; 363002744e81Swyllys } 363102744e81Swyllys 363202744e81Swyllys rv = ssl_cert2KMFDATA(kmfh, info->x509, 363302744e81Swyllys &certlist[matchcerts++]); 363471593db2Swyllys 363571593db2Swyllys if (rv != KMF_OK) { 363671593db2Swyllys free(certlist); 363771593db2Swyllys certlist = NULL; 363802744e81Swyllys ncerts = matchcerts = 0; 363971593db2Swyllys } 364071593db2Swyllys } 364171593db2Swyllys 364271593db2Swyllys if (numcerts != NULL) 364302744e81Swyllys *numcerts = matchcerts; 364471593db2Swyllys if (certs != NULL) 364571593db2Swyllys *certs = certlist; 364671593db2Swyllys 364771593db2Swyllys if (priv_key == NULL && pkey != NULL) 364871593db2Swyllys EVP_PKEY_free(pkey); 364971593db2Swyllys else if (priv_key != NULL && pkey != NULL) 365071593db2Swyllys *priv_key = pkey; 365171593db2Swyllys 365234acef67Swyllys err: 365334acef67Swyllys /* Cleanup the stack of X509 info records */ 365434acef67Swyllys for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) { 365534acef67Swyllys /*LINTED*/ 365634acef67Swyllys info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i); 365734acef67Swyllys X509_INFO_free(info); 365834acef67Swyllys } 365934acef67Swyllys if (x509_info_stack) 366034acef67Swyllys sk_X509_INFO_free(x509_info_stack); 366134acef67Swyllys 36625b3e1433Swyllys if (cert_infos != NULL) 36635b3e1433Swyllys free(cert_infos); 36645b3e1433Swyllys 366571593db2Swyllys return (rv); 366671593db2Swyllys } 366771593db2Swyllys 36685b3e1433Swyllys static KMF_RETURN 36695b3e1433Swyllys openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin, 36705b3e1433Swyllys STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs) 36715b3e1433Swyllys { 36725b3e1433Swyllys KMF_RETURN ret; 36735b3e1433Swyllys int i; 36745b3e1433Swyllys 36755b3e1433Swyllys for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 36765b3e1433Swyllys /*LINTED*/ 36775b3e1433Swyllys PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i); 36785b3e1433Swyllys ret = openssl_parse_bag(bag, pin, (pin ? strlen(pin) : 0), 36795b3e1433Swyllys keys, certs); 36805b3e1433Swyllys 36815b3e1433Swyllys if (ret != KMF_OK) 36825b3e1433Swyllys return (ret); 36835b3e1433Swyllys } 36845b3e1433Swyllys 36855b3e1433Swyllys return (ret); 36865b3e1433Swyllys } 36875b3e1433Swyllys 36885b3e1433Swyllys static KMF_RETURN 36895b3e1433Swyllys set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid) 36905b3e1433Swyllys { 36915b3e1433Swyllys X509_ATTRIBUTE *attr = NULL; 36925b3e1433Swyllys 36935b3e1433Swyllys if (pkey == NULL || attrib == NULL) 36945b3e1433Swyllys return (KMF_ERR_BAD_PARAMETER); 36955b3e1433Swyllys 36965b3e1433Swyllys if (pkey->attributes == NULL) { 36975b3e1433Swyllys pkey->attributes = sk_X509_ATTRIBUTE_new_null(); 36985b3e1433Swyllys if (pkey->attributes == NULL) 36995b3e1433Swyllys return (KMF_ERR_MEMORY); 37005b3e1433Swyllys } 37015b3e1433Swyllys attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr); 37025b3e1433Swyllys if (attr != NULL) { 37035b3e1433Swyllys int i; 37045b3e1433Swyllys X509_ATTRIBUTE *a; 37055b3e1433Swyllys for (i = 0; 37065b3e1433Swyllys i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) { 37075b3e1433Swyllys /*LINTED*/ 37085b3e1433Swyllys a = sk_X509_ATTRIBUTE_value(pkey->attributes, i); 37095b3e1433Swyllys if (OBJ_obj2nid(a->object) == nid) { 37105b3e1433Swyllys X509_ATTRIBUTE_free(a); 37115b3e1433Swyllys /*LINTED*/ 37125b3e1433Swyllys sk_X509_ATTRIBUTE_set(pkey->attributes, 37135b3e1433Swyllys i, attr); 37145b3e1433Swyllys return (KMF_OK); 37155b3e1433Swyllys } 37165b3e1433Swyllys } 37175b3e1433Swyllys if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) { 37185b3e1433Swyllys X509_ATTRIBUTE_free(attr); 37195b3e1433Swyllys return (KMF_ERR_MEMORY); 37205b3e1433Swyllys } 37215b3e1433Swyllys } else { 37225b3e1433Swyllys return (KMF_ERR_MEMORY); 37235b3e1433Swyllys } 37245b3e1433Swyllys 37255b3e1433Swyllys return (KMF_OK); 37265b3e1433Swyllys } 37275b3e1433Swyllys 37285b3e1433Swyllys static KMF_RETURN 37295b3e1433Swyllys openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen, 37305b3e1433Swyllys STACK_OF(EVP_PKEY) *keylist, STACK_OF(X509) *certlist) 37315b3e1433Swyllys { 37325b3e1433Swyllys KMF_RETURN ret = KMF_OK; 37335b3e1433Swyllys PKCS8_PRIV_KEY_INFO *p8 = NULL; 37345b3e1433Swyllys EVP_PKEY *pkey = NULL; 37355b3e1433Swyllys X509 *xcert = NULL; 37365b3e1433Swyllys ASN1_TYPE *keyid = NULL; 37375b3e1433Swyllys ASN1_TYPE *fname = NULL; 37385b3e1433Swyllys uchar_t *data = NULL; 37395b3e1433Swyllys 37405b3e1433Swyllys keyid = PKCS12_get_attr(bag, NID_localKeyID); 37415b3e1433Swyllys fname = PKCS12_get_attr(bag, NID_friendlyName); 37425b3e1433Swyllys 37435b3e1433Swyllys switch (M_PKCS12_bag_type(bag)) { 37445b3e1433Swyllys case NID_keyBag: 37455b3e1433Swyllys if (keylist == NULL) 37465b3e1433Swyllys goto end; 37475b3e1433Swyllys pkey = EVP_PKCS82PKEY(bag->value.keybag); 37485b3e1433Swyllys if (pkey == NULL) 37495b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 37505b3e1433Swyllys 37515b3e1433Swyllys break; 37525b3e1433Swyllys case NID_pkcs8ShroudedKeyBag: 37535b3e1433Swyllys if (keylist == NULL) 37545b3e1433Swyllys goto end; 37555b3e1433Swyllys p8 = M_PKCS12_decrypt_skey(bag, pass, passlen); 37565b3e1433Swyllys if (p8 == NULL) 37575b3e1433Swyllys return (KMF_ERR_AUTH_FAILED); 37585b3e1433Swyllys pkey = EVP_PKCS82PKEY(p8); 37595b3e1433Swyllys PKCS8_PRIV_KEY_INFO_free(p8); 37605b3e1433Swyllys if (pkey == NULL) 37615b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 37625b3e1433Swyllys break; 37635b3e1433Swyllys case NID_certBag: 37645b3e1433Swyllys if (certlist == NULL) 37655b3e1433Swyllys goto end; 37665b3e1433Swyllys if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) 37675b3e1433Swyllys return (KMF_ERR_PKCS12_FORMAT); 37685b3e1433Swyllys xcert = M_PKCS12_certbag2x509(bag); 37695b3e1433Swyllys if (xcert == NULL) { 37705b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 37715b3e1433Swyllys goto end; 37725b3e1433Swyllys } 37735b3e1433Swyllys if (keyid != NULL) { 37745b3e1433Swyllys if (X509_keyid_set1(xcert, 37755b3e1433Swyllys keyid->value.octet_string->data, 37765b3e1433Swyllys keyid->value.octet_string->length) == 0) { 37775b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 37785b3e1433Swyllys goto end; 37795b3e1433Swyllys } 37805b3e1433Swyllys } 37815b3e1433Swyllys if (fname != NULL) { 37825b3e1433Swyllys int len, r; 37835b3e1433Swyllys len = ASN1_STRING_to_UTF8(&data, 37845b3e1433Swyllys fname->value.asn1_string); 37855b3e1433Swyllys if (len > 0 && data != NULL) { 37865b3e1433Swyllys r = X509_alias_set1(xcert, data, len); 37875b3e1433Swyllys if (r == NULL) { 37885b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 37895b3e1433Swyllys goto end; 37905b3e1433Swyllys } 37915b3e1433Swyllys } else { 37925b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 37935b3e1433Swyllys goto end; 37945b3e1433Swyllys } 37955b3e1433Swyllys } 37965b3e1433Swyllys if (sk_X509_push(certlist, xcert) == 0) 37975b3e1433Swyllys ret = KMF_ERR_MEMORY; 37985b3e1433Swyllys else 37995b3e1433Swyllys xcert = NULL; 38005b3e1433Swyllys break; 38015b3e1433Swyllys case NID_safeContentsBag: 38025b3e1433Swyllys return (openssl_parse_bags(bag->value.safes, pass, 38035b3e1433Swyllys keylist, certlist)); 38045b3e1433Swyllys default: 38055b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 38065b3e1433Swyllys break; 38075b3e1433Swyllys } 38085b3e1433Swyllys 38095b3e1433Swyllys /* 38105b3e1433Swyllys * Set the ID and/or FriendlyName attributes on the key. 38115b3e1433Swyllys * If converting to PKCS11 objects, these can translate to CKA_ID 38125b3e1433Swyllys * and CKA_LABEL values. 38135b3e1433Swyllys */ 38145b3e1433Swyllys if (pkey != NULL && ret == KMF_OK) { 38155b3e1433Swyllys ASN1_TYPE *attr = NULL; 38165b3e1433Swyllys if (keyid != NULL && keyid->type == V_ASN1_OCTET_STRING) { 38175b3e1433Swyllys if ((attr = ASN1_TYPE_new()) == NULL) 38185b3e1433Swyllys return (KMF_ERR_MEMORY); 38195b3e1433Swyllys attr->value.octet_string = 38205b3e1433Swyllys ASN1_STRING_dup(keyid->value.octet_string); 38215b3e1433Swyllys attr->type = V_ASN1_OCTET_STRING; 38225b3e1433Swyllys attr->value.ptr = (char *)attr->value.octet_string; 38235b3e1433Swyllys ret = set_pkey_attrib(pkey, attr, NID_localKeyID); 38245b3e1433Swyllys OPENSSL_free(attr); 38255b3e1433Swyllys } 38265b3e1433Swyllys 38275b3e1433Swyllys if (ret == KMF_OK && fname != NULL && 38285b3e1433Swyllys fname->type == V_ASN1_BMPSTRING) { 38295b3e1433Swyllys if ((attr = ASN1_TYPE_new()) == NULL) 38305b3e1433Swyllys return (KMF_ERR_MEMORY); 38315b3e1433Swyllys attr->value.bmpstring = 38325b3e1433Swyllys ASN1_STRING_dup(fname->value.bmpstring); 38335b3e1433Swyllys attr->type = V_ASN1_BMPSTRING; 38345b3e1433Swyllys attr->value.ptr = (char *)attr->value.bmpstring; 38355b3e1433Swyllys ret = set_pkey_attrib(pkey, attr, NID_friendlyName); 38365b3e1433Swyllys OPENSSL_free(attr); 38375b3e1433Swyllys } 38385b3e1433Swyllys 38395b3e1433Swyllys if (ret == KMF_OK && keylist != NULL && 38405b3e1433Swyllys sk_EVP_PKEY_push(keylist, pkey) == 0) 38415b3e1433Swyllys ret = KMF_ERR_MEMORY; 38425b3e1433Swyllys } 38435b3e1433Swyllys if (ret == KMF_OK && keylist != NULL) 38445b3e1433Swyllys pkey = NULL; 38455b3e1433Swyllys end: 38465b3e1433Swyllys if (pkey != NULL) 38475b3e1433Swyllys EVP_PKEY_free(pkey); 38485b3e1433Swyllys if (xcert != NULL) 38495b3e1433Swyllys X509_free(xcert); 38505b3e1433Swyllys if (data != NULL) 38515b3e1433Swyllys OPENSSL_free(data); 38525b3e1433Swyllys 38535b3e1433Swyllys return (ret); 38545b3e1433Swyllys } 38555b3e1433Swyllys 38565b3e1433Swyllys static KMF_RETURN 38575b3e1433Swyllys openssl_pkcs12_parse(PKCS12 *p12, char *pin, 38585b3e1433Swyllys STACK_OF(EVP_PKEY) *keys, 38595b3e1433Swyllys STACK_OF(X509) *certs, 38605b3e1433Swyllys STACK_OF(X509) *ca) 38615b3e1433Swyllys /*ARGSUSED*/ 38625b3e1433Swyllys { 38635b3e1433Swyllys KMF_RETURN ret = KMF_OK; 38645b3e1433Swyllys STACK_OF(PKCS7) *asafes = NULL; 38655b3e1433Swyllys STACK_OF(PKCS12_SAFEBAG) *bags = NULL; 38665b3e1433Swyllys int i, bagnid; 38675b3e1433Swyllys PKCS7 *p7; 38685b3e1433Swyllys 38695b3e1433Swyllys if (p12 == NULL || (keys == NULL && certs == NULL)) 38705b3e1433Swyllys return (KMF_ERR_BAD_PARAMETER); 38715b3e1433Swyllys 38725b3e1433Swyllys if (pin == NULL || *pin == NULL) { 38735b3e1433Swyllys if (PKCS12_verify_mac(p12, NULL, 0)) { 38745b3e1433Swyllys pin = NULL; 38755b3e1433Swyllys } else if (PKCS12_verify_mac(p12, "", 0)) { 38765b3e1433Swyllys pin = ""; 38775b3e1433Swyllys } else { 38785b3e1433Swyllys return (KMF_ERR_AUTH_FAILED); 38795b3e1433Swyllys } 38805b3e1433Swyllys } else if (!PKCS12_verify_mac(p12, pin, -1)) { 38815b3e1433Swyllys return (KMF_ERR_AUTH_FAILED); 38825b3e1433Swyllys } 38835b3e1433Swyllys 38845b3e1433Swyllys if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) 38855b3e1433Swyllys return (KMF_ERR_PKCS12_FORMAT); 38865b3e1433Swyllys 38875b3e1433Swyllys for (i = 0; ret == KMF_OK && i < sk_PKCS7_num(asafes); i++) { 38885b3e1433Swyllys bags = NULL; 38895b3e1433Swyllys /*LINTED*/ 38905b3e1433Swyllys p7 = sk_PKCS7_value(asafes, i); 38915b3e1433Swyllys bagnid = OBJ_obj2nid(p7->type); 38925b3e1433Swyllys 38935b3e1433Swyllys if (bagnid == NID_pkcs7_data) { 38945b3e1433Swyllys bags = PKCS12_unpack_p7data(p7); 38955b3e1433Swyllys } else if (bagnid == NID_pkcs7_encrypted) { 38965b3e1433Swyllys bags = PKCS12_unpack_p7encdata(p7, pin, 38975b3e1433Swyllys (pin ? strlen(pin) : 0)); 38985b3e1433Swyllys } else { 38995b3e1433Swyllys continue; 39005b3e1433Swyllys } 39015b3e1433Swyllys if (bags == NULL) { 39025b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 39035b3e1433Swyllys goto out; 39045b3e1433Swyllys } 39055b3e1433Swyllys 39065b3e1433Swyllys if (openssl_parse_bags(bags, pin, keys, certs) != KMF_OK) 39075b3e1433Swyllys ret = KMF_ERR_PKCS12_FORMAT; 39085b3e1433Swyllys 39095b3e1433Swyllys sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 39105b3e1433Swyllys } 39115b3e1433Swyllys out: 39125b3e1433Swyllys if (asafes != NULL) 39135b3e1433Swyllys sk_PKCS7_pop_free(asafes, PKCS7_free); 39145b3e1433Swyllys 39155b3e1433Swyllys return (ret); 39165b3e1433Swyllys } 39175b3e1433Swyllys 391899ebb4caSwyllys /* 391999ebb4caSwyllys * Helper function to decrypt and parse PKCS#12 import file. 392099ebb4caSwyllys */ 392199ebb4caSwyllys static KMF_RETURN 392299ebb4caSwyllys extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 39235b3e1433Swyllys STACK_OF(EVP_PKEY) **priv_key, STACK_OF(X509) **certs, 39245b3e1433Swyllys STACK_OF(X509) **ca) 392599ebb4caSwyllys /* ARGSUSED */ 392699ebb4caSwyllys { 392799ebb4caSwyllys PKCS12 *pk12, *pk12_tmp; 39285b3e1433Swyllys STACK_OF(EVP_PKEY) *pkeylist = NULL; 39295b3e1433Swyllys STACK_OF(X509) *xcertlist = NULL; 39305b3e1433Swyllys STACK_OF(X509) *cacertlist = NULL; 393199ebb4caSwyllys 393299ebb4caSwyllys if ((pk12 = PKCS12_new()) == NULL) { 393399ebb4caSwyllys return (KMF_ERR_MEMORY); 393499ebb4caSwyllys } 393599ebb4caSwyllys 393699ebb4caSwyllys if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) { 393799ebb4caSwyllys /* This is ok; it seems to mean there is no more to read. */ 393899ebb4caSwyllys if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 && 393999ebb4caSwyllys ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG) 394099ebb4caSwyllys goto end_extract_pkcs12; 394199ebb4caSwyllys 394299ebb4caSwyllys PKCS12_free(pk12); 394399ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 394499ebb4caSwyllys } 394599ebb4caSwyllys pk12 = pk12_tmp; 394699ebb4caSwyllys 39475b3e1433Swyllys xcertlist = sk_X509_new_null(); 39485b3e1433Swyllys if (xcertlist == NULL) { 39495b3e1433Swyllys PKCS12_free(pk12); 39505b3e1433Swyllys return (KMF_ERR_MEMORY); 39515b3e1433Swyllys } 39525b3e1433Swyllys pkeylist = sk_EVP_PKEY_new_null(); 39535b3e1433Swyllys if (pkeylist == NULL) { 39545b3e1433Swyllys sk_X509_pop_free(xcertlist, X509_free); 39555b3e1433Swyllys PKCS12_free(pk12); 39565b3e1433Swyllys return (KMF_ERR_MEMORY); 39575b3e1433Swyllys } 39585b3e1433Swyllys 39595b3e1433Swyllys if (openssl_pkcs12_parse(pk12, (char *)pin, pkeylist, xcertlist, 39605b3e1433Swyllys cacertlist) != KMF_OK) { 39615b3e1433Swyllys sk_X509_pop_free(xcertlist, X509_free); 39625b3e1433Swyllys sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free); 396399ebb4caSwyllys PKCS12_free(pk12); 396499ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 396599ebb4caSwyllys } 396699ebb4caSwyllys 39675b3e1433Swyllys if (priv_key && pkeylist) 39685b3e1433Swyllys *priv_key = pkeylist; 39695b3e1433Swyllys else if (pkeylist) 39705b3e1433Swyllys sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free); 39715b3e1433Swyllys if (certs && xcertlist) 39725b3e1433Swyllys *certs = xcertlist; 39735b3e1433Swyllys else if (xcertlist) 39745b3e1433Swyllys sk_X509_pop_free(xcertlist, X509_free); 39755b3e1433Swyllys if (ca && cacertlist) 39765b3e1433Swyllys *ca = cacertlist; 39775b3e1433Swyllys else if (cacertlist) 39785b3e1433Swyllys sk_X509_pop_free(cacertlist, X509_free); 397999ebb4caSwyllys 39805b3e1433Swyllys end_extract_pkcs12: 398199ebb4caSwyllys 398299ebb4caSwyllys PKCS12_free(pk12); 398399ebb4caSwyllys return (KMF_OK); 398499ebb4caSwyllys } 398599ebb4caSwyllys 398699ebb4caSwyllys static KMF_RETURN 398799ebb4caSwyllys sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to) 398899ebb4caSwyllys { 398999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 399099ebb4caSwyllys uint32_t sz; 399199ebb4caSwyllys 399299ebb4caSwyllys sz = BN_num_bytes(from); 399399ebb4caSwyllys to->val = (uchar_t *)malloc(sz); 399499ebb4caSwyllys if (to->val == NULL) 399599ebb4caSwyllys return (KMF_ERR_MEMORY); 399699ebb4caSwyllys 399799ebb4caSwyllys if ((to->len = BN_bn2bin(from, to->val)) != sz) { 399899ebb4caSwyllys free(to->val); 399999ebb4caSwyllys to->val = NULL; 400099ebb4caSwyllys to->len = 0; 400199ebb4caSwyllys rv = KMF_ERR_MEMORY; 400299ebb4caSwyllys } 400399ebb4caSwyllys 400499ebb4caSwyllys return (rv); 400599ebb4caSwyllys } 400699ebb4caSwyllys 400799ebb4caSwyllys static KMF_RETURN 400899ebb4caSwyllys exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) 400999ebb4caSwyllys { 401099ebb4caSwyllys KMF_RETURN rv; 401199ebb4caSwyllys KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa; 401299ebb4caSwyllys 401399ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY)); 401499ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK) 401599ebb4caSwyllys goto cleanup; 401699ebb4caSwyllys 401799ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK) 401899ebb4caSwyllys goto cleanup; 401999ebb4caSwyllys 402099ebb4caSwyllys if (rsa->d != NULL) 402199ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK) 402299ebb4caSwyllys goto cleanup; 402399ebb4caSwyllys 402499ebb4caSwyllys if (rsa->p != NULL) 402599ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK) 402699ebb4caSwyllys goto cleanup; 402799ebb4caSwyllys 402899ebb4caSwyllys if (rsa->q != NULL) 402999ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK) 403099ebb4caSwyllys goto cleanup; 403199ebb4caSwyllys 403299ebb4caSwyllys if (rsa->dmp1 != NULL) 403399ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK) 403499ebb4caSwyllys goto cleanup; 403599ebb4caSwyllys 403699ebb4caSwyllys if (rsa->dmq1 != NULL) 403799ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK) 403899ebb4caSwyllys goto cleanup; 403999ebb4caSwyllys 404099ebb4caSwyllys if (rsa->iqmp != NULL) 404199ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK) 404299ebb4caSwyllys goto cleanup; 404399ebb4caSwyllys cleanup: 404499ebb4caSwyllys if (rv != KMF_OK) 404530a5e8faSwyllys kmf_free_raw_key(key); 404699ebb4caSwyllys else 404799ebb4caSwyllys key->keytype = KMF_RSA; 404899ebb4caSwyllys 404999ebb4caSwyllys /* 405099ebb4caSwyllys * Free the reference to this key, SSL will not actually free 405199ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 405299ebb4caSwyllys */ 405399ebb4caSwyllys RSA_free(rsa); 405499ebb4caSwyllys 405599ebb4caSwyllys return (rv); 405699ebb4caSwyllys } 405799ebb4caSwyllys 405899ebb4caSwyllys static KMF_RETURN 405999ebb4caSwyllys exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) 406099ebb4caSwyllys { 406199ebb4caSwyllys KMF_RETURN rv; 406299ebb4caSwyllys KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa; 406399ebb4caSwyllys 406499ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY)); 406599ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK) 406699ebb4caSwyllys goto cleanup; 406799ebb4caSwyllys 406899ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK) 406999ebb4caSwyllys goto cleanup; 407099ebb4caSwyllys 407199ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK) 407299ebb4caSwyllys goto cleanup; 407399ebb4caSwyllys 407499ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK) 407599ebb4caSwyllys goto cleanup; 407699ebb4caSwyllys 407799ebb4caSwyllys cleanup: 407899ebb4caSwyllys if (rv != KMF_OK) 407930a5e8faSwyllys kmf_free_raw_key(key); 408099ebb4caSwyllys else 408199ebb4caSwyllys key->keytype = KMF_DSA; 408299ebb4caSwyllys 408399ebb4caSwyllys /* 408499ebb4caSwyllys * Free the reference to this key, SSL will not actually free 408599ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 408699ebb4caSwyllys */ 408799ebb4caSwyllys DSA_free(dsa); 408899ebb4caSwyllys 408999ebb4caSwyllys return (rv); 409099ebb4caSwyllys } 409199ebb4caSwyllys 409299ebb4caSwyllys static KMF_RETURN 409399ebb4caSwyllys add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert, 40945b3e1433Swyllys KMF_X509_DER_CERT **certlist, int *ncerts) 409599ebb4caSwyllys { 409699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 40975b3e1433Swyllys KMF_X509_DER_CERT *list = (*certlist); 40985b3e1433Swyllys KMF_X509_DER_CERT cert; 409999ebb4caSwyllys int n = (*ncerts); 410099ebb4caSwyllys 410199ebb4caSwyllys if (list == NULL) { 41025b3e1433Swyllys list = (KMF_X509_DER_CERT *)malloc(sizeof (KMF_X509_DER_CERT)); 410399ebb4caSwyllys } else { 41045b3e1433Swyllys list = (KMF_X509_DER_CERT *)realloc(list, 41055b3e1433Swyllys sizeof (KMF_X509_DER_CERT) * (n + 1)); 410699ebb4caSwyllys } 410799ebb4caSwyllys 410899ebb4caSwyllys if (list == NULL) 410999ebb4caSwyllys return (KMF_ERR_MEMORY); 411099ebb4caSwyllys 41115b3e1433Swyllys (void) memset(&cert, 0, sizeof (cert)); 41125b3e1433Swyllys rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert.certificate); 411399ebb4caSwyllys if (rv == KMF_OK) { 41145b3e1433Swyllys int len = 0; 41155b3e1433Swyllys /* Get the alias name for the cert if there is one */ 41165b3e1433Swyllys char *a = (char *)X509_alias_get0(sslcert, &len); 41175b3e1433Swyllys if (a != NULL) 41185b3e1433Swyllys cert.kmf_private.label = strdup(a); 41195b3e1433Swyllys cert.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL; 41205b3e1433Swyllys 412199ebb4caSwyllys list[n] = cert; 412299ebb4caSwyllys (*ncerts) = n + 1; 412399ebb4caSwyllys 412499ebb4caSwyllys *certlist = list; 412599ebb4caSwyllys } else { 412699ebb4caSwyllys free(list); 412799ebb4caSwyllys } 412899ebb4caSwyllys 412999ebb4caSwyllys return (rv); 413099ebb4caSwyllys } 413199ebb4caSwyllys 413299ebb4caSwyllys static KMF_RETURN 413399ebb4caSwyllys add_key_to_list(KMF_RAW_KEY_DATA **keylist, 413499ebb4caSwyllys KMF_RAW_KEY_DATA *newkey, int *nkeys) 413599ebb4caSwyllys { 413699ebb4caSwyllys KMF_RAW_KEY_DATA *list = (*keylist); 413799ebb4caSwyllys int n = (*nkeys); 413899ebb4caSwyllys 413999ebb4caSwyllys if (list == NULL) { 414099ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA)); 414199ebb4caSwyllys } else { 414299ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)realloc(list, 414399ebb4caSwyllys sizeof (KMF_RAW_KEY_DATA) * (n + 1)); 414499ebb4caSwyllys } 414599ebb4caSwyllys 414699ebb4caSwyllys if (list == NULL) 414799ebb4caSwyllys return (KMF_ERR_MEMORY); 414899ebb4caSwyllys 414999ebb4caSwyllys list[n] = *newkey; 415099ebb4caSwyllys (*nkeys) = n + 1; 415199ebb4caSwyllys 415299ebb4caSwyllys *keylist = list; 415399ebb4caSwyllys 415499ebb4caSwyllys return (KMF_OK); 415599ebb4caSwyllys } 415699ebb4caSwyllys 41575b3e1433Swyllys static X509_ATTRIBUTE * 41585b3e1433Swyllys find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid) 41595b3e1433Swyllys { 41605b3e1433Swyllys X509_ATTRIBUTE *a; 41615b3e1433Swyllys int i; 41625b3e1433Swyllys 41635b3e1433Swyllys if (attrs == NULL) 41645b3e1433Swyllys return (NULL); 41655b3e1433Swyllys 41665b3e1433Swyllys for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { 41675b3e1433Swyllys /*LINTED*/ 41685b3e1433Swyllys a = sk_X509_ATTRIBUTE_value(attrs, i); 41695b3e1433Swyllys if (OBJ_obj2nid(a->object) == nid) 41705b3e1433Swyllys return (a); 41715b3e1433Swyllys } 41725b3e1433Swyllys return (NULL); 41735b3e1433Swyllys } 41745b3e1433Swyllys 417530a5e8faSwyllys static KMF_RETURN 417630a5e8faSwyllys convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key) 417730a5e8faSwyllys { 417830a5e8faSwyllys KMF_RETURN rv = KMF_OK; 41795b3e1433Swyllys X509_ATTRIBUTE *attr; 418030a5e8faSwyllys 418130a5e8faSwyllys if (pkey == NULL || key == NULL) 418230a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 418330a5e8faSwyllys /* Convert SSL key to raw key */ 418430a5e8faSwyllys switch (pkey->type) { 418530a5e8faSwyllys case EVP_PKEY_RSA: 418630a5e8faSwyllys rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey), 418730a5e8faSwyllys key); 418830a5e8faSwyllys if (rv != KMF_OK) 418930a5e8faSwyllys return (rv); 419030a5e8faSwyllys break; 419130a5e8faSwyllys case EVP_PKEY_DSA: 419230a5e8faSwyllys rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey), 419330a5e8faSwyllys key); 419430a5e8faSwyllys if (rv != KMF_OK) 419530a5e8faSwyllys return (rv); 419630a5e8faSwyllys break; 419730a5e8faSwyllys default: 419830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 419930a5e8faSwyllys } 42005b3e1433Swyllys /* 42015b3e1433Swyllys * If friendlyName, add it to record. 42025b3e1433Swyllys */ 42035b3e1433Swyllys attr = find_attr(pkey->attributes, NID_friendlyName); 42045b3e1433Swyllys if (attr != NULL) { 42055b3e1433Swyllys ASN1_TYPE *ty = NULL; 42065b3e1433Swyllys int numattr = sk_ASN1_TYPE_num(attr->value.set); 42075b3e1433Swyllys if (attr->single == 0 && numattr > 0) { 42085b3e1433Swyllys /*LINTED*/ 42095b3e1433Swyllys ty = sk_ASN1_TYPE_value(attr->value.set, 0); 42105b3e1433Swyllys } 42115b3e1433Swyllys if (ty != NULL) { 42125b3e1433Swyllys key->label = uni2asc(ty->value.bmpstring->data, 42135b3e1433Swyllys ty->value.bmpstring->length); 42145b3e1433Swyllys } 42155b3e1433Swyllys } else { 42165b3e1433Swyllys key->label = NULL; 42175b3e1433Swyllys } 42185b3e1433Swyllys 42195b3e1433Swyllys /* 42205b3e1433Swyllys * If KeyID, add it to record as a KMF_DATA object. 42215b3e1433Swyllys */ 42225b3e1433Swyllys attr = find_attr(pkey->attributes, NID_localKeyID); 42235b3e1433Swyllys if (attr != NULL) { 42245b3e1433Swyllys ASN1_TYPE *ty = NULL; 42255b3e1433Swyllys int numattr = sk_ASN1_TYPE_num(attr->value.set); 42265b3e1433Swyllys if (attr->single == 0 && numattr > 0) { 42275b3e1433Swyllys /*LINTED*/ 42285b3e1433Swyllys ty = sk_ASN1_TYPE_value(attr->value.set, 0); 42295b3e1433Swyllys } 42305b3e1433Swyllys key->id.Data = (uchar_t *)malloc( 42315b3e1433Swyllys ty->value.octet_string->length); 42325b3e1433Swyllys if (key->id.Data == NULL) 42335b3e1433Swyllys return (KMF_ERR_MEMORY); 42345b3e1433Swyllys (void) memcpy(key->id.Data, ty->value.octet_string->data, 42355b3e1433Swyllys ty->value.octet_string->length); 42365b3e1433Swyllys key->id.Length = ty->value.octet_string->length; 42375b3e1433Swyllys } else { 42385b3e1433Swyllys (void) memset(&key->id, 0, sizeof (KMF_DATA)); 42395b3e1433Swyllys } 424030a5e8faSwyllys 424130a5e8faSwyllys return (rv); 424230a5e8faSwyllys } 424399ebb4caSwyllys 424499ebb4caSwyllys static KMF_RETURN 424599ebb4caSwyllys convertPK12Objects( 424699ebb4caSwyllys KMF_HANDLE *kmfh, 42475b3e1433Swyllys STACK_OF(EVP_PKEY) *sslkeys, 42485b3e1433Swyllys STACK_OF(X509) *sslcert, 42495b3e1433Swyllys STACK_OF(X509) *sslcacerts, 425099ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys, 42515b3e1433Swyllys KMF_X509_DER_CERT **certlist, int *ncerts) 425299ebb4caSwyllys { 425399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 425499ebb4caSwyllys KMF_RAW_KEY_DATA key; 425599ebb4caSwyllys int i; 425699ebb4caSwyllys 42575b3e1433Swyllys for (i = 0; sslkeys != NULL && i < sk_EVP_PKEY_num(sslkeys); i++) { 42585b3e1433Swyllys /*LINTED*/ 42595b3e1433Swyllys EVP_PKEY *pkey = sk_EVP_PKEY_value(sslkeys, i); 42605b3e1433Swyllys rv = convertToRawKey(pkey, &key); 426130a5e8faSwyllys if (rv == KMF_OK) 426299ebb4caSwyllys rv = add_key_to_list(keylist, &key, nkeys); 426330a5e8faSwyllys 426499ebb4caSwyllys if (rv != KMF_OK) 426599ebb4caSwyllys return (rv); 426699ebb4caSwyllys } 426799ebb4caSwyllys 426899ebb4caSwyllys /* Now add the certificate to the certlist */ 42695b3e1433Swyllys for (i = 0; sslcert != NULL && i < sk_X509_num(sslcert); i++) { 42705b3e1433Swyllys /*LINTED*/ 42715b3e1433Swyllys X509 *cert = sk_X509_value(sslcert, i); 42725b3e1433Swyllys rv = add_cert_to_list(kmfh, cert, certlist, ncerts); 427399ebb4caSwyllys if (rv != KMF_OK) 427499ebb4caSwyllys return (rv); 427599ebb4caSwyllys } 427699ebb4caSwyllys 427799ebb4caSwyllys /* Also add any included CA certs to the list */ 427871593db2Swyllys for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) { 427999ebb4caSwyllys X509 *c; 428099ebb4caSwyllys /* 428199ebb4caSwyllys * sk_X509_value() is macro that embeds a cast to (X509 *). 428299ebb4caSwyllys * Here it translates into ((X509 *)sk_value((ca), (i))). 428399ebb4caSwyllys * Lint is complaining about the embedded casting, and 428499ebb4caSwyllys * to fix it, you need to fix openssl header files. 428599ebb4caSwyllys */ 428699ebb4caSwyllys /* LINTED E_BAD_PTR_CAST_ALIGN */ 428799ebb4caSwyllys c = sk_X509_value(sslcacerts, i); 428899ebb4caSwyllys 428999ebb4caSwyllys /* Now add the ca cert to the certlist */ 429099ebb4caSwyllys rv = add_cert_to_list(kmfh, c, certlist, ncerts); 429199ebb4caSwyllys if (rv != KMF_OK) 429299ebb4caSwyllys return (rv); 429399ebb4caSwyllys } 429499ebb4caSwyllys return (rv); 429599ebb4caSwyllys } 429699ebb4caSwyllys 429799ebb4caSwyllys KMF_RETURN 429830a5e8faSwyllys openssl_import_objects(KMF_HANDLE *kmfh, 429999ebb4caSwyllys char *filename, KMF_CREDENTIAL *cred, 43005b3e1433Swyllys KMF_X509_DER_CERT **certlist, int *ncerts, 430199ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys) 430299ebb4caSwyllys { 430399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 430430a5e8faSwyllys KMF_ENCODE_FORMAT format; 430530a5e8faSwyllys BIO *bio = NULL; 43065b3e1433Swyllys STACK_OF(EVP_PKEY) *privkeys = NULL; 43075b3e1433Swyllys STACK_OF(X509) *certs = NULL; 430899ebb4caSwyllys STACK_OF(X509) *cacerts = NULL; 430999ebb4caSwyllys 431030a5e8faSwyllys /* 431130a5e8faSwyllys * auto-detect the file format, regardless of what 431230a5e8faSwyllys * the 'format' parameters in the params say. 431330a5e8faSwyllys */ 431430a5e8faSwyllys rv = kmf_get_file_format(filename, &format); 431530a5e8faSwyllys if (rv != KMF_OK) { 431630a5e8faSwyllys return (rv); 431730a5e8faSwyllys } 431830a5e8faSwyllys 431930a5e8faSwyllys /* This function only works for PEM or PKCS#12 files */ 432030a5e8faSwyllys if (format != KMF_FORMAT_PEM && 432130a5e8faSwyllys format != KMF_FORMAT_PEM_KEYPAIR && 432230a5e8faSwyllys format != KMF_FORMAT_PKCS12) 432330a5e8faSwyllys return (KMF_ERR_ENCODING); 432430a5e8faSwyllys 432530a5e8faSwyllys *certlist = NULL; 432630a5e8faSwyllys *keylist = NULL; 432730a5e8faSwyllys *ncerts = 0; 432830a5e8faSwyllys *nkeys = 0; 432930a5e8faSwyllys 433030a5e8faSwyllys if (format == KMF_FORMAT_PKCS12) { 433199ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 433299ebb4caSwyllys if (bio == NULL) { 433399ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 433499ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 433599ebb4caSwyllys goto end; 433699ebb4caSwyllys } 433799ebb4caSwyllys 433834acef67Swyllys rv = extract_pkcs12(bio, (uchar_t *)cred->cred, 43395b3e1433Swyllys (uint32_t)cred->credlen, &privkeys, &certs, &cacerts); 434099ebb4caSwyllys 434199ebb4caSwyllys if (rv == KMF_OK) 434299ebb4caSwyllys /* Convert keys and certs to exportable format */ 43435b3e1433Swyllys rv = convertPK12Objects(kmfh, privkeys, certs, cacerts, 434499ebb4caSwyllys keylist, nkeys, certlist, ncerts); 434530a5e8faSwyllys } else { 43465b3e1433Swyllys EVP_PKEY *pkey; 43475b3e1433Swyllys KMF_DATA *certdata = NULL; 43485b3e1433Swyllys KMF_X509_DER_CERT *kmfcerts = NULL; 43495b3e1433Swyllys int i; 435030a5e8faSwyllys rv = extract_pem(kmfh, NULL, NULL, NULL, filename, 435134acef67Swyllys (uchar_t *)cred->cred, (uint32_t)cred->credlen, 43525b3e1433Swyllys &pkey, &certdata, ncerts); 435371593db2Swyllys 435471593db2Swyllys /* Reached end of import file? */ 43555b3e1433Swyllys if (rv == KMF_OK && pkey != NULL) { 43565b3e1433Swyllys privkeys = sk_EVP_PKEY_new_null(); 43575b3e1433Swyllys if (privkeys == NULL) { 43585b3e1433Swyllys rv = KMF_ERR_MEMORY; 43595b3e1433Swyllys goto end; 43605b3e1433Swyllys } 43615b3e1433Swyllys (void) sk_EVP_PKEY_push(privkeys, pkey); 43625b3e1433Swyllys /* convert the certificate list here */ 43635b3e1433Swyllys if (*ncerts > 0 && certlist != NULL) { 43645b3e1433Swyllys kmfcerts = (KMF_X509_DER_CERT *)malloc(*ncerts * 43655b3e1433Swyllys sizeof (KMF_X509_DER_CERT)); 43665b3e1433Swyllys if (kmfcerts == NULL) { 43675b3e1433Swyllys rv = KMF_ERR_MEMORY; 43685b3e1433Swyllys goto end; 43695b3e1433Swyllys } 43705b3e1433Swyllys (void) memset(kmfcerts, 0, *ncerts * 43715b3e1433Swyllys sizeof (KMF_X509_DER_CERT)); 43725b3e1433Swyllys for (i = 0; i < *ncerts; i++) { 43735b3e1433Swyllys kmfcerts[i].certificate = certdata[i]; 43745b3e1433Swyllys kmfcerts[i].kmf_private.keystore_type = 43755b3e1433Swyllys KMF_KEYSTORE_OPENSSL; 43765b3e1433Swyllys } 43775b3e1433Swyllys *certlist = kmfcerts; 43785b3e1433Swyllys } 43795b3e1433Swyllys /* 43805b3e1433Swyllys * Convert keys to exportable format, the certs 43815b3e1433Swyllys * are already OK. 43825b3e1433Swyllys */ 43835b3e1433Swyllys rv = convertPK12Objects(kmfh, privkeys, NULL, NULL, 438471593db2Swyllys keylist, nkeys, NULL, NULL); 438530a5e8faSwyllys } 43865b3e1433Swyllys } 438771593db2Swyllys end: 438830a5e8faSwyllys if (bio != NULL) 438999ebb4caSwyllys (void) BIO_free(bio); 439099ebb4caSwyllys 43915b3e1433Swyllys if (privkeys) 43925b3e1433Swyllys sk_EVP_PKEY_pop_free(privkeys, EVP_PKEY_free); 43935b3e1433Swyllys if (certs) 43945b3e1433Swyllys sk_X509_pop_free(certs, X509_free); 439530a5e8faSwyllys if (cacerts) 43965b3e1433Swyllys sk_X509_pop_free(cacerts, X509_free); 439730a5e8faSwyllys 439899ebb4caSwyllys return (rv); 439999ebb4caSwyllys } 440099ebb4caSwyllys 440199ebb4caSwyllys static KMF_RETURN 440299ebb4caSwyllys create_deskey(DES_cblock **deskey) 440399ebb4caSwyllys { 440499ebb4caSwyllys DES_cblock *key; 440599ebb4caSwyllys 440699ebb4caSwyllys key = (DES_cblock *) malloc(sizeof (DES_cblock)); 440799ebb4caSwyllys if (key == NULL) { 440899ebb4caSwyllys return (KMF_ERR_MEMORY); 440999ebb4caSwyllys } 441099ebb4caSwyllys 441199ebb4caSwyllys if (DES_random_key(key) == 0) { 441299ebb4caSwyllys free(key); 441399ebb4caSwyllys return (KMF_ERR_KEYGEN_FAILED); 441499ebb4caSwyllys } 441599ebb4caSwyllys 441699ebb4caSwyllys *deskey = key; 441799ebb4caSwyllys return (KMF_OK); 441899ebb4caSwyllys } 441999ebb4caSwyllys 442099ebb4caSwyllys #define KEYGEN_RETRY 3 442199ebb4caSwyllys #define DES3_KEY_SIZE 24 442299ebb4caSwyllys 442399ebb4caSwyllys static KMF_RETURN 442499ebb4caSwyllys create_des3key(unsigned char **des3key) 442599ebb4caSwyllys { 442699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 442799ebb4caSwyllys DES_cblock *deskey1 = NULL; 442899ebb4caSwyllys DES_cblock *deskey2 = NULL; 442999ebb4caSwyllys DES_cblock *deskey3 = NULL; 443099ebb4caSwyllys unsigned char *newkey = NULL; 443199ebb4caSwyllys int retry; 443299ebb4caSwyllys 443399ebb4caSwyllys if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) { 443499ebb4caSwyllys return (KMF_ERR_MEMORY); 443599ebb4caSwyllys } 443699ebb4caSwyllys 443799ebb4caSwyllys /* create the 1st DES key */ 443899ebb4caSwyllys if ((ret = create_deskey(&deskey1)) != KMF_OK) { 443999ebb4caSwyllys goto out; 444099ebb4caSwyllys } 444199ebb4caSwyllys 444299ebb4caSwyllys /* 444399ebb4caSwyllys * Create the 2nd DES key and make sure its value is different 444499ebb4caSwyllys * from the 1st DES key. 444599ebb4caSwyllys */ 444699ebb4caSwyllys retry = 0; 444799ebb4caSwyllys do { 444899ebb4caSwyllys if (deskey2 != NULL) { 444999ebb4caSwyllys free(deskey2); 445099ebb4caSwyllys deskey2 = NULL; 445199ebb4caSwyllys } 445299ebb4caSwyllys 445399ebb4caSwyllys if ((ret = create_deskey(&deskey2)) != KMF_OK) { 445499ebb4caSwyllys goto out; 445599ebb4caSwyllys } 445699ebb4caSwyllys 445799ebb4caSwyllys if (memcmp((const void *) deskey1, (const void *) deskey2, 8) 445899ebb4caSwyllys == 0) { 445999ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 446099ebb4caSwyllys retry++; 446199ebb4caSwyllys } 446299ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 446399ebb4caSwyllys 446499ebb4caSwyllys if (ret != KMF_OK) { 446599ebb4caSwyllys goto out; 446699ebb4caSwyllys } 446799ebb4caSwyllys 446899ebb4caSwyllys /* 446999ebb4caSwyllys * Create the 3rd DES key and make sure its value is different 447099ebb4caSwyllys * from the 2nd DES key. 447199ebb4caSwyllys */ 447299ebb4caSwyllys retry = 0; 447399ebb4caSwyllys do { 447499ebb4caSwyllys if (deskey3 != NULL) { 447599ebb4caSwyllys free(deskey3); 447699ebb4caSwyllys deskey3 = NULL; 447799ebb4caSwyllys } 447899ebb4caSwyllys 447999ebb4caSwyllys if ((ret = create_deskey(&deskey3)) != KMF_OK) { 448099ebb4caSwyllys goto out; 448199ebb4caSwyllys } 448299ebb4caSwyllys 448399ebb4caSwyllys if (memcmp((const void *)deskey2, (const void *)deskey3, 8) 448499ebb4caSwyllys == 0) { 448599ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 448699ebb4caSwyllys retry++; 448799ebb4caSwyllys } 448899ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 448999ebb4caSwyllys 449099ebb4caSwyllys if (ret != KMF_OK) { 449199ebb4caSwyllys goto out; 449299ebb4caSwyllys } 449399ebb4caSwyllys 449499ebb4caSwyllys /* Concatenate 3 DES keys into a DES3 key */ 449599ebb4caSwyllys (void) memcpy((void *)newkey, (const void *)deskey1, 8); 449699ebb4caSwyllys (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8); 449799ebb4caSwyllys (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8); 449899ebb4caSwyllys *des3key = newkey; 449999ebb4caSwyllys 450099ebb4caSwyllys out: 450199ebb4caSwyllys if (deskey1 != NULL) 450299ebb4caSwyllys free(deskey1); 450399ebb4caSwyllys 450499ebb4caSwyllys if (deskey2 != NULL) 450599ebb4caSwyllys free(deskey2); 450699ebb4caSwyllys 450799ebb4caSwyllys if (deskey3 != NULL) 450899ebb4caSwyllys free(deskey3); 450999ebb4caSwyllys 451099ebb4caSwyllys if (ret != KMF_OK && newkey != NULL) 451199ebb4caSwyllys free(newkey); 451299ebb4caSwyllys 451399ebb4caSwyllys return (ret); 451499ebb4caSwyllys } 451599ebb4caSwyllys 451699ebb4caSwyllys KMF_RETURN 451730a5e8faSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T handle, 451830a5e8faSwyllys int numattr, KMF_ATTRIBUTE *attrlist) 451999ebb4caSwyllys { 452099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 452199ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 452299ebb4caSwyllys char *fullpath = NULL; 452399ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 452499ebb4caSwyllys DES_cblock *deskey = NULL; 452599ebb4caSwyllys unsigned char *des3key = NULL; 452699ebb4caSwyllys unsigned char *random = NULL; 452799ebb4caSwyllys int fd = -1; 452830a5e8faSwyllys KMF_KEY_HANDLE *symkey; 452930a5e8faSwyllys KMF_KEY_ALG keytype; 453030a5e8faSwyllys uint32_t keylen; 453130a5e8faSwyllys uint32_t keylen_size = sizeof (keylen); 453230a5e8faSwyllys char *dirpath; 453330a5e8faSwyllys char *keyfile; 453499ebb4caSwyllys 453599ebb4caSwyllys if (kmfh == NULL) 453699ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 453799ebb4caSwyllys 453830a5e8faSwyllys symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 453930a5e8faSwyllys if (symkey == NULL) 454099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 454199ebb4caSwyllys 454230a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 454330a5e8faSwyllys 454430a5e8faSwyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 454530a5e8faSwyllys if (keyfile == NULL) 454630a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 454730a5e8faSwyllys 454830a5e8faSwyllys ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 454930a5e8faSwyllys (void *)&keytype, NULL); 455030a5e8faSwyllys if (ret != KMF_OK) 455130a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 455230a5e8faSwyllys 455330a5e8faSwyllys ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 455430a5e8faSwyllys &keylen, &keylen_size); 455530a5e8faSwyllys if (ret == KMF_ERR_ATTR_NOT_FOUND && 455630a5e8faSwyllys (keytype == KMF_DES || keytype == KMF_DES3)) 455730a5e8faSwyllys /* keylength is not required for DES and 3DES */ 455830a5e8faSwyllys ret = KMF_OK; 455930a5e8faSwyllys if (ret != KMF_OK) 456030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 456130a5e8faSwyllys 456230a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 456399ebb4caSwyllys if (fullpath == NULL) 456499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 456599ebb4caSwyllys 456699ebb4caSwyllys /* If the requested file exists, return an error */ 456730a5e8faSwyllys if (test_for_file(fullpath, 0400) == 1) { 456899ebb4caSwyllys free(fullpath); 456999ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 457099ebb4caSwyllys } 457199ebb4caSwyllys 457299ebb4caSwyllys fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400); 457399ebb4caSwyllys if (fd == -1) { 457499ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 457599ebb4caSwyllys goto out; 457699ebb4caSwyllys } 457799ebb4caSwyllys 457899ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 457999ebb4caSwyllys if (rkey == NULL) { 458099ebb4caSwyllys ret = KMF_ERR_MEMORY; 458199ebb4caSwyllys goto out; 458299ebb4caSwyllys } 458399ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 458499ebb4caSwyllys 458530a5e8faSwyllys if (keytype == KMF_DES) { 458699ebb4caSwyllys if ((ret = create_deskey(&deskey)) != KMF_OK) { 458799ebb4caSwyllys goto out; 458899ebb4caSwyllys } 458999ebb4caSwyllys rkey->keydata.val = (uchar_t *)deskey; 459099ebb4caSwyllys rkey->keydata.len = 8; 459199ebb4caSwyllys 459299ebb4caSwyllys symkey->keyalg = KMF_DES; 459399ebb4caSwyllys 459430a5e8faSwyllys } else if (keytype == KMF_DES3) { 459599ebb4caSwyllys if ((ret = create_des3key(&des3key)) != KMF_OK) { 459699ebb4caSwyllys goto out; 459799ebb4caSwyllys } 459899ebb4caSwyllys rkey->keydata.val = (uchar_t *)des3key; 459999ebb4caSwyllys rkey->keydata.len = DES3_KEY_SIZE; 460099ebb4caSwyllys symkey->keyalg = KMF_DES3; 46019b37d296Swyllys 460230a5e8faSwyllys } else if (keytype == KMF_AES || keytype == KMF_RC4 || 460330a5e8faSwyllys keytype == KMF_GENERIC_SECRET) { 460499ebb4caSwyllys int bytes; 460599ebb4caSwyllys 460630a5e8faSwyllys if (keylen % 8 != 0) { 460799ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 460899ebb4caSwyllys goto out; 460999ebb4caSwyllys } 461099ebb4caSwyllys 461130a5e8faSwyllys if (keytype == KMF_AES) { 461230a5e8faSwyllys if (keylen != 128 && 461330a5e8faSwyllys keylen != 192 && 461430a5e8faSwyllys keylen != 256) { 461599ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 461699ebb4caSwyllys goto out; 461799ebb4caSwyllys } 461899ebb4caSwyllys } 461999ebb4caSwyllys 462030a5e8faSwyllys bytes = keylen/8; 462199ebb4caSwyllys random = malloc(bytes); 462299ebb4caSwyllys if (random == NULL) { 462399ebb4caSwyllys ret = KMF_ERR_MEMORY; 462499ebb4caSwyllys goto out; 462599ebb4caSwyllys } 462699ebb4caSwyllys if (RAND_bytes(random, bytes) != 1) { 462799ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 462899ebb4caSwyllys goto out; 462999ebb4caSwyllys } 463099ebb4caSwyllys 463199ebb4caSwyllys rkey->keydata.val = (uchar_t *)random; 463299ebb4caSwyllys rkey->keydata.len = bytes; 463330a5e8faSwyllys symkey->keyalg = keytype; 463499ebb4caSwyllys 463599ebb4caSwyllys } else { 463699ebb4caSwyllys ret = KMF_ERR_BAD_KEY_TYPE; 463799ebb4caSwyllys goto out; 463899ebb4caSwyllys } 463999ebb4caSwyllys 464099ebb4caSwyllys (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len); 464199ebb4caSwyllys 464299ebb4caSwyllys symkey->kstype = KMF_KEYSTORE_OPENSSL; 464399ebb4caSwyllys symkey->keyclass = KMF_SYMMETRIC; 464499ebb4caSwyllys symkey->keylabel = (char *)fullpath; 464599ebb4caSwyllys symkey->israw = TRUE; 464699ebb4caSwyllys symkey->keyp = rkey; 464799ebb4caSwyllys 464899ebb4caSwyllys out: 464999ebb4caSwyllys if (fd != -1) 465099ebb4caSwyllys (void) close(fd); 465199ebb4caSwyllys 465299ebb4caSwyllys if (ret != KMF_OK && fullpath != NULL) { 465399ebb4caSwyllys free(fullpath); 465499ebb4caSwyllys } 465599ebb4caSwyllys if (ret != KMF_OK) { 465630a5e8faSwyllys kmf_free_raw_sym_key(rkey); 465799ebb4caSwyllys symkey->keyp = NULL; 465899ebb4caSwyllys symkey->keyalg = KMF_KEYALG_NONE; 465999ebb4caSwyllys } 466099ebb4caSwyllys 466199ebb4caSwyllys return (ret); 466299ebb4caSwyllys } 466399ebb4caSwyllys 466499ebb4caSwyllys /* 466599ebb4caSwyllys * Check a file to see if it is a CRL file with PEM or DER format. 466699ebb4caSwyllys * If success, return its format in the "pformat" argument. 466799ebb4caSwyllys */ 466899ebb4caSwyllys KMF_RETURN 466999ebb4caSwyllys OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat) 467099ebb4caSwyllys { 467199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 467299ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 467399ebb4caSwyllys BIO *bio = NULL; 467499ebb4caSwyllys X509_CRL *xcrl = NULL; 467599ebb4caSwyllys 467699ebb4caSwyllys if (filename == NULL) { 467799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 467899ebb4caSwyllys } 467999ebb4caSwyllys 468099ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 468199ebb4caSwyllys if (bio == NULL) { 468299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 468399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 468499ebb4caSwyllys goto out; 468599ebb4caSwyllys } 468699ebb4caSwyllys 468799ebb4caSwyllys if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) { 468899ebb4caSwyllys *pformat = KMF_FORMAT_PEM; 468999ebb4caSwyllys goto out; 469099ebb4caSwyllys } 469199ebb4caSwyllys (void) BIO_free(bio); 469299ebb4caSwyllys 469399ebb4caSwyllys /* 469499ebb4caSwyllys * Now try to read it as raw DER data. 469599ebb4caSwyllys */ 469699ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 469799ebb4caSwyllys if (bio == NULL) { 469899ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 469999ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 470099ebb4caSwyllys goto out; 470199ebb4caSwyllys } 470299ebb4caSwyllys 470399ebb4caSwyllys if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) { 470499ebb4caSwyllys *pformat = KMF_FORMAT_ASN1; 470599ebb4caSwyllys } else { 470699ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 470799ebb4caSwyllys } 470899ebb4caSwyllys 470999ebb4caSwyllys out: 471099ebb4caSwyllys if (bio != NULL) 471199ebb4caSwyllys (void) BIO_free(bio); 471299ebb4caSwyllys 471399ebb4caSwyllys if (xcrl != NULL) 471499ebb4caSwyllys X509_CRL_free(xcrl); 471599ebb4caSwyllys 471699ebb4caSwyllys return (ret); 471799ebb4caSwyllys } 471899ebb4caSwyllys 471999ebb4caSwyllys /* 472099ebb4caSwyllys * Check a file to see if it is a certficate file with PEM or DER format. 472199ebb4caSwyllys * If success, return its format in the pformat argument. 472299ebb4caSwyllys */ 472399ebb4caSwyllys KMF_RETURN 472499ebb4caSwyllys OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, 472599ebb4caSwyllys KMF_ENCODE_FORMAT *pformat) 472699ebb4caSwyllys { 472799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 472899ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 472999ebb4caSwyllys BIO *bio = NULL; 473099ebb4caSwyllys X509 *xcert = NULL; 473199ebb4caSwyllys 473299ebb4caSwyllys if (filename == NULL) { 473399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 473499ebb4caSwyllys } 473599ebb4caSwyllys 473630a5e8faSwyllys ret = kmf_get_file_format(filename, pformat); 473799ebb4caSwyllys if (ret != KMF_OK) 473899ebb4caSwyllys return (ret); 473999ebb4caSwyllys 474099ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 474199ebb4caSwyllys if (bio == NULL) { 474299ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 474399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 474499ebb4caSwyllys goto out; 474599ebb4caSwyllys } 474699ebb4caSwyllys 474799ebb4caSwyllys if ((*pformat) == KMF_FORMAT_PEM) { 474899ebb4caSwyllys if ((xcert = PEM_read_bio_X509(bio, NULL, 474999ebb4caSwyllys NULL, NULL)) == NULL) { 475099ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 475199ebb4caSwyllys } 475299ebb4caSwyllys } else if ((*pformat) == KMF_FORMAT_ASN1) { 475399ebb4caSwyllys if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) { 475499ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 475599ebb4caSwyllys } 475699ebb4caSwyllys } else { 475799ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 475899ebb4caSwyllys } 475999ebb4caSwyllys 476099ebb4caSwyllys out: 476199ebb4caSwyllys if (bio != NULL) 476299ebb4caSwyllys (void) BIO_free(bio); 476399ebb4caSwyllys 476499ebb4caSwyllys if (xcert != NULL) 476599ebb4caSwyllys X509_free(xcert); 476699ebb4caSwyllys 476799ebb4caSwyllys return (ret); 476899ebb4caSwyllys } 476999ebb4caSwyllys 477099ebb4caSwyllys KMF_RETURN 477199ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 477299ebb4caSwyllys KMF_RAW_SYM_KEY *rkey) 477399ebb4caSwyllys { 477499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 477599ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 477699ebb4caSwyllys KMF_DATA keyvalue; 477799ebb4caSwyllys 477899ebb4caSwyllys if (kmfh == NULL) 477999ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 478099ebb4caSwyllys 478199ebb4caSwyllys if (symkey == NULL || rkey == NULL) 478299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 478399ebb4caSwyllys else if (symkey->keyclass != KMF_SYMMETRIC) 478499ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 478599ebb4caSwyllys 478699ebb4caSwyllys if (symkey->israw) { 478799ebb4caSwyllys KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp; 478899ebb4caSwyllys 478999ebb4caSwyllys if (rawkey == NULL || 479099ebb4caSwyllys rawkey->keydata.val == NULL || 479199ebb4caSwyllys rawkey->keydata.len == 0) 479299ebb4caSwyllys return (KMF_ERR_BAD_KEYHANDLE); 479399ebb4caSwyllys 479499ebb4caSwyllys rkey->keydata.len = rawkey->keydata.len; 479599ebb4caSwyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 479699ebb4caSwyllys return (KMF_ERR_MEMORY); 479799ebb4caSwyllys (void) memcpy(rkey->keydata.val, rawkey->keydata.val, 479899ebb4caSwyllys rkey->keydata.len); 479999ebb4caSwyllys } else { 480030a5e8faSwyllys rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue); 480199ebb4caSwyllys if (rv != KMF_OK) 480299ebb4caSwyllys return (rv); 480399ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 480499ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 480599ebb4caSwyllys } 480699ebb4caSwyllys 480799ebb4caSwyllys return (rv); 480899ebb4caSwyllys } 480902744e81Swyllys 481002744e81Swyllys /* 481102744e81Swyllys * id-sha1 OBJECT IDENTIFIER ::= { 481202744e81Swyllys * iso(1) identified-organization(3) oiw(14) secsig(3) 481302744e81Swyllys * algorithms(2) 26 481402744e81Swyllys * } 481502744e81Swyllys */ 481602744e81Swyllys #define ASN1_SHA1_OID_PREFIX_LEN 15 481702744e81Swyllys static uchar_t SHA1_DER_PREFIX[ASN1_SHA1_OID_PREFIX_LEN] = { 481802744e81Swyllys 0x30, 0x21, 0x30, 0x09, 481902744e81Swyllys 0x06, 0x05, 0x2b, 0x0e, 482002744e81Swyllys 0x03, 0x02, 0x1a, 0x05, 482102744e81Swyllys 0x00, 0x04, 0x14 482202744e81Swyllys }; 482302744e81Swyllys 482402744e81Swyllys /* 482502744e81Swyllys * id-md2 OBJECT IDENTIFIER ::= { 482602744e81Swyllys * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 482702744e81Swyllys * } 482802744e81Swyllys */ 482902744e81Swyllys #define ASN1_MD2_OID_PREFIX_LEN 18 483002744e81Swyllys static uchar_t MD2_DER_PREFIX[ASN1_MD2_OID_PREFIX_LEN] = { 483102744e81Swyllys 0x30, 0x20, 0x30, 0x0c, 483202744e81Swyllys 0x06, 0x08, 0x2a, 0x86, 483302744e81Swyllys 0x48, 0x86, 0xf7, 0x0d, 483402744e81Swyllys 0x02, 0x02, 0x05, 0x00, 483502744e81Swyllys 0x04, 0x10 483602744e81Swyllys }; 483702744e81Swyllys 483802744e81Swyllys /* 483902744e81Swyllys * id-md5 OBJECT IDENTIFIER ::= { 484002744e81Swyllys * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 484102744e81Swyllys * } 484202744e81Swyllys */ 484302744e81Swyllys #define ASN1_MD5_OID_PREFIX_LEN 18 484402744e81Swyllys static uchar_t MD5_DER_PREFIX[ASN1_MD5_OID_PREFIX_LEN] = { 484502744e81Swyllys 0x30, 0x20, 0x30, 0x0c, 484602744e81Swyllys 0x06, 0x08, 0x2a, 0x86, 484702744e81Swyllys 0x48, 0x86, 0xf7, 0x0d, 484802744e81Swyllys 0x02, 0x05, 0x05, 0x00, 484902744e81Swyllys 0x04, 0x10 485002744e81Swyllys }; 485102744e81Swyllys 485202744e81Swyllys KMF_RETURN 485302744e81Swyllys OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle, 485402744e81Swyllys KMF_ALGORITHM_INDEX algid, KMF_DATA *indata, 485502744e81Swyllys KMF_DATA *insig, KMF_DATA *cert) 485602744e81Swyllys { 485702744e81Swyllys KMF_RETURN ret = KMF_OK; 485802744e81Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 485902744e81Swyllys X509 *xcert = NULL; 486002744e81Swyllys EVP_PKEY *pkey = NULL; 486102744e81Swyllys uchar_t *p; 486202744e81Swyllys uchar_t *rsaout = NULL; 486302744e81Swyllys uchar_t *pfx = NULL; 486402744e81Swyllys const EVP_MD *md; 486502744e81Swyllys int pfxlen = 0, len; 486602744e81Swyllys 486702744e81Swyllys if (handle == NULL || indata == NULL || 486802744e81Swyllys indata->Data == NULL || indata->Length == 0 || 486902744e81Swyllys insig == NULL|| insig->Data == NULL || insig->Length == 0 || 487002744e81Swyllys cert == NULL || cert->Data == NULL || cert->Length == 0) 487102744e81Swyllys return (KMF_ERR_BAD_PARAMETER); 487202744e81Swyllys 487302744e81Swyllys p = cert->Data; 487402744e81Swyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, cert->Length); 487502744e81Swyllys if (xcert == NULL) { 487602744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 487702744e81Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 487802744e81Swyllys goto cleanup; 487902744e81Swyllys } 488002744e81Swyllys 488102744e81Swyllys pkey = X509_get_pubkey(xcert); 488230a5e8faSwyllys if (pkey == NULL) { 488302744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 488402744e81Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 488502744e81Swyllys goto cleanup; 488602744e81Swyllys } 488702744e81Swyllys 488802744e81Swyllys if (algid != KMF_ALGID_NONE) { 488902744e81Swyllys switch (algid) { 489002744e81Swyllys case KMF_ALGID_MD5WithRSA: 489102744e81Swyllys md = EVP_md5(); 489202744e81Swyllys break; 489302744e81Swyllys case KMF_ALGID_MD2WithRSA: 489402744e81Swyllys md = EVP_md2(); 489502744e81Swyllys break; 489602744e81Swyllys case KMF_ALGID_SHA1WithRSA: 489702744e81Swyllys md = EVP_sha1(); 489802744e81Swyllys break; 489902744e81Swyllys case KMF_ALGID_RSA: 490002744e81Swyllys md = NULL; 490102744e81Swyllys break; 490202744e81Swyllys default: 490302744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 490402744e81Swyllys goto cleanup; 490502744e81Swyllys } 490602744e81Swyllys } else { 490702744e81Swyllys /* Get the hash type from the cert signature */ 490802744e81Swyllys md = EVP_get_digestbyobj(xcert->sig_alg->algorithm); 490902744e81Swyllys if (md == NULL) { 491002744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 491102744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 491202744e81Swyllys goto cleanup; 491302744e81Swyllys } 491402744e81Swyllys } 49159b37d296Swyllys if (md != NULL) { 491602744e81Swyllys switch (EVP_MD_type(md)) { 491702744e81Swyllys case NID_md2: 491802744e81Swyllys case NID_md2WithRSAEncryption: 491902744e81Swyllys pfxlen = ASN1_MD2_OID_PREFIX_LEN; 492002744e81Swyllys pfx = MD2_DER_PREFIX; 492102744e81Swyllys break; 492202744e81Swyllys case NID_md5: 492302744e81Swyllys case NID_md5WithRSAEncryption: 492402744e81Swyllys pfxlen = ASN1_MD5_OID_PREFIX_LEN; 492502744e81Swyllys pfx = MD5_DER_PREFIX; 492602744e81Swyllys break; 492702744e81Swyllys case NID_sha1: 492802744e81Swyllys case NID_sha1WithRSAEncryption: 492902744e81Swyllys pfxlen = ASN1_SHA1_OID_PREFIX_LEN; 493002744e81Swyllys pfx = SHA1_DER_PREFIX; 493102744e81Swyllys break; 493202744e81Swyllys default: /* Unsupported */ 493302744e81Swyllys pfxlen = 0; 493402744e81Swyllys pfx = NULL; 493502744e81Swyllys break; 493602744e81Swyllys } 49379b37d296Swyllys } 493802744e81Swyllys 493902744e81Swyllys /* RSA with no hash is a special case */ 494002744e81Swyllys rsaout = malloc(RSA_size(pkey->pkey.rsa)); 494102744e81Swyllys if (rsaout == NULL) 494202744e81Swyllys return (KMF_ERR_MEMORY); 494302744e81Swyllys 494402744e81Swyllys /* Decrypt the input signature */ 494502744e81Swyllys len = RSA_public_decrypt(insig->Length, 494602744e81Swyllys insig->Data, rsaout, pkey->pkey.rsa, RSA_PKCS1_PADDING); 494702744e81Swyllys if (len < 1) { 494802744e81Swyllys SET_ERROR(kmfh, ERR_get_error()); 494902744e81Swyllys ret = KMF_ERR_BAD_PARAMETER; 495002744e81Swyllys } else { 495102744e81Swyllys size_t hashlen = 0; 495202744e81Swyllys uint32_t dlen; 495302744e81Swyllys char *digest = NULL; 495402744e81Swyllys 495502744e81Swyllys /* 495602744e81Swyllys * If the AlgId requires it, hash the input data before 495702744e81Swyllys * comparing it to the decrypted signature. 495802744e81Swyllys */ 495902744e81Swyllys if (md) { 496002744e81Swyllys EVP_MD_CTX ctx; 496102744e81Swyllys 496202744e81Swyllys hashlen = md->md_size; 496302744e81Swyllys 496402744e81Swyllys digest = malloc(hashlen + pfxlen); 496502744e81Swyllys if (digest == NULL) 496602744e81Swyllys return (KMF_ERR_MEMORY); 496702744e81Swyllys /* Add the prefix to the comparison buffer. */ 496802744e81Swyllys if (pfx && pfxlen > 0) { 496902744e81Swyllys (void) memcpy(digest, pfx, pfxlen); 497002744e81Swyllys } 497102744e81Swyllys (void) EVP_DigestInit(&ctx, md); 497202744e81Swyllys (void) EVP_DigestUpdate(&ctx, indata->Data, 497302744e81Swyllys indata->Length); 497402744e81Swyllys 497502744e81Swyllys /* Add the digest AFTER the ASN1 prefix */ 497602744e81Swyllys (void) EVP_DigestFinal(&ctx, 497702744e81Swyllys (uchar_t *)digest + pfxlen, &dlen); 497802744e81Swyllys 497902744e81Swyllys dlen += pfxlen; 498002744e81Swyllys } else { 498102744e81Swyllys digest = (char *)indata->Data; 498202744e81Swyllys dlen = indata->Length; 498302744e81Swyllys } 498402744e81Swyllys 498502744e81Swyllys /* 498602744e81Swyllys * The result of the RSA decryption should be ASN1(OID | Hash). 498702744e81Swyllys * Compare the output hash to the input data for the final 498802744e81Swyllys * result. 498902744e81Swyllys */ 499002744e81Swyllys if (memcmp(rsaout, digest, dlen)) 499102744e81Swyllys ret = KMF_ERR_INTERNAL; 499202744e81Swyllys else 499302744e81Swyllys ret = KMF_OK; 499402744e81Swyllys 499502744e81Swyllys /* If we had to allocate space for the digest, free it now */ 499602744e81Swyllys if (hashlen) 499702744e81Swyllys free(digest); 499802744e81Swyllys } 499902744e81Swyllys cleanup: 500002744e81Swyllys if (pkey) 500102744e81Swyllys EVP_PKEY_free(pkey); 500202744e81Swyllys 500302744e81Swyllys if (xcert) 500402744e81Swyllys X509_free(xcert); 500502744e81Swyllys 500602744e81Swyllys if (rsaout) 500702744e81Swyllys free(rsaout); 500802744e81Swyllys 500902744e81Swyllys return (ret); 501002744e81Swyllys } 501130a5e8faSwyllys 501230a5e8faSwyllys /* 501330a5e8faSwyllys * substitute for the unsafe access(2) function. 501430a5e8faSwyllys * If the file in question already exists, return 1. 501530a5e8faSwyllys * else 0. If an error occurs during testing (other 501630a5e8faSwyllys * than EEXIST), return -1. 501730a5e8faSwyllys */ 501830a5e8faSwyllys static int 501930a5e8faSwyllys test_for_file(char *filename, mode_t mode) 502030a5e8faSwyllys { 502130a5e8faSwyllys int fd; 502230a5e8faSwyllys 502330a5e8faSwyllys /* 502430a5e8faSwyllys * Try to create the file with the EXCL flag. 502530a5e8faSwyllys * The call should fail if the file exists. 502630a5e8faSwyllys */ 502730a5e8faSwyllys fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode); 502830a5e8faSwyllys if (fd == -1 && errno == EEXIST) 502930a5e8faSwyllys return (1); 503030a5e8faSwyllys else if (fd == -1) /* some other error */ 503130a5e8faSwyllys return (-1); 503230a5e8faSwyllys 503330a5e8faSwyllys /* The file did NOT exist. Delete the testcase. */ 503430a5e8faSwyllys (void) close(fd); 503530a5e8faSwyllys (void) unlink(filename); 503630a5e8faSwyllys return (0); 503730a5e8faSwyllys } 503830a5e8faSwyllys 503930a5e8faSwyllys KMF_RETURN 504030a5e8faSwyllys OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr, 504130a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 504230a5e8faSwyllys { 504330a5e8faSwyllys KMF_RETURN rv = KMF_OK; 504430a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 504530a5e8faSwyllys KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL; 504630a5e8faSwyllys KMF_RAW_KEY_DATA *rawkey; 504730a5e8faSwyllys EVP_PKEY *pkey = NULL; 504830a5e8faSwyllys KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM; 504930a5e8faSwyllys KMF_CREDENTIAL cred = {NULL, 0}; 505030a5e8faSwyllys BIO *out = NULL; 505130a5e8faSwyllys int keys = 0; 505230a5e8faSwyllys char *fullpath = NULL; 505330a5e8faSwyllys char *keyfile = NULL; 505430a5e8faSwyllys char *dirpath = NULL; 505530a5e8faSwyllys 505630a5e8faSwyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); 505730a5e8faSwyllys if (pubkey != NULL) 505830a5e8faSwyllys keys++; 505930a5e8faSwyllys 506030a5e8faSwyllys prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); 506130a5e8faSwyllys if (prikey != NULL) 506230a5e8faSwyllys keys++; 506330a5e8faSwyllys 506430a5e8faSwyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); 506530a5e8faSwyllys if (rawkey != NULL) 506630a5e8faSwyllys keys++; 506730a5e8faSwyllys 506830a5e8faSwyllys /* 506930a5e8faSwyllys * Exactly 1 type of key must be passed to this function. 507030a5e8faSwyllys */ 507130a5e8faSwyllys if (keys != 1) 507230a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 507330a5e8faSwyllys 507430a5e8faSwyllys keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, 507530a5e8faSwyllys numattr); 507630a5e8faSwyllys if (keyfile == NULL) 507730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 507830a5e8faSwyllys 507930a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 508030a5e8faSwyllys 508130a5e8faSwyllys fullpath = get_fullpath(dirpath, keyfile); 508230a5e8faSwyllys 508330a5e8faSwyllys /* Once we have the full path, we don't need the pieces */ 508430a5e8faSwyllys if (fullpath == NULL) 508530a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 508630a5e8faSwyllys 508730a5e8faSwyllys /* If the requested file exists, return an error */ 508830a5e8faSwyllys if (test_for_file(fullpath, 0400) == 1) { 508930a5e8faSwyllys free(fullpath); 509030a5e8faSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 509130a5e8faSwyllys } 509230a5e8faSwyllys 509330a5e8faSwyllys rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 509430a5e8faSwyllys &format, NULL); 509530a5e8faSwyllys if (rv != KMF_OK) 509630a5e8faSwyllys /* format is optional. */ 509730a5e8faSwyllys rv = KMF_OK; 509830a5e8faSwyllys 509930a5e8faSwyllys /* CRED is not required for OpenSSL files */ 510030a5e8faSwyllys (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, 510130a5e8faSwyllys &cred, NULL); 510230a5e8faSwyllys 510330a5e8faSwyllys /* Store the private key to the keyfile */ 510430a5e8faSwyllys out = BIO_new_file(fullpath, "wb"); 510530a5e8faSwyllys if (out == NULL) { 510630a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 510730a5e8faSwyllys rv = KMF_ERR_OPEN_FILE; 510830a5e8faSwyllys goto end; 510930a5e8faSwyllys } 511030a5e8faSwyllys 511130a5e8faSwyllys if (prikey != NULL && prikey->keyp != NULL) { 511230a5e8faSwyllys if (prikey->keyalg == KMF_RSA || 511330a5e8faSwyllys prikey->keyalg == KMF_DSA) { 511430a5e8faSwyllys pkey = (EVP_PKEY *)prikey->keyp; 511530a5e8faSwyllys 511630a5e8faSwyllys rv = ssl_write_key(kmfh, format, 511730a5e8faSwyllys out, &cred, pkey, TRUE); 511830a5e8faSwyllys 511930a5e8faSwyllys if (rv == KMF_OK && prikey->keylabel == NULL) { 512030a5e8faSwyllys prikey->keylabel = strdup(fullpath); 512130a5e8faSwyllys if (prikey->keylabel == NULL) 512230a5e8faSwyllys rv = KMF_ERR_MEMORY; 512330a5e8faSwyllys } 512430a5e8faSwyllys } 512530a5e8faSwyllys } else if (pubkey != NULL && pubkey->keyp != NULL) { 512630a5e8faSwyllys if (pubkey->keyalg == KMF_RSA || 512730a5e8faSwyllys pubkey->keyalg == KMF_DSA) { 512830a5e8faSwyllys pkey = (EVP_PKEY *)pubkey->keyp; 512930a5e8faSwyllys 513030a5e8faSwyllys rv = ssl_write_key(kmfh, format, 513130a5e8faSwyllys out, &cred, pkey, FALSE); 513230a5e8faSwyllys 513330a5e8faSwyllys if (rv == KMF_OK && pubkey->keylabel == NULL) { 513430a5e8faSwyllys pubkey->keylabel = strdup(fullpath); 513530a5e8faSwyllys if (pubkey->keylabel == NULL) 513630a5e8faSwyllys rv = KMF_ERR_MEMORY; 513730a5e8faSwyllys } 513830a5e8faSwyllys } 513930a5e8faSwyllys } else if (rawkey != NULL) { 514030a5e8faSwyllys if (rawkey->keytype == KMF_RSA) { 514130a5e8faSwyllys pkey = ImportRawRSAKey(&rawkey->rawdata.rsa); 514230a5e8faSwyllys } else if (rawkey->keytype == KMF_DSA) { 514330a5e8faSwyllys pkey = ImportRawDSAKey(&rawkey->rawdata.dsa); 514430a5e8faSwyllys } else { 514530a5e8faSwyllys rv = KMF_ERR_BAD_PARAMETER; 514630a5e8faSwyllys } 51475b3e1433Swyllys if (pkey != NULL) { 5148*73cc0e02Swyllys KMF_KEY_CLASS kclass = KMF_ASYM_PRI; 5149*73cc0e02Swyllys 5150*73cc0e02Swyllys rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, 5151*73cc0e02Swyllys (void *)&kclass, NULL); 5152*73cc0e02Swyllys if (rv != KMF_OK) 5153*73cc0e02Swyllys rv = KMF_OK; 51545b3e1433Swyllys rv = ssl_write_key(kmfh, format, out, 5155*73cc0e02Swyllys &cred, pkey, (kclass == KMF_ASYM_PRI)); 51565b3e1433Swyllys EVP_PKEY_free(pkey); 51575b3e1433Swyllys } 515830a5e8faSwyllys } 515930a5e8faSwyllys 516030a5e8faSwyllys end: 516130a5e8faSwyllys 516230a5e8faSwyllys if (out) 516330a5e8faSwyllys (void) BIO_free(out); 516430a5e8faSwyllys 51655b3e1433Swyllys 516630a5e8faSwyllys if (rv == KMF_OK) 516730a5e8faSwyllys (void) chmod(fullpath, 0400); 516830a5e8faSwyllys 516930a5e8faSwyllys free(fullpath); 517030a5e8faSwyllys return (rv); 517130a5e8faSwyllys } 517230a5e8faSwyllys 517330a5e8faSwyllys KMF_RETURN 517430a5e8faSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 517530a5e8faSwyllys { 517630a5e8faSwyllys KMF_RETURN ret = KMF_OK; 517730a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 517830a5e8faSwyllys X509_CRL *xcrl = NULL; 517930a5e8faSwyllys X509 *xcert = NULL; 518030a5e8faSwyllys EVP_PKEY *pkey; 518130a5e8faSwyllys KMF_ENCODE_FORMAT format; 518230a5e8faSwyllys BIO *in = NULL, *out = NULL; 518330a5e8faSwyllys int openssl_ret = 0; 518430a5e8faSwyllys KMF_ENCODE_FORMAT outformat; 518530a5e8faSwyllys boolean_t crlcheck = FALSE; 518630a5e8faSwyllys char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile; 518730a5e8faSwyllys 518830a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 518930a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 519030a5e8faSwyllys } 519130a5e8faSwyllys 519230a5e8faSwyllys /* CRL check is optional */ 519330a5e8faSwyllys (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr, 519430a5e8faSwyllys &crlcheck, NULL); 519530a5e8faSwyllys 519630a5e8faSwyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 519730a5e8faSwyllys if (crlcheck == B_TRUE && certfile == NULL) { 519830a5e8faSwyllys return (KMF_ERR_BAD_CERTFILE); 519930a5e8faSwyllys } 520030a5e8faSwyllys 520130a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 520230a5e8faSwyllys incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr); 520330a5e8faSwyllys outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr); 520430a5e8faSwyllys 520530a5e8faSwyllys crlfile = get_fullpath(dirpath, incrl); 520630a5e8faSwyllys 520730a5e8faSwyllys if (crlfile == NULL) 520830a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 520930a5e8faSwyllys 521030a5e8faSwyllys outcrlfile = get_fullpath(dirpath, outcrl); 521130a5e8faSwyllys if (outcrlfile == NULL) 521230a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 521330a5e8faSwyllys 521430a5e8faSwyllys if (isdir(outcrlfile)) { 521530a5e8faSwyllys free(outcrlfile); 521630a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 521730a5e8faSwyllys } 521830a5e8faSwyllys 521930a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 522030a5e8faSwyllys if (ret != KMF_OK) { 522130a5e8faSwyllys free(outcrlfile); 522230a5e8faSwyllys return (ret); 522330a5e8faSwyllys } 522430a5e8faSwyllys 522530a5e8faSwyllys in = BIO_new_file(crlfile, "rb"); 522630a5e8faSwyllys if (in == NULL) { 522730a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 522830a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 522930a5e8faSwyllys goto end; 523030a5e8faSwyllys } 523130a5e8faSwyllys 523230a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 523330a5e8faSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 523430a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 523530a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 523630a5e8faSwyllys } 523730a5e8faSwyllys 523830a5e8faSwyllys if (xcrl == NULL) { 523930a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 524030a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 524130a5e8faSwyllys goto end; 524230a5e8faSwyllys } 524330a5e8faSwyllys 524430a5e8faSwyllys /* If bypasscheck is specified, no need to verify. */ 524530a5e8faSwyllys if (crlcheck == B_FALSE) 524630a5e8faSwyllys goto output; 524730a5e8faSwyllys 524830a5e8faSwyllys ret = kmf_is_cert_file(handle, certfile, &format); 524930a5e8faSwyllys if (ret != KMF_OK) 525030a5e8faSwyllys goto end; 525130a5e8faSwyllys 525230a5e8faSwyllys /* Read in the CA cert file and convert to X509 */ 525330a5e8faSwyllys if (BIO_read_filename(in, certfile) <= 0) { 525430a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 525530a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 525630a5e8faSwyllys goto end; 525730a5e8faSwyllys } 525830a5e8faSwyllys 525930a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 526030a5e8faSwyllys xcert = d2i_X509_bio(in, NULL); 526130a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 526230a5e8faSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 526330a5e8faSwyllys } else { 526430a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 526530a5e8faSwyllys goto end; 526630a5e8faSwyllys } 526730a5e8faSwyllys 526830a5e8faSwyllys if (xcert == NULL) { 526930a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 527030a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 527130a5e8faSwyllys goto end; 527230a5e8faSwyllys } 527330a5e8faSwyllys /* Now get the public key from the CA cert */ 527430a5e8faSwyllys pkey = X509_get_pubkey(xcert); 527530a5e8faSwyllys if (pkey == NULL) { 527630a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 527730a5e8faSwyllys ret = KMF_ERR_BAD_CERTFILE; 527830a5e8faSwyllys goto end; 527930a5e8faSwyllys } 528030a5e8faSwyllys 528130a5e8faSwyllys /* Verify the CRL with the CA's public key */ 528230a5e8faSwyllys openssl_ret = X509_CRL_verify(xcrl, pkey); 528330a5e8faSwyllys EVP_PKEY_free(pkey); 528430a5e8faSwyllys if (openssl_ret > 0) { 528530a5e8faSwyllys ret = KMF_OK; /* verify succeed */ 528630a5e8faSwyllys } else { 528730a5e8faSwyllys SET_ERROR(kmfh, openssl_ret); 528830a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 528930a5e8faSwyllys } 529030a5e8faSwyllys 529130a5e8faSwyllys output: 529230a5e8faSwyllys ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 529330a5e8faSwyllys &outformat, NULL); 529430a5e8faSwyllys if (ret != KMF_OK) { 529530a5e8faSwyllys ret = KMF_OK; 529630a5e8faSwyllys outformat = KMF_FORMAT_PEM; 529730a5e8faSwyllys } 529830a5e8faSwyllys 529930a5e8faSwyllys out = BIO_new_file(outcrlfile, "wb"); 530030a5e8faSwyllys if (out == NULL) { 530130a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 530230a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 530330a5e8faSwyllys goto end; 530430a5e8faSwyllys } 530530a5e8faSwyllys 530630a5e8faSwyllys if (outformat == KMF_FORMAT_ASN1) { 530730a5e8faSwyllys openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); 530830a5e8faSwyllys } else if (outformat == KMF_FORMAT_PEM) { 530930a5e8faSwyllys openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); 531030a5e8faSwyllys } else { 531130a5e8faSwyllys ret = KMF_ERR_BAD_PARAMETER; 531230a5e8faSwyllys goto end; 531330a5e8faSwyllys } 531430a5e8faSwyllys 531530a5e8faSwyllys if (openssl_ret <= 0) { 531630a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 531730a5e8faSwyllys ret = KMF_ERR_WRITE_FILE; 531830a5e8faSwyllys } else { 531930a5e8faSwyllys ret = KMF_OK; 532030a5e8faSwyllys } 532130a5e8faSwyllys 532230a5e8faSwyllys end: 532330a5e8faSwyllys if (xcrl != NULL) 532430a5e8faSwyllys X509_CRL_free(xcrl); 532530a5e8faSwyllys 532630a5e8faSwyllys if (xcert != NULL) 532730a5e8faSwyllys X509_free(xcert); 532830a5e8faSwyllys 532930a5e8faSwyllys if (in != NULL) 533030a5e8faSwyllys (void) BIO_free(in); 533130a5e8faSwyllys 533230a5e8faSwyllys if (out != NULL) 533330a5e8faSwyllys (void) BIO_free(out); 533430a5e8faSwyllys 533530a5e8faSwyllys if (outcrlfile != NULL) 533630a5e8faSwyllys free(outcrlfile); 533730a5e8faSwyllys 533830a5e8faSwyllys return (ret); 533930a5e8faSwyllys } 534030a5e8faSwyllys 534130a5e8faSwyllys KMF_RETURN 534230a5e8faSwyllys OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 534330a5e8faSwyllys { 534430a5e8faSwyllys KMF_RETURN ret = KMF_OK; 534530a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 534630a5e8faSwyllys X509_CRL *x = NULL; 534730a5e8faSwyllys KMF_ENCODE_FORMAT format; 534830a5e8faSwyllys char *crlfile = NULL; 534930a5e8faSwyllys BIO *in = NULL; 535030a5e8faSwyllys BIO *mem = NULL; 535130a5e8faSwyllys long len; 535230a5e8faSwyllys char *memptr; 535330a5e8faSwyllys char *data = NULL; 535430a5e8faSwyllys char **crldata; 535530a5e8faSwyllys char *crlfilename, *dirpath; 535630a5e8faSwyllys 535730a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 535830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 535930a5e8faSwyllys } 536030a5e8faSwyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 536130a5e8faSwyllys attrlist, numattr); 536230a5e8faSwyllys if (crlfilename == NULL) 536330a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 536430a5e8faSwyllys 536530a5e8faSwyllys crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR, 536630a5e8faSwyllys attrlist, numattr); 536730a5e8faSwyllys 536830a5e8faSwyllys if (crldata == NULL) 536930a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 537030a5e8faSwyllys 537130a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 537230a5e8faSwyllys 537330a5e8faSwyllys crlfile = get_fullpath(dirpath, crlfilename); 537430a5e8faSwyllys 537530a5e8faSwyllys if (crlfile == NULL) 537630a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 537730a5e8faSwyllys 537830a5e8faSwyllys if (isdir(crlfile)) { 537930a5e8faSwyllys free(crlfile); 538030a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 538130a5e8faSwyllys } 538230a5e8faSwyllys 538330a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 538430a5e8faSwyllys if (ret != KMF_OK) { 538530a5e8faSwyllys free(crlfile); 538630a5e8faSwyllys return (ret); 538730a5e8faSwyllys } 538830a5e8faSwyllys 538930a5e8faSwyllys if (bio_err == NULL) 539030a5e8faSwyllys bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 539130a5e8faSwyllys 539230a5e8faSwyllys in = BIO_new_file(crlfile, "rb"); 539330a5e8faSwyllys if (in == NULL) { 539430a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 539530a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 539630a5e8faSwyllys goto end; 539730a5e8faSwyllys } 539830a5e8faSwyllys 539930a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 540030a5e8faSwyllys x = d2i_X509_CRL_bio(in, NULL); 540130a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 540230a5e8faSwyllys x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 540330a5e8faSwyllys } 540430a5e8faSwyllys 540530a5e8faSwyllys if (x == NULL) { /* should not happen */ 540630a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 540730a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 540830a5e8faSwyllys goto end; 540930a5e8faSwyllys } 541030a5e8faSwyllys 541130a5e8faSwyllys mem = BIO_new(BIO_s_mem()); 541230a5e8faSwyllys if (mem == NULL) { 541330a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 541430a5e8faSwyllys ret = KMF_ERR_MEMORY; 541530a5e8faSwyllys goto end; 541630a5e8faSwyllys } 541730a5e8faSwyllys 541830a5e8faSwyllys (void) X509_CRL_print(mem, x); 541930a5e8faSwyllys len = BIO_get_mem_data(mem, &memptr); 542030a5e8faSwyllys if (len <= 0) { 542130a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 542230a5e8faSwyllys ret = KMF_ERR_MEMORY; 542330a5e8faSwyllys goto end; 542430a5e8faSwyllys } 542530a5e8faSwyllys 542630a5e8faSwyllys data = malloc(len + 1); 542730a5e8faSwyllys if (data == NULL) { 542830a5e8faSwyllys ret = KMF_ERR_MEMORY; 542930a5e8faSwyllys goto end; 543030a5e8faSwyllys } 543130a5e8faSwyllys 543230a5e8faSwyllys (void) memcpy(data, memptr, len); 543330a5e8faSwyllys data[len] = '\0'; 543430a5e8faSwyllys *crldata = data; 543530a5e8faSwyllys 543630a5e8faSwyllys end: 543730a5e8faSwyllys if (x != NULL) 543830a5e8faSwyllys X509_CRL_free(x); 543930a5e8faSwyllys 544030a5e8faSwyllys if (crlfile != NULL) 544130a5e8faSwyllys free(crlfile); 544230a5e8faSwyllys 544330a5e8faSwyllys if (in != NULL) 544430a5e8faSwyllys (void) BIO_free(in); 544530a5e8faSwyllys 544630a5e8faSwyllys if (mem != NULL) 544730a5e8faSwyllys (void) BIO_free(mem); 544830a5e8faSwyllys 544930a5e8faSwyllys return (ret); 545030a5e8faSwyllys } 545130a5e8faSwyllys 545230a5e8faSwyllys KMF_RETURN 545330a5e8faSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 545430a5e8faSwyllys { 545530a5e8faSwyllys KMF_RETURN ret = KMF_OK; 545630a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 545730a5e8faSwyllys KMF_ENCODE_FORMAT format; 545830a5e8faSwyllys char *crlfile = NULL; 545930a5e8faSwyllys BIO *in = NULL; 546030a5e8faSwyllys char *crlfilename, *dirpath; 546130a5e8faSwyllys 546230a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 546330a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 546430a5e8faSwyllys } 546530a5e8faSwyllys 546630a5e8faSwyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 546730a5e8faSwyllys attrlist, numattr); 546830a5e8faSwyllys 546930a5e8faSwyllys if (crlfilename == NULL) 547030a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 547130a5e8faSwyllys 547230a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 547330a5e8faSwyllys 547430a5e8faSwyllys crlfile = get_fullpath(dirpath, crlfilename); 547530a5e8faSwyllys 547630a5e8faSwyllys if (crlfile == NULL) 547730a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 547830a5e8faSwyllys 547930a5e8faSwyllys if (isdir(crlfile)) { 548030a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 548130a5e8faSwyllys goto end; 548230a5e8faSwyllys } 548330a5e8faSwyllys 548430a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 548530a5e8faSwyllys if (ret != KMF_OK) 548630a5e8faSwyllys goto end; 548730a5e8faSwyllys 548830a5e8faSwyllys if (unlink(crlfile) != 0) { 548930a5e8faSwyllys SET_SYS_ERROR(kmfh, errno); 549030a5e8faSwyllys ret = KMF_ERR_INTERNAL; 549130a5e8faSwyllys goto end; 549230a5e8faSwyllys } 549330a5e8faSwyllys 549430a5e8faSwyllys end: 549530a5e8faSwyllys if (in != NULL) 549630a5e8faSwyllys (void) BIO_free(in); 549730a5e8faSwyllys if (crlfile != NULL) 549830a5e8faSwyllys free(crlfile); 549930a5e8faSwyllys 550030a5e8faSwyllys return (ret); 550130a5e8faSwyllys } 550230a5e8faSwyllys 550330a5e8faSwyllys KMF_RETURN 550430a5e8faSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 550530a5e8faSwyllys { 550630a5e8faSwyllys KMF_RETURN ret = KMF_OK; 550730a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 550830a5e8faSwyllys KMF_ENCODE_FORMAT format; 550930a5e8faSwyllys BIO *in = NULL; 551030a5e8faSwyllys X509 *xcert = NULL; 551130a5e8faSwyllys X509_CRL *xcrl = NULL; 551230a5e8faSwyllys STACK_OF(X509_REVOKED) *revoke_stack = NULL; 551330a5e8faSwyllys X509_REVOKED *revoke; 551430a5e8faSwyllys int i; 551530a5e8faSwyllys char *crlfilename, *crlfile, *dirpath, *certfile; 551630a5e8faSwyllys 551730a5e8faSwyllys if (numattr == 0 || attrlist == NULL) { 551830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 551930a5e8faSwyllys } 552030a5e8faSwyllys 552130a5e8faSwyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 552230a5e8faSwyllys attrlist, numattr); 552330a5e8faSwyllys 552430a5e8faSwyllys if (crlfilename == NULL) 552530a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 552630a5e8faSwyllys 552730a5e8faSwyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 552830a5e8faSwyllys if (certfile == NULL) 552930a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 553030a5e8faSwyllys 553130a5e8faSwyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 553230a5e8faSwyllys 553330a5e8faSwyllys crlfile = get_fullpath(dirpath, crlfilename); 553430a5e8faSwyllys 553530a5e8faSwyllys if (crlfile == NULL) 553630a5e8faSwyllys return (KMF_ERR_BAD_CRLFILE); 553730a5e8faSwyllys 553830a5e8faSwyllys if (isdir(crlfile)) { 553930a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 554030a5e8faSwyllys goto end; 554130a5e8faSwyllys } 554230a5e8faSwyllys 554330a5e8faSwyllys ret = kmf_is_crl_file(handle, crlfile, &format); 554430a5e8faSwyllys if (ret != KMF_OK) 554530a5e8faSwyllys goto end; 554630a5e8faSwyllys 554730a5e8faSwyllys /* Read the CRL file and load it into a X509_CRL structure */ 554830a5e8faSwyllys in = BIO_new_file(crlfilename, "rb"); 554930a5e8faSwyllys if (in == NULL) { 555030a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 555130a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 555230a5e8faSwyllys goto end; 555330a5e8faSwyllys } 555430a5e8faSwyllys 555530a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 555630a5e8faSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 555730a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 555830a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 555930a5e8faSwyllys } 556030a5e8faSwyllys 556130a5e8faSwyllys if (xcrl == NULL) { 556230a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 556330a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 556430a5e8faSwyllys goto end; 556530a5e8faSwyllys } 556630a5e8faSwyllys (void) BIO_free(in); 556730a5e8faSwyllys 556830a5e8faSwyllys /* Read the Certificate file and load it into a X509 structure */ 556930a5e8faSwyllys ret = kmf_is_cert_file(handle, certfile, &format); 557030a5e8faSwyllys if (ret != KMF_OK) 557130a5e8faSwyllys goto end; 557230a5e8faSwyllys 557330a5e8faSwyllys in = BIO_new_file(certfile, "rb"); 557430a5e8faSwyllys if (in == NULL) { 557530a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 557630a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 557730a5e8faSwyllys goto end; 557830a5e8faSwyllys } 557930a5e8faSwyllys 558030a5e8faSwyllys if (format == KMF_FORMAT_ASN1) { 558130a5e8faSwyllys xcert = d2i_X509_bio(in, NULL); 558230a5e8faSwyllys } else if (format == KMF_FORMAT_PEM) { 558330a5e8faSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 558430a5e8faSwyllys } 558530a5e8faSwyllys 558630a5e8faSwyllys if (xcert == NULL) { 558730a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 558830a5e8faSwyllys ret = KMF_ERR_BAD_CERTFILE; 558930a5e8faSwyllys goto end; 559030a5e8faSwyllys } 559130a5e8faSwyllys 559230a5e8faSwyllys /* Check if the certificate and the CRL have same issuer */ 559330a5e8faSwyllys if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { 559430a5e8faSwyllys ret = KMF_ERR_ISSUER; 559530a5e8faSwyllys goto end; 559630a5e8faSwyllys } 559730a5e8faSwyllys 559830a5e8faSwyllys /* Check to see if the certificate serial number is revoked */ 559930a5e8faSwyllys revoke_stack = X509_CRL_get_REVOKED(xcrl); 560030a5e8faSwyllys if (sk_X509_REVOKED_num(revoke_stack) <= 0) { 560130a5e8faSwyllys /* No revoked certificates in the CRL file */ 560230a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 560330a5e8faSwyllys ret = KMF_ERR_EMPTY_CRL; 560430a5e8faSwyllys goto end; 560530a5e8faSwyllys } 560630a5e8faSwyllys 560730a5e8faSwyllys for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { 560830a5e8faSwyllys /*LINTED*/ 560930a5e8faSwyllys revoke = sk_X509_REVOKED_value(revoke_stack, i); 561030a5e8faSwyllys if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, 561130a5e8faSwyllys revoke->serialNumber) == 0) { 561230a5e8faSwyllys break; 561330a5e8faSwyllys } 561430a5e8faSwyllys } 561530a5e8faSwyllys 561630a5e8faSwyllys if (i < sk_X509_REVOKED_num(revoke_stack)) { 561730a5e8faSwyllys ret = KMF_OK; 561830a5e8faSwyllys } else { 561930a5e8faSwyllys ret = KMF_ERR_NOT_REVOKED; 562030a5e8faSwyllys } 562130a5e8faSwyllys 562230a5e8faSwyllys end: 562330a5e8faSwyllys if (in != NULL) 562430a5e8faSwyllys (void) BIO_free(in); 562530a5e8faSwyllys if (xcrl != NULL) 562630a5e8faSwyllys X509_CRL_free(xcrl); 562730a5e8faSwyllys if (xcert != NULL) 562830a5e8faSwyllys X509_free(xcert); 562930a5e8faSwyllys 563030a5e8faSwyllys return (ret); 563130a5e8faSwyllys } 563230a5e8faSwyllys 563330a5e8faSwyllys KMF_RETURN 563430a5e8faSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert) 563530a5e8faSwyllys { 563630a5e8faSwyllys KMF_RETURN ret = KMF_OK; 563730a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 563830a5e8faSwyllys BIO *bcrl = NULL; 563930a5e8faSwyllys X509_CRL *xcrl = NULL; 564030a5e8faSwyllys X509 *xcert = NULL; 564130a5e8faSwyllys EVP_PKEY *pkey; 564230a5e8faSwyllys int sslret; 564330a5e8faSwyllys KMF_ENCODE_FORMAT crl_format; 564430a5e8faSwyllys unsigned char *p; 564530a5e8faSwyllys long len; 564630a5e8faSwyllys 564730a5e8faSwyllys if (handle == NULL || crlname == NULL || tacert == NULL) { 564830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 564930a5e8faSwyllys } 565030a5e8faSwyllys 565130a5e8faSwyllys ret = kmf_get_file_format(crlname, &crl_format); 565230a5e8faSwyllys if (ret != KMF_OK) 565330a5e8faSwyllys return (ret); 565430a5e8faSwyllys 565530a5e8faSwyllys bcrl = BIO_new_file(crlname, "rb"); 565630a5e8faSwyllys if (bcrl == NULL) { 565730a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 565830a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 565930a5e8faSwyllys goto cleanup; 566030a5e8faSwyllys } 566130a5e8faSwyllys 566230a5e8faSwyllys if (crl_format == KMF_FORMAT_ASN1) { 566330a5e8faSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 566430a5e8faSwyllys } else if (crl_format == KMF_FORMAT_PEM) { 566530a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 566630a5e8faSwyllys } else { 566730a5e8faSwyllys ret = KMF_ERR_BAD_PARAMETER; 566830a5e8faSwyllys goto cleanup; 566930a5e8faSwyllys } 567030a5e8faSwyllys 567130a5e8faSwyllys if (xcrl == NULL) { 567230a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 567330a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 567430a5e8faSwyllys goto cleanup; 567530a5e8faSwyllys } 567630a5e8faSwyllys 567730a5e8faSwyllys p = tacert->Data; 567830a5e8faSwyllys len = tacert->Length; 567930a5e8faSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, len); 568030a5e8faSwyllys 568130a5e8faSwyllys if (xcert == NULL) { 568230a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 568330a5e8faSwyllys ret = KMF_ERR_BAD_CERTFILE; 568430a5e8faSwyllys goto cleanup; 568530a5e8faSwyllys } 568630a5e8faSwyllys 568730a5e8faSwyllys /* Get issuer certificate public key */ 568830a5e8faSwyllys pkey = X509_get_pubkey(xcert); 568930a5e8faSwyllys if (pkey == NULL) { 569030a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 569130a5e8faSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 569230a5e8faSwyllys goto cleanup; 569330a5e8faSwyllys } 569430a5e8faSwyllys 569530a5e8faSwyllys /* Verify CRL signature */ 569630a5e8faSwyllys sslret = X509_CRL_verify(xcrl, pkey); 569730a5e8faSwyllys EVP_PKEY_free(pkey); 569830a5e8faSwyllys if (sslret > 0) { 569930a5e8faSwyllys ret = KMF_OK; 570030a5e8faSwyllys } else { 570130a5e8faSwyllys SET_ERROR(kmfh, sslret); 570230a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 570330a5e8faSwyllys } 570430a5e8faSwyllys 570530a5e8faSwyllys cleanup: 570630a5e8faSwyllys if (bcrl != NULL) 570730a5e8faSwyllys (void) BIO_free(bcrl); 570830a5e8faSwyllys 570930a5e8faSwyllys if (xcrl != NULL) 571030a5e8faSwyllys X509_CRL_free(xcrl); 571130a5e8faSwyllys 571230a5e8faSwyllys if (xcert != NULL) 571330a5e8faSwyllys X509_free(xcert); 571430a5e8faSwyllys 571530a5e8faSwyllys return (ret); 571630a5e8faSwyllys 571730a5e8faSwyllys } 571830a5e8faSwyllys 571930a5e8faSwyllys KMF_RETURN 572030a5e8faSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname) 572130a5e8faSwyllys { 572230a5e8faSwyllys KMF_RETURN ret = KMF_OK; 572330a5e8faSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 572430a5e8faSwyllys KMF_ENCODE_FORMAT crl_format; 572530a5e8faSwyllys BIO *bcrl = NULL; 572630a5e8faSwyllys X509_CRL *xcrl = NULL; 572730a5e8faSwyllys int i; 572830a5e8faSwyllys 572930a5e8faSwyllys if (handle == NULL || crlname == NULL) { 573030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 573130a5e8faSwyllys } 573230a5e8faSwyllys 573330a5e8faSwyllys ret = kmf_is_crl_file(handle, crlname, &crl_format); 573430a5e8faSwyllys if (ret != KMF_OK) 573530a5e8faSwyllys return (ret); 573630a5e8faSwyllys 573730a5e8faSwyllys bcrl = BIO_new_file(crlname, "rb"); 573830a5e8faSwyllys if (bcrl == NULL) { 573930a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 574030a5e8faSwyllys ret = KMF_ERR_OPEN_FILE; 574130a5e8faSwyllys goto cleanup; 574230a5e8faSwyllys } 574330a5e8faSwyllys 57445b3e1433Swyllys if (crl_format == KMF_FORMAT_ASN1) 574530a5e8faSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 57465b3e1433Swyllys else if (crl_format == KMF_FORMAT_PEM) 574730a5e8faSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 574830a5e8faSwyllys 574930a5e8faSwyllys if (xcrl == NULL) { 575030a5e8faSwyllys SET_ERROR(kmfh, ERR_get_error()); 575130a5e8faSwyllys ret = KMF_ERR_BAD_CRLFILE; 575230a5e8faSwyllys goto cleanup; 575330a5e8faSwyllys } 575430a5e8faSwyllys i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); 575530a5e8faSwyllys if (i >= 0) { 575630a5e8faSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 575730a5e8faSwyllys goto cleanup; 575830a5e8faSwyllys } 575930a5e8faSwyllys if (X509_CRL_get_nextUpdate(xcrl)) { 576030a5e8faSwyllys i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); 576130a5e8faSwyllys 576230a5e8faSwyllys if (i <= 0) { 576330a5e8faSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 576430a5e8faSwyllys goto cleanup; 576530a5e8faSwyllys } 576630a5e8faSwyllys } 576730a5e8faSwyllys 576830a5e8faSwyllys ret = KMF_OK; 576930a5e8faSwyllys 577030a5e8faSwyllys cleanup: 577130a5e8faSwyllys if (bcrl != NULL) 577230a5e8faSwyllys (void) BIO_free(bcrl); 577330a5e8faSwyllys 577430a5e8faSwyllys if (xcrl != NULL) 577530a5e8faSwyllys X509_CRL_free(xcrl); 577630a5e8faSwyllys 577730a5e8faSwyllys return (ret); 577830a5e8faSwyllys } 5779