1*99ebb4caSwyllys /* 2*99ebb4caSwyllys * CDDL HEADER START 3*99ebb4caSwyllys * 4*99ebb4caSwyllys * The contents of this file are subject to the terms of the 5*99ebb4caSwyllys * Common Development and Distribution License (the "License"). 6*99ebb4caSwyllys * You may not use this file except in compliance with the License. 7*99ebb4caSwyllys * 8*99ebb4caSwyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*99ebb4caSwyllys * or http://www.opensolaris.org/os/licensing. 10*99ebb4caSwyllys * See the License for the specific language governing permissions 11*99ebb4caSwyllys * and limitations under the License. 12*99ebb4caSwyllys * 13*99ebb4caSwyllys * When distributing Covered Code, include this CDDL HEADER in each 14*99ebb4caSwyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*99ebb4caSwyllys * If applicable, add the following below this CDDL HEADER, with the 16*99ebb4caSwyllys * fields enclosed by brackets "[]" replaced with your own identifying 17*99ebb4caSwyllys * information: Portions Copyright [yyyy] [name of copyright owner] 18*99ebb4caSwyllys * 19*99ebb4caSwyllys * CDDL HEADER END 20*99ebb4caSwyllys * 21*99ebb4caSwyllys * OpenSSL keystore wrapper 22*99ebb4caSwyllys * 23*99ebb4caSwyllys * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*99ebb4caSwyllys * Use is subject to license terms. 25*99ebb4caSwyllys */ 26*99ebb4caSwyllys 27*99ebb4caSwyllys #pragma ident "%Z%%M% %I% %E% SMI" 28*99ebb4caSwyllys 29*99ebb4caSwyllys #include <kmfapiP.h> 30*99ebb4caSwyllys #include <ber_der.h> 31*99ebb4caSwyllys #include <oidsalg.h> 32*99ebb4caSwyllys #include <fcntl.h> 33*99ebb4caSwyllys #include <sys/stat.h> 34*99ebb4caSwyllys #include <dirent.h> 35*99ebb4caSwyllys #include <cryptoutil.h> 36*99ebb4caSwyllys #include <synch.h> 37*99ebb4caSwyllys #include <thread.h> 38*99ebb4caSwyllys 39*99ebb4caSwyllys /* OPENSSL related headers */ 40*99ebb4caSwyllys #include <openssl/bio.h> 41*99ebb4caSwyllys #include <openssl/bn.h> 42*99ebb4caSwyllys #include <openssl/asn1.h> 43*99ebb4caSwyllys #include <openssl/err.h> 44*99ebb4caSwyllys #include <openssl/bn.h> 45*99ebb4caSwyllys #include <openssl/x509.h> 46*99ebb4caSwyllys #include <openssl/rsa.h> 47*99ebb4caSwyllys #include <openssl/dsa.h> 48*99ebb4caSwyllys #include <openssl/x509v3.h> 49*99ebb4caSwyllys #include <openssl/objects.h> 50*99ebb4caSwyllys #include <openssl/pem.h> 51*99ebb4caSwyllys #include <openssl/pkcs12.h> 52*99ebb4caSwyllys #include <openssl/ocsp.h> 53*99ebb4caSwyllys #include <openssl/des.h> 54*99ebb4caSwyllys #include <openssl/rand.h> 55*99ebb4caSwyllys 56*99ebb4caSwyllys #define PRINT_ANY_EXTENSION (\ 57*99ebb4caSwyllys KMF_X509_EXT_KEY_USAGE |\ 58*99ebb4caSwyllys KMF_X509_EXT_CERT_POLICIES |\ 59*99ebb4caSwyllys KMF_X509_EXT_SUBJALTNAME |\ 60*99ebb4caSwyllys KMF_X509_EXT_BASIC_CONSTRAINTS |\ 61*99ebb4caSwyllys KMF_X509_EXT_NAME_CONSTRAINTS |\ 62*99ebb4caSwyllys KMF_X509_EXT_POLICY_CONSTRAINTS |\ 63*99ebb4caSwyllys KMF_X509_EXT_EXT_KEY_USAGE |\ 64*99ebb4caSwyllys KMF_X509_EXT_INHIBIT_ANY_POLICY |\ 65*99ebb4caSwyllys KMF_X509_EXT_AUTH_KEY_ID |\ 66*99ebb4caSwyllys KMF_X509_EXT_SUBJ_KEY_ID |\ 67*99ebb4caSwyllys KMF_X509_EXT_POLICY_MAPPING) 68*99ebb4caSwyllys 69*99ebb4caSwyllys static BIO *bio_err = NULL; 70*99ebb4caSwyllys static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 71*99ebb4caSwyllys 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 72*99ebb4caSwyllys 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 73*99ebb4caSwyllys 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 74*99ebb4caSwyllys 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 75*99ebb4caSwyllys 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 76*99ebb4caSwyllys 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 77*99ebb4caSwyllys 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 78*99ebb4caSwyllys 0x91 }; 79*99ebb4caSwyllys 80*99ebb4caSwyllys static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 81*99ebb4caSwyllys 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 82*99ebb4caSwyllys 0x8e, 0xda, 0xce, 0x91, 0x5f }; 83*99ebb4caSwyllys 84*99ebb4caSwyllys static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 85*99ebb4caSwyllys 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 86*99ebb4caSwyllys 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 87*99ebb4caSwyllys 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 88*99ebb4caSwyllys 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 89*99ebb4caSwyllys 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 90*99ebb4caSwyllys 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 91*99ebb4caSwyllys 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 92*99ebb4caSwyllys 0x02 }; 93*99ebb4caSwyllys 94*99ebb4caSwyllys #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \ 95*99ebb4caSwyllys h->lasterr.errcode = c; 96*99ebb4caSwyllys 97*99ebb4caSwyllys #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c; 98*99ebb4caSwyllys 99*99ebb4caSwyllys mutex_t init_lock = DEFAULTMUTEX; 100*99ebb4caSwyllys static int ssl_initialized = 0; 101*99ebb4caSwyllys 102*99ebb4caSwyllys KMF_RETURN 103*99ebb4caSwyllys OpenSSL_FindCert(KMF_HANDLE_T, 104*99ebb4caSwyllys KMF_FINDCERT_PARAMS *, 105*99ebb4caSwyllys KMF_X509_DER_CERT *, 106*99ebb4caSwyllys uint32_t *); 107*99ebb4caSwyllys 108*99ebb4caSwyllys void 109*99ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); 110*99ebb4caSwyllys 111*99ebb4caSwyllys KMF_RETURN 112*99ebb4caSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *, KMF_DATA *); 113*99ebb4caSwyllys 114*99ebb4caSwyllys KMF_RETURN 115*99ebb4caSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *); 116*99ebb4caSwyllys 117*99ebb4caSwyllys KMF_RETURN 118*99ebb4caSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, 119*99ebb4caSwyllys KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); 120*99ebb4caSwyllys 121*99ebb4caSwyllys KMF_RETURN 122*99ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 123*99ebb4caSwyllys 124*99ebb4caSwyllys KMF_RETURN 125*99ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 126*99ebb4caSwyllys KMF_DATA *, KMF_DATA *); 127*99ebb4caSwyllys 128*99ebb4caSwyllys KMF_RETURN 129*99ebb4caSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, 130*99ebb4caSwyllys KMF_KEY_HANDLE *, boolean_t); 131*99ebb4caSwyllys 132*99ebb4caSwyllys KMF_RETURN 133*99ebb4caSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *); 134*99ebb4caSwyllys 135*99ebb4caSwyllys KMF_RETURN 136*99ebb4caSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *); 137*99ebb4caSwyllys 138*99ebb4caSwyllys KMF_RETURN 139*99ebb4caSwyllys OpenSSL_ListCRL(KMF_HANDLE_T, KMF_LISTCRL_PARAMS *, char **); 140*99ebb4caSwyllys 141*99ebb4caSwyllys KMF_RETURN 142*99ebb4caSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *); 143*99ebb4caSwyllys 144*99ebb4caSwyllys KMF_RETURN 145*99ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *, 146*99ebb4caSwyllys KMF_PRINTABLE_ITEM, char *); 147*99ebb4caSwyllys 148*99ebb4caSwyllys KMF_RETURN 149*99ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T, char **); 150*99ebb4caSwyllys 151*99ebb4caSwyllys KMF_RETURN 152*99ebb4caSwyllys OpenSSL_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, 153*99ebb4caSwyllys KMF_KEY_HANDLE *, KMF_KEY_ALG); 154*99ebb4caSwyllys 155*99ebb4caSwyllys KMF_RETURN 156*99ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 157*99ebb4caSwyllys KMF_DATA *, KMF_DATA *); 158*99ebb4caSwyllys 159*99ebb4caSwyllys KMF_RETURN 160*99ebb4caSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, KMF_OCSPREQUEST_PARAMS *, 161*99ebb4caSwyllys char *reqfile); 162*99ebb4caSwyllys 163*99ebb4caSwyllys KMF_RETURN 164*99ebb4caSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, KMF_OCSPRESPONSE_PARAMS_INPUT *, 165*99ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_OUTPUT *); 166*99ebb4caSwyllys 167*99ebb4caSwyllys KMF_RETURN 168*99ebb4caSwyllys OpenSSL_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, 169*99ebb4caSwyllys KMF_KEY_HANDLE *, uint32_t *); 170*99ebb4caSwyllys 171*99ebb4caSwyllys KMF_RETURN 172*99ebb4caSwyllys OpenSSL_ExportP12(KMF_HANDLE_T, 173*99ebb4caSwyllys KMF_EXPORTP12_PARAMS *, 174*99ebb4caSwyllys int, KMF_X509_DER_CERT *, 175*99ebb4caSwyllys int, KMF_KEY_HANDLE *, 176*99ebb4caSwyllys char *); 177*99ebb4caSwyllys 178*99ebb4caSwyllys KMF_RETURN 179*99ebb4caSwyllys OpenSSL_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, 180*99ebb4caSwyllys KMF_RAW_KEY_DATA *); 181*99ebb4caSwyllys 182*99ebb4caSwyllys KMF_RETURN 183*99ebb4caSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, 184*99ebb4caSwyllys KMF_KEY_HANDLE *); 185*99ebb4caSwyllys 186*99ebb4caSwyllys KMF_RETURN 187*99ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 188*99ebb4caSwyllys 189*99ebb4caSwyllys KMF_RETURN 190*99ebb4caSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T, KMF_VERIFYCRL_PARAMS *); 191*99ebb4caSwyllys 192*99ebb4caSwyllys KMF_RETURN 193*99ebb4caSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T, KMF_CHECKCRLDATE_PARAMS *); 194*99ebb4caSwyllys 195*99ebb4caSwyllys static 196*99ebb4caSwyllys KMF_PLUGIN_FUNCLIST openssl_plugin_table = 197*99ebb4caSwyllys { 198*99ebb4caSwyllys 1, /* Version */ 199*99ebb4caSwyllys NULL, /* ConfigureKeystore */ 200*99ebb4caSwyllys OpenSSL_FindCert, 201*99ebb4caSwyllys OpenSSL_FreeKMFCert, 202*99ebb4caSwyllys OpenSSL_StoreCert, 203*99ebb4caSwyllys NULL, /* ImportCert */ 204*99ebb4caSwyllys OpenSSL_ImportCRL, 205*99ebb4caSwyllys OpenSSL_DeleteCert, 206*99ebb4caSwyllys OpenSSL_DeleteCRL, 207*99ebb4caSwyllys OpenSSL_CreateKeypair, 208*99ebb4caSwyllys OpenSSL_FindKey, 209*99ebb4caSwyllys OpenSSL_EncodePubKeyData, 210*99ebb4caSwyllys OpenSSL_SignData, 211*99ebb4caSwyllys OpenSSL_DeleteKey, 212*99ebb4caSwyllys OpenSSL_ListCRL, 213*99ebb4caSwyllys NULL, /* FindCRL */ 214*99ebb4caSwyllys OpenSSL_FindCertInCRL, 215*99ebb4caSwyllys OpenSSL_GetErrorString, 216*99ebb4caSwyllys OpenSSL_GetPrikeyByCert, 217*99ebb4caSwyllys OpenSSL_DecryptData, 218*99ebb4caSwyllys OpenSSL_ExportP12, 219*99ebb4caSwyllys OpenSSL_StorePrivateKey, 220*99ebb4caSwyllys OpenSSL_CreateSymKey, 221*99ebb4caSwyllys OpenSSL_GetSymKeyValue, 222*99ebb4caSwyllys NULL, /* SetTokenPin */ 223*99ebb4caSwyllys NULL /* Finalize */ 224*99ebb4caSwyllys }; 225*99ebb4caSwyllys 226*99ebb4caSwyllys static mutex_t *lock_cs; 227*99ebb4caSwyllys static long *lock_count; 228*99ebb4caSwyllys 229*99ebb4caSwyllys static void 230*99ebb4caSwyllys /*ARGSUSED*/ 231*99ebb4caSwyllys locking_cb(int mode, int type, char *file, int line) 232*99ebb4caSwyllys { 233*99ebb4caSwyllys if (mode & CRYPTO_LOCK) { 234*99ebb4caSwyllys (void) mutex_lock(&(lock_cs[type])); 235*99ebb4caSwyllys lock_count[type]++; 236*99ebb4caSwyllys } else { 237*99ebb4caSwyllys (void) mutex_unlock(&(lock_cs[type])); 238*99ebb4caSwyllys } 239*99ebb4caSwyllys } 240*99ebb4caSwyllys 241*99ebb4caSwyllys static unsigned long 242*99ebb4caSwyllys thread_id() 243*99ebb4caSwyllys { 244*99ebb4caSwyllys return ((unsigned long)thr_self()); 245*99ebb4caSwyllys } 246*99ebb4caSwyllys 247*99ebb4caSwyllys KMF_PLUGIN_FUNCLIST * 248*99ebb4caSwyllys KMF_Plugin_Initialize() 249*99ebb4caSwyllys { 250*99ebb4caSwyllys int i; 251*99ebb4caSwyllys 252*99ebb4caSwyllys (void) mutex_lock(&init_lock); 253*99ebb4caSwyllys if (!ssl_initialized) { 254*99ebb4caSwyllys OpenSSL_add_all_algorithms(); 255*99ebb4caSwyllys 256*99ebb4caSwyllys /* Enable error strings for reporting */ 257*99ebb4caSwyllys ERR_load_crypto_strings(); 258*99ebb4caSwyllys 259*99ebb4caSwyllys /* 260*99ebb4caSwyllys * Add support for extension OIDs that are not yet in the 261*99ebb4caSwyllys * openssl default set. 262*99ebb4caSwyllys */ 263*99ebb4caSwyllys (void) OBJ_create("2.5.29.30", "nameConstraints", 264*99ebb4caSwyllys "X509v3 Name Constraints"); 265*99ebb4caSwyllys (void) OBJ_create("2.5.29.33", "policyMappings", 266*99ebb4caSwyllys "X509v3 Policy Mappings"); 267*99ebb4caSwyllys (void) OBJ_create("2.5.29.36", "policyConstraints", 268*99ebb4caSwyllys "X509v3 Policy Constraints"); 269*99ebb4caSwyllys (void) OBJ_create("2.5.29.46", "freshestCRL", 270*99ebb4caSwyllys "X509v3 Freshest CRL"); 271*99ebb4caSwyllys (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy", 272*99ebb4caSwyllys "X509v3 Inhibit Any-Policy"); 273*99ebb4caSwyllys /* 274*99ebb4caSwyllys * Set up for thread-safe operation. 275*99ebb4caSwyllys */ 276*99ebb4caSwyllys lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t)); 277*99ebb4caSwyllys if (lock_cs == NULL) { 278*99ebb4caSwyllys (void) mutex_unlock(&init_lock); 279*99ebb4caSwyllys return (NULL); 280*99ebb4caSwyllys } 281*99ebb4caSwyllys 282*99ebb4caSwyllys lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long)); 283*99ebb4caSwyllys if (lock_count == NULL) { 284*99ebb4caSwyllys OPENSSL_free(lock_cs); 285*99ebb4caSwyllys (void) mutex_unlock(&init_lock); 286*99ebb4caSwyllys return (NULL); 287*99ebb4caSwyllys } 288*99ebb4caSwyllys 289*99ebb4caSwyllys for (i = 0; i < CRYPTO_num_locks(); i++) { 290*99ebb4caSwyllys lock_count[i] = 0; 291*99ebb4caSwyllys (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL); 292*99ebb4caSwyllys } 293*99ebb4caSwyllys 294*99ebb4caSwyllys CRYPTO_set_id_callback((unsigned long (*)())thread_id); 295*99ebb4caSwyllys CRYPTO_set_locking_callback((void (*)())locking_cb); 296*99ebb4caSwyllys ssl_initialized = 1; 297*99ebb4caSwyllys } 298*99ebb4caSwyllys (void) mutex_unlock(&init_lock); 299*99ebb4caSwyllys 300*99ebb4caSwyllys return (&openssl_plugin_table); 301*99ebb4caSwyllys } 302*99ebb4caSwyllys /* 303*99ebb4caSwyllys * Convert an SSL DN to a KMF DN. 304*99ebb4caSwyllys */ 305*99ebb4caSwyllys static KMF_RETURN 306*99ebb4caSwyllys get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN) 307*99ebb4caSwyllys { 308*99ebb4caSwyllys KMF_DATA derdata; 309*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 310*99ebb4caSwyllys uchar_t *tmp; 311*99ebb4caSwyllys 312*99ebb4caSwyllys /* Convert to raw DER format */ 313*99ebb4caSwyllys derdata.Length = i2d_X509_NAME(sslDN, NULL); 314*99ebb4caSwyllys if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length)) 315*99ebb4caSwyllys == NULL) { 316*99ebb4caSwyllys return (KMF_ERR_MEMORY); 317*99ebb4caSwyllys } 318*99ebb4caSwyllys (void) i2d_X509_NAME(sslDN, &tmp); 319*99ebb4caSwyllys 320*99ebb4caSwyllys /* Decode to KMF format */ 321*99ebb4caSwyllys rv = DerDecodeName(&derdata, kmfDN); 322*99ebb4caSwyllys if (rv != KMF_OK) { 323*99ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 324*99ebb4caSwyllys } 325*99ebb4caSwyllys OPENSSL_free(derdata.Data); 326*99ebb4caSwyllys 327*99ebb4caSwyllys return (rv); 328*99ebb4caSwyllys } 329*99ebb4caSwyllys 330*99ebb4caSwyllys static int 331*99ebb4caSwyllys isdir(char *path) 332*99ebb4caSwyllys { 333*99ebb4caSwyllys struct stat s; 334*99ebb4caSwyllys 335*99ebb4caSwyllys if (stat(path, &s) == -1) 336*99ebb4caSwyllys return (0); 337*99ebb4caSwyllys 338*99ebb4caSwyllys return (s.st_mode & S_IFDIR); 339*99ebb4caSwyllys } 340*99ebb4caSwyllys 341*99ebb4caSwyllys static KMF_RETURN 342*99ebb4caSwyllys ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert) 343*99ebb4caSwyllys { 344*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 345*99ebb4caSwyllys unsigned char *buf = NULL, *p; 346*99ebb4caSwyllys int len; 347*99ebb4caSwyllys 348*99ebb4caSwyllys /* 349*99ebb4caSwyllys * Convert the X509 internal struct to DER encoded data 350*99ebb4caSwyllys */ 351*99ebb4caSwyllys if ((len = i2d_X509(x509cert, NULL)) < 0) { 352*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 353*99ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 354*99ebb4caSwyllys goto cleanup; 355*99ebb4caSwyllys } 356*99ebb4caSwyllys if ((buf = malloc(len)) == NULL) { 357*99ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 358*99ebb4caSwyllys rv = KMF_ERR_MEMORY; 359*99ebb4caSwyllys goto cleanup; 360*99ebb4caSwyllys } 361*99ebb4caSwyllys 362*99ebb4caSwyllys /* 363*99ebb4caSwyllys * i2d_X509 will increment the buf pointer so that we need to 364*99ebb4caSwyllys * save it. 365*99ebb4caSwyllys */ 366*99ebb4caSwyllys p = buf; 367*99ebb4caSwyllys if ((len = i2d_X509(x509cert, &p)) < 0) { 368*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 369*99ebb4caSwyllys free(buf); 370*99ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 371*99ebb4caSwyllys goto cleanup; 372*99ebb4caSwyllys } 373*99ebb4caSwyllys 374*99ebb4caSwyllys /* caller's responsibility to free it */ 375*99ebb4caSwyllys cert->Data = buf; 376*99ebb4caSwyllys cert->Length = len; 377*99ebb4caSwyllys 378*99ebb4caSwyllys cleanup: 379*99ebb4caSwyllys if (rv != KMF_OK) { 380*99ebb4caSwyllys if (buf) 381*99ebb4caSwyllys free(buf); 382*99ebb4caSwyllys cert->Data = NULL; 383*99ebb4caSwyllys cert->Length = 0; 384*99ebb4caSwyllys } 385*99ebb4caSwyllys 386*99ebb4caSwyllys return (rv); 387*99ebb4caSwyllys } 388*99ebb4caSwyllys 389*99ebb4caSwyllys static KMF_RETURN 390*99ebb4caSwyllys check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match) 391*99ebb4caSwyllys { 392*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 393*99ebb4caSwyllys boolean_t findIssuer = FALSE; 394*99ebb4caSwyllys boolean_t findSubject = FALSE; 395*99ebb4caSwyllys boolean_t findSerial = FALSE; 396*99ebb4caSwyllys KMF_X509_NAME issuerDN, subjectDN; 397*99ebb4caSwyllys KMF_X509_NAME certIssuerDN, certSubjectDN; 398*99ebb4caSwyllys 399*99ebb4caSwyllys *match = FALSE; 400*99ebb4caSwyllys if (xcert == NULL) { 401*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 402*99ebb4caSwyllys } 403*99ebb4caSwyllys 404*99ebb4caSwyllys (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME)); 405*99ebb4caSwyllys (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME)); 406*99ebb4caSwyllys (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME)); 407*99ebb4caSwyllys (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME)); 408*99ebb4caSwyllys 409*99ebb4caSwyllys if (params->issuer != NULL && strlen(params->issuer)) { 410*99ebb4caSwyllys rv = KMF_DNParser(params->issuer, &issuerDN); 411*99ebb4caSwyllys if (rv != KMF_OK) 412*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 413*99ebb4caSwyllys 414*99ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); 415*99ebb4caSwyllys if (rv != KMF_OK) { 416*99ebb4caSwyllys KMF_FreeDN(&issuerDN); 417*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 418*99ebb4caSwyllys } 419*99ebb4caSwyllys 420*99ebb4caSwyllys findIssuer = TRUE; 421*99ebb4caSwyllys } 422*99ebb4caSwyllys if (params->subject != NULL && strlen(params->subject)) { 423*99ebb4caSwyllys rv = KMF_DNParser(params->subject, &subjectDN); 424*99ebb4caSwyllys if (rv != KMF_OK) { 425*99ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 426*99ebb4caSwyllys goto cleanup; 427*99ebb4caSwyllys } 428*99ebb4caSwyllys 429*99ebb4caSwyllys rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN); 430*99ebb4caSwyllys if (rv != KMF_OK) { 431*99ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 432*99ebb4caSwyllys goto cleanup; 433*99ebb4caSwyllys } 434*99ebb4caSwyllys findSubject = TRUE; 435*99ebb4caSwyllys } 436*99ebb4caSwyllys if (params->serial != NULL && params->serial->val != NULL) 437*99ebb4caSwyllys findSerial = TRUE; 438*99ebb4caSwyllys 439*99ebb4caSwyllys if (findSerial) { 440*99ebb4caSwyllys BIGNUM *bn; 441*99ebb4caSwyllys 442*99ebb4caSwyllys /* Comparing BIGNUMs is a pain! */ 443*99ebb4caSwyllys bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL); 444*99ebb4caSwyllys if (bn != NULL) { 445*99ebb4caSwyllys int bnlen = BN_num_bytes(bn); 446*99ebb4caSwyllys 447*99ebb4caSwyllys if (bnlen == params->serial->len) { 448*99ebb4caSwyllys uchar_t *a = malloc(bnlen); 449*99ebb4caSwyllys if (a == NULL) { 450*99ebb4caSwyllys rv = KMF_ERR_MEMORY; 451*99ebb4caSwyllys BN_free(bn); 452*99ebb4caSwyllys goto cleanup; 453*99ebb4caSwyllys } 454*99ebb4caSwyllys bnlen = BN_bn2bin(bn, a); 455*99ebb4caSwyllys *match = !memcmp(a, 456*99ebb4caSwyllys params->serial->val, 457*99ebb4caSwyllys params->serial->len); 458*99ebb4caSwyllys rv = KMF_OK; 459*99ebb4caSwyllys free(a); 460*99ebb4caSwyllys } 461*99ebb4caSwyllys BN_free(bn); 462*99ebb4caSwyllys if (!(*match)) 463*99ebb4caSwyllys goto cleanup; 464*99ebb4caSwyllys } else { 465*99ebb4caSwyllys rv = KMF_OK; 466*99ebb4caSwyllys goto cleanup; 467*99ebb4caSwyllys } 468*99ebb4caSwyllys } 469*99ebb4caSwyllys if (findIssuer) { 470*99ebb4caSwyllys *match = !KMF_CompareRDNs(&issuerDN, &certIssuerDN); 471*99ebb4caSwyllys if (!(*match)) { 472*99ebb4caSwyllys rv = KMF_OK; 473*99ebb4caSwyllys goto cleanup; 474*99ebb4caSwyllys } 475*99ebb4caSwyllys } 476*99ebb4caSwyllys if (findSubject) { 477*99ebb4caSwyllys *match = !KMF_CompareRDNs(&subjectDN, &certSubjectDN); 478*99ebb4caSwyllys if (!(*match)) { 479*99ebb4caSwyllys rv = KMF_OK; 480*99ebb4caSwyllys goto cleanup; 481*99ebb4caSwyllys } 482*99ebb4caSwyllys } 483*99ebb4caSwyllys 484*99ebb4caSwyllys *match = TRUE; 485*99ebb4caSwyllys cleanup: 486*99ebb4caSwyllys if (findIssuer) { 487*99ebb4caSwyllys KMF_FreeDN(&issuerDN); 488*99ebb4caSwyllys KMF_FreeDN(&certIssuerDN); 489*99ebb4caSwyllys } 490*99ebb4caSwyllys if (findSubject) { 491*99ebb4caSwyllys KMF_FreeDN(&subjectDN); 492*99ebb4caSwyllys KMF_FreeDN(&certSubjectDN); 493*99ebb4caSwyllys } 494*99ebb4caSwyllys 495*99ebb4caSwyllys return (rv); 496*99ebb4caSwyllys } 497*99ebb4caSwyllys 498*99ebb4caSwyllys static KMF_RETURN 499*99ebb4caSwyllys load_X509cert(KMF_HANDLE *kmfh, 500*99ebb4caSwyllys KMF_FINDCERT_PARAMS *params, 501*99ebb4caSwyllys char *pathname, 502*99ebb4caSwyllys X509 **outcert) 503*99ebb4caSwyllys { 504*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 505*99ebb4caSwyllys X509 *xcert = NULL; 506*99ebb4caSwyllys BIO *bcert = NULL; 507*99ebb4caSwyllys boolean_t match = FALSE; 508*99ebb4caSwyllys KMF_ENCODE_FORMAT format; 509*99ebb4caSwyllys 510*99ebb4caSwyllys /* 511*99ebb4caSwyllys * auto-detect the file format, regardless of what 512*99ebb4caSwyllys * the 'format' parameters in the params say. 513*99ebb4caSwyllys */ 514*99ebb4caSwyllys rv = KMF_GetFileFormat(pathname, &format); 515*99ebb4caSwyllys if (rv != KMF_OK) { 516*99ebb4caSwyllys if (rv == KMF_ERR_OPEN_FILE) 517*99ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 518*99ebb4caSwyllys return (rv); 519*99ebb4caSwyllys } 520*99ebb4caSwyllys 521*99ebb4caSwyllys /* Not ASN1(DER) format */ 522*99ebb4caSwyllys if ((bcert = BIO_new_file(pathname, "rb")) == NULL) { 523*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 524*99ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 525*99ebb4caSwyllys goto cleanup; 526*99ebb4caSwyllys } 527*99ebb4caSwyllys 528*99ebb4caSwyllys if (format == KMF_FORMAT_PEM) 529*99ebb4caSwyllys xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL); 530*99ebb4caSwyllys else if (format == KMF_FORMAT_ASN1) 531*99ebb4caSwyllys xcert = d2i_X509_bio(bcert, NULL); 532*99ebb4caSwyllys else if (format == KMF_FORMAT_PKCS12) { 533*99ebb4caSwyllys PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL); 534*99ebb4caSwyllys if (p12 != NULL) { 535*99ebb4caSwyllys (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL); 536*99ebb4caSwyllys PKCS12_free(p12); 537*99ebb4caSwyllys p12 = NULL; 538*99ebb4caSwyllys } else { 539*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 540*99ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 541*99ebb4caSwyllys } 542*99ebb4caSwyllys } else { 543*99ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 544*99ebb4caSwyllys goto cleanup; 545*99ebb4caSwyllys } 546*99ebb4caSwyllys 547*99ebb4caSwyllys if (xcert == NULL) { 548*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 549*99ebb4caSwyllys rv = KMF_ERR_BAD_CERT_FORMAT; 550*99ebb4caSwyllys goto cleanup; 551*99ebb4caSwyllys } 552*99ebb4caSwyllys 553*99ebb4caSwyllys if (check_cert(xcert, params, &match) != KMF_OK || match == FALSE) { 554*99ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 555*99ebb4caSwyllys goto cleanup; 556*99ebb4caSwyllys } 557*99ebb4caSwyllys 558*99ebb4caSwyllys if (outcert != NULL) { 559*99ebb4caSwyllys *outcert = xcert; 560*99ebb4caSwyllys } 561*99ebb4caSwyllys 562*99ebb4caSwyllys cleanup: 563*99ebb4caSwyllys if (bcert != NULL) (void) BIO_free(bcert); 564*99ebb4caSwyllys if (rv != KMF_OK && xcert != NULL) 565*99ebb4caSwyllys X509_free(xcert); 566*99ebb4caSwyllys 567*99ebb4caSwyllys return (rv); 568*99ebb4caSwyllys } 569*99ebb4caSwyllys 570*99ebb4caSwyllys static KMF_RETURN 571*99ebb4caSwyllys kmf_load_cert(KMF_HANDLE *kmfh, 572*99ebb4caSwyllys KMF_FINDCERT_PARAMS *params, 573*99ebb4caSwyllys char *pathname, 574*99ebb4caSwyllys KMF_DATA *cert) 575*99ebb4caSwyllys { 576*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 577*99ebb4caSwyllys X509 *x509cert = NULL; 578*99ebb4caSwyllys 579*99ebb4caSwyllys rv = load_X509cert(kmfh, params, pathname, &x509cert); 580*99ebb4caSwyllys if (rv == KMF_OK && x509cert != NULL && cert != NULL) { 581*99ebb4caSwyllys rv = ssl_cert2KMFDATA(kmfh, x509cert, cert); 582*99ebb4caSwyllys if (rv != KMF_OK) { 583*99ebb4caSwyllys goto cleanup; 584*99ebb4caSwyllys } 585*99ebb4caSwyllys if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) { 586*99ebb4caSwyllys rv = KMF_CheckCertDate(kmfh, cert); 587*99ebb4caSwyllys } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) { 588*99ebb4caSwyllys rv = KMF_CheckCertDate(kmfh, cert); 589*99ebb4caSwyllys if (rv == KMF_OK) { 590*99ebb4caSwyllys /* 591*99ebb4caSwyllys * This is a valid cert so skip it. 592*99ebb4caSwyllys */ 593*99ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 594*99ebb4caSwyllys } 595*99ebb4caSwyllys if (rv == KMF_ERR_VALIDITY_PERIOD) { 596*99ebb4caSwyllys /* 597*99ebb4caSwyllys * We want to return success when we 598*99ebb4caSwyllys * find an invalid cert. 599*99ebb4caSwyllys */ 600*99ebb4caSwyllys rv = KMF_OK; 601*99ebb4caSwyllys goto cleanup; 602*99ebb4caSwyllys } 603*99ebb4caSwyllys } 604*99ebb4caSwyllys } 605*99ebb4caSwyllys cleanup: 606*99ebb4caSwyllys if (x509cert != NULL) 607*99ebb4caSwyllys X509_free(x509cert); 608*99ebb4caSwyllys 609*99ebb4caSwyllys return (rv); 610*99ebb4caSwyllys } 611*99ebb4caSwyllys 612*99ebb4caSwyllys static EVP_PKEY * 613*99ebb4caSwyllys openssl_load_key(KMF_HANDLE_T handle, const char *file) 614*99ebb4caSwyllys { 615*99ebb4caSwyllys BIO *keyfile = NULL; 616*99ebb4caSwyllys EVP_PKEY *pkey = NULL; 617*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 618*99ebb4caSwyllys KMF_ENCODE_FORMAT format; 619*99ebb4caSwyllys 620*99ebb4caSwyllys if (file == NULL) { 621*99ebb4caSwyllys return (NULL); 622*99ebb4caSwyllys } 623*99ebb4caSwyllys 624*99ebb4caSwyllys if (KMF_GetFileFormat((char *)file, &format) != KMF_OK) 625*99ebb4caSwyllys return (NULL); 626*99ebb4caSwyllys 627*99ebb4caSwyllys keyfile = BIO_new_file(file, "rb"); 628*99ebb4caSwyllys if (keyfile == NULL) { 629*99ebb4caSwyllys goto end; 630*99ebb4caSwyllys } 631*99ebb4caSwyllys 632*99ebb4caSwyllys if (format == KMF_FORMAT_ASN1) 633*99ebb4caSwyllys pkey = d2i_PrivateKey_bio(keyfile, NULL); 634*99ebb4caSwyllys else if (format == KMF_FORMAT_PEM) 635*99ebb4caSwyllys pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL); 636*99ebb4caSwyllys 637*99ebb4caSwyllys end: 638*99ebb4caSwyllys if (pkey == NULL) 639*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 640*99ebb4caSwyllys 641*99ebb4caSwyllys if (keyfile != NULL) 642*99ebb4caSwyllys (void) BIO_free(keyfile); 643*99ebb4caSwyllys 644*99ebb4caSwyllys return (pkey); 645*99ebb4caSwyllys } 646*99ebb4caSwyllys 647*99ebb4caSwyllys KMF_RETURN 648*99ebb4caSwyllys OpenSSL_FindCert(KMF_HANDLE_T handle, 649*99ebb4caSwyllys KMF_FINDCERT_PARAMS *params, 650*99ebb4caSwyllys KMF_X509_DER_CERT *kmf_cert, 651*99ebb4caSwyllys uint32_t *num_certs) 652*99ebb4caSwyllys { 653*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 654*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 655*99ebb4caSwyllys KMF_DATA certdata = {NULL, 0}; 656*99ebb4caSwyllys char *fullpath; 657*99ebb4caSwyllys 658*99ebb4caSwyllys if (num_certs == NULL || params == NULL) 659*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 660*99ebb4caSwyllys 661*99ebb4caSwyllys *num_certs = 0; 662*99ebb4caSwyllys 663*99ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 664*99ebb4caSwyllys params->sslparms.certfile); 665*99ebb4caSwyllys 666*99ebb4caSwyllys if (fullpath == NULL) 667*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 668*99ebb4caSwyllys 669*99ebb4caSwyllys if (isdir(fullpath)) { 670*99ebb4caSwyllys DIR *dirp; 671*99ebb4caSwyllys struct dirent *dp; 672*99ebb4caSwyllys int n = 0; 673*99ebb4caSwyllys 674*99ebb4caSwyllys /* open all files in the directory and attempt to read them */ 675*99ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 676*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 677*99ebb4caSwyllys } 678*99ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 679*99ebb4caSwyllys char *fname; 680*99ebb4caSwyllys if (strcmp(dp->d_name, ".") == 0 || 681*99ebb4caSwyllys strcmp(dp->d_name, "..") == 0) 682*99ebb4caSwyllys continue; 683*99ebb4caSwyllys 684*99ebb4caSwyllys fname = get_fullpath(fullpath, 685*99ebb4caSwyllys (char *)&dp->d_name); 686*99ebb4caSwyllys 687*99ebb4caSwyllys rv = kmf_load_cert(kmfh, params, fname, 688*99ebb4caSwyllys &certdata); 689*99ebb4caSwyllys 690*99ebb4caSwyllys if (rv != KMF_OK) { 691*99ebb4caSwyllys free(fname); 692*99ebb4caSwyllys KMF_FreeData(&certdata); 693*99ebb4caSwyllys continue; 694*99ebb4caSwyllys } 695*99ebb4caSwyllys 696*99ebb4caSwyllys /* If load succeeds, add certdata to the list */ 697*99ebb4caSwyllys if (kmf_cert != NULL) { 698*99ebb4caSwyllys kmf_cert[n].certificate.Data = certdata.Data; 699*99ebb4caSwyllys kmf_cert[n].certificate.Length = 700*99ebb4caSwyllys certdata.Length; 701*99ebb4caSwyllys 702*99ebb4caSwyllys kmf_cert[n].kmf_private.keystore_type = 703*99ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 704*99ebb4caSwyllys kmf_cert[n].kmf_private.flags = 705*99ebb4caSwyllys KMF_FLAG_CERT_VALID; 706*99ebb4caSwyllys kmf_cert[n].kmf_private.label = fname; 707*99ebb4caSwyllys } else { 708*99ebb4caSwyllys free(fname); 709*99ebb4caSwyllys KMF_FreeData(&certdata); 710*99ebb4caSwyllys } 711*99ebb4caSwyllys n++; 712*99ebb4caSwyllys } 713*99ebb4caSwyllys (*num_certs) = n; 714*99ebb4caSwyllys if (*num_certs == 0) 715*99ebb4caSwyllys rv = KMF_ERR_CERT_NOT_FOUND; 716*99ebb4caSwyllys if (*num_certs > 0) 717*99ebb4caSwyllys rv = KMF_OK; 718*99ebb4caSwyllys exit: 719*99ebb4caSwyllys (void) closedir(dirp); 720*99ebb4caSwyllys } else { 721*99ebb4caSwyllys /* Just try to load a single certificate */ 722*99ebb4caSwyllys rv = kmf_load_cert(kmfh, params, fullpath, &certdata); 723*99ebb4caSwyllys if (rv != KMF_OK) { 724*99ebb4caSwyllys free(fullpath); 725*99ebb4caSwyllys KMF_FreeData(&certdata); 726*99ebb4caSwyllys return (rv); 727*99ebb4caSwyllys } 728*99ebb4caSwyllys 729*99ebb4caSwyllys if (kmf_cert != NULL) { 730*99ebb4caSwyllys kmf_cert->certificate.Data = certdata.Data; 731*99ebb4caSwyllys kmf_cert->certificate.Length = certdata.Length; 732*99ebb4caSwyllys kmf_cert->kmf_private.keystore_type = 733*99ebb4caSwyllys KMF_KEYSTORE_OPENSSL; 734*99ebb4caSwyllys kmf_cert->kmf_private.flags = KMF_FLAG_CERT_VALID; 735*99ebb4caSwyllys kmf_cert->kmf_private.label = fullpath; 736*99ebb4caSwyllys } else { 737*99ebb4caSwyllys KMF_FreeData(&certdata); 738*99ebb4caSwyllys } 739*99ebb4caSwyllys 740*99ebb4caSwyllys *num_certs = 1; 741*99ebb4caSwyllys } 742*99ebb4caSwyllys 743*99ebb4caSwyllys if (kmf_cert == NULL || rv != KMF_OK) 744*99ebb4caSwyllys free(fullpath); 745*99ebb4caSwyllys 746*99ebb4caSwyllys return (rv); 747*99ebb4caSwyllys 748*99ebb4caSwyllys } 749*99ebb4caSwyllys 750*99ebb4caSwyllys void 751*99ebb4caSwyllys /*ARGSUSED*/ 752*99ebb4caSwyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, 753*99ebb4caSwyllys KMF_X509_DER_CERT *kmf_cert) 754*99ebb4caSwyllys { 755*99ebb4caSwyllys if (kmf_cert != NULL) { 756*99ebb4caSwyllys if (kmf_cert->certificate.Data != NULL) { 757*99ebb4caSwyllys free(kmf_cert->certificate.Data); 758*99ebb4caSwyllys kmf_cert->certificate.Data = NULL; 759*99ebb4caSwyllys kmf_cert->certificate.Length = 0; 760*99ebb4caSwyllys } 761*99ebb4caSwyllys if (kmf_cert->kmf_private.label) 762*99ebb4caSwyllys free(kmf_cert->kmf_private.label); 763*99ebb4caSwyllys } 764*99ebb4caSwyllys } 765*99ebb4caSwyllys 766*99ebb4caSwyllys KMF_RETURN 767*99ebb4caSwyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, 768*99ebb4caSwyllys KMF_DATA * pcert) 769*99ebb4caSwyllys { 770*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 771*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 772*99ebb4caSwyllys X509 *xcert = NULL; 773*99ebb4caSwyllys FILE *fp; 774*99ebb4caSwyllys unsigned char *outbuf; 775*99ebb4caSwyllys unsigned char *outbuf_p; 776*99ebb4caSwyllys char *fullpath; 777*99ebb4caSwyllys int outbuflen; 778*99ebb4caSwyllys int len; 779*99ebb4caSwyllys KMF_ENCODE_FORMAT format; 780*99ebb4caSwyllys 781*99ebb4caSwyllys if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) { 782*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 783*99ebb4caSwyllys } 784*99ebb4caSwyllys 785*99ebb4caSwyllys /* 786*99ebb4caSwyllys * check if the cert output format is supported by OPENSSL. 787*99ebb4caSwyllys * however, since the keystore for OPENSSL is just a file, we have 788*99ebb4caSwyllys * no way to store the format along with the file. 789*99ebb4caSwyllys */ 790*99ebb4caSwyllys format = params->sslparms.format; 791*99ebb4caSwyllys if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) 792*99ebb4caSwyllys return (KMF_ERR_BAD_CERT_FORMAT); 793*99ebb4caSwyllys 794*99ebb4caSwyllys 795*99ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 796*99ebb4caSwyllys params->sslparms.certfile); 797*99ebb4caSwyllys if (fullpath == NULL) 798*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 799*99ebb4caSwyllys 800*99ebb4caSwyllys /* 801*99ebb4caSwyllys * When storing a certificate, you must specify a filename. 802*99ebb4caSwyllys */ 803*99ebb4caSwyllys if (isdir(fullpath)) { 804*99ebb4caSwyllys free(fullpath); 805*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 806*99ebb4caSwyllys } 807*99ebb4caSwyllys 808*99ebb4caSwyllys /* copy cert data to outbuf */ 809*99ebb4caSwyllys outbuflen = pcert->Length; 810*99ebb4caSwyllys outbuf = malloc(outbuflen); 811*99ebb4caSwyllys if (outbuf == NULL) { 812*99ebb4caSwyllys free(fullpath); 813*99ebb4caSwyllys return (KMF_ERR_MEMORY); 814*99ebb4caSwyllys } 815*99ebb4caSwyllys (void) memcpy(outbuf, pcert->Data, pcert->Length); 816*99ebb4caSwyllys 817*99ebb4caSwyllys if ((fp = fopen(fullpath, "w")) == 818*99ebb4caSwyllys NULL) { 819*99ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 820*99ebb4caSwyllys ret = KMF_ERR_INTERNAL; 821*99ebb4caSwyllys goto out; 822*99ebb4caSwyllys } 823*99ebb4caSwyllys 824*99ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 825*99ebb4caSwyllys len = fwrite(outbuf, 1, outbuflen, fp); 826*99ebb4caSwyllys if (len != outbuflen) { 827*99ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 828*99ebb4caSwyllys ret = KMF_ERR_WRITE_FILE; 829*99ebb4caSwyllys } else { 830*99ebb4caSwyllys ret = KMF_OK; 831*99ebb4caSwyllys } 832*99ebb4caSwyllys goto out; 833*99ebb4caSwyllys } 834*99ebb4caSwyllys 835*99ebb4caSwyllys /* 836*99ebb4caSwyllys * The output format is not KMF_FORMAT_ASN1, so we will 837*99ebb4caSwyllys * Convert the cert data to OpenSSL internal X509 first. 838*99ebb4caSwyllys */ 839*99ebb4caSwyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 840*99ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen); 841*99ebb4caSwyllys if (xcert == NULL) { 842*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 843*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 844*99ebb4caSwyllys goto out; 845*99ebb4caSwyllys } 846*99ebb4caSwyllys 847*99ebb4caSwyllys if (format == KMF_FORMAT_PEM) { 848*99ebb4caSwyllys /* Convert to the PEM format and write it out */ 849*99ebb4caSwyllys if (!PEM_write_X509(fp, xcert)) { 850*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 851*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 852*99ebb4caSwyllys } else { 853*99ebb4caSwyllys ret = KMF_OK; 854*99ebb4caSwyllys } 855*99ebb4caSwyllys goto out; 856*99ebb4caSwyllys } 857*99ebb4caSwyllys 858*99ebb4caSwyllys out: 859*99ebb4caSwyllys if (fullpath != NULL) 860*99ebb4caSwyllys free(fullpath); 861*99ebb4caSwyllys 862*99ebb4caSwyllys if (outbuf != NULL) { 863*99ebb4caSwyllys free(outbuf); 864*99ebb4caSwyllys } 865*99ebb4caSwyllys if (fp != NULL) { 866*99ebb4caSwyllys (void) fclose(fp); 867*99ebb4caSwyllys } 868*99ebb4caSwyllys 869*99ebb4caSwyllys if (xcert != NULL) { 870*99ebb4caSwyllys X509_free(xcert); 871*99ebb4caSwyllys } 872*99ebb4caSwyllys 873*99ebb4caSwyllys return (ret); 874*99ebb4caSwyllys } 875*99ebb4caSwyllys 876*99ebb4caSwyllys KMF_RETURN 877*99ebb4caSwyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) 878*99ebb4caSwyllys { 879*99ebb4caSwyllys KMF_RETURN rv; 880*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 881*99ebb4caSwyllys char *fullpath = NULL; 882*99ebb4caSwyllys KMF_DATA certdata = {NULL, 0}; 883*99ebb4caSwyllys 884*99ebb4caSwyllys if (params == NULL) { 885*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 886*99ebb4caSwyllys } 887*99ebb4caSwyllys 888*99ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 889*99ebb4caSwyllys params->sslparms.certfile); 890*99ebb4caSwyllys 891*99ebb4caSwyllys if (fullpath == NULL) 892*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 893*99ebb4caSwyllys 894*99ebb4caSwyllys if (isdir(fullpath)) { 895*99ebb4caSwyllys DIR *dirp; 896*99ebb4caSwyllys struct dirent *dp; 897*99ebb4caSwyllys 898*99ebb4caSwyllys /* open all files in the directory and attempt to read them */ 899*99ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 900*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 901*99ebb4caSwyllys } 902*99ebb4caSwyllys 903*99ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 904*99ebb4caSwyllys if (strcmp(dp->d_name, ".") != 0 && 905*99ebb4caSwyllys strcmp(dp->d_name, "..") != 0) { 906*99ebb4caSwyllys char *fname; 907*99ebb4caSwyllys 908*99ebb4caSwyllys fname = get_fullpath(fullpath, 909*99ebb4caSwyllys (char *)&dp->d_name); 910*99ebb4caSwyllys 911*99ebb4caSwyllys if (fname == NULL) { 912*99ebb4caSwyllys rv = KMF_ERR_MEMORY; 913*99ebb4caSwyllys break; 914*99ebb4caSwyllys } 915*99ebb4caSwyllys 916*99ebb4caSwyllys rv = kmf_load_cert(kmfh, params, fname, 917*99ebb4caSwyllys &certdata); 918*99ebb4caSwyllys 919*99ebb4caSwyllys if (rv == KMF_ERR_CERT_NOT_FOUND) { 920*99ebb4caSwyllys free(fname); 921*99ebb4caSwyllys if (certdata.Data) 922*99ebb4caSwyllys free(certdata.Data); 923*99ebb4caSwyllys rv = KMF_OK; 924*99ebb4caSwyllys continue; 925*99ebb4caSwyllys } else if (rv != KMF_OK) { 926*99ebb4caSwyllys free(fname); 927*99ebb4caSwyllys break; 928*99ebb4caSwyllys } 929*99ebb4caSwyllys 930*99ebb4caSwyllys if (unlink(fname) != 0) { 931*99ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 932*99ebb4caSwyllys rv = KMF_ERR_INTERNAL; 933*99ebb4caSwyllys free(fname); 934*99ebb4caSwyllys break; 935*99ebb4caSwyllys } 936*99ebb4caSwyllys free(fname); 937*99ebb4caSwyllys if (certdata.Data) 938*99ebb4caSwyllys free(certdata.Data); 939*99ebb4caSwyllys } 940*99ebb4caSwyllys } 941*99ebb4caSwyllys (void) closedir(dirp); 942*99ebb4caSwyllys } else { 943*99ebb4caSwyllys /* Just try to load a single certificate */ 944*99ebb4caSwyllys rv = kmf_load_cert(kmfh, params, fullpath, &certdata); 945*99ebb4caSwyllys if (rv == KMF_OK) { 946*99ebb4caSwyllys if (unlink(fullpath) != 0) { 947*99ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 948*99ebb4caSwyllys rv = KMF_ERR_INTERNAL; 949*99ebb4caSwyllys } 950*99ebb4caSwyllys } 951*99ebb4caSwyllys } 952*99ebb4caSwyllys 953*99ebb4caSwyllys out: 954*99ebb4caSwyllys if (fullpath != NULL) 955*99ebb4caSwyllys free(fullpath); 956*99ebb4caSwyllys 957*99ebb4caSwyllys if (certdata.Data) 958*99ebb4caSwyllys free(certdata.Data); 959*99ebb4caSwyllys 960*99ebb4caSwyllys return (rv); 961*99ebb4caSwyllys } 962*99ebb4caSwyllys 963*99ebb4caSwyllys KMF_RETURN 964*99ebb4caSwyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 965*99ebb4caSwyllys KMF_DATA *keydata) 966*99ebb4caSwyllys { 967*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 968*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 969*99ebb4caSwyllys int n; 970*99ebb4caSwyllys 971*99ebb4caSwyllys if (key == NULL || keydata == NULL || 972*99ebb4caSwyllys key->keyp == NULL) 973*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 974*99ebb4caSwyllys 975*99ebb4caSwyllys if (key->keyalg == KMF_RSA) { 976*99ebb4caSwyllys RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp); 977*99ebb4caSwyllys 978*99ebb4caSwyllys if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) { 979*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 980*99ebb4caSwyllys return (KMF_ERR_ENCODING); 981*99ebb4caSwyllys } 982*99ebb4caSwyllys RSA_free(pubkey); 983*99ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 984*99ebb4caSwyllys DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp); 985*99ebb4caSwyllys 986*99ebb4caSwyllys if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) { 987*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 988*99ebb4caSwyllys return (KMF_ERR_ENCODING); 989*99ebb4caSwyllys } 990*99ebb4caSwyllys DSA_free(pubkey); 991*99ebb4caSwyllys } else { 992*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 993*99ebb4caSwyllys } 994*99ebb4caSwyllys keydata->Length = n; 995*99ebb4caSwyllys 996*99ebb4caSwyllys cleanup: 997*99ebb4caSwyllys if (rv != KMF_OK) { 998*99ebb4caSwyllys if (keydata->Data) 999*99ebb4caSwyllys free(keydata->Data); 1000*99ebb4caSwyllys keydata->Data = NULL; 1001*99ebb4caSwyllys keydata->Length = 0; 1002*99ebb4caSwyllys } 1003*99ebb4caSwyllys 1004*99ebb4caSwyllys return (rv); 1005*99ebb4caSwyllys } 1006*99ebb4caSwyllys 1007*99ebb4caSwyllys static KMF_RETURN 1008*99ebb4caSwyllys ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, 1009*99ebb4caSwyllys KMF_CREDENTIAL *cred, EVP_PKEY *pkey) 1010*99ebb4caSwyllys { 1011*99ebb4caSwyllys int rv = 0; 1012*99ebb4caSwyllys RSA *rsa; 1013*99ebb4caSwyllys DSA *dsa; 1014*99ebb4caSwyllys 1015*99ebb4caSwyllys switch (format) { 1016*99ebb4caSwyllys case KMF_FORMAT_ASN1: 1017*99ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 1018*99ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 1019*99ebb4caSwyllys rv = i2d_RSAPrivateKey_bio(out, rsa); 1020*99ebb4caSwyllys RSA_free(rsa); 1021*99ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 1022*99ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 1023*99ebb4caSwyllys rv = i2d_DSAPrivateKey_bio(out, dsa); 1024*99ebb4caSwyllys DSA_free(dsa); 1025*99ebb4caSwyllys } 1026*99ebb4caSwyllys if (rv == 1) { 1027*99ebb4caSwyllys rv = KMF_OK; 1028*99ebb4caSwyllys } else { 1029*99ebb4caSwyllys SET_ERROR(kmfh, rv); 1030*99ebb4caSwyllys } 1031*99ebb4caSwyllys break; 1032*99ebb4caSwyllys case KMF_FORMAT_PEM: 1033*99ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 1034*99ebb4caSwyllys rsa = EVP_PKEY_get1_RSA(pkey); 1035*99ebb4caSwyllys rv = PEM_write_bio_RSAPrivateKey(out, 1036*99ebb4caSwyllys rsa, 1037*99ebb4caSwyllys NULL /* encryption type */, 1038*99ebb4caSwyllys NULL, 0, NULL, 1039*99ebb4caSwyllys cred->cred); 1040*99ebb4caSwyllys RSA_free(rsa); 1041*99ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 1042*99ebb4caSwyllys dsa = EVP_PKEY_get1_DSA(pkey); 1043*99ebb4caSwyllys rv = PEM_write_bio_DSAPrivateKey(out, 1044*99ebb4caSwyllys dsa, 1045*99ebb4caSwyllys NULL /* encryption type */, 1046*99ebb4caSwyllys NULL, 0, NULL, 1047*99ebb4caSwyllys cred->cred); 1048*99ebb4caSwyllys DSA_free(dsa); 1049*99ebb4caSwyllys } 1050*99ebb4caSwyllys 1051*99ebb4caSwyllys if (rv == 1) { 1052*99ebb4caSwyllys rv = KMF_OK; 1053*99ebb4caSwyllys } else { 1054*99ebb4caSwyllys SET_ERROR(kmfh, rv); 1055*99ebb4caSwyllys } 1056*99ebb4caSwyllys break; 1057*99ebb4caSwyllys 1058*99ebb4caSwyllys default: 1059*99ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 1060*99ebb4caSwyllys } 1061*99ebb4caSwyllys 1062*99ebb4caSwyllys return (rv); 1063*99ebb4caSwyllys } 1064*99ebb4caSwyllys 1065*99ebb4caSwyllys KMF_RETURN 1066*99ebb4caSwyllys OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, 1067*99ebb4caSwyllys KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) 1068*99ebb4caSwyllys { 1069*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 1070*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1071*99ebb4caSwyllys int format; 1072*99ebb4caSwyllys uint32_t eValue = 0x010001; 1073*99ebb4caSwyllys RSA *sslPrivKey = NULL; 1074*99ebb4caSwyllys DSA *sslDSAKey = NULL; 1075*99ebb4caSwyllys EVP_PKEY *eprikey = NULL; 1076*99ebb4caSwyllys EVP_PKEY *epubkey = NULL; 1077*99ebb4caSwyllys BIO *out = NULL; 1078*99ebb4caSwyllys char *fullpath = NULL; 1079*99ebb4caSwyllys 1080*99ebb4caSwyllys if (params == NULL || params->sslparms.keyfile == NULL) { 1081*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1082*99ebb4caSwyllys } 1083*99ebb4caSwyllys 1084*99ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 1085*99ebb4caSwyllys params->sslparms.keyfile); 1086*99ebb4caSwyllys 1087*99ebb4caSwyllys if (fullpath == NULL) 1088*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1089*99ebb4caSwyllys 1090*99ebb4caSwyllys /* If the requested file exists, return an error */ 1091*99ebb4caSwyllys if (access(fullpath, F_OK) == 0) { 1092*99ebb4caSwyllys free(fullpath); 1093*99ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 1094*99ebb4caSwyllys } 1095*99ebb4caSwyllys 1096*99ebb4caSwyllys eprikey = EVP_PKEY_new(); 1097*99ebb4caSwyllys if (eprikey == NULL) { 1098*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1099*99ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 1100*99ebb4caSwyllys goto cleanup; 1101*99ebb4caSwyllys } 1102*99ebb4caSwyllys epubkey = EVP_PKEY_new(); 1103*99ebb4caSwyllys if (epubkey == NULL) { 1104*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1105*99ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 1106*99ebb4caSwyllys goto cleanup; 1107*99ebb4caSwyllys } 1108*99ebb4caSwyllys if (params->keytype == KMF_RSA) { 1109*99ebb4caSwyllys if (params->rsa_exponent.len > 0 && 1110*99ebb4caSwyllys params->rsa_exponent.len <= sizeof (eValue) && 1111*99ebb4caSwyllys params->rsa_exponent.val != NULL) 1112*99ebb4caSwyllys /*LINTED*/ 1113*99ebb4caSwyllys eValue = *(uint32_t *)params->rsa_exponent.val; 1114*99ebb4caSwyllys 1115*99ebb4caSwyllys sslPrivKey = RSA_generate_key(params->keylength, eValue, 1116*99ebb4caSwyllys NULL, NULL); 1117*99ebb4caSwyllys if (sslPrivKey == NULL) { 1118*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1119*99ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 1120*99ebb4caSwyllys } else { 1121*99ebb4caSwyllys if (privkey != NULL && 1122*99ebb4caSwyllys EVP_PKEY_set1_RSA(eprikey, sslPrivKey)) { 1123*99ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 1124*99ebb4caSwyllys privkey->keyalg = KMF_RSA; 1125*99ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 1126*99ebb4caSwyllys privkey->israw = FALSE; 1127*99ebb4caSwyllys privkey->keylabel = (char *)strdup(fullpath); 1128*99ebb4caSwyllys privkey->keyp = (void *)eprikey; 1129*99ebb4caSwyllys } 1130*99ebb4caSwyllys /* OpenSSL derives the public key from the private */ 1131*99ebb4caSwyllys if (pubkey != NULL && 1132*99ebb4caSwyllys EVP_PKEY_set1_RSA(epubkey, sslPrivKey)) { 1133*99ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 1134*99ebb4caSwyllys pubkey->keyalg = KMF_RSA; 1135*99ebb4caSwyllys pubkey->israw = FALSE; 1136*99ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 1137*99ebb4caSwyllys pubkey->keylabel = (char *)strdup(fullpath); 1138*99ebb4caSwyllys pubkey->keyp = (void *)epubkey; 1139*99ebb4caSwyllys } 1140*99ebb4caSwyllys } 1141*99ebb4caSwyllys } else if (params->keytype == KMF_DSA) { 1142*99ebb4caSwyllys sslDSAKey = DSA_new(); 1143*99ebb4caSwyllys if (sslDSAKey == NULL) { 1144*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1145*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1146*99ebb4caSwyllys } 1147*99ebb4caSwyllys 1148*99ebb4caSwyllys if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) == 1149*99ebb4caSwyllys NULL) { 1150*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1151*99ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 1152*99ebb4caSwyllys goto cleanup; 1153*99ebb4caSwyllys } 1154*99ebb4caSwyllys if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) == 1155*99ebb4caSwyllys NULL) { 1156*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1157*99ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 1158*99ebb4caSwyllys goto cleanup; 1159*99ebb4caSwyllys } 1160*99ebb4caSwyllys if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) == 1161*99ebb4caSwyllys NULL) { 1162*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1163*99ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 1164*99ebb4caSwyllys goto cleanup; 1165*99ebb4caSwyllys } 1166*99ebb4caSwyllys 1167*99ebb4caSwyllys if (!DSA_generate_key(sslDSAKey)) { 1168*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1169*99ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 1170*99ebb4caSwyllys goto cleanup; 1171*99ebb4caSwyllys } 1172*99ebb4caSwyllys 1173*99ebb4caSwyllys if (privkey != NULL) { 1174*99ebb4caSwyllys privkey->kstype = KMF_KEYSTORE_OPENSSL; 1175*99ebb4caSwyllys privkey->keyalg = KMF_DSA; 1176*99ebb4caSwyllys privkey->keyclass = KMF_ASYM_PRI; 1177*99ebb4caSwyllys privkey->israw = FALSE; 1178*99ebb4caSwyllys privkey->keylabel = (char *)strdup(fullpath); 1179*99ebb4caSwyllys if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { 1180*99ebb4caSwyllys privkey->keyp = (void *)eprikey; 1181*99ebb4caSwyllys } else { 1182*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1183*99ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 1184*99ebb4caSwyllys goto cleanup; 1185*99ebb4caSwyllys } 1186*99ebb4caSwyllys } 1187*99ebb4caSwyllys if (pubkey != NULL) { 1188*99ebb4caSwyllys DSA *dp = DSA_new(); 1189*99ebb4caSwyllys /* Make a copy for the public key */ 1190*99ebb4caSwyllys if (dp != NULL) { 1191*99ebb4caSwyllys if ((dp->p = BN_new()) == NULL) { 1192*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1193*99ebb4caSwyllys rv = KMF_ERR_MEMORY; 1194*99ebb4caSwyllys DSA_free(dp); 1195*99ebb4caSwyllys goto cleanup; 1196*99ebb4caSwyllys } 1197*99ebb4caSwyllys if ((dp->q = BN_new()) == NULL) { 1198*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1199*99ebb4caSwyllys rv = KMF_ERR_MEMORY; 1200*99ebb4caSwyllys BN_free(dp->p); 1201*99ebb4caSwyllys DSA_free(dp); 1202*99ebb4caSwyllys goto cleanup; 1203*99ebb4caSwyllys } 1204*99ebb4caSwyllys if ((dp->g = BN_new()) == NULL) { 1205*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1206*99ebb4caSwyllys rv = KMF_ERR_MEMORY; 1207*99ebb4caSwyllys BN_free(dp->q); 1208*99ebb4caSwyllys BN_free(dp->p); 1209*99ebb4caSwyllys DSA_free(dp); 1210*99ebb4caSwyllys goto cleanup; 1211*99ebb4caSwyllys } 1212*99ebb4caSwyllys if ((dp->pub_key = BN_new()) == NULL) { 1213*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1214*99ebb4caSwyllys rv = KMF_ERR_MEMORY; 1215*99ebb4caSwyllys BN_free(dp->q); 1216*99ebb4caSwyllys BN_free(dp->p); 1217*99ebb4caSwyllys BN_free(dp->g); 1218*99ebb4caSwyllys DSA_free(dp); 1219*99ebb4caSwyllys goto cleanup; 1220*99ebb4caSwyllys } 1221*99ebb4caSwyllys (void) BN_copy(dp->p, sslDSAKey->p); 1222*99ebb4caSwyllys (void) BN_copy(dp->q, sslDSAKey->q); 1223*99ebb4caSwyllys (void) BN_copy(dp->g, sslDSAKey->g); 1224*99ebb4caSwyllys (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); 1225*99ebb4caSwyllys 1226*99ebb4caSwyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL; 1227*99ebb4caSwyllys pubkey->keyalg = KMF_DSA; 1228*99ebb4caSwyllys pubkey->keyclass = KMF_ASYM_PUB; 1229*99ebb4caSwyllys pubkey->israw = FALSE; 1230*99ebb4caSwyllys pubkey->keylabel = (char *)strdup(fullpath); 1231*99ebb4caSwyllys 1232*99ebb4caSwyllys if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { 1233*99ebb4caSwyllys pubkey->keyp = (void *)epubkey; 1234*99ebb4caSwyllys } else { 1235*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1236*99ebb4caSwyllys rv = KMF_ERR_KEYGEN_FAILED; 1237*99ebb4caSwyllys goto cleanup; 1238*99ebb4caSwyllys } 1239*99ebb4caSwyllys } 1240*99ebb4caSwyllys } 1241*99ebb4caSwyllys } 1242*99ebb4caSwyllys 1243*99ebb4caSwyllys if (rv != KMF_OK) { 1244*99ebb4caSwyllys goto cleanup; 1245*99ebb4caSwyllys } 1246*99ebb4caSwyllys 1247*99ebb4caSwyllys /* Store the private key to the keyfile */ 1248*99ebb4caSwyllys format = params->sslparms.format; 1249*99ebb4caSwyllys out = BIO_new_file(fullpath, "wb"); 1250*99ebb4caSwyllys if (out == NULL) { 1251*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1252*99ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 1253*99ebb4caSwyllys goto cleanup; 1254*99ebb4caSwyllys } 1255*99ebb4caSwyllys rv = ssl_write_private_key(kmfh, format, out, ¶ms->cred, eprikey); 1256*99ebb4caSwyllys 1257*99ebb4caSwyllys cleanup: 1258*99ebb4caSwyllys if (rv != KMF_OK) { 1259*99ebb4caSwyllys if (eprikey != NULL) 1260*99ebb4caSwyllys EVP_PKEY_free(eprikey); 1261*99ebb4caSwyllys 1262*99ebb4caSwyllys if (epubkey != NULL) 1263*99ebb4caSwyllys EVP_PKEY_free(epubkey); 1264*99ebb4caSwyllys 1265*99ebb4caSwyllys if (pubkey->keylabel) { 1266*99ebb4caSwyllys free(pubkey->keylabel); 1267*99ebb4caSwyllys pubkey->keylabel = NULL; 1268*99ebb4caSwyllys } 1269*99ebb4caSwyllys 1270*99ebb4caSwyllys if (privkey->keylabel) { 1271*99ebb4caSwyllys free(privkey->keylabel); 1272*99ebb4caSwyllys privkey->keylabel = NULL; 1273*99ebb4caSwyllys } 1274*99ebb4caSwyllys 1275*99ebb4caSwyllys pubkey->keyp = NULL; 1276*99ebb4caSwyllys privkey->keyp = NULL; 1277*99ebb4caSwyllys } 1278*99ebb4caSwyllys 1279*99ebb4caSwyllys if (sslPrivKey) 1280*99ebb4caSwyllys RSA_free(sslPrivKey); 1281*99ebb4caSwyllys 1282*99ebb4caSwyllys if (sslDSAKey) 1283*99ebb4caSwyllys DSA_free(sslDSAKey); 1284*99ebb4caSwyllys 1285*99ebb4caSwyllys 1286*99ebb4caSwyllys if (out != NULL) 1287*99ebb4caSwyllys (void) BIO_free(out); 1288*99ebb4caSwyllys 1289*99ebb4caSwyllys if (fullpath) 1290*99ebb4caSwyllys free(fullpath); 1291*99ebb4caSwyllys 1292*99ebb4caSwyllys /* Protect the file by making it read-only */ 1293*99ebb4caSwyllys if (rv == KMF_OK) { 1294*99ebb4caSwyllys (void) chmod(fullpath, 0400); 1295*99ebb4caSwyllys } 1296*99ebb4caSwyllys return (rv); 1297*99ebb4caSwyllys } 1298*99ebb4caSwyllys 1299*99ebb4caSwyllys KMF_RETURN 1300*99ebb4caSwyllys OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1301*99ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output) 1302*99ebb4caSwyllys { 1303*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1304*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1305*99ebb4caSwyllys KMF_ALGORITHM_INDEX AlgId; 1306*99ebb4caSwyllys EVP_MD_CTX ctx; 1307*99ebb4caSwyllys const EVP_MD *md; 1308*99ebb4caSwyllys if (key == NULL || AlgOID == NULL || 1309*99ebb4caSwyllys tobesigned == NULL || output == NULL || 1310*99ebb4caSwyllys tobesigned->Data == NULL || 1311*99ebb4caSwyllys output->Data == NULL) 1312*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1313*99ebb4caSwyllys 1314*99ebb4caSwyllys /* Map the OID to an OpenSSL algorithm */ 1315*99ebb4caSwyllys AlgId = X509_AlgorithmOidToAlgId(AlgOID); 1316*99ebb4caSwyllys if (AlgId == KMF_ALGID_NONE) 1317*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1318*99ebb4caSwyllys 1319*99ebb4caSwyllys if (key->keyalg == KMF_RSA) { 1320*99ebb4caSwyllys EVP_PKEY *pkey = (EVP_PKEY *)key->keyp; 1321*99ebb4caSwyllys uchar_t *p; 1322*99ebb4caSwyllys uint32_t len; 1323*99ebb4caSwyllys if (AlgId == KMF_ALGID_MD5WithRSA) 1324*99ebb4caSwyllys md = EVP_md5(); 1325*99ebb4caSwyllys else if (AlgId == KMF_ALGID_MD2WithRSA) 1326*99ebb4caSwyllys md = EVP_md2(); 1327*99ebb4caSwyllys else if (AlgId == KMF_ALGID_SHA1WithRSA) 1328*99ebb4caSwyllys md = EVP_sha1(); 1329*99ebb4caSwyllys else 1330*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1331*99ebb4caSwyllys 1332*99ebb4caSwyllys if (md == NULL) { 1333*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1334*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1335*99ebb4caSwyllys } 1336*99ebb4caSwyllys 1337*99ebb4caSwyllys (void) EVP_MD_CTX_init(&ctx); 1338*99ebb4caSwyllys (void) EVP_SignInit_ex(&ctx, md, NULL); 1339*99ebb4caSwyllys (void) EVP_SignUpdate(&ctx, tobesigned->Data, 1340*99ebb4caSwyllys (uint32_t)tobesigned->Length); 1341*99ebb4caSwyllys len = (uint32_t)output->Length; 1342*99ebb4caSwyllys p = output->Data; 1343*99ebb4caSwyllys if (!EVP_SignFinal(&ctx, p, &len, pkey)) { 1344*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1345*99ebb4caSwyllys output->Length = 0; 1346*99ebb4caSwyllys } 1347*99ebb4caSwyllys output->Length = len; 1348*99ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 1349*99ebb4caSwyllys } else if (key->keyalg == KMF_DSA) { 1350*99ebb4caSwyllys DSA *dsa = EVP_PKEY_get1_DSA(key->keyp); 1351*99ebb4caSwyllys 1352*99ebb4caSwyllys uchar_t hash[EVP_MAX_MD_SIZE]; 1353*99ebb4caSwyllys uint32_t hashlen; 1354*99ebb4caSwyllys DSA_SIG *dsasig; 1355*99ebb4caSwyllys 1356*99ebb4caSwyllys /* 1357*99ebb4caSwyllys * OpenSSL EVP_Sign operation automatically converts to 1358*99ebb4caSwyllys * ASN.1 output so we do the operations separately so we 1359*99ebb4caSwyllys * are assured of NOT getting ASN.1 output returned. 1360*99ebb4caSwyllys * KMF does not want ASN.1 encoded results because 1361*99ebb4caSwyllys * not all mechanisms return ASN.1 encodings (PKCS#11 1362*99ebb4caSwyllys * and NSS return raw signature data). 1363*99ebb4caSwyllys */ 1364*99ebb4caSwyllys md = EVP_sha1(); 1365*99ebb4caSwyllys EVP_MD_CTX_init(&ctx); 1366*99ebb4caSwyllys (void) EVP_DigestInit_ex(&ctx, md, NULL); 1367*99ebb4caSwyllys (void) EVP_DigestUpdate(&ctx, tobesigned->Data, 1368*99ebb4caSwyllys tobesigned->Length); 1369*99ebb4caSwyllys (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen); 1370*99ebb4caSwyllys (void) EVP_MD_CTX_cleanup(&ctx); 1371*99ebb4caSwyllys 1372*99ebb4caSwyllys dsasig = DSA_do_sign(hash, hashlen, dsa); 1373*99ebb4caSwyllys if (dsasig != NULL) { 1374*99ebb4caSwyllys int i; 1375*99ebb4caSwyllys output->Length = i = BN_bn2bin(dsasig->r, output->Data); 1376*99ebb4caSwyllys output->Length += BN_bn2bin(dsasig->s, 1377*99ebb4caSwyllys &output->Data[i]); 1378*99ebb4caSwyllys DSA_SIG_free(dsasig); 1379*99ebb4caSwyllys } else { 1380*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1381*99ebb4caSwyllys } 1382*99ebb4caSwyllys } else { 1383*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1384*99ebb4caSwyllys } 1385*99ebb4caSwyllys cleanup: 1386*99ebb4caSwyllys return (ret); 1387*99ebb4caSwyllys } 1388*99ebb4caSwyllys 1389*99ebb4caSwyllys KMF_RETURN 1390*99ebb4caSwyllys /*ARGSUSED*/ 1391*99ebb4caSwyllys OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, 1392*99ebb4caSwyllys KMF_KEY_HANDLE *key, boolean_t destroy) 1393*99ebb4caSwyllys { 1394*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 1395*99ebb4caSwyllys if (key == NULL || key->keyp == NULL) 1396*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1397*99ebb4caSwyllys 1398*99ebb4caSwyllys if (key->keyclass != KMF_ASYM_PUB && 1399*99ebb4caSwyllys key->keyclass != KMF_ASYM_PRI && 1400*99ebb4caSwyllys key->keyclass != KMF_SYMMETRIC) 1401*99ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 1402*99ebb4caSwyllys 1403*99ebb4caSwyllys if (key->keyclass == KMF_SYMMETRIC) { 1404*99ebb4caSwyllys KMF_FreeRawSymKey((KMF_RAW_SYM_KEY *)key->keyp); 1405*99ebb4caSwyllys key->keyp = NULL; 1406*99ebb4caSwyllys } else { 1407*99ebb4caSwyllys if (key->keyp != NULL) { 1408*99ebb4caSwyllys EVP_PKEY_free(key->keyp); 1409*99ebb4caSwyllys key->keyp = NULL; 1410*99ebb4caSwyllys } 1411*99ebb4caSwyllys } 1412*99ebb4caSwyllys 1413*99ebb4caSwyllys if (key->keylabel != NULL) { 1414*99ebb4caSwyllys EVP_PKEY *pkey = NULL; 1415*99ebb4caSwyllys /* If the file exists, make sure it is a proper key. */ 1416*99ebb4caSwyllys pkey = openssl_load_key(handle, key->keylabel); 1417*99ebb4caSwyllys if (pkey == NULL) { 1418*99ebb4caSwyllys free(key->keylabel); 1419*99ebb4caSwyllys key->keylabel = NULL; 1420*99ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 1421*99ebb4caSwyllys } 1422*99ebb4caSwyllys EVP_PKEY_free(pkey); 1423*99ebb4caSwyllys 1424*99ebb4caSwyllys if (destroy) { 1425*99ebb4caSwyllys if (unlink(key->keylabel) != 0) { 1426*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1427*99ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 1428*99ebb4caSwyllys rv = KMF_ERR_INTERNAL; 1429*99ebb4caSwyllys } 1430*99ebb4caSwyllys } 1431*99ebb4caSwyllys if (key->keylabel != NULL) { 1432*99ebb4caSwyllys free(key->keylabel); 1433*99ebb4caSwyllys key->keylabel = NULL; 1434*99ebb4caSwyllys } 1435*99ebb4caSwyllys } 1436*99ebb4caSwyllys return (rv); 1437*99ebb4caSwyllys } 1438*99ebb4caSwyllys 1439*99ebb4caSwyllys KMF_RETURN 1440*99ebb4caSwyllys OpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) 1441*99ebb4caSwyllys { 1442*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1443*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1444*99ebb4caSwyllys X509_CRL *xcrl = NULL; 1445*99ebb4caSwyllys X509 *xcert = NULL; 1446*99ebb4caSwyllys EVP_PKEY *pkey; 1447*99ebb4caSwyllys KMF_ENCODE_FORMAT format; 1448*99ebb4caSwyllys BIO *in = NULL, *out = NULL; 1449*99ebb4caSwyllys int openssl_ret = 0; 1450*99ebb4caSwyllys char *outcrlfile = NULL; 1451*99ebb4caSwyllys KMF_ENCODE_FORMAT outformat; 1452*99ebb4caSwyllys 1453*99ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL) { 1454*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1455*99ebb4caSwyllys } 1456*99ebb4caSwyllys 1457*99ebb4caSwyllys if (params->sslparms.crl_check == B_TRUE && 1458*99ebb4caSwyllys params->sslparms.certfile == NULL) { 1459*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1460*99ebb4caSwyllys } 1461*99ebb4caSwyllys 1462*99ebb4caSwyllys outcrlfile = get_fullpath(params->sslparms.dirpath, 1463*99ebb4caSwyllys params->sslparms.outcrlfile); 1464*99ebb4caSwyllys 1465*99ebb4caSwyllys if (outcrlfile == NULL) 1466*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1467*99ebb4caSwyllys 1468*99ebb4caSwyllys if (isdir(outcrlfile)) { 1469*99ebb4caSwyllys free(outcrlfile); 1470*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1471*99ebb4caSwyllys } 1472*99ebb4caSwyllys 1473*99ebb4caSwyllys ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); 1474*99ebb4caSwyllys if (ret != KMF_OK) { 1475*99ebb4caSwyllys free(outcrlfile); 1476*99ebb4caSwyllys return (ret); 1477*99ebb4caSwyllys } 1478*99ebb4caSwyllys 1479*99ebb4caSwyllys in = BIO_new_file(params->sslparms.crlfile, "rb"); 1480*99ebb4caSwyllys if (in == NULL) { 1481*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1482*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 1483*99ebb4caSwyllys goto end; 1484*99ebb4caSwyllys } 1485*99ebb4caSwyllys 1486*99ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 1487*99ebb4caSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 1488*99ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 1489*99ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 1490*99ebb4caSwyllys } 1491*99ebb4caSwyllys 1492*99ebb4caSwyllys if (xcrl == NULL) { 1493*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1494*99ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 1495*99ebb4caSwyllys goto end; 1496*99ebb4caSwyllys } 1497*99ebb4caSwyllys 1498*99ebb4caSwyllys /* If bypasscheck is specified, no need to verify. */ 1499*99ebb4caSwyllys if (params->sslparms.crl_check == B_FALSE) { 1500*99ebb4caSwyllys goto output; 1501*99ebb4caSwyllys } 1502*99ebb4caSwyllys 1503*99ebb4caSwyllys ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); 1504*99ebb4caSwyllys if (ret != KMF_OK) 1505*99ebb4caSwyllys goto end; 1506*99ebb4caSwyllys 1507*99ebb4caSwyllys /* Read in the CA cert file and convert to X509 */ 1508*99ebb4caSwyllys if (BIO_read_filename(in, params->sslparms.certfile) <= 0) { 1509*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1510*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 1511*99ebb4caSwyllys goto end; 1512*99ebb4caSwyllys } 1513*99ebb4caSwyllys 1514*99ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 1515*99ebb4caSwyllys xcert = d2i_X509_bio(in, NULL); 1516*99ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 1517*99ebb4caSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 1518*99ebb4caSwyllys } else { 1519*99ebb4caSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 1520*99ebb4caSwyllys goto end; 1521*99ebb4caSwyllys } 1522*99ebb4caSwyllys 1523*99ebb4caSwyllys if (xcert == NULL) { 1524*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1525*99ebb4caSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 1526*99ebb4caSwyllys goto end; 1527*99ebb4caSwyllys } 1528*99ebb4caSwyllys /* Now get the public key from the CA cert */ 1529*99ebb4caSwyllys pkey = X509_get_pubkey(xcert); 1530*99ebb4caSwyllys if (!pkey) { 1531*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1532*99ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 1533*99ebb4caSwyllys goto end; 1534*99ebb4caSwyllys } 1535*99ebb4caSwyllys 1536*99ebb4caSwyllys /* Verify the CRL with the CA's public key */ 1537*99ebb4caSwyllys openssl_ret = X509_CRL_verify(xcrl, pkey); 1538*99ebb4caSwyllys EVP_PKEY_free(pkey); 1539*99ebb4caSwyllys if (openssl_ret > 0) { 1540*99ebb4caSwyllys ret = KMF_OK; /* verify succeed */ 1541*99ebb4caSwyllys } else { 1542*99ebb4caSwyllys SET_ERROR(kmfh, openssl_ret); 1543*99ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 1544*99ebb4caSwyllys } 1545*99ebb4caSwyllys 1546*99ebb4caSwyllys output: 1547*99ebb4caSwyllys outformat = params->sslparms.format; 1548*99ebb4caSwyllys 1549*99ebb4caSwyllys out = BIO_new_file(outcrlfile, "wb"); 1550*99ebb4caSwyllys if (out == NULL) { 1551*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1552*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 1553*99ebb4caSwyllys goto end; 1554*99ebb4caSwyllys } 1555*99ebb4caSwyllys 1556*99ebb4caSwyllys if (outformat == KMF_FORMAT_ASN1) { 1557*99ebb4caSwyllys openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); 1558*99ebb4caSwyllys } else if (outformat == KMF_FORMAT_PEM) { 1559*99ebb4caSwyllys openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); 1560*99ebb4caSwyllys } else { 1561*99ebb4caSwyllys ret = KMF_ERR_BAD_PARAMETER; 1562*99ebb4caSwyllys goto end; 1563*99ebb4caSwyllys } 1564*99ebb4caSwyllys 1565*99ebb4caSwyllys if (openssl_ret <= 0) { 1566*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1567*99ebb4caSwyllys ret = KMF_ERR_WRITE_FILE; 1568*99ebb4caSwyllys } else { 1569*99ebb4caSwyllys ret = KMF_OK; 1570*99ebb4caSwyllys } 1571*99ebb4caSwyllys 1572*99ebb4caSwyllys end: 1573*99ebb4caSwyllys if (xcrl != NULL) 1574*99ebb4caSwyllys X509_CRL_free(xcrl); 1575*99ebb4caSwyllys 1576*99ebb4caSwyllys if (xcert != NULL) 1577*99ebb4caSwyllys X509_free(xcert); 1578*99ebb4caSwyllys 1579*99ebb4caSwyllys if (in != NULL) 1580*99ebb4caSwyllys (void) BIO_free(in); 1581*99ebb4caSwyllys 1582*99ebb4caSwyllys if (out != NULL) 1583*99ebb4caSwyllys (void) BIO_free(out); 1584*99ebb4caSwyllys 1585*99ebb4caSwyllys if (outcrlfile != NULL) 1586*99ebb4caSwyllys free(outcrlfile); 1587*99ebb4caSwyllys 1588*99ebb4caSwyllys return (ret); 1589*99ebb4caSwyllys } 1590*99ebb4caSwyllys 1591*99ebb4caSwyllys KMF_RETURN 1592*99ebb4caSwyllys OpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, 1593*99ebb4caSwyllys char **crldata) 1594*99ebb4caSwyllys { 1595*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1596*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1597*99ebb4caSwyllys X509_CRL *x = NULL; 1598*99ebb4caSwyllys KMF_ENCODE_FORMAT format; 1599*99ebb4caSwyllys char *crlfile = NULL; 1600*99ebb4caSwyllys BIO *in = NULL; 1601*99ebb4caSwyllys BIO *mem = NULL; 1602*99ebb4caSwyllys long len; 1603*99ebb4caSwyllys char *memptr; 1604*99ebb4caSwyllys char *data = NULL; 1605*99ebb4caSwyllys 1606*99ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL) { 1607*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1608*99ebb4caSwyllys } 1609*99ebb4caSwyllys 1610*99ebb4caSwyllys crlfile = get_fullpath(params->sslparms.dirpath, 1611*99ebb4caSwyllys params->sslparms.crlfile); 1612*99ebb4caSwyllys 1613*99ebb4caSwyllys if (crlfile == NULL) 1614*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1615*99ebb4caSwyllys 1616*99ebb4caSwyllys if (isdir(crlfile)) { 1617*99ebb4caSwyllys free(crlfile); 1618*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1619*99ebb4caSwyllys } 1620*99ebb4caSwyllys 1621*99ebb4caSwyllys ret = KMF_IsCRLFile(handle, crlfile, &format); 1622*99ebb4caSwyllys if (ret != KMF_OK) { 1623*99ebb4caSwyllys free(crlfile); 1624*99ebb4caSwyllys return (ret); 1625*99ebb4caSwyllys } 1626*99ebb4caSwyllys 1627*99ebb4caSwyllys if (bio_err == NULL) 1628*99ebb4caSwyllys bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 1629*99ebb4caSwyllys 1630*99ebb4caSwyllys in = BIO_new_file(crlfile, "rb"); 1631*99ebb4caSwyllys if (in == NULL) { 1632*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1633*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 1634*99ebb4caSwyllys goto end; 1635*99ebb4caSwyllys } 1636*99ebb4caSwyllys 1637*99ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 1638*99ebb4caSwyllys x = d2i_X509_CRL_bio(in, NULL); 1639*99ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 1640*99ebb4caSwyllys x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 1641*99ebb4caSwyllys } 1642*99ebb4caSwyllys 1643*99ebb4caSwyllys if (x == NULL) { /* should not happen */ 1644*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1645*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 1646*99ebb4caSwyllys goto end; 1647*99ebb4caSwyllys } 1648*99ebb4caSwyllys 1649*99ebb4caSwyllys mem = BIO_new(BIO_s_mem()); 1650*99ebb4caSwyllys if (mem == NULL) { 1651*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1652*99ebb4caSwyllys ret = KMF_ERR_MEMORY; 1653*99ebb4caSwyllys goto end; 1654*99ebb4caSwyllys } 1655*99ebb4caSwyllys 1656*99ebb4caSwyllys (void) X509_CRL_print(mem, x); 1657*99ebb4caSwyllys len = BIO_get_mem_data(mem, &memptr); 1658*99ebb4caSwyllys if (len <= 0) { 1659*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1660*99ebb4caSwyllys ret = KMF_ERR_MEMORY; 1661*99ebb4caSwyllys goto end; 1662*99ebb4caSwyllys } 1663*99ebb4caSwyllys 1664*99ebb4caSwyllys data = malloc(len + 1); 1665*99ebb4caSwyllys if (data == NULL) { 1666*99ebb4caSwyllys ret = KMF_ERR_MEMORY; 1667*99ebb4caSwyllys goto end; 1668*99ebb4caSwyllys } 1669*99ebb4caSwyllys 1670*99ebb4caSwyllys (void) memcpy(data, memptr, len); 1671*99ebb4caSwyllys data[len] = '\0'; 1672*99ebb4caSwyllys *crldata = data; 1673*99ebb4caSwyllys 1674*99ebb4caSwyllys end: 1675*99ebb4caSwyllys if (x != NULL) 1676*99ebb4caSwyllys X509_CRL_free(x); 1677*99ebb4caSwyllys 1678*99ebb4caSwyllys if (crlfile != NULL) 1679*99ebb4caSwyllys free(crlfile); 1680*99ebb4caSwyllys 1681*99ebb4caSwyllys if (in != NULL) 1682*99ebb4caSwyllys (void) BIO_free(in); 1683*99ebb4caSwyllys 1684*99ebb4caSwyllys if (mem != NULL) 1685*99ebb4caSwyllys (void) BIO_free(mem); 1686*99ebb4caSwyllys 1687*99ebb4caSwyllys return (ret); 1688*99ebb4caSwyllys } 1689*99ebb4caSwyllys 1690*99ebb4caSwyllys KMF_RETURN 1691*99ebb4caSwyllys OpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) 1692*99ebb4caSwyllys { 1693*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1694*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1695*99ebb4caSwyllys KMF_ENCODE_FORMAT format; 1696*99ebb4caSwyllys char *crlfile = NULL; 1697*99ebb4caSwyllys BIO *in = NULL; 1698*99ebb4caSwyllys 1699*99ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL) { 1700*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1701*99ebb4caSwyllys } 1702*99ebb4caSwyllys 1703*99ebb4caSwyllys crlfile = get_fullpath(params->sslparms.dirpath, 1704*99ebb4caSwyllys params->sslparms.crlfile); 1705*99ebb4caSwyllys 1706*99ebb4caSwyllys if (crlfile == NULL) 1707*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1708*99ebb4caSwyllys 1709*99ebb4caSwyllys if (isdir(crlfile)) { 1710*99ebb4caSwyllys ret = KMF_ERR_BAD_PARAMETER; 1711*99ebb4caSwyllys goto end; 1712*99ebb4caSwyllys } 1713*99ebb4caSwyllys 1714*99ebb4caSwyllys ret = KMF_IsCRLFile(handle, crlfile, &format); 1715*99ebb4caSwyllys if (ret != KMF_OK) 1716*99ebb4caSwyllys goto end; 1717*99ebb4caSwyllys 1718*99ebb4caSwyllys if (unlink(crlfile) != 0) { 1719*99ebb4caSwyllys SET_SYS_ERROR(kmfh, errno); 1720*99ebb4caSwyllys ret = KMF_ERR_INTERNAL; 1721*99ebb4caSwyllys goto end; 1722*99ebb4caSwyllys } 1723*99ebb4caSwyllys 1724*99ebb4caSwyllys end: 1725*99ebb4caSwyllys if (in != NULL) 1726*99ebb4caSwyllys (void) BIO_free(in); 1727*99ebb4caSwyllys if (crlfile != NULL) 1728*99ebb4caSwyllys free(crlfile); 1729*99ebb4caSwyllys 1730*99ebb4caSwyllys return (ret); 1731*99ebb4caSwyllys } 1732*99ebb4caSwyllys 1733*99ebb4caSwyllys 1734*99ebb4caSwyllys KMF_RETURN 1735*99ebb4caSwyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) 1736*99ebb4caSwyllys { 1737*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1738*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1739*99ebb4caSwyllys KMF_ENCODE_FORMAT format; 1740*99ebb4caSwyllys BIO *in = NULL; 1741*99ebb4caSwyllys X509 *xcert = NULL; 1742*99ebb4caSwyllys X509_CRL *xcrl = NULL; 1743*99ebb4caSwyllys STACK_OF(X509_REVOKED) *revoke_stack = NULL; 1744*99ebb4caSwyllys X509_REVOKED *revoke; 1745*99ebb4caSwyllys int i; 1746*99ebb4caSwyllys 1747*99ebb4caSwyllys if (params == NULL || params->sslparms.crlfile == NULL || 1748*99ebb4caSwyllys params->sslparms.certfile == NULL) { 1749*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1750*99ebb4caSwyllys } 1751*99ebb4caSwyllys 1752*99ebb4caSwyllys ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format); 1753*99ebb4caSwyllys if (ret != KMF_OK) 1754*99ebb4caSwyllys return (ret); 1755*99ebb4caSwyllys 1756*99ebb4caSwyllys /* Read the CRL file and load it into a X509_CRL structure */ 1757*99ebb4caSwyllys in = BIO_new_file(params->sslparms.crlfile, "rb"); 1758*99ebb4caSwyllys if (in == NULL) { 1759*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1760*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 1761*99ebb4caSwyllys goto end; 1762*99ebb4caSwyllys } 1763*99ebb4caSwyllys 1764*99ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 1765*99ebb4caSwyllys xcrl = d2i_X509_CRL_bio(in, NULL); 1766*99ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 1767*99ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 1768*99ebb4caSwyllys } 1769*99ebb4caSwyllys 1770*99ebb4caSwyllys if (xcrl == NULL) { 1771*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1772*99ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 1773*99ebb4caSwyllys goto end; 1774*99ebb4caSwyllys } 1775*99ebb4caSwyllys (void) BIO_free(in); 1776*99ebb4caSwyllys 1777*99ebb4caSwyllys /* Read the Certificate file and load it into a X509 structure */ 1778*99ebb4caSwyllys ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format); 1779*99ebb4caSwyllys if (ret != KMF_OK) 1780*99ebb4caSwyllys goto end; 1781*99ebb4caSwyllys 1782*99ebb4caSwyllys in = BIO_new_file(params->sslparms.certfile, "rb"); 1783*99ebb4caSwyllys if (in == NULL) { 1784*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1785*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 1786*99ebb4caSwyllys goto end; 1787*99ebb4caSwyllys } 1788*99ebb4caSwyllys 1789*99ebb4caSwyllys if (format == KMF_FORMAT_ASN1) { 1790*99ebb4caSwyllys xcert = d2i_X509_bio(in, NULL); 1791*99ebb4caSwyllys } else if (format == KMF_FORMAT_PEM) { 1792*99ebb4caSwyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 1793*99ebb4caSwyllys } 1794*99ebb4caSwyllys 1795*99ebb4caSwyllys if (xcert == NULL) { 1796*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1797*99ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 1798*99ebb4caSwyllys goto end; 1799*99ebb4caSwyllys } 1800*99ebb4caSwyllys 1801*99ebb4caSwyllys /* Check if the certificate and the CRL have same issuer */ 1802*99ebb4caSwyllys if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { 1803*99ebb4caSwyllys ret = KMF_ERR_ISSUER; 1804*99ebb4caSwyllys goto end; 1805*99ebb4caSwyllys } 1806*99ebb4caSwyllys 1807*99ebb4caSwyllys /* Check to see if the certificate serial number is revoked */ 1808*99ebb4caSwyllys revoke_stack = X509_CRL_get_REVOKED(xcrl); 1809*99ebb4caSwyllys if (sk_X509_REVOKED_num(revoke_stack) <= 0) { 1810*99ebb4caSwyllys /* No revoked certificates in the CRL file */ 1811*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1812*99ebb4caSwyllys ret = KMF_ERR_EMPTY_CRL; 1813*99ebb4caSwyllys goto end; 1814*99ebb4caSwyllys } 1815*99ebb4caSwyllys 1816*99ebb4caSwyllys for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { 1817*99ebb4caSwyllys /*LINTED*/ 1818*99ebb4caSwyllys revoke = sk_X509_REVOKED_value(revoke_stack, i); 1819*99ebb4caSwyllys if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, 1820*99ebb4caSwyllys revoke->serialNumber) == 0) { 1821*99ebb4caSwyllys break; 1822*99ebb4caSwyllys } 1823*99ebb4caSwyllys } 1824*99ebb4caSwyllys 1825*99ebb4caSwyllys if (i < sk_X509_REVOKED_num(revoke_stack)) { 1826*99ebb4caSwyllys ret = KMF_OK; 1827*99ebb4caSwyllys } else { 1828*99ebb4caSwyllys ret = KMF_ERR_NOT_REVOKED; 1829*99ebb4caSwyllys } 1830*99ebb4caSwyllys 1831*99ebb4caSwyllys end: 1832*99ebb4caSwyllys if (in != NULL) 1833*99ebb4caSwyllys (void) BIO_free(in); 1834*99ebb4caSwyllys if (xcrl != NULL) 1835*99ebb4caSwyllys X509_CRL_free(xcrl); 1836*99ebb4caSwyllys if (xcert != NULL) 1837*99ebb4caSwyllys X509_free(xcert); 1838*99ebb4caSwyllys 1839*99ebb4caSwyllys return (ret); 1840*99ebb4caSwyllys } 1841*99ebb4caSwyllys 1842*99ebb4caSwyllys KMF_RETURN 1843*99ebb4caSwyllys OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 1844*99ebb4caSwyllys { 1845*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1846*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1847*99ebb4caSwyllys char str[256]; /* OpenSSL needs at least 120 byte buffer */ 1848*99ebb4caSwyllys 1849*99ebb4caSwyllys ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str)); 1850*99ebb4caSwyllys if (strlen(str)) { 1851*99ebb4caSwyllys *msgstr = (char *)strdup(str); 1852*99ebb4caSwyllys if ((*msgstr) == NULL) 1853*99ebb4caSwyllys ret = KMF_ERR_MEMORY; 1854*99ebb4caSwyllys } else { 1855*99ebb4caSwyllys *msgstr = NULL; 1856*99ebb4caSwyllys } 1857*99ebb4caSwyllys 1858*99ebb4caSwyllys return (ret); 1859*99ebb4caSwyllys } 1860*99ebb4caSwyllys 1861*99ebb4caSwyllys static int 1862*99ebb4caSwyllys ext2NID(int kmfext) 1863*99ebb4caSwyllys { 1864*99ebb4caSwyllys switch (kmfext) { 1865*99ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 1866*99ebb4caSwyllys return (NID_key_usage); 1867*99ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 1868*99ebb4caSwyllys return (NID_private_key_usage_period); 1869*99ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 1870*99ebb4caSwyllys return (NID_certificate_policies); 1871*99ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 1872*99ebb4caSwyllys return (NID_subject_alt_name); 1873*99ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 1874*99ebb4caSwyllys return (NID_issuer_alt_name); 1875*99ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 1876*99ebb4caSwyllys return (NID_basic_constraints); 1877*99ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 1878*99ebb4caSwyllys return (NID_ext_key_usage); 1879*99ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 1880*99ebb4caSwyllys return (NID_authority_key_identifier); 1881*99ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 1882*99ebb4caSwyllys return (NID_crl_distribution_points); 1883*99ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 1884*99ebb4caSwyllys return (NID_subject_key_identifier); 1885*99ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 1886*99ebb4caSwyllys return (OBJ_sn2nid("policyMappings")); 1887*99ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 1888*99ebb4caSwyllys return (OBJ_sn2nid("nameConstraints")); 1889*99ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 1890*99ebb4caSwyllys return (OBJ_sn2nid("policyConstraints")); 1891*99ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 1892*99ebb4caSwyllys return (OBJ_sn2nid("inhibitAnyPolicy")); 1893*99ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 1894*99ebb4caSwyllys return (OBJ_sn2nid("freshestCRL")); 1895*99ebb4caSwyllys default: 1896*99ebb4caSwyllys return (NID_undef); 1897*99ebb4caSwyllys } 1898*99ebb4caSwyllys } 1899*99ebb4caSwyllys 1900*99ebb4caSwyllys KMF_RETURN 1901*99ebb4caSwyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, 1902*99ebb4caSwyllys KMF_PRINTABLE_ITEM flag, char *resultStr) 1903*99ebb4caSwyllys { 1904*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1905*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1906*99ebb4caSwyllys X509 *xcert = NULL; 1907*99ebb4caSwyllys unsigned char *outbuf = NULL; 1908*99ebb4caSwyllys unsigned char *outbuf_p; 1909*99ebb4caSwyllys char *tmpstr = NULL; 1910*99ebb4caSwyllys int j; 1911*99ebb4caSwyllys int ext_index, nid, len; 1912*99ebb4caSwyllys BIO *mem = NULL; 1913*99ebb4caSwyllys STACK *emlst = NULL; 1914*99ebb4caSwyllys X509_EXTENSION *ex; 1915*99ebb4caSwyllys X509_CINF *ci; 1916*99ebb4caSwyllys 1917*99ebb4caSwyllys if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) { 1918*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1919*99ebb4caSwyllys } 1920*99ebb4caSwyllys 1921*99ebb4caSwyllys /* copy cert data to outbuf */ 1922*99ebb4caSwyllys outbuf = malloc(pcert->Length); 1923*99ebb4caSwyllys if (outbuf == NULL) { 1924*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1925*99ebb4caSwyllys } 1926*99ebb4caSwyllys (void) memcpy(outbuf, pcert->Data, pcert->Length); 1927*99ebb4caSwyllys 1928*99ebb4caSwyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 1929*99ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length); 1930*99ebb4caSwyllys if (xcert == NULL) { 1931*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1932*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1933*99ebb4caSwyllys goto out; 1934*99ebb4caSwyllys } 1935*99ebb4caSwyllys 1936*99ebb4caSwyllys mem = BIO_new(BIO_s_mem()); 1937*99ebb4caSwyllys if (mem == NULL) { 1938*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1939*99ebb4caSwyllys ret = KMF_ERR_MEMORY; 1940*99ebb4caSwyllys goto out; 1941*99ebb4caSwyllys } 1942*99ebb4caSwyllys 1943*99ebb4caSwyllys switch (flag) { 1944*99ebb4caSwyllys case KMF_CERT_ISSUER: 1945*99ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0, 1946*99ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 1947*99ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 1948*99ebb4caSwyllys break; 1949*99ebb4caSwyllys 1950*99ebb4caSwyllys case KMF_CERT_SUBJECT: 1951*99ebb4caSwyllys (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0, 1952*99ebb4caSwyllys XN_FLAG_SEP_CPLUS_SPC); 1953*99ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 1954*99ebb4caSwyllys break; 1955*99ebb4caSwyllys 1956*99ebb4caSwyllys case KMF_CERT_VERSION: 1957*99ebb4caSwyllys tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version); 1958*99ebb4caSwyllys (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN); 1959*99ebb4caSwyllys OPENSSL_free(tmpstr); 1960*99ebb4caSwyllys len = strlen(resultStr); 1961*99ebb4caSwyllys break; 1962*99ebb4caSwyllys 1963*99ebb4caSwyllys case KMF_CERT_SERIALNUM: 1964*99ebb4caSwyllys if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) { 1965*99ebb4caSwyllys (void) strcpy(resultStr, "0x"); 1966*99ebb4caSwyllys len = BIO_gets(mem, &resultStr[2], 1967*99ebb4caSwyllys KMF_CERT_PRINTABLE_LEN - 2); 1968*99ebb4caSwyllys } 1969*99ebb4caSwyllys break; 1970*99ebb4caSwyllys 1971*99ebb4caSwyllys case KMF_CERT_NOTBEFORE: 1972*99ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert)); 1973*99ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 1974*99ebb4caSwyllys break; 1975*99ebb4caSwyllys 1976*99ebb4caSwyllys case KMF_CERT_NOTAFTER: 1977*99ebb4caSwyllys (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert)); 1978*99ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 1979*99ebb4caSwyllys break; 1980*99ebb4caSwyllys 1981*99ebb4caSwyllys case KMF_CERT_PUBKEY_DATA: 1982*99ebb4caSwyllys { 1983*99ebb4caSwyllys EVP_PKEY *pkey = X509_get_pubkey(xcert); 1984*99ebb4caSwyllys if (pkey == NULL) { 1985*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 1986*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1987*99ebb4caSwyllys goto out; 1988*99ebb4caSwyllys } 1989*99ebb4caSwyllys 1990*99ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) { 1991*99ebb4caSwyllys (void) BIO_printf(mem, 1992*99ebb4caSwyllys "RSA Public Key: (%d bit)\n", 1993*99ebb4caSwyllys BN_num_bits(pkey->pkey.rsa->n)); 1994*99ebb4caSwyllys (void) RSA_print(mem, pkey->pkey.rsa, 0); 1995*99ebb4caSwyllys } else if (pkey->type == EVP_PKEY_DSA) { 1996*99ebb4caSwyllys (void) BIO_printf(mem, 1997*99ebb4caSwyllys "%12sDSA Public Key:\n", ""); 1998*99ebb4caSwyllys (void) DSA_print(mem, pkey->pkey.dsa, 0); 1999*99ebb4caSwyllys } else { 2000*99ebb4caSwyllys (void) BIO_printf(mem, 2001*99ebb4caSwyllys "%12sUnknown Public Key:\n", ""); 2002*99ebb4caSwyllys } 2003*99ebb4caSwyllys (void) BIO_printf(mem, "\n"); 2004*99ebb4caSwyllys EVP_PKEY_free(pkey); 2005*99ebb4caSwyllys } 2006*99ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2007*99ebb4caSwyllys break; 2008*99ebb4caSwyllys case KMF_CERT_SIGNATURE_ALG: 2009*99ebb4caSwyllys case KMF_CERT_PUBKEY_ALG: 2010*99ebb4caSwyllys if (flag == KMF_CERT_SIGNATURE_ALG) { 2011*99ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 2012*99ebb4caSwyllys xcert->sig_alg->algorithm); 2013*99ebb4caSwyllys } else { 2014*99ebb4caSwyllys len = i2a_ASN1_OBJECT(mem, 2015*99ebb4caSwyllys xcert->cert_info->key->algor->algorithm); 2016*99ebb4caSwyllys } 2017*99ebb4caSwyllys 2018*99ebb4caSwyllys if (len > 0) { 2019*99ebb4caSwyllys len = BIO_read(mem, resultStr, 2020*99ebb4caSwyllys KMF_CERT_PRINTABLE_LEN); 2021*99ebb4caSwyllys } 2022*99ebb4caSwyllys break; 2023*99ebb4caSwyllys 2024*99ebb4caSwyllys case KMF_CERT_EMAIL: 2025*99ebb4caSwyllys emlst = X509_get1_email(xcert); 2026*99ebb4caSwyllys for (j = 0; j < sk_num(emlst); j++) 2027*99ebb4caSwyllys (void) BIO_printf(mem, "%s\n", sk_value(emlst, j)); 2028*99ebb4caSwyllys 2029*99ebb4caSwyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2030*99ebb4caSwyllys X509_email_free(emlst); 2031*99ebb4caSwyllys break; 2032*99ebb4caSwyllys case KMF_X509_EXT_ISSUER_ALTNAME: 2033*99ebb4caSwyllys case KMF_X509_EXT_SUBJ_ALTNAME: 2034*99ebb4caSwyllys case KMF_X509_EXT_KEY_USAGE: 2035*99ebb4caSwyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 2036*99ebb4caSwyllys case KMF_X509_EXT_CERT_POLICIES: 2037*99ebb4caSwyllys case KMF_X509_EXT_BASIC_CONSTRAINTS: 2038*99ebb4caSwyllys case KMF_X509_EXT_NAME_CONSTRAINTS: 2039*99ebb4caSwyllys case KMF_X509_EXT_POLICY_CONSTRAINTS: 2040*99ebb4caSwyllys case KMF_X509_EXT_EXT_KEY_USAGE: 2041*99ebb4caSwyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY: 2042*99ebb4caSwyllys case KMF_X509_EXT_AUTH_KEY_ID: 2043*99ebb4caSwyllys case KMF_X509_EXT_SUBJ_KEY_ID: 2044*99ebb4caSwyllys case KMF_X509_EXT_POLICY_MAPPINGS: 2045*99ebb4caSwyllys case KMF_X509_EXT_CRL_DIST_POINTS: 2046*99ebb4caSwyllys case KMF_X509_EXT_FRESHEST_CRL: 2047*99ebb4caSwyllys nid = ext2NID(flag); 2048*99ebb4caSwyllys if (nid == NID_undef) { 2049*99ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 2050*99ebb4caSwyllys goto out; 2051*99ebb4caSwyllys } 2052*99ebb4caSwyllys ci = xcert->cert_info; 2053*99ebb4caSwyllys 2054*99ebb4caSwyllys ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1); 2055*99ebb4caSwyllys if (ext_index == -1) { 2056*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2057*99ebb4caSwyllys 2058*99ebb4caSwyllys ret = KMF_ERR_EXTENSION_NOT_FOUND; 2059*99ebb4caSwyllys goto out; 2060*99ebb4caSwyllys } 2061*99ebb4caSwyllys ex = X509v3_get_ext(ci->extensions, ext_index); 2062*99ebb4caSwyllys 2063*99ebb4caSwyllys (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); 2064*99ebb4caSwyllys 2065*99ebb4caSwyllys if (BIO_printf(mem, ": %s\n", 2066*99ebb4caSwyllys X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 2067*99ebb4caSwyllys 0) { 2068*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2069*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 2070*99ebb4caSwyllys goto out; 2071*99ebb4caSwyllys } 2072*99ebb4caSwyllys if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) { 2073*99ebb4caSwyllys (void) BIO_printf(mem, "%*s", 4, ""); 2074*99ebb4caSwyllys (void) M_ASN1_OCTET_STRING_print(mem, ex->value); 2075*99ebb4caSwyllys } 2076*99ebb4caSwyllys if (BIO_write(mem, "\n", 1) <= 0) { 2077*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2078*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 2079*99ebb4caSwyllys goto out; 2080*99ebb4caSwyllys } 2081*99ebb4caSwyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2082*99ebb4caSwyllys } 2083*99ebb4caSwyllys if (len <= 0) { 2084*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2085*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 2086*99ebb4caSwyllys } 2087*99ebb4caSwyllys 2088*99ebb4caSwyllys out: 2089*99ebb4caSwyllys if (outbuf != NULL) { 2090*99ebb4caSwyllys free(outbuf); 2091*99ebb4caSwyllys } 2092*99ebb4caSwyllys 2093*99ebb4caSwyllys if (xcert != NULL) { 2094*99ebb4caSwyllys X509_free(xcert); 2095*99ebb4caSwyllys } 2096*99ebb4caSwyllys 2097*99ebb4caSwyllys if (mem != NULL) { 2098*99ebb4caSwyllys (void) BIO_free(mem); 2099*99ebb4caSwyllys } 2100*99ebb4caSwyllys 2101*99ebb4caSwyllys return (ret); 2102*99ebb4caSwyllys } 2103*99ebb4caSwyllys KMF_RETURN 2104*99ebb4caSwyllys /*ARGSUSED*/ 2105*99ebb4caSwyllys OpenSSL_GetPrikeyByCert(KMF_HANDLE_T handle, 2106*99ebb4caSwyllys KMF_CRYPTOWITHCERT_PARAMS *params, 2107*99ebb4caSwyllys KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, 2108*99ebb4caSwyllys KMF_KEY_ALG keytype) 2109*99ebb4caSwyllys { 2110*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 2111*99ebb4caSwyllys KMF_FINDKEY_PARAMS fkparms; 2112*99ebb4caSwyllys uint32_t numkeys = 0; 2113*99ebb4caSwyllys 2114*99ebb4caSwyllys if (params == NULL && params->sslparms.keyfile == NULL) 2115*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2116*99ebb4caSwyllys 2117*99ebb4caSwyllys /* 2118*99ebb4caSwyllys * This is really just a FindKey operation, reuse the 2119*99ebb4caSwyllys * FindKey function. 2120*99ebb4caSwyllys */ 2121*99ebb4caSwyllys (void *)memset(&fkparms, 0, sizeof (fkparms)); 2122*99ebb4caSwyllys fkparms.kstype = KMF_KEYSTORE_OPENSSL; 2123*99ebb4caSwyllys fkparms.keyclass = KMF_ASYM_PRI; 2124*99ebb4caSwyllys fkparms.keytype = keytype; 2125*99ebb4caSwyllys fkparms.format = params->format; 2126*99ebb4caSwyllys fkparms.sslparms = params->sslparms; 2127*99ebb4caSwyllys 2128*99ebb4caSwyllys rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys); 2129*99ebb4caSwyllys 2130*99ebb4caSwyllys return (rv); 2131*99ebb4caSwyllys } 2132*99ebb4caSwyllys 2133*99ebb4caSwyllys KMF_RETURN 2134*99ebb4caSwyllys /*ARGSUSED*/ 2135*99ebb4caSwyllys OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 2136*99ebb4caSwyllys KMF_OID *AlgOID, KMF_DATA *ciphertext, 2137*99ebb4caSwyllys KMF_DATA *output) 2138*99ebb4caSwyllys { 2139*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 2140*99ebb4caSwyllys RSA *rsa = NULL; 2141*99ebb4caSwyllys unsigned int in_len = 0, out_len = 0; 2142*99ebb4caSwyllys unsigned int total_decrypted = 0, modulus_len = 0; 2143*99ebb4caSwyllys uint8_t *in_data, *out_data; 2144*99ebb4caSwyllys int i, blocks; 2145*99ebb4caSwyllys 2146*99ebb4caSwyllys if (key == NULL || AlgOID == NULL || 2147*99ebb4caSwyllys ciphertext == NULL || output == NULL || 2148*99ebb4caSwyllys ciphertext->Data == NULL || 2149*99ebb4caSwyllys output->Data == NULL) 2150*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2151*99ebb4caSwyllys 2152*99ebb4caSwyllys if (key->keyalg == KMF_RSA) { 2153*99ebb4caSwyllys rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp); 2154*99ebb4caSwyllys modulus_len = RSA_size(rsa); 2155*99ebb4caSwyllys } else { 2156*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2157*99ebb4caSwyllys } 2158*99ebb4caSwyllys 2159*99ebb4caSwyllys blocks = ciphertext->Length/modulus_len; 2160*99ebb4caSwyllys out_data = output->Data; 2161*99ebb4caSwyllys in_data = ciphertext->Data; 2162*99ebb4caSwyllys out_len = modulus_len - 11; 2163*99ebb4caSwyllys in_len = modulus_len; 2164*99ebb4caSwyllys 2165*99ebb4caSwyllys for (i = 0; i < blocks; i++) { 2166*99ebb4caSwyllys out_len = RSA_private_decrypt(in_len, 2167*99ebb4caSwyllys in_data, out_data, rsa, RSA_PKCS1_PADDING); 2168*99ebb4caSwyllys 2169*99ebb4caSwyllys if (out_len == 0) { 2170*99ebb4caSwyllys ret = KMF_ERR_INTERNAL; 2171*99ebb4caSwyllys goto cleanup; 2172*99ebb4caSwyllys } 2173*99ebb4caSwyllys 2174*99ebb4caSwyllys out_data += out_len; 2175*99ebb4caSwyllys total_decrypted += out_len; 2176*99ebb4caSwyllys in_data += in_len; 2177*99ebb4caSwyllys } 2178*99ebb4caSwyllys 2179*99ebb4caSwyllys output->Length = total_decrypted; 2180*99ebb4caSwyllys 2181*99ebb4caSwyllys cleanup: 2182*99ebb4caSwyllys RSA_free(rsa); 2183*99ebb4caSwyllys if (ret != KMF_OK) 2184*99ebb4caSwyllys output->Length = 0; 2185*99ebb4caSwyllys 2186*99ebb4caSwyllys return (ret); 2187*99ebb4caSwyllys 2188*99ebb4caSwyllys } 2189*99ebb4caSwyllys 2190*99ebb4caSwyllys /* 2191*99ebb4caSwyllys * This function will create a certid from issuer_cert and user_cert. 2192*99ebb4caSwyllys * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate 2193*99ebb4caSwyllys * certid memory after use. 2194*99ebb4caSwyllys */ 2195*99ebb4caSwyllys static KMF_RETURN 2196*99ebb4caSwyllys create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert, 2197*99ebb4caSwyllys const KMF_DATA *user_cert, OCSP_CERTID **certid) 2198*99ebb4caSwyllys { 2199*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 2200*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2201*99ebb4caSwyllys X509 *issuer = NULL; 2202*99ebb4caSwyllys X509 *cert = NULL; 2203*99ebb4caSwyllys unsigned char *ptmp; 2204*99ebb4caSwyllys 2205*99ebb4caSwyllys if (issuer_cert == NULL || user_cert == NULL) { 2206*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2207*99ebb4caSwyllys } 2208*99ebb4caSwyllys 2209*99ebb4caSwyllys /* convert the DER-encoded issuer cert to an internal X509 */ 2210*99ebb4caSwyllys ptmp = issuer_cert->Data; 2211*99ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2212*99ebb4caSwyllys issuer_cert->Length); 2213*99ebb4caSwyllys if (issuer == NULL) { 2214*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2215*99ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 2216*99ebb4caSwyllys goto end; 2217*99ebb4caSwyllys } 2218*99ebb4caSwyllys 2219*99ebb4caSwyllys /* convert the DER-encoded user cert to an internal X509 */ 2220*99ebb4caSwyllys ptmp = user_cert->Data; 2221*99ebb4caSwyllys cert = d2i_X509(NULL, (const uchar_t **)&ptmp, 2222*99ebb4caSwyllys user_cert->Length); 2223*99ebb4caSwyllys if (cert == NULL) { 2224*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2225*99ebb4caSwyllys 2226*99ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_CERT; 2227*99ebb4caSwyllys goto end; 2228*99ebb4caSwyllys } 2229*99ebb4caSwyllys 2230*99ebb4caSwyllys /* create a CERTID */ 2231*99ebb4caSwyllys *certid = OCSP_cert_to_id(NULL, cert, issuer); 2232*99ebb4caSwyllys if (*certid == NULL) { 2233*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2234*99ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 2235*99ebb4caSwyllys goto end; 2236*99ebb4caSwyllys } 2237*99ebb4caSwyllys 2238*99ebb4caSwyllys end: 2239*99ebb4caSwyllys if (issuer != NULL) { 2240*99ebb4caSwyllys X509_free(issuer); 2241*99ebb4caSwyllys } 2242*99ebb4caSwyllys 2243*99ebb4caSwyllys if (cert != NULL) { 2244*99ebb4caSwyllys X509_free(cert); 2245*99ebb4caSwyllys } 2246*99ebb4caSwyllys 2247*99ebb4caSwyllys return (ret); 2248*99ebb4caSwyllys } 2249*99ebb4caSwyllys 2250*99ebb4caSwyllys KMF_RETURN 2251*99ebb4caSwyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, 2252*99ebb4caSwyllys char *reqfile) 2253*99ebb4caSwyllys { 2254*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 2255*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2256*99ebb4caSwyllys OCSP_CERTID *id = NULL; 2257*99ebb4caSwyllys OCSP_REQUEST *req = NULL; 2258*99ebb4caSwyllys BIO *derbio = NULL; 2259*99ebb4caSwyllys 2260*99ebb4caSwyllys if (params->user_cert == NULL || params->issuer_cert == NULL || 2261*99ebb4caSwyllys reqfile == NULL) { 2262*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2263*99ebb4caSwyllys } 2264*99ebb4caSwyllys 2265*99ebb4caSwyllys ret = create_certid(handle, params->issuer_cert, params->user_cert, 2266*99ebb4caSwyllys &id); 2267*99ebb4caSwyllys if (ret != KMF_OK) { 2268*99ebb4caSwyllys return (ret); 2269*99ebb4caSwyllys } 2270*99ebb4caSwyllys 2271*99ebb4caSwyllys /* Create an OCSP request */ 2272*99ebb4caSwyllys req = OCSP_REQUEST_new(); 2273*99ebb4caSwyllys if (req == NULL) { 2274*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2275*99ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 2276*99ebb4caSwyllys goto end; 2277*99ebb4caSwyllys } 2278*99ebb4caSwyllys 2279*99ebb4caSwyllys if (!OCSP_request_add0_id(req, id)) { 2280*99ebb4caSwyllys ret = KMF_ERR_OCSP_CREATE_REQUEST; 2281*99ebb4caSwyllys goto end; 2282*99ebb4caSwyllys } 2283*99ebb4caSwyllys 2284*99ebb4caSwyllys /* Write the request to the output file with DER encoding */ 2285*99ebb4caSwyllys derbio = BIO_new_file(reqfile, "wb"); 2286*99ebb4caSwyllys if (!derbio) { 2287*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2288*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 2289*99ebb4caSwyllys goto end; 2290*99ebb4caSwyllys } 2291*99ebb4caSwyllys if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) { 2292*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 2293*99ebb4caSwyllys } 2294*99ebb4caSwyllys 2295*99ebb4caSwyllys end: 2296*99ebb4caSwyllys /* 2297*99ebb4caSwyllys * We don't need to free "id" explicitely, because OCSP_REQUEST_free() 2298*99ebb4caSwyllys * will deallocate certid's space also. 2299*99ebb4caSwyllys */ 2300*99ebb4caSwyllys if (req != NULL) { 2301*99ebb4caSwyllys OCSP_REQUEST_free(req); 2302*99ebb4caSwyllys } 2303*99ebb4caSwyllys 2304*99ebb4caSwyllys if (derbio != NULL) { 2305*99ebb4caSwyllys (void) BIO_free(derbio); 2306*99ebb4caSwyllys } 2307*99ebb4caSwyllys 2308*99ebb4caSwyllys return (ret); 2309*99ebb4caSwyllys } 2310*99ebb4caSwyllys 2311*99ebb4caSwyllys /* ocsp_find_signer_sk() is copied from openssl source */ 2312*99ebb4caSwyllys static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 2313*99ebb4caSwyllys { 2314*99ebb4caSwyllys int i; 2315*99ebb4caSwyllys unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 2316*99ebb4caSwyllys 2317*99ebb4caSwyllys /* Easy if lookup by name */ 2318*99ebb4caSwyllys if (id->type == V_OCSP_RESPID_NAME) 2319*99ebb4caSwyllys return (X509_find_by_subject(certs, id->value.byName)); 2320*99ebb4caSwyllys 2321*99ebb4caSwyllys /* Lookup by key hash */ 2322*99ebb4caSwyllys 2323*99ebb4caSwyllys /* If key hash isn't SHA1 length then forget it */ 2324*99ebb4caSwyllys if (id->value.byKey->length != SHA_DIGEST_LENGTH) 2325*99ebb4caSwyllys return (NULL); 2326*99ebb4caSwyllys 2327*99ebb4caSwyllys keyhash = id->value.byKey->data; 2328*99ebb4caSwyllys /* Calculate hash of each key and compare */ 2329*99ebb4caSwyllys for (i = 0; i < sk_X509_num(certs); i++) { 2330*99ebb4caSwyllys /*LINTED*/ 2331*99ebb4caSwyllys X509 *x = sk_X509_value(certs, i); 2332*99ebb4caSwyllys (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 2333*99ebb4caSwyllys if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 2334*99ebb4caSwyllys return (x); 2335*99ebb4caSwyllys } 2336*99ebb4caSwyllys return (NULL); 2337*99ebb4caSwyllys } 2338*99ebb4caSwyllys 2339*99ebb4caSwyllys /* ocsp_find_signer() is copied from openssl source */ 2340*99ebb4caSwyllys /*ARGSUSED*/ 2341*99ebb4caSwyllys static int 2342*99ebb4caSwyllys ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, 2343*99ebb4caSwyllys X509_STORE *st, unsigned long flags) 2344*99ebb4caSwyllys { 2345*99ebb4caSwyllys X509 *signer; 2346*99ebb4caSwyllys OCSP_RESPID *rid = bs->tbsResponseData->responderId; 2347*99ebb4caSwyllys if ((signer = ocsp_find_signer_sk(certs, rid))) { 2348*99ebb4caSwyllys *psigner = signer; 2349*99ebb4caSwyllys return (2); 2350*99ebb4caSwyllys } 2351*99ebb4caSwyllys if (!(flags & OCSP_NOINTERN) && 2352*99ebb4caSwyllys (signer = ocsp_find_signer_sk(bs->certs, rid))) { 2353*99ebb4caSwyllys *psigner = signer; 2354*99ebb4caSwyllys return (1); 2355*99ebb4caSwyllys } 2356*99ebb4caSwyllys /* Maybe lookup from store if by subject name */ 2357*99ebb4caSwyllys 2358*99ebb4caSwyllys *psigner = NULL; 2359*99ebb4caSwyllys return (0); 2360*99ebb4caSwyllys } 2361*99ebb4caSwyllys 2362*99ebb4caSwyllys /* 2363*99ebb4caSwyllys * This function will verify the signature of a basic response, using 2364*99ebb4caSwyllys * the public key from the OCSP responder certificate. 2365*99ebb4caSwyllys */ 2366*99ebb4caSwyllys static KMF_RETURN 2367*99ebb4caSwyllys check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, 2368*99ebb4caSwyllys KMF_DATA *signer_cert, KMF_DATA *issuer_cert) 2369*99ebb4caSwyllys { 2370*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 2371*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2372*99ebb4caSwyllys STACK_OF(X509) *cert_stack = NULL; 2373*99ebb4caSwyllys X509 *signer = NULL; 2374*99ebb4caSwyllys X509 *issuer = NULL; 2375*99ebb4caSwyllys EVP_PKEY *skey = NULL; 2376*99ebb4caSwyllys unsigned char *ptmp; 2377*99ebb4caSwyllys 2378*99ebb4caSwyllys 2379*99ebb4caSwyllys if (bs == NULL || issuer_cert == NULL) 2380*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2381*99ebb4caSwyllys 2382*99ebb4caSwyllys /* 2383*99ebb4caSwyllys * Find the certificate that signed the basic response. 2384*99ebb4caSwyllys * 2385*99ebb4caSwyllys * If signer_cert is not NULL, we will use that as the signer cert. 2386*99ebb4caSwyllys * Otherwise, we will check if the issuer cert is actually the signer. 2387*99ebb4caSwyllys * If we still do not find a signer, we will look for it from the 2388*99ebb4caSwyllys * certificate list came with the response file. 2389*99ebb4caSwyllys */ 2390*99ebb4caSwyllys if (signer_cert != NULL) { 2391*99ebb4caSwyllys ptmp = signer_cert->Data; 2392*99ebb4caSwyllys signer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2393*99ebb4caSwyllys signer_cert->Length); 2394*99ebb4caSwyllys if (signer == NULL) { 2395*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2396*99ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 2397*99ebb4caSwyllys goto end; 2398*99ebb4caSwyllys } 2399*99ebb4caSwyllys } else { 2400*99ebb4caSwyllys /* 2401*99ebb4caSwyllys * Convert the issuer cert into X509 and push it into a 2402*99ebb4caSwyllys * stack to be used by ocsp_find_signer(). 2403*99ebb4caSwyllys */ 2404*99ebb4caSwyllys ptmp = issuer_cert->Data; 2405*99ebb4caSwyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2406*99ebb4caSwyllys issuer_cert->Length); 2407*99ebb4caSwyllys if (issuer == NULL) { 2408*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 2409*99ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_ISSUER; 2410*99ebb4caSwyllys goto end; 2411*99ebb4caSwyllys } 2412*99ebb4caSwyllys 2413*99ebb4caSwyllys if ((cert_stack = sk_X509_new_null()) == NULL) { 2414*99ebb4caSwyllys ret = KMF_ERR_INTERNAL; 2415*99ebb4caSwyllys goto end; 2416*99ebb4caSwyllys } 2417*99ebb4caSwyllys 2418*99ebb4caSwyllys if (sk_X509_push(cert_stack, issuer) == NULL) { 2419*99ebb4caSwyllys ret = KMF_ERR_INTERNAL; 2420*99ebb4caSwyllys goto end; 2421*99ebb4caSwyllys } 2422*99ebb4caSwyllys 2423*99ebb4caSwyllys ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0); 2424*99ebb4caSwyllys if (!ret) { 2425*99ebb4caSwyllys /* can not find the signer */ 2426*99ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 2427*99ebb4caSwyllys goto end; 2428*99ebb4caSwyllys } 2429*99ebb4caSwyllys } 2430*99ebb4caSwyllys 2431*99ebb4caSwyllys /* Verify the signature of the response */ 2432*99ebb4caSwyllys skey = X509_get_pubkey(signer); 2433*99ebb4caSwyllys if (skey == NULL) { 2434*99ebb4caSwyllys ret = KMF_ERR_OCSP_BAD_SIGNER; 2435*99ebb4caSwyllys goto end; 2436*99ebb4caSwyllys } 2437*99ebb4caSwyllys 2438*99ebb4caSwyllys ret = OCSP_BASICRESP_verify(bs, skey, 0); 2439*99ebb4caSwyllys if (ret == 0) { 2440*99ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE; 2441*99ebb4caSwyllys goto end; 2442*99ebb4caSwyllys } 2443*99ebb4caSwyllys 2444*99ebb4caSwyllys end: 2445*99ebb4caSwyllys if (issuer != NULL) { 2446*99ebb4caSwyllys X509_free(issuer); 2447*99ebb4caSwyllys } 2448*99ebb4caSwyllys 2449*99ebb4caSwyllys if (signer != NULL) { 2450*99ebb4caSwyllys X509_free(signer); 2451*99ebb4caSwyllys } 2452*99ebb4caSwyllys 2453*99ebb4caSwyllys if (skey != NULL) { 2454*99ebb4caSwyllys EVP_PKEY_free(skey); 2455*99ebb4caSwyllys } 2456*99ebb4caSwyllys 2457*99ebb4caSwyllys if (cert_stack != NULL) { 2458*99ebb4caSwyllys sk_X509_free(cert_stack); 2459*99ebb4caSwyllys } 2460*99ebb4caSwyllys 2461*99ebb4caSwyllys return (ret); 2462*99ebb4caSwyllys } 2463*99ebb4caSwyllys 2464*99ebb4caSwyllys 2465*99ebb4caSwyllys 2466*99ebb4caSwyllys KMF_RETURN 2467*99ebb4caSwyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, 2468*99ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 2469*99ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) 2470*99ebb4caSwyllys { 2471*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 2472*99ebb4caSwyllys BIO *derbio = NULL; 2473*99ebb4caSwyllys OCSP_RESPONSE *resp = NULL; 2474*99ebb4caSwyllys OCSP_BASICRESP *bs = NULL; 2475*99ebb4caSwyllys OCSP_CERTID *id = NULL; 2476*99ebb4caSwyllys OCSP_SINGLERESP *single = NULL; 2477*99ebb4caSwyllys ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 2478*99ebb4caSwyllys int index, status, reason; 2479*99ebb4caSwyllys 2480*99ebb4caSwyllys if (params_in == NULL || params_in->issuer_cert == NULL || 2481*99ebb4caSwyllys params_in->user_cert == NULL || params_in->response == NULL) { 2482*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2483*99ebb4caSwyllys } 2484*99ebb4caSwyllys 2485*99ebb4caSwyllys if (params_out == NULL) { 2486*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2487*99ebb4caSwyllys } 2488*99ebb4caSwyllys 2489*99ebb4caSwyllys /* Read in the response */ 2490*99ebb4caSwyllys derbio = BIO_new_mem_buf(params_in->response->Data, 2491*99ebb4caSwyllys params_in->response->Length); 2492*99ebb4caSwyllys if (!derbio) { 2493*99ebb4caSwyllys ret = KMF_ERR_MEMORY; 2494*99ebb4caSwyllys return (ret); 2495*99ebb4caSwyllys } 2496*99ebb4caSwyllys 2497*99ebb4caSwyllys resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 2498*99ebb4caSwyllys if (resp == NULL) { 2499*99ebb4caSwyllys ret = KMF_ERR_OCSP_MALFORMED_RESPONSE; 2500*99ebb4caSwyllys goto end; 2501*99ebb4caSwyllys } 2502*99ebb4caSwyllys 2503*99ebb4caSwyllys /* Check the response status */ 2504*99ebb4caSwyllys status = OCSP_response_status(resp); 2505*99ebb4caSwyllys params_out->response_status = status; 2506*99ebb4caSwyllys if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 2507*99ebb4caSwyllys ret = KMF_ERR_OCSP_RESPONSE_STATUS; 2508*99ebb4caSwyllys goto end; 2509*99ebb4caSwyllys } 2510*99ebb4caSwyllys 2511*99ebb4caSwyllys #ifdef DEBUG 2512*99ebb4caSwyllys printf("Successfully checked the response file status.\n"); 2513*99ebb4caSwyllys #endif /* DEBUG */ 2514*99ebb4caSwyllys 2515*99ebb4caSwyllys /* Extract basic response */ 2516*99ebb4caSwyllys bs = OCSP_response_get1_basic(resp); 2517*99ebb4caSwyllys if (bs == NULL) { 2518*99ebb4caSwyllys ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE; 2519*99ebb4caSwyllys goto end; 2520*99ebb4caSwyllys } 2521*99ebb4caSwyllys 2522*99ebb4caSwyllys #ifdef DEBUG 2523*99ebb4caSwyllys printf("Successfully retrieved the basic response.\n"); 2524*99ebb4caSwyllys #endif /* DEBUG */ 2525*99ebb4caSwyllys 2526*99ebb4caSwyllys /* Check the basic response signature if required */ 2527*99ebb4caSwyllys if (params_in->ignore_response_sign == B_FALSE) { 2528*99ebb4caSwyllys ret = check_response_signature(handle, bs, 2529*99ebb4caSwyllys params_in->signer_cert, params_in->issuer_cert); 2530*99ebb4caSwyllys if (ret != KMF_OK) 2531*99ebb4caSwyllys goto end; 2532*99ebb4caSwyllys } 2533*99ebb4caSwyllys 2534*99ebb4caSwyllys #ifdef DEBUG 2535*99ebb4caSwyllys printf("Successfully verified the response signature.\n"); 2536*99ebb4caSwyllys #endif /* DEBUG */ 2537*99ebb4caSwyllys 2538*99ebb4caSwyllys /* Create a certid for the certificate in question */ 2539*99ebb4caSwyllys ret = create_certid(handle, params_in->issuer_cert, 2540*99ebb4caSwyllys params_in->user_cert, &id); 2541*99ebb4caSwyllys if (ret != KMF_OK) { 2542*99ebb4caSwyllys ret = KMF_ERR_OCSP_CERTID; 2543*99ebb4caSwyllys goto end; 2544*99ebb4caSwyllys } 2545*99ebb4caSwyllys 2546*99ebb4caSwyllys #ifdef DEBUG 2547*99ebb4caSwyllys printf("successfully created a certid for the cert.\n"); 2548*99ebb4caSwyllys #endif /* DEBUG */ 2549*99ebb4caSwyllys 2550*99ebb4caSwyllys /* Find the index of the single response for the certid */ 2551*99ebb4caSwyllys index = OCSP_resp_find(bs, id, -1); 2552*99ebb4caSwyllys if (index < 0) { 2553*99ebb4caSwyllys /* cound not find this certificate in the response */ 2554*99ebb4caSwyllys ret = KMF_ERR_OCSP_UNKNOWN_CERT; 2555*99ebb4caSwyllys goto end; 2556*99ebb4caSwyllys } 2557*99ebb4caSwyllys 2558*99ebb4caSwyllys #ifdef DEBUG 2559*99ebb4caSwyllys printf("Successfully found the single response index for the cert.\n"); 2560*99ebb4caSwyllys #endif /* DEBUG */ 2561*99ebb4caSwyllys 2562*99ebb4caSwyllys /* Retrieve the single response and get the cert status */ 2563*99ebb4caSwyllys single = OCSP_resp_get0(bs, index); 2564*99ebb4caSwyllys status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, 2565*99ebb4caSwyllys &nextupd); 2566*99ebb4caSwyllys if (status == V_OCSP_CERTSTATUS_GOOD) { 2567*99ebb4caSwyllys params_out->cert_status = OCSP_GOOD; 2568*99ebb4caSwyllys } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { 2569*99ebb4caSwyllys params_out->cert_status = OCSP_UNKNOWN; 2570*99ebb4caSwyllys } else { /* revoked */ 2571*99ebb4caSwyllys params_out->cert_status = OCSP_REVOKED; 2572*99ebb4caSwyllys params_out->reason = reason; 2573*99ebb4caSwyllys } 2574*99ebb4caSwyllys ret = KMF_OK; 2575*99ebb4caSwyllys 2576*99ebb4caSwyllys /* Verify the time */ 2577*99ebb4caSwyllys if (!OCSP_check_validity(thisupd, nextupd, 300, 2578*99ebb4caSwyllys params_in->response_lifetime)) { 2579*99ebb4caSwyllys ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; 2580*99ebb4caSwyllys goto end; 2581*99ebb4caSwyllys } 2582*99ebb4caSwyllys 2583*99ebb4caSwyllys #ifdef DEBUG 2584*99ebb4caSwyllys printf("Successfully verify the time.\n"); 2585*99ebb4caSwyllys #endif /* DEBUG */ 2586*99ebb4caSwyllys 2587*99ebb4caSwyllys end: 2588*99ebb4caSwyllys if (derbio != NULL) 2589*99ebb4caSwyllys (void) BIO_free(derbio); 2590*99ebb4caSwyllys 2591*99ebb4caSwyllys if (resp != NULL) 2592*99ebb4caSwyllys OCSP_RESPONSE_free(resp); 2593*99ebb4caSwyllys 2594*99ebb4caSwyllys if (bs != NULL) 2595*99ebb4caSwyllys OCSP_BASICRESP_free(bs); 2596*99ebb4caSwyllys 2597*99ebb4caSwyllys if (id != NULL) 2598*99ebb4caSwyllys OCSP_CERTID_free(id); 2599*99ebb4caSwyllys 2600*99ebb4caSwyllys return (ret); 2601*99ebb4caSwyllys } 2602*99ebb4caSwyllys 2603*99ebb4caSwyllys static KMF_RETURN 2604*99ebb4caSwyllys fetch_key(KMF_HANDLE_T handle, char *path, 2605*99ebb4caSwyllys KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) 2606*99ebb4caSwyllys { 2607*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 2608*99ebb4caSwyllys EVP_PKEY *pkey; 2609*99ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 2610*99ebb4caSwyllys 2611*99ebb4caSwyllys /* Make sure the requested file actually exists. */ 2612*99ebb4caSwyllys if (access(path, F_OK) != 0) { 2613*99ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 2614*99ebb4caSwyllys } 2615*99ebb4caSwyllys 2616*99ebb4caSwyllys if (keyclass == KMF_ASYM_PRI || 2617*99ebb4caSwyllys keyclass == KMF_ASYM_PUB) { 2618*99ebb4caSwyllys pkey = openssl_load_key(handle, path); 2619*99ebb4caSwyllys if (pkey == NULL) { 2620*99ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 2621*99ebb4caSwyllys } 2622*99ebb4caSwyllys if (key != NULL) { 2623*99ebb4caSwyllys if (pkey->type == EVP_PKEY_RSA) 2624*99ebb4caSwyllys key->keyalg = KMF_RSA; 2625*99ebb4caSwyllys else if (pkey->type == EVP_PKEY_DSA) 2626*99ebb4caSwyllys key->keyalg = KMF_DSA; 2627*99ebb4caSwyllys 2628*99ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 2629*99ebb4caSwyllys key->keyclass = keyclass; 2630*99ebb4caSwyllys key->keyp = (void *)pkey; 2631*99ebb4caSwyllys key->israw = FALSE; 2632*99ebb4caSwyllys key->keylabel = path; 2633*99ebb4caSwyllys } else { 2634*99ebb4caSwyllys EVP_PKEY_free(pkey); 2635*99ebb4caSwyllys pkey = NULL; 2636*99ebb4caSwyllys } 2637*99ebb4caSwyllys } else if (keyclass == KMF_SYMMETRIC) { 2638*99ebb4caSwyllys KMF_ENCODE_FORMAT fmt; 2639*99ebb4caSwyllys /* 2640*99ebb4caSwyllys * If the file is a recognized format, 2641*99ebb4caSwyllys * then it is NOT a symmetric key. 2642*99ebb4caSwyllys */ 2643*99ebb4caSwyllys rv = KMF_GetFileFormat(path, &fmt); 2644*99ebb4caSwyllys if (rv == KMF_OK || fmt != 0) { 2645*99ebb4caSwyllys return (KMF_ERR_KEY_NOT_FOUND); 2646*99ebb4caSwyllys } else if (rv == KMF_ERR_ENCODING) { 2647*99ebb4caSwyllys /* 2648*99ebb4caSwyllys * If we don't know the encoding, 2649*99ebb4caSwyllys * it is probably a symmetric key. 2650*99ebb4caSwyllys */ 2651*99ebb4caSwyllys rv = KMF_OK; 2652*99ebb4caSwyllys } 2653*99ebb4caSwyllys 2654*99ebb4caSwyllys if (key != NULL) { 2655*99ebb4caSwyllys KMF_DATA keyvalue; 2656*99ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 2657*99ebb4caSwyllys if (rkey == NULL) { 2658*99ebb4caSwyllys rv = KMF_ERR_MEMORY; 2659*99ebb4caSwyllys goto out; 2660*99ebb4caSwyllys } 2661*99ebb4caSwyllys 2662*99ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 2663*99ebb4caSwyllys rv = KMF_ReadInputFile(handle, path, &keyvalue); 2664*99ebb4caSwyllys if (rv != KMF_OK) 2665*99ebb4caSwyllys goto out; 2666*99ebb4caSwyllys 2667*99ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 2668*99ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 2669*99ebb4caSwyllys 2670*99ebb4caSwyllys key->kstype = KMF_KEYSTORE_OPENSSL; 2671*99ebb4caSwyllys key->keyclass = keyclass; 2672*99ebb4caSwyllys key->israw = TRUE; 2673*99ebb4caSwyllys key->keylabel = path; 2674*99ebb4caSwyllys key->keyp = (void *)rkey; 2675*99ebb4caSwyllys } 2676*99ebb4caSwyllys } 2677*99ebb4caSwyllys out: 2678*99ebb4caSwyllys if (rv != KMF_OK) { 2679*99ebb4caSwyllys if (rkey != NULL) { 2680*99ebb4caSwyllys KMF_FreeRawSymKey(rkey); 2681*99ebb4caSwyllys } 2682*99ebb4caSwyllys if (pkey != NULL) 2683*99ebb4caSwyllys EVP_PKEY_free(pkey); 2684*99ebb4caSwyllys 2685*99ebb4caSwyllys if (key != NULL) { 2686*99ebb4caSwyllys key->keyalg = KMF_KEYALG_NONE; 2687*99ebb4caSwyllys key->keyclass = KMF_KEYCLASS_NONE; 2688*99ebb4caSwyllys key->keyp = NULL; 2689*99ebb4caSwyllys } 2690*99ebb4caSwyllys } 2691*99ebb4caSwyllys 2692*99ebb4caSwyllys return (rv); 2693*99ebb4caSwyllys } 2694*99ebb4caSwyllys 2695*99ebb4caSwyllys KMF_RETURN 2696*99ebb4caSwyllys OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params, 2697*99ebb4caSwyllys KMF_KEY_HANDLE *key, uint32_t *numkeys) 2698*99ebb4caSwyllys { 2699*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 2700*99ebb4caSwyllys char *fullpath = NULL; 2701*99ebb4caSwyllys 2702*99ebb4caSwyllys if (handle == NULL || params == NULL || numkeys == NULL) 2703*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2704*99ebb4caSwyllys 2705*99ebb4caSwyllys if (params->keyclass != KMF_ASYM_PUB && 2706*99ebb4caSwyllys params->keyclass != KMF_ASYM_PRI && 2707*99ebb4caSwyllys params->keyclass != KMF_SYMMETRIC) 2708*99ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 2709*99ebb4caSwyllys 2710*99ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 2711*99ebb4caSwyllys params->sslparms.keyfile); 2712*99ebb4caSwyllys 2713*99ebb4caSwyllys if (fullpath == NULL) 2714*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2715*99ebb4caSwyllys 2716*99ebb4caSwyllys *numkeys = 0; 2717*99ebb4caSwyllys 2718*99ebb4caSwyllys if (isdir(fullpath)) { 2719*99ebb4caSwyllys DIR *dirp; 2720*99ebb4caSwyllys struct dirent *dp; 2721*99ebb4caSwyllys int n = 0; 2722*99ebb4caSwyllys 2723*99ebb4caSwyllys /* open all files in the directory and attempt to read them */ 2724*99ebb4caSwyllys if ((dirp = opendir(fullpath)) == NULL) { 2725*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2726*99ebb4caSwyllys } 2727*99ebb4caSwyllys rewinddir(dirp); 2728*99ebb4caSwyllys while ((dp = readdir(dirp)) != NULL) { 2729*99ebb4caSwyllys if (strcmp(dp->d_name, ".") && 2730*99ebb4caSwyllys strcmp(dp->d_name, "..")) { 2731*99ebb4caSwyllys char *fname; 2732*99ebb4caSwyllys 2733*99ebb4caSwyllys fname = get_fullpath(fullpath, 2734*99ebb4caSwyllys (char *)&dp->d_name); 2735*99ebb4caSwyllys 2736*99ebb4caSwyllys rv = fetch_key(handle, fname, 2737*99ebb4caSwyllys params->keyclass, 2738*99ebb4caSwyllys key ? &key[n] : NULL); 2739*99ebb4caSwyllys 2740*99ebb4caSwyllys if (rv == KMF_OK) 2741*99ebb4caSwyllys n++; 2742*99ebb4caSwyllys 2743*99ebb4caSwyllys if (rv != KMF_OK || key == NULL) 2744*99ebb4caSwyllys free(fname); 2745*99ebb4caSwyllys } 2746*99ebb4caSwyllys } 2747*99ebb4caSwyllys (void) closedir(dirp); 2748*99ebb4caSwyllys free(fullpath); 2749*99ebb4caSwyllys (*numkeys) = n; 2750*99ebb4caSwyllys } else { 2751*99ebb4caSwyllys rv = fetch_key(handle, fullpath, params->keyclass, key); 2752*99ebb4caSwyllys if (rv == KMF_OK) 2753*99ebb4caSwyllys (*numkeys) = 1; 2754*99ebb4caSwyllys 2755*99ebb4caSwyllys if (rv != KMF_OK || key == NULL) 2756*99ebb4caSwyllys free(fullpath); 2757*99ebb4caSwyllys } 2758*99ebb4caSwyllys 2759*99ebb4caSwyllys if ((*numkeys) == 0) 2760*99ebb4caSwyllys rv = KMF_ERR_KEY_NOT_FOUND; 2761*99ebb4caSwyllys 2762*99ebb4caSwyllys return (rv); 2763*99ebb4caSwyllys } 2764*99ebb4caSwyllys 2765*99ebb4caSwyllys #define HANDLE_PK12_ERROR { \ 2766*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); \ 2767*99ebb4caSwyllys rv = KMF_ERR_ENCODING; \ 2768*99ebb4caSwyllys goto out; \ 2769*99ebb4caSwyllys } 2770*99ebb4caSwyllys 2771*99ebb4caSwyllys static KMF_RETURN 2772*99ebb4caSwyllys write_pkcs12(KMF_HANDLE *kmfh, 2773*99ebb4caSwyllys BIO *bio, 2774*99ebb4caSwyllys KMF_CREDENTIAL *cred, 2775*99ebb4caSwyllys EVP_PKEY *pkey, 2776*99ebb4caSwyllys X509 *sslcert) 2777*99ebb4caSwyllys { 2778*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 2779*99ebb4caSwyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 2780*99ebb4caSwyllys PKCS12_SAFEBAG *bag = NULL; 2781*99ebb4caSwyllys PKCS7 *cert_authsafe = NULL; 2782*99ebb4caSwyllys PKCS8_PRIV_KEY_INFO *p8 = NULL; 2783*99ebb4caSwyllys PKCS7 *key_authsafe = NULL; 2784*99ebb4caSwyllys STACK_OF(PKCS7) *authsafe_stack = NULL; 2785*99ebb4caSwyllys PKCS12 *p12_elem = NULL; 2786*99ebb4caSwyllys char *lab = NULL; 2787*99ebb4caSwyllys int lab_len = 0; 2788*99ebb4caSwyllys unsigned char keyid[EVP_MAX_MD_SIZE]; 2789*99ebb4caSwyllys unsigned int keyidlen = 0; 2790*99ebb4caSwyllys 2791*99ebb4caSwyllys /* Must have at least a cert OR a key */ 2792*99ebb4caSwyllys if (sslcert == NULL && pkey == NULL) 2793*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 2794*99ebb4caSwyllys 2795*99ebb4caSwyllys (void) memset(keyid, 0, sizeof (keyid)); 2796*99ebb4caSwyllys /* 2797*99ebb4caSwyllys * Section 1: 2798*99ebb4caSwyllys * 2799*99ebb4caSwyllys * The first PKCS#12 container (safebag) will hold the certificates 2800*99ebb4caSwyllys * associated with this key. The result of this section is a 2801*99ebb4caSwyllys * PIN-encrypted PKCS#7 container (authsafe). If there are no 2802*99ebb4caSwyllys * certificates, there is no point in creating the "safebag" or the 2803*99ebb4caSwyllys * "authsafe" so we go to the next section. 2804*99ebb4caSwyllys */ 2805*99ebb4caSwyllys if (sslcert != NULL && pkey != NULL) { 2806*99ebb4caSwyllys if (X509_check_private_key(sslcert, pkey)) { 2807*99ebb4caSwyllys (void) X509_digest(sslcert, EVP_sha1(), keyid, 2808*99ebb4caSwyllys &keyidlen); 2809*99ebb4caSwyllys } else { 2810*99ebb4caSwyllys /* The key doesn't match the cert */ 2811*99ebb4caSwyllys HANDLE_PK12_ERROR 2812*99ebb4caSwyllys } 2813*99ebb4caSwyllys } 2814*99ebb4caSwyllys 2815*99ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 2816*99ebb4caSwyllys if (bag_stack == NULL) 2817*99ebb4caSwyllys return (KMF_ERR_MEMORY); 2818*99ebb4caSwyllys 2819*99ebb4caSwyllys if (sslcert != NULL) { 2820*99ebb4caSwyllys /* Convert cert from X509 struct to PKCS#12 bag */ 2821*99ebb4caSwyllys bag = PKCS12_x5092certbag(sslcert); 2822*99ebb4caSwyllys if (bag == NULL) { 2823*99ebb4caSwyllys HANDLE_PK12_ERROR 2824*99ebb4caSwyllys } 2825*99ebb4caSwyllys 2826*99ebb4caSwyllys /* Add the key id to the certificate bag. */ 2827*99ebb4caSwyllys if (keyidlen > 0 && 2828*99ebb4caSwyllys !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 2829*99ebb4caSwyllys HANDLE_PK12_ERROR 2830*99ebb4caSwyllys } 2831*99ebb4caSwyllys 2832*99ebb4caSwyllys /* Pile it on the bag_stack. */ 2833*99ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 2834*99ebb4caSwyllys HANDLE_PK12_ERROR 2835*99ebb4caSwyllys } 2836*99ebb4caSwyllys #if 0 2837*99ebb4caSwyllys /* No support for CA certs yet */ 2838*99ebb4caSwyllys if (cacerts != NULL && ncacerts > 0) { 2839*99ebb4caSwyllys int i; 2840*99ebb4caSwyllys for (i = 0; i < ncacerts; i++) { 2841*99ebb4caSwyllys KMF_X509_DER_CERT *c = &cacerts[i]; 2842*99ebb4caSwyllys X509 *ca = NULL; 2843*99ebb4caSwyllys 2844*99ebb4caSwyllys uchar_t *p = (uchar_t *)c->certificate.Data; 2845*99ebb4caSwyllys ca = d2i_X509(NULL, &p, 2846*99ebb4caSwyllys c->certificate.Length); 2847*99ebb4caSwyllys if (ca == NULL) { 2848*99ebb4caSwyllys HANDLE_PK12_ERROR 2849*99ebb4caSwyllys } 2850*99ebb4caSwyllys /* Convert CA cert to PKCS#12 bag. */ 2851*99ebb4caSwyllys bag = PKCS12_x5092certbag(ca); 2852*99ebb4caSwyllys if (bag == NULL) { 2853*99ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, 2854*99ebb4caSwyllys PKCS12_SAFEBAG_free); 2855*99ebb4caSwyllys HANDLE_PK12_ERROR 2856*99ebb4caSwyllys } 2857*99ebb4caSwyllys /* Pile it onto the bag_stack. */ 2858*99ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 2859*99ebb4caSwyllys HANDLE_PK12_ERROR 2860*99ebb4caSwyllys } 2861*99ebb4caSwyllys } 2862*99ebb4caSwyllys } 2863*99ebb4caSwyllys #endif 2864*99ebb4caSwyllys /* Turn bag_stack of certs into encrypted authsafe. */ 2865*99ebb4caSwyllys cert_authsafe = PKCS12_pack_p7encdata( 2866*99ebb4caSwyllys NID_pbe_WithSHA1And40BitRC2_CBC, 2867*99ebb4caSwyllys cred->cred, 2868*99ebb4caSwyllys cred->credlen, NULL, 0, 2869*99ebb4caSwyllys PKCS12_DEFAULT_ITER, 2870*99ebb4caSwyllys bag_stack); 2871*99ebb4caSwyllys 2872*99ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 2873*99ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 2874*99ebb4caSwyllys bag_stack = NULL; 2875*99ebb4caSwyllys 2876*99ebb4caSwyllys if (cert_authsafe == NULL) { 2877*99ebb4caSwyllys HANDLE_PK12_ERROR 2878*99ebb4caSwyllys } 2879*99ebb4caSwyllys } 2880*99ebb4caSwyllys /* 2881*99ebb4caSwyllys * Section 2: 2882*99ebb4caSwyllys * 2883*99ebb4caSwyllys * The second PKCS#12 container (safebag) will hold the private key 2884*99ebb4caSwyllys * that goes with the certificates above. The results of this section 2885*99ebb4caSwyllys * is an unencrypted PKCS#7 container (authsafe). If there is no 2886*99ebb4caSwyllys * private key, there is no point in creating the "safebag" or the 2887*99ebb4caSwyllys * "authsafe" so we go to the next section. 2888*99ebb4caSwyllys */ 2889*99ebb4caSwyllys if (pkey != NULL) { 2890*99ebb4caSwyllys p8 = EVP_PKEY2PKCS8(pkey); 2891*99ebb4caSwyllys if (p8 == NULL) { 2892*99ebb4caSwyllys HANDLE_PK12_ERROR 2893*99ebb4caSwyllys } 2894*99ebb4caSwyllys /* Put the shrouded key into a PKCS#12 bag. */ 2895*99ebb4caSwyllys bag = PKCS12_MAKE_SHKEYBAG( 2896*99ebb4caSwyllys NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 2897*99ebb4caSwyllys cred->cred, cred->credlen, 2898*99ebb4caSwyllys NULL, 0, PKCS12_DEFAULT_ITER, p8); 2899*99ebb4caSwyllys 2900*99ebb4caSwyllys /* Clean up the PKCS#8 shrouded key, don't need it now. */ 2901*99ebb4caSwyllys PKCS8_PRIV_KEY_INFO_free(p8); 2902*99ebb4caSwyllys p8 = NULL; 2903*99ebb4caSwyllys 2904*99ebb4caSwyllys if (bag == NULL) { 2905*99ebb4caSwyllys HANDLE_PK12_ERROR 2906*99ebb4caSwyllys } 2907*99ebb4caSwyllys if (keyidlen && 2908*99ebb4caSwyllys !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 2909*99ebb4caSwyllys HANDLE_PK12_ERROR 2910*99ebb4caSwyllys } 2911*99ebb4caSwyllys if (lab != NULL) { 2912*99ebb4caSwyllys if (!PKCS12_add_friendlyname(bag, 2913*99ebb4caSwyllys (char *)lab, lab_len)) { 2914*99ebb4caSwyllys HANDLE_PK12_ERROR 2915*99ebb4caSwyllys } 2916*99ebb4caSwyllys } 2917*99ebb4caSwyllys /* Start a PKCS#12 safebag container for the private key. */ 2918*99ebb4caSwyllys bag_stack = sk_PKCS12_SAFEBAG_new_null(); 2919*99ebb4caSwyllys if (bag_stack == NULL) { 2920*99ebb4caSwyllys HANDLE_PK12_ERROR 2921*99ebb4caSwyllys } 2922*99ebb4caSwyllys 2923*99ebb4caSwyllys /* Pile on the private key on the bag_stack. */ 2924*99ebb4caSwyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 2925*99ebb4caSwyllys HANDLE_PK12_ERROR 2926*99ebb4caSwyllys } 2927*99ebb4caSwyllys key_authsafe = PKCS12_pack_p7data(bag_stack); 2928*99ebb4caSwyllys 2929*99ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 2930*99ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 2931*99ebb4caSwyllys bag_stack = NULL; 2932*99ebb4caSwyllys 2933*99ebb4caSwyllys if (key_authsafe == NULL) { 2934*99ebb4caSwyllys HANDLE_PK12_ERROR 2935*99ebb4caSwyllys } 2936*99ebb4caSwyllys } 2937*99ebb4caSwyllys /* 2938*99ebb4caSwyllys * Section 3: 2939*99ebb4caSwyllys * 2940*99ebb4caSwyllys * This is where the two PKCS#7 containers, one for the certificates 2941*99ebb4caSwyllys * and one for the private key, are put together into a PKCS#12 2942*99ebb4caSwyllys * element. This final PKCS#12 element is written to the export file. 2943*99ebb4caSwyllys */ 2944*99ebb4caSwyllys 2945*99ebb4caSwyllys /* Start a PKCS#7 stack. */ 2946*99ebb4caSwyllys authsafe_stack = sk_PKCS7_new_null(); 2947*99ebb4caSwyllys if (authsafe_stack == NULL) { 2948*99ebb4caSwyllys HANDLE_PK12_ERROR 2949*99ebb4caSwyllys } 2950*99ebb4caSwyllys if (key_authsafe != NULL) { 2951*99ebb4caSwyllys if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) { 2952*99ebb4caSwyllys HANDLE_PK12_ERROR 2953*99ebb4caSwyllys } 2954*99ebb4caSwyllys } 2955*99ebb4caSwyllys if (cert_authsafe != NULL) { 2956*99ebb4caSwyllys if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) { 2957*99ebb4caSwyllys HANDLE_PK12_ERROR 2958*99ebb4caSwyllys } 2959*99ebb4caSwyllys } 2960*99ebb4caSwyllys p12_elem = PKCS12_init(NID_pkcs7_data); 2961*99ebb4caSwyllys if (p12_elem == NULL) { 2962*99ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 2963*99ebb4caSwyllys HANDLE_PK12_ERROR 2964*99ebb4caSwyllys } 2965*99ebb4caSwyllys 2966*99ebb4caSwyllys /* Put the PKCS#7 stack into the PKCS#12 element. */ 2967*99ebb4caSwyllys if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) { 2968*99ebb4caSwyllys HANDLE_PK12_ERROR 2969*99ebb4caSwyllys } 2970*99ebb4caSwyllys /* Clear away the PKCS#7 stack, we're done with it. */ 2971*99ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 2972*99ebb4caSwyllys authsafe_stack = NULL; 2973*99ebb4caSwyllys 2974*99ebb4caSwyllys /* Set the integrity MAC on the PKCS#12 element. */ 2975*99ebb4caSwyllys if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen, 2976*99ebb4caSwyllys NULL, 0, PKCS12_DEFAULT_ITER, NULL)) { 2977*99ebb4caSwyllys HANDLE_PK12_ERROR 2978*99ebb4caSwyllys } 2979*99ebb4caSwyllys 2980*99ebb4caSwyllys /* Write the PKCS#12 element to the export file. */ 2981*99ebb4caSwyllys if (!i2d_PKCS12_bio(bio, p12_elem)) { 2982*99ebb4caSwyllys HANDLE_PK12_ERROR 2983*99ebb4caSwyllys } 2984*99ebb4caSwyllys 2985*99ebb4caSwyllys PKCS12_free(p12_elem); 2986*99ebb4caSwyllys out: 2987*99ebb4caSwyllys if (rv != KMF_OK) { 2988*99ebb4caSwyllys /* Clear away this bag_stack, we're done with it. */ 2989*99ebb4caSwyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 2990*99ebb4caSwyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 2991*99ebb4caSwyllys } 2992*99ebb4caSwyllys return (rv); 2993*99ebb4caSwyllys } 2994*99ebb4caSwyllys 2995*99ebb4caSwyllys static EVP_PKEY * 2996*99ebb4caSwyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *key) 2997*99ebb4caSwyllys { 2998*99ebb4caSwyllys RSA *rsa = NULL; 2999*99ebb4caSwyllys EVP_PKEY *newkey = NULL; 3000*99ebb4caSwyllys 3001*99ebb4caSwyllys if ((rsa = RSA_new()) == NULL) 3002*99ebb4caSwyllys return (NULL); 3003*99ebb4caSwyllys 3004*99ebb4caSwyllys if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL) 3005*99ebb4caSwyllys return (NULL); 3006*99ebb4caSwyllys 3007*99ebb4caSwyllys if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) == 3008*99ebb4caSwyllys NULL) 3009*99ebb4caSwyllys return (NULL); 3010*99ebb4caSwyllys 3011*99ebb4caSwyllys if (key->priexp.val != NULL) 3012*99ebb4caSwyllys if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len, 3013*99ebb4caSwyllys rsa->d)) == NULL) 3014*99ebb4caSwyllys return (NULL); 3015*99ebb4caSwyllys 3016*99ebb4caSwyllys if (key->prime1.val != NULL) 3017*99ebb4caSwyllys if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len, 3018*99ebb4caSwyllys rsa->p)) == NULL) 3019*99ebb4caSwyllys return (NULL); 3020*99ebb4caSwyllys 3021*99ebb4caSwyllys if (key->prime2.val != NULL) 3022*99ebb4caSwyllys if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len, 3023*99ebb4caSwyllys rsa->q)) == NULL) 3024*99ebb4caSwyllys return (NULL); 3025*99ebb4caSwyllys 3026*99ebb4caSwyllys if (key->exp1.val != NULL) 3027*99ebb4caSwyllys if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, 3028*99ebb4caSwyllys rsa->dmp1)) == NULL) 3029*99ebb4caSwyllys return (NULL); 3030*99ebb4caSwyllys 3031*99ebb4caSwyllys if (key->exp2.val != NULL) 3032*99ebb4caSwyllys if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, 3033*99ebb4caSwyllys rsa->dmq1)) == NULL) 3034*99ebb4caSwyllys return (NULL); 3035*99ebb4caSwyllys 3036*99ebb4caSwyllys if (key->coef.val != NULL) 3037*99ebb4caSwyllys if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len, 3038*99ebb4caSwyllys rsa->iqmp)) == NULL) 3039*99ebb4caSwyllys return (NULL); 3040*99ebb4caSwyllys 3041*99ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 3042*99ebb4caSwyllys return (NULL); 3043*99ebb4caSwyllys 3044*99ebb4caSwyllys (void) EVP_PKEY_set1_RSA(newkey, rsa); 3045*99ebb4caSwyllys 3046*99ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 3047*99ebb4caSwyllys RSA_free(rsa); 3048*99ebb4caSwyllys 3049*99ebb4caSwyllys return (newkey); 3050*99ebb4caSwyllys } 3051*99ebb4caSwyllys 3052*99ebb4caSwyllys static EVP_PKEY * 3053*99ebb4caSwyllys ImportRawDSAKey(KMF_RAW_DSA_KEY *key) 3054*99ebb4caSwyllys { 3055*99ebb4caSwyllys DSA *dsa = NULL; 3056*99ebb4caSwyllys EVP_PKEY *newkey = NULL; 3057*99ebb4caSwyllys 3058*99ebb4caSwyllys if ((dsa = DSA_new()) == NULL) 3059*99ebb4caSwyllys return (NULL); 3060*99ebb4caSwyllys 3061*99ebb4caSwyllys if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len, 3062*99ebb4caSwyllys dsa->p)) == NULL) 3063*99ebb4caSwyllys return (NULL); 3064*99ebb4caSwyllys 3065*99ebb4caSwyllys if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len, 3066*99ebb4caSwyllys dsa->q)) == NULL) 3067*99ebb4caSwyllys return (NULL); 3068*99ebb4caSwyllys 3069*99ebb4caSwyllys if ((dsa->g = BN_bin2bn(key->base.val, key->base.len, 3070*99ebb4caSwyllys dsa->g)) == NULL) 3071*99ebb4caSwyllys return (NULL); 3072*99ebb4caSwyllys 3073*99ebb4caSwyllys if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len, 3074*99ebb4caSwyllys dsa->priv_key)) == NULL) 3075*99ebb4caSwyllys return (NULL); 3076*99ebb4caSwyllys 3077*99ebb4caSwyllys if ((newkey = EVP_PKEY_new()) == NULL) 3078*99ebb4caSwyllys return (NULL); 3079*99ebb4caSwyllys 3080*99ebb4caSwyllys (void) EVP_PKEY_set1_DSA(newkey, dsa); 3081*99ebb4caSwyllys 3082*99ebb4caSwyllys /* The original key must be freed once here or it leaks memory */ 3083*99ebb4caSwyllys DSA_free(dsa); 3084*99ebb4caSwyllys return (newkey); 3085*99ebb4caSwyllys } 3086*99ebb4caSwyllys 3087*99ebb4caSwyllys static KMF_RETURN 3088*99ebb4caSwyllys ExportPK12FromRawData(KMF_HANDLE_T handle, 3089*99ebb4caSwyllys KMF_CREDENTIAL *cred, 3090*99ebb4caSwyllys int numcerts, KMF_X509_DER_CERT *certlist, 3091*99ebb4caSwyllys int numkeys, KMF_KEY_HANDLE *keylist, 3092*99ebb4caSwyllys char *filename) 3093*99ebb4caSwyllys { 3094*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 3095*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3096*99ebb4caSwyllys BIO *bio = NULL; 3097*99ebb4caSwyllys X509 *xcert = NULL; 3098*99ebb4caSwyllys EVP_PKEY *pkey = NULL; 3099*99ebb4caSwyllys int i; 3100*99ebb4caSwyllys 3101*99ebb4caSwyllys /* 3102*99ebb4caSwyllys * Open the output file. 3103*99ebb4caSwyllys */ 3104*99ebb4caSwyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) { 3105*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 3106*99ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 3107*99ebb4caSwyllys goto cleanup; 3108*99ebb4caSwyllys } 3109*99ebb4caSwyllys 3110*99ebb4caSwyllys if (numcerts > 0 && numkeys > 0) { 3111*99ebb4caSwyllys for (i = 0; rv == KMF_OK && i < numcerts; i++) { 3112*99ebb4caSwyllys KMF_RAW_KEY_DATA *key = NULL; 3113*99ebb4caSwyllys const uchar_t *p = certlist[i].certificate.Data; 3114*99ebb4caSwyllys long len = certlist[i].certificate.Length; 3115*99ebb4caSwyllys 3116*99ebb4caSwyllys if (i < numkeys) { 3117*99ebb4caSwyllys key = (KMF_RAW_KEY_DATA *)keylist[i].keyp; 3118*99ebb4caSwyllys 3119*99ebb4caSwyllys if (key->keytype == KMF_RSA) { 3120*99ebb4caSwyllys pkey = ImportRawRSAKey( 3121*99ebb4caSwyllys &key->rawdata.rsa); 3122*99ebb4caSwyllys } else if (key->keytype == KMF_DSA) { 3123*99ebb4caSwyllys pkey = ImportRawDSAKey( 3124*99ebb4caSwyllys &key->rawdata.dsa); 3125*99ebb4caSwyllys } else { 3126*99ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 3127*99ebb4caSwyllys } 3128*99ebb4caSwyllys } 3129*99ebb4caSwyllys 3130*99ebb4caSwyllys xcert = d2i_X509(NULL, &p, len); 3131*99ebb4caSwyllys if (xcert == NULL) { 3132*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 3133*99ebb4caSwyllys rv = KMF_ERR_ENCODING; 3134*99ebb4caSwyllys } 3135*99ebb4caSwyllys /* Stick the key and the cert into a PKCS#12 file */ 3136*99ebb4caSwyllys rv = write_pkcs12(kmfh, bio, cred, pkey, xcert); 3137*99ebb4caSwyllys if (xcert) 3138*99ebb4caSwyllys X509_free(xcert); 3139*99ebb4caSwyllys if (pkey) 3140*99ebb4caSwyllys EVP_PKEY_free(pkey); 3141*99ebb4caSwyllys } 3142*99ebb4caSwyllys } 3143*99ebb4caSwyllys 3144*99ebb4caSwyllys cleanup: 3145*99ebb4caSwyllys 3146*99ebb4caSwyllys if (bio != NULL) 3147*99ebb4caSwyllys (void) BIO_free_all(bio); 3148*99ebb4caSwyllys 3149*99ebb4caSwyllys return (rv); 3150*99ebb4caSwyllys } 3151*99ebb4caSwyllys 3152*99ebb4caSwyllys KMF_RETURN 3153*99ebb4caSwyllys OpenSSL_ExportP12(KMF_HANDLE_T handle, 3154*99ebb4caSwyllys KMF_EXPORTP12_PARAMS *params, 3155*99ebb4caSwyllys int numcerts, KMF_X509_DER_CERT *certlist, 3156*99ebb4caSwyllys int numkeys, KMF_KEY_HANDLE *keylist, 3157*99ebb4caSwyllys char *filename) 3158*99ebb4caSwyllys { 3159*99ebb4caSwyllys KMF_RETURN rv; 3160*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3161*99ebb4caSwyllys KMF_FINDCERT_PARAMS fcargs; 3162*99ebb4caSwyllys BIO *bio = NULL; 3163*99ebb4caSwyllys X509 *xcert = NULL; 3164*99ebb4caSwyllys char *fullpath = NULL; 3165*99ebb4caSwyllys EVP_PKEY *pkey = NULL; 3166*99ebb4caSwyllys 3167*99ebb4caSwyllys /* 3168*99ebb4caSwyllys * First, find the certificate. 3169*99ebb4caSwyllys */ 3170*99ebb4caSwyllys if (params == NULL) 3171*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 3172*99ebb4caSwyllys 3173*99ebb4caSwyllys /* 3174*99ebb4caSwyllys * If the caller already sent the raw keys and certs, 3175*99ebb4caSwyllys * shortcut the search and just export that 3176*99ebb4caSwyllys * data. 3177*99ebb4caSwyllys * 3178*99ebb4caSwyllys * One *may* export a key OR a cert by itself. 3179*99ebb4caSwyllys */ 3180*99ebb4caSwyllys if (certlist != NULL || keylist != NULL) { 3181*99ebb4caSwyllys rv = ExportPK12FromRawData(handle, 3182*99ebb4caSwyllys ¶ms->p12cred, 3183*99ebb4caSwyllys numcerts, certlist, 3184*99ebb4caSwyllys numkeys, keylist, 3185*99ebb4caSwyllys filename); 3186*99ebb4caSwyllys return (rv); 3187*99ebb4caSwyllys } 3188*99ebb4caSwyllys 3189*99ebb4caSwyllys if (params->sslparms.certfile != NULL) { 3190*99ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 3191*99ebb4caSwyllys params->sslparms.certfile); 3192*99ebb4caSwyllys 3193*99ebb4caSwyllys if (fullpath == NULL) 3194*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 3195*99ebb4caSwyllys 3196*99ebb4caSwyllys if (isdir(fullpath)) { 3197*99ebb4caSwyllys free(fullpath); 3198*99ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 3199*99ebb4caSwyllys } 3200*99ebb4caSwyllys 3201*99ebb4caSwyllys (void *)memset(&fcargs, 0, sizeof (fcargs)); 3202*99ebb4caSwyllys fcargs.kstype = params->kstype; 3203*99ebb4caSwyllys fcargs.certLabel = params->certLabel; 3204*99ebb4caSwyllys fcargs.issuer = params->issuer; 3205*99ebb4caSwyllys fcargs.subject = params->subject; 3206*99ebb4caSwyllys fcargs.serial = params->serial; 3207*99ebb4caSwyllys fcargs.idstr = params->idstr; 3208*99ebb4caSwyllys fcargs.sslparms.dirpath = NULL; 3209*99ebb4caSwyllys fcargs.sslparms.certfile = fullpath; 3210*99ebb4caSwyllys fcargs.sslparms.format = params->sslparms.format; 3211*99ebb4caSwyllys 3212*99ebb4caSwyllys rv = load_X509cert(kmfh, &fcargs, fullpath, &xcert); 3213*99ebb4caSwyllys if (rv != KMF_OK) 3214*99ebb4caSwyllys goto end; 3215*99ebb4caSwyllys } 3216*99ebb4caSwyllys 3217*99ebb4caSwyllys /* 3218*99ebb4caSwyllys * Now find the private key. 3219*99ebb4caSwyllys */ 3220*99ebb4caSwyllys if (params->sslparms.keyfile != NULL) { 3221*99ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 3222*99ebb4caSwyllys params->sslparms.keyfile); 3223*99ebb4caSwyllys 3224*99ebb4caSwyllys if (fullpath == NULL) 3225*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 3226*99ebb4caSwyllys 3227*99ebb4caSwyllys if (isdir(fullpath)) { 3228*99ebb4caSwyllys free(fullpath); 3229*99ebb4caSwyllys return (KMF_ERR_AMBIGUOUS_PATHNAME); 3230*99ebb4caSwyllys } 3231*99ebb4caSwyllys 3232*99ebb4caSwyllys pkey = openssl_load_key(handle, fullpath); 3233*99ebb4caSwyllys if (pkey == NULL) { 3234*99ebb4caSwyllys rv = KMF_ERR_KEY_NOT_FOUND; 3235*99ebb4caSwyllys goto end; 3236*99ebb4caSwyllys } 3237*99ebb4caSwyllys } 3238*99ebb4caSwyllys 3239*99ebb4caSwyllys /* 3240*99ebb4caSwyllys * Open the output file. 3241*99ebb4caSwyllys */ 3242*99ebb4caSwyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) { 3243*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 3244*99ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 3245*99ebb4caSwyllys goto end; 3246*99ebb4caSwyllys } 3247*99ebb4caSwyllys 3248*99ebb4caSwyllys /* Stick the key and the cert into a PKCS#12 file */ 3249*99ebb4caSwyllys rv = write_pkcs12(kmfh, bio, ¶ms->p12cred, 3250*99ebb4caSwyllys pkey, xcert); 3251*99ebb4caSwyllys 3252*99ebb4caSwyllys end: 3253*99ebb4caSwyllys if (fullpath) 3254*99ebb4caSwyllys free(fullpath); 3255*99ebb4caSwyllys if (xcert) 3256*99ebb4caSwyllys X509_free(xcert); 3257*99ebb4caSwyllys if (pkey) 3258*99ebb4caSwyllys EVP_PKEY_free(pkey); 3259*99ebb4caSwyllys if (bio) 3260*99ebb4caSwyllys (void) BIO_free(bio); 3261*99ebb4caSwyllys 3262*99ebb4caSwyllys return (rv); 3263*99ebb4caSwyllys } 3264*99ebb4caSwyllys 3265*99ebb4caSwyllys /* 3266*99ebb4caSwyllys * Helper function to decrypt and parse PKCS#12 import file. 3267*99ebb4caSwyllys */ 3268*99ebb4caSwyllys static KMF_RETURN 3269*99ebb4caSwyllys extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 3270*99ebb4caSwyllys EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca) 3271*99ebb4caSwyllys /* ARGSUSED */ 3272*99ebb4caSwyllys { 3273*99ebb4caSwyllys PKCS12 *pk12, *pk12_tmp; 3274*99ebb4caSwyllys EVP_PKEY *temp_pkey = NULL; 3275*99ebb4caSwyllys X509 *temp_cert = NULL; 3276*99ebb4caSwyllys STACK_OF(X509) *temp_ca = NULL; 3277*99ebb4caSwyllys 3278*99ebb4caSwyllys if ((pk12 = PKCS12_new()) == NULL) { 3279*99ebb4caSwyllys return (KMF_ERR_MEMORY); 3280*99ebb4caSwyllys } 3281*99ebb4caSwyllys 3282*99ebb4caSwyllys if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) { 3283*99ebb4caSwyllys /* This is ok; it seems to mean there is no more to read. */ 3284*99ebb4caSwyllys if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 && 3285*99ebb4caSwyllys ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG) 3286*99ebb4caSwyllys goto end_extract_pkcs12; 3287*99ebb4caSwyllys 3288*99ebb4caSwyllys PKCS12_free(pk12); 3289*99ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 3290*99ebb4caSwyllys } 3291*99ebb4caSwyllys pk12 = pk12_tmp; 3292*99ebb4caSwyllys 3293*99ebb4caSwyllys if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert, 3294*99ebb4caSwyllys &temp_ca) <= 0) { 3295*99ebb4caSwyllys PKCS12_free(pk12); 3296*99ebb4caSwyllys return (KMF_ERR_PKCS12_FORMAT); 3297*99ebb4caSwyllys } 3298*99ebb4caSwyllys 3299*99ebb4caSwyllys end_extract_pkcs12: 3300*99ebb4caSwyllys 3301*99ebb4caSwyllys *priv_key = temp_pkey; 3302*99ebb4caSwyllys *cert = temp_cert; 3303*99ebb4caSwyllys *ca = temp_ca; 3304*99ebb4caSwyllys 3305*99ebb4caSwyllys PKCS12_free(pk12); 3306*99ebb4caSwyllys return (KMF_OK); 3307*99ebb4caSwyllys } 3308*99ebb4caSwyllys 3309*99ebb4caSwyllys static KMF_RETURN 3310*99ebb4caSwyllys sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to) 3311*99ebb4caSwyllys { 3312*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 3313*99ebb4caSwyllys uint32_t sz; 3314*99ebb4caSwyllys 3315*99ebb4caSwyllys sz = BN_num_bytes(from); 3316*99ebb4caSwyllys to->val = (uchar_t *)malloc(sz); 3317*99ebb4caSwyllys if (to->val == NULL) 3318*99ebb4caSwyllys return (KMF_ERR_MEMORY); 3319*99ebb4caSwyllys 3320*99ebb4caSwyllys if ((to->len = BN_bn2bin(from, to->val)) != sz) { 3321*99ebb4caSwyllys free(to->val); 3322*99ebb4caSwyllys to->val = NULL; 3323*99ebb4caSwyllys to->len = 0; 3324*99ebb4caSwyllys rv = KMF_ERR_MEMORY; 3325*99ebb4caSwyllys } 3326*99ebb4caSwyllys 3327*99ebb4caSwyllys return (rv); 3328*99ebb4caSwyllys } 3329*99ebb4caSwyllys 3330*99ebb4caSwyllys static KMF_RETURN 3331*99ebb4caSwyllys exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) 3332*99ebb4caSwyllys { 3333*99ebb4caSwyllys KMF_RETURN rv; 3334*99ebb4caSwyllys KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa; 3335*99ebb4caSwyllys 3336*99ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY)); 3337*99ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK) 3338*99ebb4caSwyllys goto cleanup; 3339*99ebb4caSwyllys 3340*99ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK) 3341*99ebb4caSwyllys goto cleanup; 3342*99ebb4caSwyllys 3343*99ebb4caSwyllys if (rsa->d != NULL) 3344*99ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK) 3345*99ebb4caSwyllys goto cleanup; 3346*99ebb4caSwyllys 3347*99ebb4caSwyllys if (rsa->p != NULL) 3348*99ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK) 3349*99ebb4caSwyllys goto cleanup; 3350*99ebb4caSwyllys 3351*99ebb4caSwyllys if (rsa->q != NULL) 3352*99ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK) 3353*99ebb4caSwyllys goto cleanup; 3354*99ebb4caSwyllys 3355*99ebb4caSwyllys if (rsa->dmp1 != NULL) 3356*99ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK) 3357*99ebb4caSwyllys goto cleanup; 3358*99ebb4caSwyllys 3359*99ebb4caSwyllys if (rsa->dmq1 != NULL) 3360*99ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK) 3361*99ebb4caSwyllys goto cleanup; 3362*99ebb4caSwyllys 3363*99ebb4caSwyllys if (rsa->iqmp != NULL) 3364*99ebb4caSwyllys if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK) 3365*99ebb4caSwyllys goto cleanup; 3366*99ebb4caSwyllys cleanup: 3367*99ebb4caSwyllys if (rv != KMF_OK) 3368*99ebb4caSwyllys KMF_FreeRawKey(key); 3369*99ebb4caSwyllys else 3370*99ebb4caSwyllys key->keytype = KMF_RSA; 3371*99ebb4caSwyllys 3372*99ebb4caSwyllys /* 3373*99ebb4caSwyllys * Free the reference to this key, SSL will not actually free 3374*99ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 3375*99ebb4caSwyllys */ 3376*99ebb4caSwyllys RSA_free(rsa); 3377*99ebb4caSwyllys 3378*99ebb4caSwyllys return (rv); 3379*99ebb4caSwyllys } 3380*99ebb4caSwyllys 3381*99ebb4caSwyllys static KMF_RETURN 3382*99ebb4caSwyllys exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) 3383*99ebb4caSwyllys { 3384*99ebb4caSwyllys KMF_RETURN rv; 3385*99ebb4caSwyllys KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa; 3386*99ebb4caSwyllys 3387*99ebb4caSwyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY)); 3388*99ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK) 3389*99ebb4caSwyllys goto cleanup; 3390*99ebb4caSwyllys 3391*99ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK) 3392*99ebb4caSwyllys goto cleanup; 3393*99ebb4caSwyllys 3394*99ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK) 3395*99ebb4caSwyllys goto cleanup; 3396*99ebb4caSwyllys 3397*99ebb4caSwyllys if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK) 3398*99ebb4caSwyllys goto cleanup; 3399*99ebb4caSwyllys 3400*99ebb4caSwyllys cleanup: 3401*99ebb4caSwyllys if (rv != KMF_OK) 3402*99ebb4caSwyllys KMF_FreeRawKey(key); 3403*99ebb4caSwyllys else 3404*99ebb4caSwyllys key->keytype = KMF_DSA; 3405*99ebb4caSwyllys 3406*99ebb4caSwyllys /* 3407*99ebb4caSwyllys * Free the reference to this key, SSL will not actually free 3408*99ebb4caSwyllys * the memory until the refcount == 0, so this is safe. 3409*99ebb4caSwyllys */ 3410*99ebb4caSwyllys DSA_free(dsa); 3411*99ebb4caSwyllys 3412*99ebb4caSwyllys return (rv); 3413*99ebb4caSwyllys } 3414*99ebb4caSwyllys 3415*99ebb4caSwyllys static KMF_RETURN 3416*99ebb4caSwyllys add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert, 3417*99ebb4caSwyllys KMF_DATA **certlist, int *ncerts) 3418*99ebb4caSwyllys { 3419*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 3420*99ebb4caSwyllys KMF_DATA *list = (*certlist); 3421*99ebb4caSwyllys KMF_DATA cert; 3422*99ebb4caSwyllys int n = (*ncerts); 3423*99ebb4caSwyllys 3424*99ebb4caSwyllys if (list == NULL) { 3425*99ebb4caSwyllys list = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 3426*99ebb4caSwyllys } else { 3427*99ebb4caSwyllys list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1)); 3428*99ebb4caSwyllys } 3429*99ebb4caSwyllys 3430*99ebb4caSwyllys if (list == NULL) 3431*99ebb4caSwyllys return (KMF_ERR_MEMORY); 3432*99ebb4caSwyllys 3433*99ebb4caSwyllys rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert); 3434*99ebb4caSwyllys if (rv == KMF_OK) { 3435*99ebb4caSwyllys list[n] = cert; 3436*99ebb4caSwyllys (*ncerts) = n + 1; 3437*99ebb4caSwyllys 3438*99ebb4caSwyllys *certlist = list; 3439*99ebb4caSwyllys } else { 3440*99ebb4caSwyllys free(list); 3441*99ebb4caSwyllys } 3442*99ebb4caSwyllys 3443*99ebb4caSwyllys return (rv); 3444*99ebb4caSwyllys } 3445*99ebb4caSwyllys 3446*99ebb4caSwyllys static KMF_RETURN 3447*99ebb4caSwyllys add_key_to_list(KMF_RAW_KEY_DATA **keylist, 3448*99ebb4caSwyllys KMF_RAW_KEY_DATA *newkey, int *nkeys) 3449*99ebb4caSwyllys { 3450*99ebb4caSwyllys KMF_RAW_KEY_DATA *list = (*keylist); 3451*99ebb4caSwyllys int n = (*nkeys); 3452*99ebb4caSwyllys 3453*99ebb4caSwyllys if (list == NULL) { 3454*99ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA)); 3455*99ebb4caSwyllys } else { 3456*99ebb4caSwyllys list = (KMF_RAW_KEY_DATA *)realloc(list, 3457*99ebb4caSwyllys sizeof (KMF_RAW_KEY_DATA) * (n + 1)); 3458*99ebb4caSwyllys } 3459*99ebb4caSwyllys 3460*99ebb4caSwyllys if (list == NULL) 3461*99ebb4caSwyllys return (KMF_ERR_MEMORY); 3462*99ebb4caSwyllys 3463*99ebb4caSwyllys list[n] = *newkey; 3464*99ebb4caSwyllys (*nkeys) = n + 1; 3465*99ebb4caSwyllys 3466*99ebb4caSwyllys *keylist = list; 3467*99ebb4caSwyllys 3468*99ebb4caSwyllys return (KMF_OK); 3469*99ebb4caSwyllys } 3470*99ebb4caSwyllys 3471*99ebb4caSwyllys 3472*99ebb4caSwyllys static KMF_RETURN 3473*99ebb4caSwyllys convertPK12Objects( 3474*99ebb4caSwyllys KMF_HANDLE *kmfh, 3475*99ebb4caSwyllys EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts, 3476*99ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys, 3477*99ebb4caSwyllys KMF_DATA **certlist, int *ncerts) 3478*99ebb4caSwyllys { 3479*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 3480*99ebb4caSwyllys KMF_RAW_KEY_DATA key; 3481*99ebb4caSwyllys int i; 3482*99ebb4caSwyllys 3483*99ebb4caSwyllys if (sslkey != NULL) { 3484*99ebb4caSwyllys /* Convert SSL key to raw key */ 3485*99ebb4caSwyllys switch (sslkey->type) { 3486*99ebb4caSwyllys case EVP_PKEY_RSA: 3487*99ebb4caSwyllys rv = exportRawRSAKey(EVP_PKEY_get1_RSA(sslkey), 3488*99ebb4caSwyllys &key); 3489*99ebb4caSwyllys if (rv != KMF_OK) 3490*99ebb4caSwyllys return (rv); 3491*99ebb4caSwyllys 3492*99ebb4caSwyllys break; 3493*99ebb4caSwyllys case EVP_PKEY_DSA: 3494*99ebb4caSwyllys rv = exportRawDSAKey(EVP_PKEY_get1_DSA(sslkey), 3495*99ebb4caSwyllys &key); 3496*99ebb4caSwyllys if (rv != KMF_OK) 3497*99ebb4caSwyllys return (rv); 3498*99ebb4caSwyllys 3499*99ebb4caSwyllys break; 3500*99ebb4caSwyllys default: 3501*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 3502*99ebb4caSwyllys } 3503*99ebb4caSwyllys 3504*99ebb4caSwyllys rv = add_key_to_list(keylist, &key, nkeys); 3505*99ebb4caSwyllys if (rv != KMF_OK) 3506*99ebb4caSwyllys return (rv); 3507*99ebb4caSwyllys } 3508*99ebb4caSwyllys 3509*99ebb4caSwyllys /* Now add the certificate to the certlist */ 3510*99ebb4caSwyllys if (sslcert != NULL) { 3511*99ebb4caSwyllys rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts); 3512*99ebb4caSwyllys if (rv != KMF_OK) 3513*99ebb4caSwyllys return (rv); 3514*99ebb4caSwyllys } 3515*99ebb4caSwyllys 3516*99ebb4caSwyllys /* Also add any included CA certs to the list */ 3517*99ebb4caSwyllys for (i = 0; i != sk_X509_num(sslcacerts); i++) { 3518*99ebb4caSwyllys X509 *c; 3519*99ebb4caSwyllys /* 3520*99ebb4caSwyllys * sk_X509_value() is macro that embeds a cast to (X509 *). 3521*99ebb4caSwyllys * Here it translates into ((X509 *)sk_value((ca), (i))). 3522*99ebb4caSwyllys * Lint is complaining about the embedded casting, and 3523*99ebb4caSwyllys * to fix it, you need to fix openssl header files. 3524*99ebb4caSwyllys */ 3525*99ebb4caSwyllys /* LINTED E_BAD_PTR_CAST_ALIGN */ 3526*99ebb4caSwyllys c = sk_X509_value(sslcacerts, i); 3527*99ebb4caSwyllys 3528*99ebb4caSwyllys /* Now add the ca cert to the certlist */ 3529*99ebb4caSwyllys rv = add_cert_to_list(kmfh, c, certlist, ncerts); 3530*99ebb4caSwyllys if (rv != KMF_OK) 3531*99ebb4caSwyllys return (rv); 3532*99ebb4caSwyllys } 3533*99ebb4caSwyllys return (rv); 3534*99ebb4caSwyllys } 3535*99ebb4caSwyllys 3536*99ebb4caSwyllys KMF_RETURN 3537*99ebb4caSwyllys openssl_read_pkcs12(KMF_HANDLE *kmfh, 3538*99ebb4caSwyllys char *filename, KMF_CREDENTIAL *cred, 3539*99ebb4caSwyllys KMF_DATA **certlist, int *ncerts, 3540*99ebb4caSwyllys KMF_RAW_KEY_DATA **keylist, int *nkeys) 3541*99ebb4caSwyllys { 3542*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 3543*99ebb4caSwyllys BIO *bio = NULL; 3544*99ebb4caSwyllys EVP_PKEY *privkey = NULL; 3545*99ebb4caSwyllys X509 *cert = NULL; 3546*99ebb4caSwyllys STACK_OF(X509) *cacerts = NULL; 3547*99ebb4caSwyllys 3548*99ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 3549*99ebb4caSwyllys if (bio == NULL) { 3550*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 3551*99ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 3552*99ebb4caSwyllys goto end; 3553*99ebb4caSwyllys } 3554*99ebb4caSwyllys 3555*99ebb4caSwyllys *certlist = NULL; 3556*99ebb4caSwyllys *keylist = NULL; 3557*99ebb4caSwyllys *ncerts = 0; 3558*99ebb4caSwyllys *nkeys = 0; 3559*99ebb4caSwyllys while (rv == KMF_OK) { 3560*99ebb4caSwyllys rv = extract_pkcs12(bio, 3561*99ebb4caSwyllys (uchar_t *)cred->cred, 3562*99ebb4caSwyllys (uint32_t)cred->credlen, 3563*99ebb4caSwyllys &privkey, &cert, &cacerts); 3564*99ebb4caSwyllys 3565*99ebb4caSwyllys /* Reached end of import file? */ 3566*99ebb4caSwyllys if (rv == KMF_OK && privkey == NULL && 3567*99ebb4caSwyllys cert == NULL && cacerts == NULL) 3568*99ebb4caSwyllys break; 3569*99ebb4caSwyllys 3570*99ebb4caSwyllys if (rv == KMF_OK) 3571*99ebb4caSwyllys /* Convert keys and certs to exportable format */ 3572*99ebb4caSwyllys rv = convertPK12Objects(kmfh, privkey, cert, cacerts, 3573*99ebb4caSwyllys keylist, nkeys, certlist, ncerts); 3574*99ebb4caSwyllys 3575*99ebb4caSwyllys if (privkey) 3576*99ebb4caSwyllys EVP_PKEY_free(privkey); 3577*99ebb4caSwyllys 3578*99ebb4caSwyllys if (cert) 3579*99ebb4caSwyllys X509_free(cert); 3580*99ebb4caSwyllys 3581*99ebb4caSwyllys if (cacerts) 3582*99ebb4caSwyllys sk_X509_free(cacerts); 3583*99ebb4caSwyllys } 3584*99ebb4caSwyllys end: 3585*99ebb4caSwyllys if (bio != NULL) 3586*99ebb4caSwyllys (void) BIO_free(bio); 3587*99ebb4caSwyllys 3588*99ebb4caSwyllys if (privkey) 3589*99ebb4caSwyllys EVP_PKEY_free(privkey); 3590*99ebb4caSwyllys 3591*99ebb4caSwyllys if (cert) 3592*99ebb4caSwyllys X509_free(cert); 3593*99ebb4caSwyllys 3594*99ebb4caSwyllys if (cacerts) 3595*99ebb4caSwyllys sk_X509_free(cacerts); 3596*99ebb4caSwyllys 3597*99ebb4caSwyllys return (rv); 3598*99ebb4caSwyllys } 3599*99ebb4caSwyllys 3600*99ebb4caSwyllys KMF_RETURN 3601*99ebb4caSwyllys OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, 3602*99ebb4caSwyllys KMF_RAW_KEY_DATA *key) 3603*99ebb4caSwyllys { 3604*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 3605*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3606*99ebb4caSwyllys char *fullpath; 3607*99ebb4caSwyllys EVP_PKEY *pkey = NULL; 3608*99ebb4caSwyllys BIO *bio = NULL; 3609*99ebb4caSwyllys 3610*99ebb4caSwyllys if (key != NULL) { 3611*99ebb4caSwyllys if (key->keytype == KMF_RSA) { 3612*99ebb4caSwyllys pkey = ImportRawRSAKey(&key->rawdata.rsa); 3613*99ebb4caSwyllys } else if (key->keytype == KMF_DSA) { 3614*99ebb4caSwyllys pkey = ImportRawDSAKey(&key->rawdata.dsa); 3615*99ebb4caSwyllys } else { 3616*99ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 3617*99ebb4caSwyllys } 3618*99ebb4caSwyllys } else { 3619*99ebb4caSwyllys rv = KMF_ERR_BAD_PARAMETER; 3620*99ebb4caSwyllys } 3621*99ebb4caSwyllys if (rv != KMF_OK || pkey == NULL) 3622*99ebb4caSwyllys return (rv); 3623*99ebb4caSwyllys 3624*99ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 3625*99ebb4caSwyllys params->sslparms.keyfile); 3626*99ebb4caSwyllys 3627*99ebb4caSwyllys if (fullpath == NULL) 3628*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 3629*99ebb4caSwyllys 3630*99ebb4caSwyllys /* If the requested file exists, return an error */ 3631*99ebb4caSwyllys if (access(fullpath, F_OK) == 0) { 3632*99ebb4caSwyllys free(fullpath); 3633*99ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 3634*99ebb4caSwyllys } 3635*99ebb4caSwyllys 3636*99ebb4caSwyllys bio = BIO_new_file(fullpath, "wb"); 3637*99ebb4caSwyllys if (bio == NULL) { 3638*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 3639*99ebb4caSwyllys rv = KMF_ERR_OPEN_FILE; 3640*99ebb4caSwyllys goto cleanup; 3641*99ebb4caSwyllys } 3642*99ebb4caSwyllys 3643*99ebb4caSwyllys rv = ssl_write_private_key(kmfh, 3644*99ebb4caSwyllys params->sslparms.format, 3645*99ebb4caSwyllys bio, ¶ms->cred, pkey); 3646*99ebb4caSwyllys 3647*99ebb4caSwyllys cleanup: 3648*99ebb4caSwyllys if (fullpath) 3649*99ebb4caSwyllys free(fullpath); 3650*99ebb4caSwyllys 3651*99ebb4caSwyllys if (pkey) 3652*99ebb4caSwyllys EVP_PKEY_free(pkey); 3653*99ebb4caSwyllys 3654*99ebb4caSwyllys if (bio) 3655*99ebb4caSwyllys (void) BIO_free(bio); 3656*99ebb4caSwyllys 3657*99ebb4caSwyllys /* Protect the file by making it read-only */ 3658*99ebb4caSwyllys if (rv == KMF_OK) { 3659*99ebb4caSwyllys (void) chmod(fullpath, 0400); 3660*99ebb4caSwyllys } 3661*99ebb4caSwyllys return (rv); 3662*99ebb4caSwyllys } 3663*99ebb4caSwyllys 3664*99ebb4caSwyllys static KMF_RETURN 3665*99ebb4caSwyllys create_deskey(DES_cblock **deskey) 3666*99ebb4caSwyllys { 3667*99ebb4caSwyllys DES_cblock *key; 3668*99ebb4caSwyllys 3669*99ebb4caSwyllys key = (DES_cblock *) malloc(sizeof (DES_cblock)); 3670*99ebb4caSwyllys if (key == NULL) { 3671*99ebb4caSwyllys return (KMF_ERR_MEMORY); 3672*99ebb4caSwyllys } 3673*99ebb4caSwyllys 3674*99ebb4caSwyllys if (DES_random_key(key) == 0) { 3675*99ebb4caSwyllys free(key); 3676*99ebb4caSwyllys return (KMF_ERR_KEYGEN_FAILED); 3677*99ebb4caSwyllys } 3678*99ebb4caSwyllys 3679*99ebb4caSwyllys *deskey = key; 3680*99ebb4caSwyllys return (KMF_OK); 3681*99ebb4caSwyllys } 3682*99ebb4caSwyllys 3683*99ebb4caSwyllys #define KEYGEN_RETRY 3 3684*99ebb4caSwyllys #define DES3_KEY_SIZE 24 3685*99ebb4caSwyllys 3686*99ebb4caSwyllys static KMF_RETURN 3687*99ebb4caSwyllys create_des3key(unsigned char **des3key) 3688*99ebb4caSwyllys { 3689*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 3690*99ebb4caSwyllys DES_cblock *deskey1 = NULL; 3691*99ebb4caSwyllys DES_cblock *deskey2 = NULL; 3692*99ebb4caSwyllys DES_cblock *deskey3 = NULL; 3693*99ebb4caSwyllys unsigned char *newkey = NULL; 3694*99ebb4caSwyllys int retry; 3695*99ebb4caSwyllys 3696*99ebb4caSwyllys if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) { 3697*99ebb4caSwyllys return (KMF_ERR_MEMORY); 3698*99ebb4caSwyllys } 3699*99ebb4caSwyllys 3700*99ebb4caSwyllys /* create the 1st DES key */ 3701*99ebb4caSwyllys if ((ret = create_deskey(&deskey1)) != KMF_OK) { 3702*99ebb4caSwyllys goto out; 3703*99ebb4caSwyllys } 3704*99ebb4caSwyllys 3705*99ebb4caSwyllys /* 3706*99ebb4caSwyllys * Create the 2nd DES key and make sure its value is different 3707*99ebb4caSwyllys * from the 1st DES key. 3708*99ebb4caSwyllys */ 3709*99ebb4caSwyllys retry = 0; 3710*99ebb4caSwyllys do { 3711*99ebb4caSwyllys if (deskey2 != NULL) { 3712*99ebb4caSwyllys free(deskey2); 3713*99ebb4caSwyllys deskey2 = NULL; 3714*99ebb4caSwyllys } 3715*99ebb4caSwyllys 3716*99ebb4caSwyllys if ((ret = create_deskey(&deskey2)) != KMF_OK) { 3717*99ebb4caSwyllys goto out; 3718*99ebb4caSwyllys } 3719*99ebb4caSwyllys 3720*99ebb4caSwyllys if (memcmp((const void *) deskey1, (const void *) deskey2, 8) 3721*99ebb4caSwyllys == 0) { 3722*99ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 3723*99ebb4caSwyllys retry++; 3724*99ebb4caSwyllys } 3725*99ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 3726*99ebb4caSwyllys 3727*99ebb4caSwyllys if (ret != KMF_OK) { 3728*99ebb4caSwyllys goto out; 3729*99ebb4caSwyllys } 3730*99ebb4caSwyllys 3731*99ebb4caSwyllys /* 3732*99ebb4caSwyllys * Create the 3rd DES key and make sure its value is different 3733*99ebb4caSwyllys * from the 2nd DES key. 3734*99ebb4caSwyllys */ 3735*99ebb4caSwyllys retry = 0; 3736*99ebb4caSwyllys do { 3737*99ebb4caSwyllys if (deskey3 != NULL) { 3738*99ebb4caSwyllys free(deskey3); 3739*99ebb4caSwyllys deskey3 = NULL; 3740*99ebb4caSwyllys } 3741*99ebb4caSwyllys 3742*99ebb4caSwyllys if ((ret = create_deskey(&deskey3)) != KMF_OK) { 3743*99ebb4caSwyllys goto out; 3744*99ebb4caSwyllys } 3745*99ebb4caSwyllys 3746*99ebb4caSwyllys if (memcmp((const void *)deskey2, (const void *)deskey3, 8) 3747*99ebb4caSwyllys == 0) { 3748*99ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 3749*99ebb4caSwyllys retry++; 3750*99ebb4caSwyllys } 3751*99ebb4caSwyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 3752*99ebb4caSwyllys 3753*99ebb4caSwyllys if (ret != KMF_OK) { 3754*99ebb4caSwyllys goto out; 3755*99ebb4caSwyllys } 3756*99ebb4caSwyllys 3757*99ebb4caSwyllys /* Concatenate 3 DES keys into a DES3 key */ 3758*99ebb4caSwyllys (void) memcpy((void *)newkey, (const void *)deskey1, 8); 3759*99ebb4caSwyllys (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8); 3760*99ebb4caSwyllys (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8); 3761*99ebb4caSwyllys *des3key = newkey; 3762*99ebb4caSwyllys 3763*99ebb4caSwyllys out: 3764*99ebb4caSwyllys if (deskey1 != NULL) 3765*99ebb4caSwyllys free(deskey1); 3766*99ebb4caSwyllys 3767*99ebb4caSwyllys if (deskey2 != NULL) 3768*99ebb4caSwyllys free(deskey2); 3769*99ebb4caSwyllys 3770*99ebb4caSwyllys if (deskey3 != NULL) 3771*99ebb4caSwyllys free(deskey3); 3772*99ebb4caSwyllys 3773*99ebb4caSwyllys if (ret != KMF_OK && newkey != NULL) 3774*99ebb4caSwyllys free(newkey); 3775*99ebb4caSwyllys 3776*99ebb4caSwyllys return (ret); 3777*99ebb4caSwyllys } 3778*99ebb4caSwyllys 3779*99ebb4caSwyllys KMF_RETURN 3780*99ebb4caSwyllys OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, 3781*99ebb4caSwyllys KMF_KEY_HANDLE *symkey) 3782*99ebb4caSwyllys { 3783*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 3784*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3785*99ebb4caSwyllys char *fullpath = NULL; 3786*99ebb4caSwyllys KMF_RAW_SYM_KEY *rkey = NULL; 3787*99ebb4caSwyllys DES_cblock *deskey = NULL; 3788*99ebb4caSwyllys unsigned char *des3key = NULL; 3789*99ebb4caSwyllys unsigned char *random = NULL; 3790*99ebb4caSwyllys int fd = -1; 3791*99ebb4caSwyllys 3792*99ebb4caSwyllys if (kmfh == NULL) 3793*99ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 3794*99ebb4caSwyllys 3795*99ebb4caSwyllys if (params == NULL || params->sslparms.keyfile == NULL) { 3796*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 3797*99ebb4caSwyllys } 3798*99ebb4caSwyllys 3799*99ebb4caSwyllys fullpath = get_fullpath(params->sslparms.dirpath, 3800*99ebb4caSwyllys params->sslparms.keyfile); 3801*99ebb4caSwyllys if (fullpath == NULL) 3802*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 3803*99ebb4caSwyllys 3804*99ebb4caSwyllys /* If the requested file exists, return an error */ 3805*99ebb4caSwyllys if (access(fullpath, F_OK) == 0) { 3806*99ebb4caSwyllys free(fullpath); 3807*99ebb4caSwyllys return (KMF_ERR_DUPLICATE_KEYFILE); 3808*99ebb4caSwyllys } 3809*99ebb4caSwyllys 3810*99ebb4caSwyllys fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400); 3811*99ebb4caSwyllys if (fd == -1) { 3812*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 3813*99ebb4caSwyllys goto out; 3814*99ebb4caSwyllys } 3815*99ebb4caSwyllys 3816*99ebb4caSwyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 3817*99ebb4caSwyllys if (rkey == NULL) { 3818*99ebb4caSwyllys ret = KMF_ERR_MEMORY; 3819*99ebb4caSwyllys goto out; 3820*99ebb4caSwyllys } 3821*99ebb4caSwyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 3822*99ebb4caSwyllys 3823*99ebb4caSwyllys if (params->keytype == KMF_DES) { 3824*99ebb4caSwyllys if ((ret = create_deskey(&deskey)) != KMF_OK) { 3825*99ebb4caSwyllys goto out; 3826*99ebb4caSwyllys } 3827*99ebb4caSwyllys rkey->keydata.val = (uchar_t *)deskey; 3828*99ebb4caSwyllys rkey->keydata.len = 8; 3829*99ebb4caSwyllys 3830*99ebb4caSwyllys symkey->keyalg = KMF_DES; 3831*99ebb4caSwyllys 3832*99ebb4caSwyllys } else if (params->keytype == KMF_DES3) { 3833*99ebb4caSwyllys if ((ret = create_des3key(&des3key)) != KMF_OK) { 3834*99ebb4caSwyllys goto out; 3835*99ebb4caSwyllys } 3836*99ebb4caSwyllys rkey->keydata.val = (uchar_t *)des3key; 3837*99ebb4caSwyllys rkey->keydata.len = DES3_KEY_SIZE; 3838*99ebb4caSwyllys symkey->keyalg = KMF_DES3; 3839*99ebb4caSwyllys 3840*99ebb4caSwyllys } else if (params->keytype == KMF_AES || params->keytype == KMF_RC4) { 3841*99ebb4caSwyllys int bytes; 3842*99ebb4caSwyllys 3843*99ebb4caSwyllys if (params->keylength % 8 != 0) { 3844*99ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 3845*99ebb4caSwyllys goto out; 3846*99ebb4caSwyllys } 3847*99ebb4caSwyllys 3848*99ebb4caSwyllys if (params->keytype == KMF_AES) { 3849*99ebb4caSwyllys if (params->keylength != 128 && 3850*99ebb4caSwyllys params->keylength != 192 && 3851*99ebb4caSwyllys params->keylength != 256) { 3852*99ebb4caSwyllys ret = KMF_ERR_BAD_KEY_SIZE; 3853*99ebb4caSwyllys goto out; 3854*99ebb4caSwyllys } 3855*99ebb4caSwyllys } 3856*99ebb4caSwyllys 3857*99ebb4caSwyllys bytes = params->keylength/8; 3858*99ebb4caSwyllys random = malloc(bytes); 3859*99ebb4caSwyllys if (random == NULL) { 3860*99ebb4caSwyllys ret = KMF_ERR_MEMORY; 3861*99ebb4caSwyllys goto out; 3862*99ebb4caSwyllys } 3863*99ebb4caSwyllys if (RAND_bytes(random, bytes) != 1) { 3864*99ebb4caSwyllys ret = KMF_ERR_KEYGEN_FAILED; 3865*99ebb4caSwyllys goto out; 3866*99ebb4caSwyllys } 3867*99ebb4caSwyllys 3868*99ebb4caSwyllys rkey->keydata.val = (uchar_t *)random; 3869*99ebb4caSwyllys rkey->keydata.len = bytes; 3870*99ebb4caSwyllys symkey->keyalg = params->keytype; 3871*99ebb4caSwyllys 3872*99ebb4caSwyllys } else { 3873*99ebb4caSwyllys ret = KMF_ERR_BAD_KEY_TYPE; 3874*99ebb4caSwyllys goto out; 3875*99ebb4caSwyllys } 3876*99ebb4caSwyllys 3877*99ebb4caSwyllys (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len); 3878*99ebb4caSwyllys 3879*99ebb4caSwyllys symkey->kstype = KMF_KEYSTORE_OPENSSL; 3880*99ebb4caSwyllys symkey->keyclass = KMF_SYMMETRIC; 3881*99ebb4caSwyllys symkey->keylabel = (char *)fullpath; 3882*99ebb4caSwyllys symkey->israw = TRUE; 3883*99ebb4caSwyllys symkey->keyp = rkey; 3884*99ebb4caSwyllys 3885*99ebb4caSwyllys out: 3886*99ebb4caSwyllys if (fd != -1) 3887*99ebb4caSwyllys (void) close(fd); 3888*99ebb4caSwyllys 3889*99ebb4caSwyllys if (ret != KMF_OK && fullpath != NULL) { 3890*99ebb4caSwyllys free(fullpath); 3891*99ebb4caSwyllys } 3892*99ebb4caSwyllys if (ret != KMF_OK) { 3893*99ebb4caSwyllys KMF_FreeRawSymKey(rkey); 3894*99ebb4caSwyllys symkey->keyp = NULL; 3895*99ebb4caSwyllys symkey->keyalg = KMF_KEYALG_NONE; 3896*99ebb4caSwyllys } 3897*99ebb4caSwyllys 3898*99ebb4caSwyllys return (ret); 3899*99ebb4caSwyllys } 3900*99ebb4caSwyllys 3901*99ebb4caSwyllys 3902*99ebb4caSwyllys KMF_RETURN 3903*99ebb4caSwyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params) 3904*99ebb4caSwyllys { 3905*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 3906*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3907*99ebb4caSwyllys BIO *bcrl = NULL; 3908*99ebb4caSwyllys X509_CRL *xcrl = NULL; 3909*99ebb4caSwyllys X509 *xcert = NULL; 3910*99ebb4caSwyllys EVP_PKEY *pkey; 3911*99ebb4caSwyllys int sslret; 3912*99ebb4caSwyllys KMF_ENCODE_FORMAT crl_format; 3913*99ebb4caSwyllys unsigned char *p; 3914*99ebb4caSwyllys long len; 3915*99ebb4caSwyllys 3916*99ebb4caSwyllys if (params->crl_name == NULL || params->tacert == NULL) { 3917*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 3918*99ebb4caSwyllys } 3919*99ebb4caSwyllys 3920*99ebb4caSwyllys ret = KMF_GetFileFormat(params->crl_name, &crl_format); 3921*99ebb4caSwyllys if (ret != KMF_OK) 3922*99ebb4caSwyllys return (ret); 3923*99ebb4caSwyllys 3924*99ebb4caSwyllys bcrl = BIO_new_file(params->crl_name, "rb"); 3925*99ebb4caSwyllys if (bcrl == NULL) { 3926*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 3927*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 3928*99ebb4caSwyllys goto cleanup; 3929*99ebb4caSwyllys } 3930*99ebb4caSwyllys 3931*99ebb4caSwyllys if (crl_format == KMF_FORMAT_ASN1) { 3932*99ebb4caSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 3933*99ebb4caSwyllys } else if (crl_format == KMF_FORMAT_PEM) { 3934*99ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 3935*99ebb4caSwyllys } else { 3936*99ebb4caSwyllys ret = KMF_ERR_BAD_PARAMETER; 3937*99ebb4caSwyllys goto cleanup; 3938*99ebb4caSwyllys } 3939*99ebb4caSwyllys 3940*99ebb4caSwyllys if (xcrl == NULL) { 3941*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 3942*99ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 3943*99ebb4caSwyllys goto cleanup; 3944*99ebb4caSwyllys } 3945*99ebb4caSwyllys 3946*99ebb4caSwyllys p = params->tacert->Data; 3947*99ebb4caSwyllys len = params->tacert->Length; 3948*99ebb4caSwyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, len); 3949*99ebb4caSwyllys 3950*99ebb4caSwyllys if (xcert == NULL) { 3951*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 3952*99ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 3953*99ebb4caSwyllys goto cleanup; 3954*99ebb4caSwyllys } 3955*99ebb4caSwyllys 3956*99ebb4caSwyllys /* Get issuer certificate public key */ 3957*99ebb4caSwyllys pkey = X509_get_pubkey(xcert); 3958*99ebb4caSwyllys if (!pkey) { 3959*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 3960*99ebb4caSwyllys ret = KMF_ERR_BAD_CERT_FORMAT; 3961*99ebb4caSwyllys goto cleanup; 3962*99ebb4caSwyllys } 3963*99ebb4caSwyllys 3964*99ebb4caSwyllys /* Verify CRL signature */ 3965*99ebb4caSwyllys sslret = X509_CRL_verify(xcrl, pkey); 3966*99ebb4caSwyllys EVP_PKEY_free(pkey); 3967*99ebb4caSwyllys if (sslret > 0) { 3968*99ebb4caSwyllys ret = KMF_OK; 3969*99ebb4caSwyllys } else { 3970*99ebb4caSwyllys SET_ERROR(kmfh, sslret); 3971*99ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 3972*99ebb4caSwyllys } 3973*99ebb4caSwyllys 3974*99ebb4caSwyllys cleanup: 3975*99ebb4caSwyllys if (bcrl != NULL) 3976*99ebb4caSwyllys (void) BIO_free(bcrl); 3977*99ebb4caSwyllys 3978*99ebb4caSwyllys if (xcrl != NULL) 3979*99ebb4caSwyllys X509_CRL_free(xcrl); 3980*99ebb4caSwyllys 3981*99ebb4caSwyllys if (xcert != NULL) 3982*99ebb4caSwyllys X509_free(xcert); 3983*99ebb4caSwyllys 3984*99ebb4caSwyllys return (ret); 3985*99ebb4caSwyllys 3986*99ebb4caSwyllys } 3987*99ebb4caSwyllys 3988*99ebb4caSwyllys KMF_RETURN 3989*99ebb4caSwyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, 3990*99ebb4caSwyllys KMF_CHECKCRLDATE_PARAMS *params) 3991*99ebb4caSwyllys { 3992*99ebb4caSwyllys 3993*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 3994*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3995*99ebb4caSwyllys KMF_ENCODE_FORMAT crl_format; 3996*99ebb4caSwyllys BIO *bcrl = NULL; 3997*99ebb4caSwyllys X509_CRL *xcrl = NULL; 3998*99ebb4caSwyllys int i; 3999*99ebb4caSwyllys 4000*99ebb4caSwyllys if (params == NULL || params->crl_name == NULL) { 4001*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 4002*99ebb4caSwyllys } 4003*99ebb4caSwyllys 4004*99ebb4caSwyllys ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format); 4005*99ebb4caSwyllys if (ret != KMF_OK) 4006*99ebb4caSwyllys return (ret); 4007*99ebb4caSwyllys 4008*99ebb4caSwyllys bcrl = BIO_new_file(params->crl_name, "rb"); 4009*99ebb4caSwyllys if (bcrl == NULL) { 4010*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 4011*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 4012*99ebb4caSwyllys goto cleanup; 4013*99ebb4caSwyllys } 4014*99ebb4caSwyllys 4015*99ebb4caSwyllys if (crl_format == KMF_FORMAT_ASN1) { 4016*99ebb4caSwyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL); 4017*99ebb4caSwyllys } else if (crl_format == KMF_FORMAT_PEM) { 4018*99ebb4caSwyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 4019*99ebb4caSwyllys } 4020*99ebb4caSwyllys 4021*99ebb4caSwyllys if (xcrl == NULL) { 4022*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 4023*99ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 4024*99ebb4caSwyllys goto cleanup; 4025*99ebb4caSwyllys } 4026*99ebb4caSwyllys 4027*99ebb4caSwyllys i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); 4028*99ebb4caSwyllys if (i >= 0) { 4029*99ebb4caSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 4030*99ebb4caSwyllys goto cleanup; 4031*99ebb4caSwyllys } 4032*99ebb4caSwyllys 4033*99ebb4caSwyllys if (X509_CRL_get_nextUpdate(xcrl)) { 4034*99ebb4caSwyllys i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); 4035*99ebb4caSwyllys 4036*99ebb4caSwyllys if (i <= 0) { 4037*99ebb4caSwyllys ret = KMF_ERR_VALIDITY_PERIOD; 4038*99ebb4caSwyllys goto cleanup; 4039*99ebb4caSwyllys } 4040*99ebb4caSwyllys } 4041*99ebb4caSwyllys 4042*99ebb4caSwyllys ret = KMF_OK; 4043*99ebb4caSwyllys 4044*99ebb4caSwyllys cleanup: 4045*99ebb4caSwyllys if (bcrl != NULL) 4046*99ebb4caSwyllys (void) BIO_free(bcrl); 4047*99ebb4caSwyllys 4048*99ebb4caSwyllys if (xcrl != NULL) 4049*99ebb4caSwyllys X509_CRL_free(xcrl); 4050*99ebb4caSwyllys 4051*99ebb4caSwyllys return (ret); 4052*99ebb4caSwyllys } 4053*99ebb4caSwyllys 4054*99ebb4caSwyllys /* 4055*99ebb4caSwyllys * Check a file to see if it is a CRL file with PEM or DER format. 4056*99ebb4caSwyllys * If success, return its format in the "pformat" argument. 4057*99ebb4caSwyllys */ 4058*99ebb4caSwyllys KMF_RETURN 4059*99ebb4caSwyllys OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat) 4060*99ebb4caSwyllys { 4061*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 4062*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4063*99ebb4caSwyllys BIO *bio = NULL; 4064*99ebb4caSwyllys X509_CRL *xcrl = NULL; 4065*99ebb4caSwyllys 4066*99ebb4caSwyllys if (filename == NULL) { 4067*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 4068*99ebb4caSwyllys } 4069*99ebb4caSwyllys 4070*99ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 4071*99ebb4caSwyllys if (bio == NULL) { 4072*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 4073*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 4074*99ebb4caSwyllys goto out; 4075*99ebb4caSwyllys } 4076*99ebb4caSwyllys 4077*99ebb4caSwyllys if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) { 4078*99ebb4caSwyllys *pformat = KMF_FORMAT_PEM; 4079*99ebb4caSwyllys goto out; 4080*99ebb4caSwyllys } 4081*99ebb4caSwyllys (void) BIO_free(bio); 4082*99ebb4caSwyllys 4083*99ebb4caSwyllys /* 4084*99ebb4caSwyllys * Now try to read it as raw DER data. 4085*99ebb4caSwyllys */ 4086*99ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 4087*99ebb4caSwyllys if (bio == NULL) { 4088*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 4089*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 4090*99ebb4caSwyllys goto out; 4091*99ebb4caSwyllys } 4092*99ebb4caSwyllys 4093*99ebb4caSwyllys if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) { 4094*99ebb4caSwyllys *pformat = KMF_FORMAT_ASN1; 4095*99ebb4caSwyllys } else { 4096*99ebb4caSwyllys ret = KMF_ERR_BAD_CRLFILE; 4097*99ebb4caSwyllys } 4098*99ebb4caSwyllys 4099*99ebb4caSwyllys out: 4100*99ebb4caSwyllys if (bio != NULL) 4101*99ebb4caSwyllys (void) BIO_free(bio); 4102*99ebb4caSwyllys 4103*99ebb4caSwyllys if (xcrl != NULL) 4104*99ebb4caSwyllys X509_CRL_free(xcrl); 4105*99ebb4caSwyllys 4106*99ebb4caSwyllys return (ret); 4107*99ebb4caSwyllys } 4108*99ebb4caSwyllys 4109*99ebb4caSwyllys /* 4110*99ebb4caSwyllys * Check a file to see if it is a certficate file with PEM or DER format. 4111*99ebb4caSwyllys * If success, return its format in the pformat argument. 4112*99ebb4caSwyllys */ 4113*99ebb4caSwyllys KMF_RETURN 4114*99ebb4caSwyllys OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, 4115*99ebb4caSwyllys KMF_ENCODE_FORMAT *pformat) 4116*99ebb4caSwyllys { 4117*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 4118*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4119*99ebb4caSwyllys BIO *bio = NULL; 4120*99ebb4caSwyllys X509 *xcert = NULL; 4121*99ebb4caSwyllys 4122*99ebb4caSwyllys if (filename == NULL) { 4123*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 4124*99ebb4caSwyllys } 4125*99ebb4caSwyllys 4126*99ebb4caSwyllys ret = KMF_GetFileFormat(filename, pformat); 4127*99ebb4caSwyllys if (ret != KMF_OK) 4128*99ebb4caSwyllys return (ret); 4129*99ebb4caSwyllys 4130*99ebb4caSwyllys bio = BIO_new_file(filename, "rb"); 4131*99ebb4caSwyllys if (bio == NULL) { 4132*99ebb4caSwyllys SET_ERROR(kmfh, ERR_get_error()); 4133*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 4134*99ebb4caSwyllys goto out; 4135*99ebb4caSwyllys } 4136*99ebb4caSwyllys 4137*99ebb4caSwyllys if ((*pformat) == KMF_FORMAT_PEM) { 4138*99ebb4caSwyllys if ((xcert = PEM_read_bio_X509(bio, NULL, 4139*99ebb4caSwyllys NULL, NULL)) == NULL) { 4140*99ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 4141*99ebb4caSwyllys } 4142*99ebb4caSwyllys } else if ((*pformat) == KMF_FORMAT_ASN1) { 4143*99ebb4caSwyllys if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) { 4144*99ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 4145*99ebb4caSwyllys } 4146*99ebb4caSwyllys } else { 4147*99ebb4caSwyllys ret = KMF_ERR_BAD_CERTFILE; 4148*99ebb4caSwyllys } 4149*99ebb4caSwyllys 4150*99ebb4caSwyllys out: 4151*99ebb4caSwyllys if (bio != NULL) 4152*99ebb4caSwyllys (void) BIO_free(bio); 4153*99ebb4caSwyllys 4154*99ebb4caSwyllys if (xcert != NULL) 4155*99ebb4caSwyllys X509_free(xcert); 4156*99ebb4caSwyllys 4157*99ebb4caSwyllys return (ret); 4158*99ebb4caSwyllys } 4159*99ebb4caSwyllys 4160*99ebb4caSwyllys KMF_RETURN 4161*99ebb4caSwyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 4162*99ebb4caSwyllys KMF_RAW_SYM_KEY *rkey) 4163*99ebb4caSwyllys { 4164*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 4165*99ebb4caSwyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4166*99ebb4caSwyllys KMF_DATA keyvalue; 4167*99ebb4caSwyllys 4168*99ebb4caSwyllys if (kmfh == NULL) 4169*99ebb4caSwyllys return (KMF_ERR_UNINITIALIZED); 4170*99ebb4caSwyllys 4171*99ebb4caSwyllys if (symkey == NULL || rkey == NULL) 4172*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 4173*99ebb4caSwyllys else if (symkey->keyclass != KMF_SYMMETRIC) 4174*99ebb4caSwyllys return (KMF_ERR_BAD_KEY_CLASS); 4175*99ebb4caSwyllys 4176*99ebb4caSwyllys if (symkey->israw) { 4177*99ebb4caSwyllys KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp; 4178*99ebb4caSwyllys 4179*99ebb4caSwyllys if (rawkey == NULL || 4180*99ebb4caSwyllys rawkey->keydata.val == NULL || 4181*99ebb4caSwyllys rawkey->keydata.len == 0) 4182*99ebb4caSwyllys return (KMF_ERR_BAD_KEYHANDLE); 4183*99ebb4caSwyllys 4184*99ebb4caSwyllys rkey->keydata.len = rawkey->keydata.len; 4185*99ebb4caSwyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 4186*99ebb4caSwyllys return (KMF_ERR_MEMORY); 4187*99ebb4caSwyllys (void) memcpy(rkey->keydata.val, rawkey->keydata.val, 4188*99ebb4caSwyllys rkey->keydata.len); 4189*99ebb4caSwyllys } else { 4190*99ebb4caSwyllys rv = KMF_ReadInputFile(handle, symkey->keylabel, &keyvalue); 4191*99ebb4caSwyllys if (rv != KMF_OK) 4192*99ebb4caSwyllys return (rv); 4193*99ebb4caSwyllys rkey->keydata.len = keyvalue.Length; 4194*99ebb4caSwyllys rkey->keydata.val = keyvalue.Data; 4195*99ebb4caSwyllys } 4196*99ebb4caSwyllys 4197*99ebb4caSwyllys return (rv); 4198*99ebb4caSwyllys } 4199