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 /* 22*99ebb4caSwyllys * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*99ebb4caSwyllys * Use is subject to license terms. 24*99ebb4caSwyllys * 25*99ebb4caSwyllys * Copyright(c) 1995-2000 Intel Corporation. All rights reserved. 26*99ebb4caSwyllys */ 27*99ebb4caSwyllys 28*99ebb4caSwyllys #pragma ident "%Z%%M% %I% %E% SMI" 29*99ebb4caSwyllys 30*99ebb4caSwyllys #include <stdio.h> 31*99ebb4caSwyllys #include <dlfcn.h> 32*99ebb4caSwyllys #include <link.h> 33*99ebb4caSwyllys #include <fcntl.h> 34*99ebb4caSwyllys #include <ctype.h> 35*99ebb4caSwyllys #include <sys/param.h> 36*99ebb4caSwyllys #include <sys/types.h> 37*99ebb4caSwyllys #include <sys/stat.h> 38*99ebb4caSwyllys #include <errno.h> 39*99ebb4caSwyllys #include <sys/socket.h> 40*99ebb4caSwyllys #include <netinet/in.h> 41*99ebb4caSwyllys #include <arpa/inet.h> 42*99ebb4caSwyllys #include <thread.h> 43*99ebb4caSwyllys 44*99ebb4caSwyllys #include <ber_der.h> 45*99ebb4caSwyllys #include <kmfapiP.h> 46*99ebb4caSwyllys 47*99ebb4caSwyllys #include <pem_encode.h> 48*99ebb4caSwyllys #include <rdn_parser.h> 49*99ebb4caSwyllys #include <libxml2/libxml/uri.h> 50*99ebb4caSwyllys #include <libgen.h> 51*99ebb4caSwyllys #include <cryptoutil.h> 52*99ebb4caSwyllys 53*99ebb4caSwyllys static uchar_t pkcs11_initialized = 0; 54*99ebb4caSwyllys mutex_t init_lock = DEFAULTMUTEX; 55*99ebb4caSwyllys extern int errno; 56*99ebb4caSwyllys 57*99ebb4caSwyllys typedef struct { 58*99ebb4caSwyllys KMF_RETURN code; 59*99ebb4caSwyllys char *message; 60*99ebb4caSwyllys } kmf_error_map; 61*99ebb4caSwyllys 62*99ebb4caSwyllys static kmf_error_map kmf_errcodes[] = { 63*99ebb4caSwyllys {KMF_OK, "KMF_OK"}, 64*99ebb4caSwyllys {KMF_ERR_BAD_PARAMETER, "KMF_ERR_BAD_PARAMETER"}, 65*99ebb4caSwyllys {KMF_ERR_BAD_KEY_FORMAT, "KMF_ERR_BAD_KEY_FORMAT"}, 66*99ebb4caSwyllys {KMF_ERR_BAD_ALGORITHM, "KMF_ERR_BAD_ALGORITHM"}, 67*99ebb4caSwyllys {KMF_ERR_MEMORY, "KMF_ERR_MEMORY"}, 68*99ebb4caSwyllys {KMF_ERR_ENCODING, "KMF_ERR_ENCODING"}, 69*99ebb4caSwyllys {KMF_ERR_PLUGIN_INIT, "KMF_ERR_PLUGIN_INIT"}, 70*99ebb4caSwyllys {KMF_ERR_PLUGIN_NOTFOUND, "KMF_ERR_PLUGIN_NOTFOUND"}, 71*99ebb4caSwyllys {KMF_ERR_INTERNAL, "KMF_ERR_INTERNAL"}, 72*99ebb4caSwyllys {KMF_ERR_BAD_CERT_FORMAT, "KMF_ERR_BAD_CERT_FORMAT"}, 73*99ebb4caSwyllys {KMF_ERR_KEYGEN_FAILED, "KMF_ERR_KEYGEN_FAILED"}, 74*99ebb4caSwyllys {KMF_ERR_UNINITIALIZED, "KMF_ERR_UNINITIALIZED"}, 75*99ebb4caSwyllys {KMF_ERR_ISSUER, "KMF_ERR_ISSUER"}, 76*99ebb4caSwyllys {KMF_ERR_NOT_REVOKED, "KMF_ERR_NOT_REVOKED"}, 77*99ebb4caSwyllys {KMF_ERR_CERT_NOT_FOUND, "KMF_ERR_CERT_NOT_FOUND"}, 78*99ebb4caSwyllys {KMF_ERR_CRL_NOT_FOUND, "KMF_ERR_CRL_NOT_FOUND"}, 79*99ebb4caSwyllys {KMF_ERR_RDN_PARSER, "KMF_ERR_RDN_PARSER"}, 80*99ebb4caSwyllys {KMF_ERR_RDN_ATTR, "KMF_ERR_RDN_ATTR"}, 81*99ebb4caSwyllys {KMF_ERR_SLOTNAME, "KMF_ERR_SLOTNAME"}, 82*99ebb4caSwyllys {KMF_ERR_EMPTY_CRL, "KMF_ERR_EMPTY_CRL"}, 83*99ebb4caSwyllys {KMF_ERR_BUFFER_SIZE, "KMF_ERR_BUFFER_SIZE"}, 84*99ebb4caSwyllys {KMF_ERR_AUTH_FAILED, "KMF_ERR_AUTH_FAILED"}, 85*99ebb4caSwyllys {KMF_ERR_TOKEN_SELECTED, "KMF_ERR_TOKEN_SELECTED"}, 86*99ebb4caSwyllys {KMF_ERR_NO_TOKEN_SELECTED, "KMF_ERR_NO_TOKEN_SELECTED"}, 87*99ebb4caSwyllys {KMF_ERR_TOKEN_NOT_PRESENT, "KMF_ERR_TOKEN_NOT_PRESENT"}, 88*99ebb4caSwyllys {KMF_ERR_EXTENSION_NOT_FOUND, "KMF_ERR_EXTENSION_NOT_FOUND"}, 89*99ebb4caSwyllys {KMF_ERR_POLICY_ENGINE, "KMF_ERR_POLICY_ENGINE"}, 90*99ebb4caSwyllys {KMF_ERR_POLICY_DB_FORMAT, "KMF_ERR_POLICY_DB_FORMAT"}, 91*99ebb4caSwyllys {KMF_ERR_POLICY_NOT_FOUND, "KMF_ERR_POLICY_NOT_FOUND"}, 92*99ebb4caSwyllys {KMF_ERR_POLICY_DB_FILE, "KMF_ERR_POLICY_DB_FILE"}, 93*99ebb4caSwyllys {KMF_ERR_POLICY_NAME, "KMF_ERR_POLICY_NAME"}, 94*99ebb4caSwyllys {KMF_ERR_OCSP_POLICY, "KMF_ERR_OCSP_POLICY"}, 95*99ebb4caSwyllys {KMF_ERR_TA_POLICY, "KMF_ERR_TA_POLICY"}, 96*99ebb4caSwyllys {KMF_ERR_KEY_NOT_FOUND, "KMF_ERR_KEY_NOT_FOUND"}, 97*99ebb4caSwyllys {KMF_ERR_OPEN_FILE, "KMF_ERR_OPEN_FILE"}, 98*99ebb4caSwyllys {KMF_ERR_OCSP_BAD_ISSUER, "KMF_ERR_OCSP_BAD_ISSUER"}, 99*99ebb4caSwyllys {KMF_ERR_OCSP_BAD_CERT, "KMF_ERR_OCSP_BAD_CERT"}, 100*99ebb4caSwyllys {KMF_ERR_OCSP_CREATE_REQUEST, "KMF_ERR_OCSP_CREATE_REQUEST"}, 101*99ebb4caSwyllys {KMF_ERR_CONNECT_SERVER, "KMF_ERR_CONNECT_SERVER"}, 102*99ebb4caSwyllys {KMF_ERR_SEND_REQUEST, "KMF_ERR_SEND_REQUEST"}, 103*99ebb4caSwyllys {KMF_ERR_OCSP_CERTID, "KMF_ERR_OCSP_CERTID"}, 104*99ebb4caSwyllys {KMF_ERR_OCSP_MALFORMED_RESPONSE, "KMF_ERR_OCSP_MALFORMED_RESPONSE"}, 105*99ebb4caSwyllys {KMF_ERR_OCSP_RESPONSE_STATUS, "KMF_ERR_OCSP_RESPONSE_STATUS"}, 106*99ebb4caSwyllys {KMF_ERR_OCSP_NO_BASIC_RESPONSE, "KMF_ERR_OCSP_NO_BASIC_RESPONSE"}, 107*99ebb4caSwyllys {KMF_ERR_OCSP_BAD_SIGNER, "KMF_ERR_OCSP_BAD_SIGNER"}, 108*99ebb4caSwyllys {KMF_ERR_OCSP_RESPONSE_SIGNATURE, "KMF_ERR_OCSP_RESPONSE_SIGNATURE"}, 109*99ebb4caSwyllys {KMF_ERR_OCSP_UNKNOWN_CERT, "KMF_ERR_OCSP_UNKNOWN_CERT"}, 110*99ebb4caSwyllys {KMF_ERR_OCSP_STATUS_TIME_INVALID, "KMF_ERR_OCSP_STATUS_TIME_INVALID"}, 111*99ebb4caSwyllys {KMF_ERR_BAD_HTTP_RESPONSE, "KMF_ERR_BAD_HTTP_RESPONSE"}, 112*99ebb4caSwyllys {KMF_ERR_RECV_RESPONSE, "KMF_ERR_RECV_RESPONSE"}, 113*99ebb4caSwyllys {KMF_ERR_RECV_TIMEOUT, "KMF_ERR_RECV_TIMEOUT"}, 114*99ebb4caSwyllys {KMF_ERR_DUPLICATE_KEYFILE, "KMF_ERR_DUPLICATE_KEYFILE"}, 115*99ebb4caSwyllys {KMF_ERR_AMBIGUOUS_PATHNAME, "KMF_ERR_AMBIGUOUS_PATHNAME"}, 116*99ebb4caSwyllys {KMF_ERR_FUNCTION_NOT_FOUND, "KMF_ERR_FUNCTION_NOT_FOUND"}, 117*99ebb4caSwyllys {KMF_ERR_PKCS12_FORMAT, "KMF_ERR_PKCS12_FORMAT"}, 118*99ebb4caSwyllys {KMF_ERR_BAD_KEY_TYPE, "KMF_ERR_BAD_KEY_TYPE"}, 119*99ebb4caSwyllys {KMF_ERR_BAD_KEY_CLASS, "KMF_ERR_BAD_KEY_CLASS"}, 120*99ebb4caSwyllys {KMF_ERR_BAD_KEY_SIZE, "KMF_ERR_BAD_KEY_SIZE"}, 121*99ebb4caSwyllys {KMF_ERR_BAD_HEX_STRING, "KMF_ERR_BAD_HEX_STRING"}, 122*99ebb4caSwyllys {KMF_ERR_KEYUSAGE, "KMF_ERR_KEYUSAGE"}, 123*99ebb4caSwyllys {KMF_ERR_VALIDITY_PERIOD, "KMF_ERR_VALIDITY_PERIOD"}, 124*99ebb4caSwyllys {KMF_ERR_OCSP_REVOKED, "KMF_ERR_OCSP_REVOKED"}, 125*99ebb4caSwyllys {KMF_ERR_CERT_MULTIPLE_FOUND, "KMF_ERR_CERT_MULTIPLE_FOUND"}, 126*99ebb4caSwyllys {KMF_ERR_WRITE_FILE, "KMF_ERR_WRITE_FILE"}, 127*99ebb4caSwyllys {KMF_ERR_BAD_URI, "KMF_ERR_BAD_URI"}, 128*99ebb4caSwyllys {KMF_ERR_BAD_CRLFILE, "KMF_ERR_BAD_CRLFILE"}, 129*99ebb4caSwyllys {KMF_ERR_BAD_CERTFILE, "KMF_ERR_BAD_CERTFILE"}, 130*99ebb4caSwyllys {KMF_ERR_GETKEYVALUE_FAILED, "KMF_ERR_GETKEYVALUE_FAILED"}, 131*99ebb4caSwyllys {KMF_ERR_BAD_KEYHANDLE, "KMF_ERR_BAD_KEYHANDLE"}, 132*99ebb4caSwyllys {KMF_ERR_BAD_OBJECT_TYPE, "KMF_ERR_BAD_OBJECT_TYPE"}, 133*99ebb4caSwyllys {KMF_ERR_OCSP_RESPONSE_LIFETIME, "KMF_ERR_OCSP_RESPONSE_LIFETIME"}, 134*99ebb4caSwyllys {KMF_ERR_UNKNOWN_CSR_ATTRIBUTE, "KMF_ERR_UNKNOWN_CSR_ATTRIBUTE"}, 135*99ebb4caSwyllys {KMF_ERR_UNINITIALIZED_TOKEN, "KMF_ERR_UNINITIALIZED_TOKEN"}, 136*99ebb4caSwyllys {KMF_ERR_INCOMPLETE_TBS_CERT, "KMF_ERR_INCOMPLETE_TBS_CERT"}, 137*99ebb4caSwyllys {KMF_ERR_MISSING_ERRCODE, "KMF_ERR_MISSING_ERRCODE"}, 138*99ebb4caSwyllys {KMF_KEYSTORE_ALREADY_INITIALIZED, "KMF_KEYSTORE_ALREADY_INITIALIZED"} 139*99ebb4caSwyllys }; 140*99ebb4caSwyllys 141*99ebb4caSwyllys 142*99ebb4caSwyllys static void free_extensions(KMF_X509_EXTENSIONS *extns); 143*99ebb4caSwyllys 144*99ebb4caSwyllys int 145*99ebb4caSwyllys is_pk11_ready() 146*99ebb4caSwyllys { 147*99ebb4caSwyllys return (pkcs11_initialized); 148*99ebb4caSwyllys } 149*99ebb4caSwyllys 150*99ebb4caSwyllys /* 151*99ebb4caSwyllys * Private method for searching the plugin list for the correct 152*99ebb4caSwyllys * Plugin to use. 153*99ebb4caSwyllys */ 154*99ebb4caSwyllys KMF_PLUGIN * 155*99ebb4caSwyllys FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype) 156*99ebb4caSwyllys { 157*99ebb4caSwyllys KMF_PLUGIN_LIST *node; 158*99ebb4caSwyllys 159*99ebb4caSwyllys if (handle == NULL) 160*99ebb4caSwyllys return (NULL); 161*99ebb4caSwyllys 162*99ebb4caSwyllys node = handle->plugins; 163*99ebb4caSwyllys 164*99ebb4caSwyllys while (node != NULL && node->plugin->type != kstype) 165*99ebb4caSwyllys node = node->next; 166*99ebb4caSwyllys 167*99ebb4caSwyllys /* If it is NULL, that is indication enough of an error */ 168*99ebb4caSwyllys return (node ? node->plugin : NULL); 169*99ebb4caSwyllys } 170*99ebb4caSwyllys 171*99ebb4caSwyllys static KMF_RETURN 172*99ebb4caSwyllys InitializePlugin(KMF_KEYSTORE_TYPE kstype, char *path, KMF_PLUGIN **plugin) 173*99ebb4caSwyllys { 174*99ebb4caSwyllys KMF_PLUGIN *p = NULL; 175*99ebb4caSwyllys KMF_PLUGIN_FUNCLIST *(*sym)(); 176*99ebb4caSwyllys 177*99ebb4caSwyllys if (path == NULL || plugin == NULL) 178*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 179*99ebb4caSwyllys 180*99ebb4caSwyllys *plugin = NULL; 181*99ebb4caSwyllys 182*99ebb4caSwyllys p = (KMF_PLUGIN *)malloc(sizeof (KMF_PLUGIN)); 183*99ebb4caSwyllys if (p == NULL) 184*99ebb4caSwyllys return (KMF_ERR_MEMORY); 185*99ebb4caSwyllys 186*99ebb4caSwyllys p->type = kstype; 187*99ebb4caSwyllys p->path = strdup(path); 188*99ebb4caSwyllys if (p->path == NULL) { 189*99ebb4caSwyllys free(p); 190*99ebb4caSwyllys return (KMF_ERR_MEMORY); 191*99ebb4caSwyllys } 192*99ebb4caSwyllys p->dldesc = dlopen(path, RTLD_NOW | RTLD_GROUP | RTLD_PARENT); 193*99ebb4caSwyllys if (p->dldesc == NULL) { 194*99ebb4caSwyllys free(p->path); 195*99ebb4caSwyllys free(p); 196*99ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 197*99ebb4caSwyllys } 198*99ebb4caSwyllys 199*99ebb4caSwyllys sym = (KMF_PLUGIN_FUNCLIST *(*)())dlsym(p->dldesc, 200*99ebb4caSwyllys KMF_PLUGIN_INIT_SYMBOL); 201*99ebb4caSwyllys if (sym == NULL) { 202*99ebb4caSwyllys (void) dlclose(p->dldesc); 203*99ebb4caSwyllys free(p->path); 204*99ebb4caSwyllys free(p); 205*99ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 206*99ebb4caSwyllys } 207*99ebb4caSwyllys 208*99ebb4caSwyllys /* Get the function list */ 209*99ebb4caSwyllys if ((p->funclist = (*sym)()) == NULL) { 210*99ebb4caSwyllys (void) dlclose(p->dldesc); 211*99ebb4caSwyllys free(p->path); 212*99ebb4caSwyllys free(p); 213*99ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 214*99ebb4caSwyllys } 215*99ebb4caSwyllys 216*99ebb4caSwyllys *plugin = p; 217*99ebb4caSwyllys 218*99ebb4caSwyllys return (KMF_OK); 219*99ebb4caSwyllys } 220*99ebb4caSwyllys 221*99ebb4caSwyllys static KMF_RETURN 222*99ebb4caSwyllys AddPlugin(KMF_HANDLE_T handle, KMF_PLUGIN *plugin) 223*99ebb4caSwyllys { 224*99ebb4caSwyllys KMF_PLUGIN_LIST *n; 225*99ebb4caSwyllys 226*99ebb4caSwyllys if (handle == NULL || plugin == NULL) 227*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 228*99ebb4caSwyllys 229*99ebb4caSwyllys /* If the head is NULL, create it */ 230*99ebb4caSwyllys if (handle->plugins == NULL) { 231*99ebb4caSwyllys handle->plugins = (KMF_PLUGIN_LIST *)malloc( 232*99ebb4caSwyllys sizeof (KMF_PLUGIN_LIST)); 233*99ebb4caSwyllys if (handle->plugins == NULL) 234*99ebb4caSwyllys return (KMF_ERR_MEMORY); 235*99ebb4caSwyllys handle->plugins->plugin = plugin; 236*99ebb4caSwyllys handle->plugins->next = NULL; 237*99ebb4caSwyllys } else { 238*99ebb4caSwyllys /* walk the list to find the tail */ 239*99ebb4caSwyllys n = handle->plugins; 240*99ebb4caSwyllys while (n->next != NULL) 241*99ebb4caSwyllys n = n->next; 242*99ebb4caSwyllys n->next = (KMF_PLUGIN_LIST *)malloc(sizeof (KMF_PLUGIN_LIST)); 243*99ebb4caSwyllys if (n->next == NULL) 244*99ebb4caSwyllys return (KMF_ERR_MEMORY); 245*99ebb4caSwyllys 246*99ebb4caSwyllys n->next->plugin = plugin; 247*99ebb4caSwyllys n->next->next = NULL; 248*99ebb4caSwyllys } 249*99ebb4caSwyllys return (0); 250*99ebb4caSwyllys } 251*99ebb4caSwyllys 252*99ebb4caSwyllys static void 253*99ebb4caSwyllys DestroyPlugin(KMF_PLUGIN *plugin) 254*99ebb4caSwyllys { 255*99ebb4caSwyllys if (plugin) { 256*99ebb4caSwyllys if (plugin->path) 257*99ebb4caSwyllys free(plugin->path); 258*99ebb4caSwyllys free(plugin); 259*99ebb4caSwyllys } 260*99ebb4caSwyllys } 261*99ebb4caSwyllys 262*99ebb4caSwyllys static void 263*99ebb4caSwyllys Cleanup_KMF_Handle(KMF_HANDLE_T handle) 264*99ebb4caSwyllys { 265*99ebb4caSwyllys if (handle != NULL) { 266*99ebb4caSwyllys while (handle->plugins != NULL) { 267*99ebb4caSwyllys KMF_PLUGIN_LIST *next = handle->plugins->next; 268*99ebb4caSwyllys 269*99ebb4caSwyllys DestroyPlugin(handle->plugins->plugin); 270*99ebb4caSwyllys 271*99ebb4caSwyllys free(handle->plugins); 272*99ebb4caSwyllys 273*99ebb4caSwyllys handle->plugins = next; 274*99ebb4caSwyllys } 275*99ebb4caSwyllys 276*99ebb4caSwyllys KMF_FreePolicyRecord(handle->policy); 277*99ebb4caSwyllys free(handle->policy); 278*99ebb4caSwyllys } 279*99ebb4caSwyllys free(handle); 280*99ebb4caSwyllys } 281*99ebb4caSwyllys 282*99ebb4caSwyllys void 283*99ebb4caSwyllys Cleanup_PK11_Session(KMF_HANDLE_T handle) 284*99ebb4caSwyllys { 285*99ebb4caSwyllys if (handle != NULL) { 286*99ebb4caSwyllys /* Close active session on a pkcs11 token */ 287*99ebb4caSwyllys if (handle->pk11handle != NULL) { 288*99ebb4caSwyllys (void) C_CloseSession(handle->pk11handle); 289*99ebb4caSwyllys handle->pk11handle = NULL; 290*99ebb4caSwyllys } 291*99ebb4caSwyllys } 292*99ebb4caSwyllys } 293*99ebb4caSwyllys 294*99ebb4caSwyllys KMF_RETURN 295*99ebb4caSwyllys KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 296*99ebb4caSwyllys { 297*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 298*99ebb4caSwyllys KMF_HANDLE *handle = NULL; 299*99ebb4caSwyllys KMF_PLUGIN *pluginrec = NULL; 300*99ebb4caSwyllys 301*99ebb4caSwyllys if (outhandle == NULL) 302*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 303*99ebb4caSwyllys 304*99ebb4caSwyllys *outhandle = NULL; 305*99ebb4caSwyllys handle = (KMF_HANDLE *)malloc(sizeof (KMF_HANDLE)); 306*99ebb4caSwyllys if (handle == NULL) 307*99ebb4caSwyllys return (KMF_ERR_MEMORY); 308*99ebb4caSwyllys 309*99ebb4caSwyllys (void) memset(handle, 0, sizeof (KMF_HANDLE)); 310*99ebb4caSwyllys handle->plugins = NULL; 311*99ebb4caSwyllys 312*99ebb4caSwyllys (void) mutex_lock(&init_lock); 313*99ebb4caSwyllys if (!pkcs11_initialized) { 314*99ebb4caSwyllys CK_RV rv = C_Initialize(NULL); 315*99ebb4caSwyllys if ((rv != CKR_OK) && 316*99ebb4caSwyllys (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 317*99ebb4caSwyllys ret = KMF_ERR_UNINITIALIZED; 318*99ebb4caSwyllys (void) mutex_unlock(&init_lock); 319*99ebb4caSwyllys goto errout; 320*99ebb4caSwyllys } else { 321*99ebb4caSwyllys pkcs11_initialized = 1; 322*99ebb4caSwyllys } 323*99ebb4caSwyllys } 324*99ebb4caSwyllys (void) mutex_unlock(&init_lock); 325*99ebb4caSwyllys 326*99ebb4caSwyllys /* Initialize the handle with the policy */ 327*99ebb4caSwyllys ret = KMF_SetPolicy((void *)handle, 328*99ebb4caSwyllys policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile, 329*99ebb4caSwyllys policyname == NULL ? KMF_DEFAULT_POLICY_NAME : policyname); 330*99ebb4caSwyllys if (ret != KMF_OK) 331*99ebb4caSwyllys goto errout; 332*99ebb4caSwyllys 333*99ebb4caSwyllys /* Create a record for the plugin */ 334*99ebb4caSwyllys if ((ret = InitializePlugin(KMF_KEYSTORE_NSS, 335*99ebb4caSwyllys KMF_PLUGIN_PATH "kmf_nss.so.1", &pluginrec)) != KMF_OK) 336*99ebb4caSwyllys goto errout; 337*99ebb4caSwyllys 338*99ebb4caSwyllys /* Add it to the handle */ 339*99ebb4caSwyllys if (pluginrec != NULL) { 340*99ebb4caSwyllys if ((ret = AddPlugin(handle, pluginrec))) 341*99ebb4caSwyllys goto errout; 342*99ebb4caSwyllys } 343*99ebb4caSwyllys if ((ret = InitializePlugin(KMF_KEYSTORE_OPENSSL, 344*99ebb4caSwyllys KMF_PLUGIN_PATH "kmf_openssl.so.1", &pluginrec)) != KMF_OK) 345*99ebb4caSwyllys goto errout; 346*99ebb4caSwyllys 347*99ebb4caSwyllys /* Add it to the handle */ 348*99ebb4caSwyllys if (pluginrec != NULL) 349*99ebb4caSwyllys if ((ret = AddPlugin(handle, pluginrec))) 350*99ebb4caSwyllys goto errout; 351*99ebb4caSwyllys 352*99ebb4caSwyllys if ((ret = InitializePlugin(KMF_KEYSTORE_PK11TOKEN, 353*99ebb4caSwyllys KMF_PLUGIN_PATH "kmf_pkcs11.so.1", &pluginrec)) != KMF_OK) 354*99ebb4caSwyllys goto errout; 355*99ebb4caSwyllys 356*99ebb4caSwyllys /* Add it to the handle */ 357*99ebb4caSwyllys if (pluginrec != NULL) 358*99ebb4caSwyllys if ((ret = AddPlugin(handle, pluginrec))) 359*99ebb4caSwyllys goto errout; 360*99ebb4caSwyllys 361*99ebb4caSwyllys CLEAR_ERROR(handle, ret); 362*99ebb4caSwyllys errout: 363*99ebb4caSwyllys if (ret != KMF_OK) { 364*99ebb4caSwyllys Cleanup_KMF_Handle(handle); 365*99ebb4caSwyllys handle = NULL; 366*99ebb4caSwyllys } 367*99ebb4caSwyllys 368*99ebb4caSwyllys *outhandle = (KMF_HANDLE_T)handle; 369*99ebb4caSwyllys return (ret); 370*99ebb4caSwyllys } 371*99ebb4caSwyllys 372*99ebb4caSwyllys KMF_RETURN 373*99ebb4caSwyllys KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 374*99ebb4caSwyllys { 375*99ebb4caSwyllys KMF_PLUGIN *plugin; 376*99ebb4caSwyllys KMF_RETURN ret; 377*99ebb4caSwyllys 378*99ebb4caSwyllys CLEAR_ERROR(handle, ret); 379*99ebb4caSwyllys if (ret != KMF_OK) 380*99ebb4caSwyllys return (ret); 381*99ebb4caSwyllys 382*99ebb4caSwyllys if (params == NULL) 383*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 384*99ebb4caSwyllys 385*99ebb4caSwyllys plugin = FindPlugin(handle, params->kstype); 386*99ebb4caSwyllys if (plugin == NULL) 387*99ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 388*99ebb4caSwyllys 389*99ebb4caSwyllys if (plugin->funclist->ConfigureKeystore != NULL) 390*99ebb4caSwyllys return (plugin->funclist->ConfigureKeystore(handle, params)); 391*99ebb4caSwyllys else 392*99ebb4caSwyllys /* return KMF_OK, if the plugin does not have an entry */ 393*99ebb4caSwyllys return (KMF_OK); 394*99ebb4caSwyllys } 395*99ebb4caSwyllys 396*99ebb4caSwyllys KMF_RETURN 397*99ebb4caSwyllys KMF_Finalize(KMF_HANDLE_T handle) 398*99ebb4caSwyllys { 399*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 400*99ebb4caSwyllys 401*99ebb4caSwyllys CLEAR_ERROR(handle, ret); 402*99ebb4caSwyllys if (ret != KMF_OK) 403*99ebb4caSwyllys return (ret); 404*99ebb4caSwyllys 405*99ebb4caSwyllys if (pkcs11_initialized) { 406*99ebb4caSwyllys Cleanup_PK11_Session(handle); 407*99ebb4caSwyllys } 408*99ebb4caSwyllys Cleanup_KMF_Handle(handle); 409*99ebb4caSwyllys 410*99ebb4caSwyllys return (ret); 411*99ebb4caSwyllys } 412*99ebb4caSwyllys 413*99ebb4caSwyllys KMF_RETURN 414*99ebb4caSwyllys KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) 415*99ebb4caSwyllys { 416*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 417*99ebb4caSwyllys int i, maxerr; 418*99ebb4caSwyllys 419*99ebb4caSwyllys if (errmsg == NULL) 420*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 421*99ebb4caSwyllys 422*99ebb4caSwyllys *errmsg = NULL; 423*99ebb4caSwyllys maxerr = sizeof (kmf_errcodes) / sizeof (kmf_error_map); 424*99ebb4caSwyllys 425*99ebb4caSwyllys for (i = 0; i < maxerr && errcode != kmf_errcodes[i].code; i++); 426*99ebb4caSwyllys 427*99ebb4caSwyllys if (i == maxerr) 428*99ebb4caSwyllys return (KMF_ERR_MISSING_ERRCODE); 429*99ebb4caSwyllys else { 430*99ebb4caSwyllys *errmsg = strdup(kmf_errcodes[i].message); 431*99ebb4caSwyllys if ((*errmsg) == NULL) 432*99ebb4caSwyllys return (KMF_ERR_MEMORY); 433*99ebb4caSwyllys } 434*99ebb4caSwyllys return (ret); 435*99ebb4caSwyllys } 436*99ebb4caSwyllys 437*99ebb4caSwyllys KMF_RETURN 438*99ebb4caSwyllys KMF_GetPluginErrorString(KMF_HANDLE_T handle, char **msgstr) 439*99ebb4caSwyllys { 440*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 441*99ebb4caSwyllys KMF_PLUGIN *plugin; 442*99ebb4caSwyllys 443*99ebb4caSwyllys if (handle == NULL || msgstr == NULL) 444*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 445*99ebb4caSwyllys 446*99ebb4caSwyllys *msgstr = NULL; 447*99ebb4caSwyllys 448*99ebb4caSwyllys if (handle->lasterr.errcode == 0) { 449*99ebb4caSwyllys return (KMF_ERR_MISSING_ERRCODE); 450*99ebb4caSwyllys } 451*99ebb4caSwyllys 452*99ebb4caSwyllys if (handle->lasterr.kstype == -1) { /* System error */ 453*99ebb4caSwyllys char *str = strerror(handle->lasterr.errcode); 454*99ebb4caSwyllys if (str != NULL) { 455*99ebb4caSwyllys *msgstr = strdup(str); 456*99ebb4caSwyllys if ((*msgstr) == NULL) 457*99ebb4caSwyllys return (KMF_ERR_MEMORY); 458*99ebb4caSwyllys } 459*99ebb4caSwyllys return (KMF_OK); 460*99ebb4caSwyllys } 461*99ebb4caSwyllys 462*99ebb4caSwyllys plugin = FindPlugin(handle, handle->lasterr.kstype); 463*99ebb4caSwyllys if (plugin == NULL) 464*99ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 465*99ebb4caSwyllys 466*99ebb4caSwyllys if (plugin->funclist->GetErrorString != NULL) { 467*99ebb4caSwyllys ret = plugin->funclist->GetErrorString(handle, msgstr); 468*99ebb4caSwyllys } else { 469*99ebb4caSwyllys return (KMF_ERR_FUNCTION_NOT_FOUND); 470*99ebb4caSwyllys } 471*99ebb4caSwyllys 472*99ebb4caSwyllys return (ret); 473*99ebb4caSwyllys } 474*99ebb4caSwyllys 475*99ebb4caSwyllys KMF_RETURN 476*99ebb4caSwyllys KMF_DNParser(char *string, KMF_X509_NAME *name) 477*99ebb4caSwyllys { 478*99ebb4caSwyllys KMF_RETURN err; 479*99ebb4caSwyllys 480*99ebb4caSwyllys if (string == NULL || name == NULL) 481*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 482*99ebb4caSwyllys 483*99ebb4caSwyllys err = ParseDistinguishedName(string, (int)strlen(string), name); 484*99ebb4caSwyllys return (err); 485*99ebb4caSwyllys } 486*99ebb4caSwyllys 487*99ebb4caSwyllys KMF_RETURN 488*99ebb4caSwyllys KMF_DN2Der(KMF_X509_NAME *dn, KMF_DATA *der) 489*99ebb4caSwyllys { 490*99ebb4caSwyllys KMF_RETURN rv; 491*99ebb4caSwyllys 492*99ebb4caSwyllys if (dn == NULL || der == NULL) 493*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 494*99ebb4caSwyllys 495*99ebb4caSwyllys rv = DerEncodeName(dn, der); 496*99ebb4caSwyllys return (rv); 497*99ebb4caSwyllys } 498*99ebb4caSwyllys 499*99ebb4caSwyllys #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c; 500*99ebb4caSwyllys 501*99ebb4caSwyllys KMF_RETURN 502*99ebb4caSwyllys KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 503*99ebb4caSwyllys { 504*99ebb4caSwyllys struct stat s; 505*99ebb4caSwyllys long nread, total = 0; 506*99ebb4caSwyllys int fd; 507*99ebb4caSwyllys unsigned char *buf = NULL; 508*99ebb4caSwyllys KMF_RETURN ret; 509*99ebb4caSwyllys 510*99ebb4caSwyllys CLEAR_ERROR(handle, ret); 511*99ebb4caSwyllys if (ret != KMF_OK) 512*99ebb4caSwyllys return (ret); 513*99ebb4caSwyllys 514*99ebb4caSwyllys 515*99ebb4caSwyllys if (filename == NULL || pdata == NULL) { 516*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 517*99ebb4caSwyllys } 518*99ebb4caSwyllys 519*99ebb4caSwyllys if ((fd = open(filename, O_RDONLY)) < 0) { 520*99ebb4caSwyllys SET_SYS_ERROR(handle, errno); 521*99ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 522*99ebb4caSwyllys } 523*99ebb4caSwyllys 524*99ebb4caSwyllys if (fstat(fd, &s) < 0) { 525*99ebb4caSwyllys SET_SYS_ERROR(handle, errno); 526*99ebb4caSwyllys (void) close(fd); 527*99ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 528*99ebb4caSwyllys } 529*99ebb4caSwyllys 530*99ebb4caSwyllys if ((buf = (unsigned char *) malloc(s.st_size)) == NULL) { 531*99ebb4caSwyllys (void) close(fd); 532*99ebb4caSwyllys return (KMF_ERR_MEMORY); 533*99ebb4caSwyllys } 534*99ebb4caSwyllys 535*99ebb4caSwyllys do { 536*99ebb4caSwyllys nread = read(fd, buf+total, s.st_size-total); 537*99ebb4caSwyllys if (nread < 0) { 538*99ebb4caSwyllys SET_SYS_ERROR(handle, errno); 539*99ebb4caSwyllys (void) close(fd); 540*99ebb4caSwyllys free(buf); 541*99ebb4caSwyllys return (KMF_ERR_INTERNAL); 542*99ebb4caSwyllys } 543*99ebb4caSwyllys total += nread; 544*99ebb4caSwyllys } while (total < s.st_size); 545*99ebb4caSwyllys 546*99ebb4caSwyllys pdata->Data = buf; 547*99ebb4caSwyllys pdata->Length = s.st_size; 548*99ebb4caSwyllys (void) close(fd); 549*99ebb4caSwyllys return (KMF_OK); 550*99ebb4caSwyllys } 551*99ebb4caSwyllys 552*99ebb4caSwyllys /* 553*99ebb4caSwyllys * 554*99ebb4caSwyllys * Name: KMF_Der2Pem 555*99ebb4caSwyllys * 556*99ebb4caSwyllys * Description: 557*99ebb4caSwyllys * Function for converting DER encoded format to PEM encoded format 558*99ebb4caSwyllys * 559*99ebb4caSwyllys * Parameters: 560*99ebb4caSwyllys * type(input) - CERTIFICATE or CSR 561*99ebb4caSwyllys * data(input) - pointer to the DER encoded data 562*99ebb4caSwyllys * len(input) - length of input data 563*99ebb4caSwyllys * out(output) - contains the output buffer address to be returned 564*99ebb4caSwyllys * outlen(output) - pointer to the returned output length 565*99ebb4caSwyllys * 566*99ebb4caSwyllys * Returns: 567*99ebb4caSwyllys * A KMF_RETURN value indicating success or specifying a particular 568*99ebb4caSwyllys * error condition. 569*99ebb4caSwyllys * The value KMF_OK indicates success. All other values represent 570*99ebb4caSwyllys * an error condition. 571*99ebb4caSwyllys * 572*99ebb4caSwyllys */ 573*99ebb4caSwyllys KMF_RETURN 574*99ebb4caSwyllys KMF_Der2Pem(KMF_OBJECT_TYPE type, unsigned char *data, 575*99ebb4caSwyllys int len, unsigned char **out, int *outlen) 576*99ebb4caSwyllys { 577*99ebb4caSwyllys 578*99ebb4caSwyllys KMF_RETURN err; 579*99ebb4caSwyllys if (data == NULL || out == NULL || outlen == NULL) 580*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 581*99ebb4caSwyllys 582*99ebb4caSwyllys err = Der2Pem(type, data, len, out, outlen); 583*99ebb4caSwyllys return (err); 584*99ebb4caSwyllys 585*99ebb4caSwyllys } 586*99ebb4caSwyllys 587*99ebb4caSwyllys /* 588*99ebb4caSwyllys * 589*99ebb4caSwyllys * Name: KMF_Pem2Der 590*99ebb4caSwyllys * 591*99ebb4caSwyllys * Description: 592*99ebb4caSwyllys * Function for converting PEM encoded format to DER encoded format 593*99ebb4caSwyllys * 594*99ebb4caSwyllys * Parameters: 595*99ebb4caSwyllys * in(input) - pointer to the PEM encoded data 596*99ebb4caSwyllys * inlen(input) - length of input data 597*99ebb4caSwyllys * out(output) - contains the output buffer address to be returned 598*99ebb4caSwyllys * outlen(output) - pointer to the returned output length 599*99ebb4caSwyllys * 600*99ebb4caSwyllys * Returns: 601*99ebb4caSwyllys * A KMF_RETURN value indicating success or specifying a particular 602*99ebb4caSwyllys * error condition. 603*99ebb4caSwyllys * The value KMF_OK indicates success. All other values represent 604*99ebb4caSwyllys * an error condition. 605*99ebb4caSwyllys * 606*99ebb4caSwyllys */ 607*99ebb4caSwyllys KMF_RETURN 608*99ebb4caSwyllys KMF_Pem2Der(unsigned char *in, int inlen, 609*99ebb4caSwyllys unsigned char **out, int *outlen) 610*99ebb4caSwyllys { 611*99ebb4caSwyllys KMF_RETURN err; 612*99ebb4caSwyllys if (in == NULL || out == NULL || outlen == NULL) 613*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 614*99ebb4caSwyllys 615*99ebb4caSwyllys err = Pem2Der(in, inlen, out, outlen); 616*99ebb4caSwyllys return (err); 617*99ebb4caSwyllys } 618*99ebb4caSwyllys 619*99ebb4caSwyllys char * 620*99ebb4caSwyllys KMF_OID2String(KMF_OID *oid) 621*99ebb4caSwyllys { 622*99ebb4caSwyllys char numstr[128]; 623*99ebb4caSwyllys uint32_t number; 624*99ebb4caSwyllys int numshift; 625*99ebb4caSwyllys uint32_t i, string_length; 626*99ebb4caSwyllys uchar_t *cp; 627*99ebb4caSwyllys char *bp; 628*99ebb4caSwyllys 629*99ebb4caSwyllys /* First determine the size of the string */ 630*99ebb4caSwyllys string_length = 0; 631*99ebb4caSwyllys number = 0; 632*99ebb4caSwyllys numshift = 0; 633*99ebb4caSwyllys cp = (unsigned char *)oid->Data; 634*99ebb4caSwyllys 635*99ebb4caSwyllys number = (uint32_t)cp[0]; 636*99ebb4caSwyllys (void) sprintf(numstr, "%d ", number/40); 637*99ebb4caSwyllys 638*99ebb4caSwyllys string_length += strlen(numstr); 639*99ebb4caSwyllys (void) sprintf(numstr, "%d ", number%40); 640*99ebb4caSwyllys 641*99ebb4caSwyllys string_length += strlen(numstr); 642*99ebb4caSwyllys 643*99ebb4caSwyllys for (i = 1; i < oid->Length; i++) { 644*99ebb4caSwyllys if ((uint32_t)(numshift+7) < (sizeof (uint32_t)*8)) { 645*99ebb4caSwyllys number = (number << 7) | (cp[i] & 0x7f); 646*99ebb4caSwyllys numshift += 7; 647*99ebb4caSwyllys } else { 648*99ebb4caSwyllys return (NULL); 649*99ebb4caSwyllys } 650*99ebb4caSwyllys 651*99ebb4caSwyllys if ((cp[i] & 0x80) == 0) { 652*99ebb4caSwyllys (void) sprintf(numstr, "%d ", number); 653*99ebb4caSwyllys string_length += strlen(numstr); 654*99ebb4caSwyllys number = 0; 655*99ebb4caSwyllys numshift = 0; 656*99ebb4caSwyllys } 657*99ebb4caSwyllys } 658*99ebb4caSwyllys /* 659*99ebb4caSwyllys * If we get here, we've calculated the length of "n n n ... n ". Add 4 660*99ebb4caSwyllys * here for "{ " and "}\0". 661*99ebb4caSwyllys */ 662*99ebb4caSwyllys string_length += 4; 663*99ebb4caSwyllys if ((bp = (char *)malloc(string_length))) { 664*99ebb4caSwyllys number = (uint32_t)cp[0]; 665*99ebb4caSwyllys 666*99ebb4caSwyllys (void) sprintf(numstr, "%d.", number/40); 667*99ebb4caSwyllys (void) strcpy(bp, numstr); 668*99ebb4caSwyllys 669*99ebb4caSwyllys (void) sprintf(numstr, "%d.", number%40); 670*99ebb4caSwyllys (void) strcat(bp, numstr); 671*99ebb4caSwyllys 672*99ebb4caSwyllys number = 0; 673*99ebb4caSwyllys cp = (unsigned char *) oid->Data; 674*99ebb4caSwyllys for (i = 1; i < oid->Length; i++) { 675*99ebb4caSwyllys number = (number << 7) | (cp[i] & 0x7f); 676*99ebb4caSwyllys if ((cp[i] & 0x80) == 0) { 677*99ebb4caSwyllys (void) sprintf(numstr, "%d", number); 678*99ebb4caSwyllys (void) strcat(bp, numstr); 679*99ebb4caSwyllys number = 0; 680*99ebb4caSwyllys if (i+1 < oid->Length) 681*99ebb4caSwyllys (void) strcat(bp, "."); 682*99ebb4caSwyllys } 683*99ebb4caSwyllys } 684*99ebb4caSwyllys } 685*99ebb4caSwyllys return (bp); 686*99ebb4caSwyllys } 687*99ebb4caSwyllys 688*99ebb4caSwyllys KMF_RETURN 689*99ebb4caSwyllys KMF_GetFileFormat(char *filename, KMF_ENCODE_FORMAT *fmt) 690*99ebb4caSwyllys { 691*99ebb4caSwyllys int f; 692*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 693*99ebb4caSwyllys uchar_t buf[16]; 694*99ebb4caSwyllys 695*99ebb4caSwyllys if (filename == NULL || !strlen(filename) || fmt == NULL) 696*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 697*99ebb4caSwyllys 698*99ebb4caSwyllys *fmt = 0; 699*99ebb4caSwyllys if ((f = open(filename, O_RDONLY)) == -1) { 700*99ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 701*99ebb4caSwyllys } 702*99ebb4caSwyllys 703*99ebb4caSwyllys if (read(f, buf, 8) != 8) { 704*99ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 705*99ebb4caSwyllys goto end; 706*99ebb4caSwyllys } 707*99ebb4caSwyllys 708*99ebb4caSwyllys if (memcmp(buf, "-----BEG", 8) == 0) { 709*99ebb4caSwyllys *fmt = KMF_FORMAT_PEM; 710*99ebb4caSwyllys } else if (buf[0] == 0x30 && (buf[1] & 0x80)) { 711*99ebb4caSwyllys if ((buf[1] & 0xFF) == 0x80 && 712*99ebb4caSwyllys (buf[2] & 0xFF) == 0x02 && 713*99ebb4caSwyllys (buf[5] & 0xFF) == 0x30) { 714*99ebb4caSwyllys *fmt = KMF_FORMAT_PKCS12; 715*99ebb4caSwyllys } else if ((buf[1] & 0xFF) == 0x82 && 716*99ebb4caSwyllys (buf[4] & 0xFF) == 0x02 && 717*99ebb4caSwyllys (buf[7] & 0xFF) == 0x30) { 718*99ebb4caSwyllys *fmt = KMF_FORMAT_PKCS12; 719*99ebb4caSwyllys /* It is most likely a generic ASN.1 encoded file */ 720*99ebb4caSwyllys } else { 721*99ebb4caSwyllys *fmt = KMF_FORMAT_ASN1; 722*99ebb4caSwyllys } 723*99ebb4caSwyllys } else { 724*99ebb4caSwyllys /* Cannot determine this file format */ 725*99ebb4caSwyllys *fmt = 0; 726*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 727*99ebb4caSwyllys } 728*99ebb4caSwyllys end: 729*99ebb4caSwyllys (void) close(f); 730*99ebb4caSwyllys return (ret); 731*99ebb4caSwyllys } 732*99ebb4caSwyllys 733*99ebb4caSwyllys KMF_RETURN 734*99ebb4caSwyllys KMF_HexString2Bytes(unsigned char *hexstr, unsigned char **bytes, 735*99ebb4caSwyllys size_t *outlen) 736*99ebb4caSwyllys { 737*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 738*99ebb4caSwyllys unsigned char *buf = NULL; 739*99ebb4caSwyllys int len, stringlen; 740*99ebb4caSwyllys int i; 741*99ebb4caSwyllys unsigned char ch; 742*99ebb4caSwyllys 743*99ebb4caSwyllys if (hexstr == NULL) { 744*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 745*99ebb4caSwyllys } 746*99ebb4caSwyllys 747*99ebb4caSwyllys if (hexstr[0] == '0' && 748*99ebb4caSwyllys ((hexstr[1] == 'x') || (hexstr[1] == 'X'))) 749*99ebb4caSwyllys hexstr += 2; 750*99ebb4caSwyllys 751*99ebb4caSwyllys for (i = 0; i < strlen((char *)hexstr) && isxdigit(hexstr[i]); i++); 752*99ebb4caSwyllys /* 753*99ebb4caSwyllys * If all the characters are not legitimate hex chars, 754*99ebb4caSwyllys * return an error. 755*99ebb4caSwyllys */ 756*99ebb4caSwyllys if (i != strlen((char *)hexstr)) 757*99ebb4caSwyllys return (KMF_ERR_BAD_HEX_STRING); 758*99ebb4caSwyllys stringlen = i; 759*99ebb4caSwyllys len = (i / 2) + (i % 2); 760*99ebb4caSwyllys 761*99ebb4caSwyllys buf = malloc(len); 762*99ebb4caSwyllys if (buf == NULL) { 763*99ebb4caSwyllys return (KMF_ERR_MEMORY); 764*99ebb4caSwyllys } 765*99ebb4caSwyllys (void) memset(buf, 0, len); 766*99ebb4caSwyllys 767*99ebb4caSwyllys for (i = 0; i < stringlen; i++) { 768*99ebb4caSwyllys ch = (unsigned char) *hexstr; 769*99ebb4caSwyllys hexstr++; 770*99ebb4caSwyllys if ((ch >= '0') && (ch <= '9')) 771*99ebb4caSwyllys ch -= '0'; 772*99ebb4caSwyllys else if ((ch >= 'A') && (ch <= 'F')) 773*99ebb4caSwyllys ch = ch - 'A' + 10; 774*99ebb4caSwyllys else if ((ch >= 'a') && (ch <= 'f')) 775*99ebb4caSwyllys ch = ch - 'a' + 10; 776*99ebb4caSwyllys else { 777*99ebb4caSwyllys ret = KMF_ERR_BAD_HEX_STRING; 778*99ebb4caSwyllys goto out; 779*99ebb4caSwyllys } 780*99ebb4caSwyllys 781*99ebb4caSwyllys if (i & 1) { 782*99ebb4caSwyllys buf[i/2] |= ch; 783*99ebb4caSwyllys } else { 784*99ebb4caSwyllys buf[i/2] = (ch << 4); 785*99ebb4caSwyllys } 786*99ebb4caSwyllys } 787*99ebb4caSwyllys 788*99ebb4caSwyllys *bytes = buf; 789*99ebb4caSwyllys *outlen = len; 790*99ebb4caSwyllys out: 791*99ebb4caSwyllys if (buf != NULL && ret != KMF_OK) { 792*99ebb4caSwyllys free(buf); 793*99ebb4caSwyllys } 794*99ebb4caSwyllys return (ret); 795*99ebb4caSwyllys } 796*99ebb4caSwyllys 797*99ebb4caSwyllys void 798*99ebb4caSwyllys KMF_FreeDN(KMF_X509_NAME *name) 799*99ebb4caSwyllys { 800*99ebb4caSwyllys KMF_X509_RDN *newrdn = NULL; 801*99ebb4caSwyllys KMF_X509_TYPE_VALUE_PAIR *av = NULL; 802*99ebb4caSwyllys int i, j; 803*99ebb4caSwyllys 804*99ebb4caSwyllys if (name && name->numberOfRDNs) { 805*99ebb4caSwyllys for (i = 0; i < name->numberOfRDNs; i++) { 806*99ebb4caSwyllys newrdn = &name->RelativeDistinguishedName[i]; 807*99ebb4caSwyllys for (j = 0; j < newrdn->numberOfPairs; j++) { 808*99ebb4caSwyllys av = &newrdn->AttributeTypeAndValue[j]; 809*99ebb4caSwyllys KMF_FreeData(&av->type); 810*99ebb4caSwyllys KMF_FreeData(&av->value); 811*99ebb4caSwyllys } 812*99ebb4caSwyllys free(newrdn->AttributeTypeAndValue); 813*99ebb4caSwyllys newrdn->numberOfPairs = 0; 814*99ebb4caSwyllys newrdn->AttributeTypeAndValue = NULL; 815*99ebb4caSwyllys } 816*99ebb4caSwyllys free(name->RelativeDistinguishedName); 817*99ebb4caSwyllys name->numberOfRDNs = 0; 818*99ebb4caSwyllys name->RelativeDistinguishedName = NULL; 819*99ebb4caSwyllys } 820*99ebb4caSwyllys } 821*99ebb4caSwyllys 822*99ebb4caSwyllys void 823*99ebb4caSwyllys KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 824*99ebb4caSwyllys { 825*99ebb4caSwyllys KMF_PLUGIN *plugin; 826*99ebb4caSwyllys KMF_RETURN ret; 827*99ebb4caSwyllys 828*99ebb4caSwyllys CLEAR_ERROR(handle, ret); 829*99ebb4caSwyllys if (ret != KMF_OK) 830*99ebb4caSwyllys return; 831*99ebb4caSwyllys 832*99ebb4caSwyllys if (kmf_cert == NULL) 833*99ebb4caSwyllys return; 834*99ebb4caSwyllys 835*99ebb4caSwyllys plugin = FindPlugin(handle, kmf_cert->kmf_private.keystore_type); 836*99ebb4caSwyllys 837*99ebb4caSwyllys if (plugin != NULL && plugin->funclist->FreeKMFCert != NULL) { 838*99ebb4caSwyllys plugin->funclist->FreeKMFCert(handle, kmf_cert); 839*99ebb4caSwyllys } 840*99ebb4caSwyllys } 841*99ebb4caSwyllys 842*99ebb4caSwyllys void 843*99ebb4caSwyllys KMF_FreeData(KMF_DATA *datablock) 844*99ebb4caSwyllys { 845*99ebb4caSwyllys if (datablock != NULL && datablock->Data != NULL) { 846*99ebb4caSwyllys free(datablock->Data); 847*99ebb4caSwyllys datablock->Data = NULL; 848*99ebb4caSwyllys datablock->Length = 0; 849*99ebb4caSwyllys } 850*99ebb4caSwyllys } 851*99ebb4caSwyllys 852*99ebb4caSwyllys void 853*99ebb4caSwyllys KMF_FreeAlgOID(KMF_X509_ALGORITHM_IDENTIFIER *algoid) 854*99ebb4caSwyllys { 855*99ebb4caSwyllys if (algoid == NULL) 856*99ebb4caSwyllys return; 857*99ebb4caSwyllys KMF_FreeData(&algoid->algorithm); 858*99ebb4caSwyllys KMF_FreeData(&algoid->parameters); 859*99ebb4caSwyllys } 860*99ebb4caSwyllys 861*99ebb4caSwyllys void 862*99ebb4caSwyllys KMF_FreeExtension(KMF_X509_EXTENSION *exptr) 863*99ebb4caSwyllys { 864*99ebb4caSwyllys if (exptr == NULL) 865*99ebb4caSwyllys return; 866*99ebb4caSwyllys 867*99ebb4caSwyllys KMF_FreeData((KMF_DATA *)&exptr->extnId); 868*99ebb4caSwyllys KMF_FreeData(&exptr->BERvalue); 869*99ebb4caSwyllys 870*99ebb4caSwyllys if (exptr->value.tagAndValue) { 871*99ebb4caSwyllys KMF_FreeData(&exptr->value.tagAndValue->value); 872*99ebb4caSwyllys free(exptr->value.tagAndValue); 873*99ebb4caSwyllys } 874*99ebb4caSwyllys } 875*99ebb4caSwyllys 876*99ebb4caSwyllys void 877*99ebb4caSwyllys KMF_FreeTBSCSR(KMF_TBS_CSR *tbscsr) 878*99ebb4caSwyllys { 879*99ebb4caSwyllys if (tbscsr) { 880*99ebb4caSwyllys KMF_FreeData(&tbscsr->version); 881*99ebb4caSwyllys 882*99ebb4caSwyllys KMF_FreeDN(&tbscsr->subject); 883*99ebb4caSwyllys 884*99ebb4caSwyllys KMF_FreeAlgOID(&tbscsr->subjectPublicKeyInfo.algorithm); 885*99ebb4caSwyllys KMF_FreeData(&tbscsr->subjectPublicKeyInfo.subjectPublicKey); 886*99ebb4caSwyllys 887*99ebb4caSwyllys free_extensions(&tbscsr->extensions); 888*99ebb4caSwyllys } 889*99ebb4caSwyllys } 890*99ebb4caSwyllys 891*99ebb4caSwyllys void 892*99ebb4caSwyllys KMF_FreeSignedCSR(KMF_CSR_DATA *csr) 893*99ebb4caSwyllys { 894*99ebb4caSwyllys if (csr) { 895*99ebb4caSwyllys KMF_FreeTBSCSR(&csr->csr); 896*99ebb4caSwyllys 897*99ebb4caSwyllys KMF_FreeAlgOID(&csr->signature.algorithmIdentifier); 898*99ebb4caSwyllys KMF_FreeData(&csr->signature.encrypted); 899*99ebb4caSwyllys } 900*99ebb4caSwyllys } 901*99ebb4caSwyllys 902*99ebb4caSwyllys static void 903*99ebb4caSwyllys free_validity(KMF_X509_VALIDITY *validity) 904*99ebb4caSwyllys { 905*99ebb4caSwyllys if (validity == NULL) 906*99ebb4caSwyllys return; 907*99ebb4caSwyllys KMF_FreeData(&validity->notBefore.time); 908*99ebb4caSwyllys KMF_FreeData(&validity->notAfter.time); 909*99ebb4caSwyllys } 910*99ebb4caSwyllys 911*99ebb4caSwyllys static void 912*99ebb4caSwyllys free_extensions(KMF_X509_EXTENSIONS *extns) 913*99ebb4caSwyllys { 914*99ebb4caSwyllys int i; 915*99ebb4caSwyllys KMF_X509_EXTENSION *exptr; 916*99ebb4caSwyllys 917*99ebb4caSwyllys if (extns && extns->numberOfExtensions > 0) { 918*99ebb4caSwyllys for (i = 0; i < extns->numberOfExtensions; i++) { 919*99ebb4caSwyllys exptr = &extns->extensions[i]; 920*99ebb4caSwyllys KMF_FreeExtension(exptr); 921*99ebb4caSwyllys } 922*99ebb4caSwyllys free(extns->extensions); 923*99ebb4caSwyllys extns->numberOfExtensions = 0; 924*99ebb4caSwyllys extns->extensions = NULL; 925*99ebb4caSwyllys } 926*99ebb4caSwyllys } 927*99ebb4caSwyllys 928*99ebb4caSwyllys void 929*99ebb4caSwyllys KMF_FreeTBSCert(KMF_X509_TBS_CERT *tbscert) 930*99ebb4caSwyllys { 931*99ebb4caSwyllys if (tbscert) { 932*99ebb4caSwyllys KMF_FreeData(&tbscert->version); 933*99ebb4caSwyllys KMF_FreeBigint(&tbscert->serialNumber); 934*99ebb4caSwyllys KMF_FreeAlgOID(&tbscert->signature); 935*99ebb4caSwyllys 936*99ebb4caSwyllys KMF_FreeDN(&tbscert->issuer); 937*99ebb4caSwyllys KMF_FreeDN(&tbscert->subject); 938*99ebb4caSwyllys 939*99ebb4caSwyllys free_validity(&tbscert->validity); 940*99ebb4caSwyllys 941*99ebb4caSwyllys KMF_FreeData(&tbscert->issuerUniqueIdentifier); 942*99ebb4caSwyllys KMF_FreeData(&tbscert->subjectUniqueIdentifier); 943*99ebb4caSwyllys 944*99ebb4caSwyllys KMF_FreeAlgOID(&tbscert->subjectPublicKeyInfo.algorithm); 945*99ebb4caSwyllys KMF_FreeData(&tbscert->subjectPublicKeyInfo.subjectPublicKey); 946*99ebb4caSwyllys 947*99ebb4caSwyllys free_extensions(&tbscert->extensions); 948*99ebb4caSwyllys 949*99ebb4caSwyllys KMF_FreeData(&tbscert->issuerUniqueIdentifier); 950*99ebb4caSwyllys KMF_FreeData(&tbscert->subjectUniqueIdentifier); 951*99ebb4caSwyllys } 952*99ebb4caSwyllys } 953*99ebb4caSwyllys 954*99ebb4caSwyllys void 955*99ebb4caSwyllys KMF_FreeSignedCert(KMF_X509_CERTIFICATE *certptr) 956*99ebb4caSwyllys { 957*99ebb4caSwyllys if (!certptr) 958*99ebb4caSwyllys return; 959*99ebb4caSwyllys 960*99ebb4caSwyllys KMF_FreeTBSCert(&certptr->certificate); 961*99ebb4caSwyllys 962*99ebb4caSwyllys KMF_FreeAlgOID(&certptr->signature.algorithmIdentifier); 963*99ebb4caSwyllys KMF_FreeData(&certptr->signature.encrypted); 964*99ebb4caSwyllys } 965*99ebb4caSwyllys 966*99ebb4caSwyllys void 967*99ebb4caSwyllys KMF_FreeString(char *pstr) 968*99ebb4caSwyllys { 969*99ebb4caSwyllys if (pstr != NULL) 970*99ebb4caSwyllys free(pstr); 971*99ebb4caSwyllys } 972*99ebb4caSwyllys 973*99ebb4caSwyllys void 974*99ebb4caSwyllys free_keyidlist(KMF_OID *oidlist, int len) 975*99ebb4caSwyllys { 976*99ebb4caSwyllys int i; 977*99ebb4caSwyllys for (i = 0; i < len; i++) { 978*99ebb4caSwyllys KMF_FreeData((KMF_DATA *)&oidlist[i]); 979*99ebb4caSwyllys } 980*99ebb4caSwyllys free(oidlist); 981*99ebb4caSwyllys } 982*99ebb4caSwyllys 983*99ebb4caSwyllys void 984*99ebb4caSwyllys KMF_FreeEKU(KMF_X509EXT_EKU *eptr) 985*99ebb4caSwyllys { 986*99ebb4caSwyllys if (eptr && eptr->nEKUs > 0 && 987*99ebb4caSwyllys eptr->keyPurposeIdList != NULL) 988*99ebb4caSwyllys free_keyidlist(eptr->keyPurposeIdList, eptr->nEKUs); 989*99ebb4caSwyllys } 990*99ebb4caSwyllys 991*99ebb4caSwyllys void 992*99ebb4caSwyllys KMF_FreeSPKI(KMF_X509_SPKI *spki) 993*99ebb4caSwyllys { 994*99ebb4caSwyllys if (spki != NULL) { 995*99ebb4caSwyllys KMF_FreeAlgOID(&spki->algorithm); 996*99ebb4caSwyllys KMF_FreeData(&spki->subjectPublicKey); 997*99ebb4caSwyllys } 998*99ebb4caSwyllys } 999*99ebb4caSwyllys 1000*99ebb4caSwyllys void 1001*99ebb4caSwyllys KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 1002*99ebb4caSwyllys { 1003*99ebb4caSwyllys KMF_PLUGIN *plugin; 1004*99ebb4caSwyllys KMF_RETURN ret; 1005*99ebb4caSwyllys 1006*99ebb4caSwyllys CLEAR_ERROR(handle, ret); 1007*99ebb4caSwyllys if (ret != KMF_OK) 1008*99ebb4caSwyllys return; 1009*99ebb4caSwyllys 1010*99ebb4caSwyllys if (key == NULL) 1011*99ebb4caSwyllys return; 1012*99ebb4caSwyllys 1013*99ebb4caSwyllys plugin = FindPlugin(handle, key->kstype); 1014*99ebb4caSwyllys if (plugin != NULL && plugin->funclist->DeleteKey != NULL) { 1015*99ebb4caSwyllys (void) plugin->funclist->DeleteKey(handle, NULL, key, FALSE); 1016*99ebb4caSwyllys } 1017*99ebb4caSwyllys 1018*99ebb4caSwyllys if (key == NULL) 1019*99ebb4caSwyllys return; 1020*99ebb4caSwyllys 1021*99ebb4caSwyllys if (key->keylabel) 1022*99ebb4caSwyllys free(key->keylabel); 1023*99ebb4caSwyllys 1024*99ebb4caSwyllys if (key->israw) { 1025*99ebb4caSwyllys KMF_FreeRawKey(key->keyp); 1026*99ebb4caSwyllys free(key->keyp); 1027*99ebb4caSwyllys } 1028*99ebb4caSwyllys 1029*99ebb4caSwyllys (void) memset(key, 0, sizeof (KMF_KEY_HANDLE)); 1030*99ebb4caSwyllys } 1031*99ebb4caSwyllys 1032*99ebb4caSwyllys void 1033*99ebb4caSwyllys KMF_FreeBigint(KMF_BIGINT *big) 1034*99ebb4caSwyllys { 1035*99ebb4caSwyllys if (big != NULL && big->val != NULL) { 1036*99ebb4caSwyllys free(big->val); 1037*99ebb4caSwyllys big->val = NULL; 1038*99ebb4caSwyllys big->len = 0; 1039*99ebb4caSwyllys } 1040*99ebb4caSwyllys } 1041*99ebb4caSwyllys 1042*99ebb4caSwyllys static void 1043*99ebb4caSwyllys free_raw_rsa(KMF_RAW_RSA_KEY *key) 1044*99ebb4caSwyllys { 1045*99ebb4caSwyllys if (key == NULL) 1046*99ebb4caSwyllys return; 1047*99ebb4caSwyllys KMF_FreeBigint(&key->mod); 1048*99ebb4caSwyllys KMF_FreeBigint(&key->pubexp); 1049*99ebb4caSwyllys KMF_FreeBigint(&key->priexp); 1050*99ebb4caSwyllys KMF_FreeBigint(&key->prime1); 1051*99ebb4caSwyllys KMF_FreeBigint(&key->prime2); 1052*99ebb4caSwyllys KMF_FreeBigint(&key->exp1); 1053*99ebb4caSwyllys KMF_FreeBigint(&key->exp2); 1054*99ebb4caSwyllys KMF_FreeBigint(&key->coef); 1055*99ebb4caSwyllys } 1056*99ebb4caSwyllys 1057*99ebb4caSwyllys static void 1058*99ebb4caSwyllys free_raw_dsa(KMF_RAW_DSA_KEY *key) 1059*99ebb4caSwyllys { 1060*99ebb4caSwyllys if (key == NULL) 1061*99ebb4caSwyllys return; 1062*99ebb4caSwyllys KMF_FreeBigint(&key->prime); 1063*99ebb4caSwyllys KMF_FreeBigint(&key->subprime); 1064*99ebb4caSwyllys KMF_FreeBigint(&key->base); 1065*99ebb4caSwyllys KMF_FreeBigint(&key->value); 1066*99ebb4caSwyllys } 1067*99ebb4caSwyllys 1068*99ebb4caSwyllys static void 1069*99ebb4caSwyllys free_raw_sym(KMF_RAW_SYM_KEY *key) 1070*99ebb4caSwyllys { 1071*99ebb4caSwyllys if (key == NULL) 1072*99ebb4caSwyllys return; 1073*99ebb4caSwyllys KMF_FreeBigint(&key->keydata); 1074*99ebb4caSwyllys } 1075*99ebb4caSwyllys 1076*99ebb4caSwyllys void 1077*99ebb4caSwyllys KMF_FreeRawKey(KMF_RAW_KEY_DATA *key) 1078*99ebb4caSwyllys { 1079*99ebb4caSwyllys if (key == NULL) 1080*99ebb4caSwyllys return; 1081*99ebb4caSwyllys 1082*99ebb4caSwyllys switch (key->keytype) { 1083*99ebb4caSwyllys case KMF_RSA: 1084*99ebb4caSwyllys free_raw_rsa(&key->rawdata.rsa); 1085*99ebb4caSwyllys break; 1086*99ebb4caSwyllys case KMF_DSA: 1087*99ebb4caSwyllys free_raw_dsa(&key->rawdata.dsa); 1088*99ebb4caSwyllys break; 1089*99ebb4caSwyllys case KMF_AES: 1090*99ebb4caSwyllys case KMF_RC4: 1091*99ebb4caSwyllys case KMF_DES: 1092*99ebb4caSwyllys case KMF_DES3: 1093*99ebb4caSwyllys free_raw_sym(&key->rawdata.sym); 1094*99ebb4caSwyllys break; 1095*99ebb4caSwyllys } 1096*99ebb4caSwyllys } 1097*99ebb4caSwyllys 1098*99ebb4caSwyllys void 1099*99ebb4caSwyllys KMF_FreeRawSymKey(KMF_RAW_SYM_KEY *key) 1100*99ebb4caSwyllys { 1101*99ebb4caSwyllys if (key == NULL) 1102*99ebb4caSwyllys return; 1103*99ebb4caSwyllys KMF_FreeBigint(&key->keydata); 1104*99ebb4caSwyllys free(key); 1105*99ebb4caSwyllys } 1106*99ebb4caSwyllys 1107*99ebb4caSwyllys /* 1108*99ebb4caSwyllys * This function frees the space allocated for the name portion of a 1109*99ebb4caSwyllys * KMF_CRL_DIST_POINT. 1110*99ebb4caSwyllys */ 1111*99ebb4caSwyllys void 1112*99ebb4caSwyllys free_dp_name(KMF_CRL_DIST_POINT *dp) 1113*99ebb4caSwyllys { 1114*99ebb4caSwyllys KMF_GENERALNAMES *fullname; 1115*99ebb4caSwyllys KMF_DATA *urldata; 1116*99ebb4caSwyllys int i; 1117*99ebb4caSwyllys 1118*99ebb4caSwyllys if (dp == NULL) 1119*99ebb4caSwyllys return; 1120*99ebb4caSwyllys 1121*99ebb4caSwyllys /* For phase 1, we only need to free the fullname space. */ 1122*99ebb4caSwyllys fullname = &(dp->name.full_name); 1123*99ebb4caSwyllys if (fullname->number == 0) 1124*99ebb4caSwyllys return; 1125*99ebb4caSwyllys 1126*99ebb4caSwyllys for (i = 0; i < fullname->number; i++) { 1127*99ebb4caSwyllys urldata = &(fullname->namelist[fullname->number - 1].name); 1128*99ebb4caSwyllys KMF_FreeData(urldata); 1129*99ebb4caSwyllys } 1130*99ebb4caSwyllys 1131*99ebb4caSwyllys free(fullname->namelist); 1132*99ebb4caSwyllys } 1133*99ebb4caSwyllys 1134*99ebb4caSwyllys /* 1135*99ebb4caSwyllys * This function frees the space allocated for a KMF_CRL_DIST_POINT. 1136*99ebb4caSwyllys */ 1137*99ebb4caSwyllys void 1138*99ebb4caSwyllys free_dp(KMF_CRL_DIST_POINT *dp) 1139*99ebb4caSwyllys { 1140*99ebb4caSwyllys if (dp == NULL) 1141*99ebb4caSwyllys return; 1142*99ebb4caSwyllys 1143*99ebb4caSwyllys free_dp_name(dp); 1144*99ebb4caSwyllys KMF_FreeData(&(dp->reasons)); 1145*99ebb4caSwyllys /* Need not to free crl_issuer space at phase 1 */ 1146*99ebb4caSwyllys } 1147*99ebb4caSwyllys 1148*99ebb4caSwyllys /* 1149*99ebb4caSwyllys * This function frees space for a KMF_X509EXT_CRLDISTPOINTS internally. 1150*99ebb4caSwyllys */ 1151*99ebb4caSwyllys void 1152*99ebb4caSwyllys KMF_FreeCRLDistributionPoints(KMF_X509EXT_CRLDISTPOINTS *crl_dps) 1153*99ebb4caSwyllys { 1154*99ebb4caSwyllys int i; 1155*99ebb4caSwyllys 1156*99ebb4caSwyllys if (crl_dps == NULL) 1157*99ebb4caSwyllys return; 1158*99ebb4caSwyllys 1159*99ebb4caSwyllys for (i = 0; i < crl_dps->number; i++) 1160*99ebb4caSwyllys free_dp(&(crl_dps->dplist[i])); 1161*99ebb4caSwyllys 1162*99ebb4caSwyllys free(crl_dps->dplist); 1163*99ebb4caSwyllys } 1164*99ebb4caSwyllys 1165*99ebb4caSwyllys KMF_RETURN 1166*99ebb4caSwyllys KMF_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, 1167*99ebb4caSwyllys char *reqfile) 1168*99ebb4caSwyllys { 1169*99ebb4caSwyllys KMF_PLUGIN *plugin; 1170*99ebb4caSwyllys KMF_RETURN (*createReqFn)(void *, KMF_OCSPREQUEST_PARAMS *params, 1171*99ebb4caSwyllys char *reqfile); 1172*99ebb4caSwyllys KMF_RETURN ret; 1173*99ebb4caSwyllys 1174*99ebb4caSwyllys CLEAR_ERROR(handle, ret); 1175*99ebb4caSwyllys if (ret != KMF_OK) 1176*99ebb4caSwyllys return (ret); 1177*99ebb4caSwyllys 1178*99ebb4caSwyllys 1179*99ebb4caSwyllys if (params == NULL || 1180*99ebb4caSwyllys reqfile == NULL) 1181*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1182*99ebb4caSwyllys 1183*99ebb4caSwyllys /* 1184*99ebb4caSwyllys * This framework function is actually implemented in the openssl 1185*99ebb4caSwyllys * plugin library, so we find the function address and call it. 1186*99ebb4caSwyllys */ 1187*99ebb4caSwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 1188*99ebb4caSwyllys if (plugin == NULL || plugin->dldesc == NULL) { 1189*99ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 1190*99ebb4caSwyllys } 1191*99ebb4caSwyllys 1192*99ebb4caSwyllys createReqFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 1193*99ebb4caSwyllys "OpenSSL_CreateOCSPRequest"); 1194*99ebb4caSwyllys if (createReqFn == NULL) { 1195*99ebb4caSwyllys return (KMF_ERR_FUNCTION_NOT_FOUND); 1196*99ebb4caSwyllys } 1197*99ebb4caSwyllys 1198*99ebb4caSwyllys return (createReqFn(handle, params, reqfile)); 1199*99ebb4caSwyllys } 1200*99ebb4caSwyllys 1201*99ebb4caSwyllys KMF_RETURN 1202*99ebb4caSwyllys KMF_GetOCSPStatusForCert(KMF_HANDLE_T handle, 1203*99ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 1204*99ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) 1205*99ebb4caSwyllys { 1206*99ebb4caSwyllys KMF_PLUGIN *plugin; 1207*99ebb4caSwyllys KMF_RETURN (*getCertStatusFn)(void *, 1208*99ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 1209*99ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out); 1210*99ebb4caSwyllys KMF_RETURN ret; 1211*99ebb4caSwyllys 1212*99ebb4caSwyllys CLEAR_ERROR(handle, ret); 1213*99ebb4caSwyllys if (ret != KMF_OK) 1214*99ebb4caSwyllys return (ret); 1215*99ebb4caSwyllys 1216*99ebb4caSwyllys 1217*99ebb4caSwyllys if (params_in == NULL || 1218*99ebb4caSwyllys params_out == NULL) 1219*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1220*99ebb4caSwyllys 1221*99ebb4caSwyllys /* 1222*99ebb4caSwyllys * This framework function is actually implemented in the openssl 1223*99ebb4caSwyllys * plugin library, so we find the function address and call it. 1224*99ebb4caSwyllys */ 1225*99ebb4caSwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 1226*99ebb4caSwyllys if (plugin == NULL || plugin->dldesc == NULL) { 1227*99ebb4caSwyllys return (KMF_ERR_INTERNAL); 1228*99ebb4caSwyllys } 1229*99ebb4caSwyllys 1230*99ebb4caSwyllys getCertStatusFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 1231*99ebb4caSwyllys "OpenSSL_GetOCSPStatusForCert"); 1232*99ebb4caSwyllys if (getCertStatusFn == NULL) { 1233*99ebb4caSwyllys return (KMF_ERR_INTERNAL); 1234*99ebb4caSwyllys } 1235*99ebb4caSwyllys 1236*99ebb4caSwyllys return (getCertStatusFn(handle, params_in, params_out)); 1237*99ebb4caSwyllys } 1238*99ebb4caSwyllys 1239*99ebb4caSwyllys KMF_RETURN 1240*99ebb4caSwyllys KMF_String2OID(char *oidstring, KMF_OID *oid) 1241*99ebb4caSwyllys { 1242*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 1243*99ebb4caSwyllys char *cp, *bp, *startp; 1244*99ebb4caSwyllys int numbuf; 1245*99ebb4caSwyllys int onumbuf; 1246*99ebb4caSwyllys int nbytes, index; 1247*99ebb4caSwyllys int len; 1248*99ebb4caSwyllys unsigned char *op; 1249*99ebb4caSwyllys 1250*99ebb4caSwyllys if (oidstring == NULL || oid == NULL) 1251*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1252*99ebb4caSwyllys 1253*99ebb4caSwyllys len = strlen(oidstring); 1254*99ebb4caSwyllys 1255*99ebb4caSwyllys bp = oidstring; 1256*99ebb4caSwyllys cp = bp; 1257*99ebb4caSwyllys /* Skip over leading space */ 1258*99ebb4caSwyllys while ((bp < &cp[len]) && isspace(*bp)) 1259*99ebb4caSwyllys bp++; 1260*99ebb4caSwyllys 1261*99ebb4caSwyllys startp = bp; 1262*99ebb4caSwyllys nbytes = 0; 1263*99ebb4caSwyllys 1264*99ebb4caSwyllys /* 1265*99ebb4caSwyllys * The first two numbers are chewed up by the first octet. 1266*99ebb4caSwyllys */ 1267*99ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 1268*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1269*99ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 1270*99ebb4caSwyllys bp++; 1271*99ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1272*99ebb4caSwyllys bp++; 1273*99ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 1274*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1275*99ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 1276*99ebb4caSwyllys bp++; 1277*99ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1278*99ebb4caSwyllys bp++; 1279*99ebb4caSwyllys nbytes++; 1280*99ebb4caSwyllys 1281*99ebb4caSwyllys while (isdigit(*bp)) { 1282*99ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 1283*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1284*99ebb4caSwyllys while (numbuf) { 1285*99ebb4caSwyllys nbytes++; 1286*99ebb4caSwyllys numbuf >>= 7; 1287*99ebb4caSwyllys } 1288*99ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 1289*99ebb4caSwyllys bp++; 1290*99ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1291*99ebb4caSwyllys bp++; 1292*99ebb4caSwyllys } 1293*99ebb4caSwyllys 1294*99ebb4caSwyllys oid->Length = nbytes; 1295*99ebb4caSwyllys oid->Data = malloc(oid->Length); 1296*99ebb4caSwyllys if (oid->Data == NULL) { 1297*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1298*99ebb4caSwyllys } 1299*99ebb4caSwyllys (void) memset(oid->Data, 0, oid->Length); 1300*99ebb4caSwyllys 1301*99ebb4caSwyllys op = oid->Data; 1302*99ebb4caSwyllys 1303*99ebb4caSwyllys bp = startp; 1304*99ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 1305*99ebb4caSwyllys 1306*99ebb4caSwyllys while (isdigit(*bp)) bp++; 1307*99ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 1308*99ebb4caSwyllys 1309*99ebb4caSwyllys onumbuf = 40 * numbuf; 1310*99ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 1311*99ebb4caSwyllys onumbuf += numbuf; 1312*99ebb4caSwyllys *op = (unsigned char) onumbuf; 1313*99ebb4caSwyllys op++; 1314*99ebb4caSwyllys 1315*99ebb4caSwyllys while (isdigit(*bp)) bp++; 1316*99ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 1317*99ebb4caSwyllys while (isdigit(*bp)) { 1318*99ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 1319*99ebb4caSwyllys nbytes = 0; 1320*99ebb4caSwyllys /* Have to fill in the bytes msb-first */ 1321*99ebb4caSwyllys onumbuf = numbuf; 1322*99ebb4caSwyllys while (numbuf) { 1323*99ebb4caSwyllys nbytes++; 1324*99ebb4caSwyllys numbuf >>= 7; 1325*99ebb4caSwyllys } 1326*99ebb4caSwyllys numbuf = onumbuf; 1327*99ebb4caSwyllys op += nbytes; 1328*99ebb4caSwyllys index = -1; 1329*99ebb4caSwyllys while (numbuf) { 1330*99ebb4caSwyllys op[index] = (unsigned char)numbuf & 0x7f; 1331*99ebb4caSwyllys if (index != -1) 1332*99ebb4caSwyllys op[index] |= 0x80; 1333*99ebb4caSwyllys index--; 1334*99ebb4caSwyllys numbuf >>= 7; 1335*99ebb4caSwyllys } 1336*99ebb4caSwyllys while (isdigit(*bp)) bp++; 1337*99ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 1338*99ebb4caSwyllys } 1339*99ebb4caSwyllys 1340*99ebb4caSwyllys return (rv); 1341*99ebb4caSwyllys } 1342*99ebb4caSwyllys 1343*99ebb4caSwyllys static KMF_RETURN 1344*99ebb4caSwyllys encode_rid(char *name, KMF_DATA *derdata) 1345*99ebb4caSwyllys { 1346*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 1347*99ebb4caSwyllys 1348*99ebb4caSwyllys if (name == NULL || derdata == NULL) 1349*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1350*99ebb4caSwyllys 1351*99ebb4caSwyllys rv = KMF_String2OID(name, (KMF_OID *)derdata); 1352*99ebb4caSwyllys 1353*99ebb4caSwyllys return (rv); 1354*99ebb4caSwyllys } 1355*99ebb4caSwyllys 1356*99ebb4caSwyllys static KMF_RETURN 1357*99ebb4caSwyllys encode_ipaddr(char *name, KMF_DATA *derdata) 1358*99ebb4caSwyllys { 1359*99ebb4caSwyllys KMF_RETURN rv = KMF_OK; 1360*99ebb4caSwyllys size_t len; 1361*99ebb4caSwyllys in_addr_t v4; 1362*99ebb4caSwyllys in6_addr_t v6; 1363*99ebb4caSwyllys uint8_t *ptr; 1364*99ebb4caSwyllys 1365*99ebb4caSwyllys if (name == NULL || derdata == NULL) 1366*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1367*99ebb4caSwyllys 1368*99ebb4caSwyllys v4 = inet_addr(name); 1369*99ebb4caSwyllys if (v4 == (in_addr_t)-1) { 1370*99ebb4caSwyllys ptr = (uint8_t *)&v6; 1371*99ebb4caSwyllys if (inet_pton(AF_INET6, name, ptr) != 1) 1372*99ebb4caSwyllys return (KMF_ERR_ENCODING); 1373*99ebb4caSwyllys len = sizeof (v6); 1374*99ebb4caSwyllys } else { 1375*99ebb4caSwyllys ptr = (uint8_t *)&v4; 1376*99ebb4caSwyllys len = sizeof (v4); 1377*99ebb4caSwyllys } 1378*99ebb4caSwyllys 1379*99ebb4caSwyllys derdata->Data = malloc(len); 1380*99ebb4caSwyllys if (derdata->Data == NULL) 1381*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1382*99ebb4caSwyllys (void) memcpy(derdata->Data, ptr, len); 1383*99ebb4caSwyllys derdata->Length = len; 1384*99ebb4caSwyllys 1385*99ebb4caSwyllys return (rv); 1386*99ebb4caSwyllys } 1387*99ebb4caSwyllys 1388*99ebb4caSwyllys static KMF_RETURN 1389*99ebb4caSwyllys verify_uri_format(char *uristring) 1390*99ebb4caSwyllys { 1391*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1392*99ebb4caSwyllys xmlURIPtr uriptr = NULL; 1393*99ebb4caSwyllys 1394*99ebb4caSwyllys /* Parse the URI string; get the hostname and port */ 1395*99ebb4caSwyllys uriptr = xmlParseURI(uristring); 1396*99ebb4caSwyllys if (uriptr == NULL) { 1397*99ebb4caSwyllys ret = KMF_ERR_BAD_URI; 1398*99ebb4caSwyllys goto out; 1399*99ebb4caSwyllys } 1400*99ebb4caSwyllys 1401*99ebb4caSwyllys if (uriptr->scheme == NULL || !strlen(uriptr->scheme)) { 1402*99ebb4caSwyllys ret = KMF_ERR_BAD_URI; 1403*99ebb4caSwyllys goto out; 1404*99ebb4caSwyllys } 1405*99ebb4caSwyllys 1406*99ebb4caSwyllys if (uriptr->server == NULL || !strlen(uriptr->server)) { 1407*99ebb4caSwyllys ret = KMF_ERR_BAD_URI; 1408*99ebb4caSwyllys goto out; 1409*99ebb4caSwyllys } 1410*99ebb4caSwyllys out: 1411*99ebb4caSwyllys if (uriptr != NULL) 1412*99ebb4caSwyllys xmlFreeURI(uriptr); 1413*99ebb4caSwyllys return (ret); 1414*99ebb4caSwyllys } 1415*99ebb4caSwyllys 1416*99ebb4caSwyllys static KMF_RETURN 1417*99ebb4caSwyllys encode_altname(char *namedata, 1418*99ebb4caSwyllys KMF_GENERALNAMECHOICES nametype, KMF_DATA *encodedname) 1419*99ebb4caSwyllys { 1420*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1421*99ebb4caSwyllys KMF_X509_NAME dnname; 1422*99ebb4caSwyllys uchar_t tagval; 1423*99ebb4caSwyllys BerElement *asn1 = NULL; 1424*99ebb4caSwyllys BerValue *extdata; 1425*99ebb4caSwyllys 1426*99ebb4caSwyllys if (namedata == NULL || encodedname == NULL) 1427*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1428*99ebb4caSwyllys 1429*99ebb4caSwyllys /* 1430*99ebb4caSwyllys * Encode the namedata according to rules in RFC 3280 for GeneralName. 1431*99ebb4caSwyllys * The input "namedata" is assumed to be an ASCII string representation 1432*99ebb4caSwyllys * of the AltName, we need to convert it to correct ASN.1 here before 1433*99ebb4caSwyllys * adding it to the cert. 1434*99ebb4caSwyllys */ 1435*99ebb4caSwyllys switch (nametype) { 1436*99ebb4caSwyllys case GENNAME_RFC822NAME: /* rfc 822 */ 1437*99ebb4caSwyllys /* IA5String, no encoding needed */ 1438*99ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 1439*99ebb4caSwyllys if (encodedname->Data == NULL) 1440*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1441*99ebb4caSwyllys encodedname->Length = strlen(namedata); 1442*99ebb4caSwyllys tagval = (0x80 | nametype); 1443*99ebb4caSwyllys break; 1444*99ebb4caSwyllys case GENNAME_DNSNAME: /* rfc 1034 */ 1445*99ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 1446*99ebb4caSwyllys if (encodedname->Data == NULL) 1447*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1448*99ebb4caSwyllys encodedname->Length = strlen(namedata); 1449*99ebb4caSwyllys tagval = (0x80 | nametype); 1450*99ebb4caSwyllys break; 1451*99ebb4caSwyllys case GENNAME_URI: /* rfc 1738 */ 1452*99ebb4caSwyllys ret = verify_uri_format(namedata); 1453*99ebb4caSwyllys if (ret != KMF_OK) 1454*99ebb4caSwyllys return (ret); 1455*99ebb4caSwyllys /* IA5String, no encoding needed */ 1456*99ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 1457*99ebb4caSwyllys if (encodedname->Data == NULL) 1458*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1459*99ebb4caSwyllys encodedname->Length = strlen(namedata); 1460*99ebb4caSwyllys tagval = (0x80 | nametype); 1461*99ebb4caSwyllys break; 1462*99ebb4caSwyllys case GENNAME_IPADDRESS: 1463*99ebb4caSwyllys ret = encode_ipaddr(namedata, encodedname); 1464*99ebb4caSwyllys tagval = (0x80 | nametype); 1465*99ebb4caSwyllys break; 1466*99ebb4caSwyllys case GENNAME_REGISTEREDID: 1467*99ebb4caSwyllys ret = encode_rid(namedata, encodedname); 1468*99ebb4caSwyllys tagval = (0x80 | nametype); 1469*99ebb4caSwyllys break; 1470*99ebb4caSwyllys case GENNAME_DIRECTORYNAME: 1471*99ebb4caSwyllys ret = KMF_DNParser(namedata, &dnname); 1472*99ebb4caSwyllys if (ret == KMF_OK) { 1473*99ebb4caSwyllys ret = KMF_DN2Der(&dnname, encodedname); 1474*99ebb4caSwyllys } 1475*99ebb4caSwyllys (void) KMF_FreeDN(&dnname); 1476*99ebb4caSwyllys tagval = (0xA0 | nametype); 1477*99ebb4caSwyllys break; 1478*99ebb4caSwyllys default: 1479*99ebb4caSwyllys /* unsupported */ 1480*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1481*99ebb4caSwyllys 1482*99ebb4caSwyllys } 1483*99ebb4caSwyllys if (ret != KMF_OK) { 1484*99ebb4caSwyllys KMF_FreeData(encodedname); 1485*99ebb4caSwyllys return (ret); 1486*99ebb4caSwyllys } 1487*99ebb4caSwyllys 1488*99ebb4caSwyllys if ((asn1 = kmfder_alloc()) == NULL) 1489*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1490*99ebb4caSwyllys 1491*99ebb4caSwyllys if (kmfber_printf(asn1, "Tl", 1492*99ebb4caSwyllys tagval, encodedname->Length) == -1) 1493*99ebb4caSwyllys goto cleanup; 1494*99ebb4caSwyllys 1495*99ebb4caSwyllys if (kmfber_write(asn1, (char *)encodedname->Data, 1496*99ebb4caSwyllys encodedname->Length, 0) == -1) { 1497*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1498*99ebb4caSwyllys goto cleanup; 1499*99ebb4caSwyllys } 1500*99ebb4caSwyllys if (kmfber_flatten(asn1, &extdata) == -1) { 1501*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1502*99ebb4caSwyllys goto cleanup; 1503*99ebb4caSwyllys } 1504*99ebb4caSwyllys 1505*99ebb4caSwyllys KMF_FreeData(encodedname); 1506*99ebb4caSwyllys encodedname->Data = (uchar_t *)extdata->bv_val; 1507*99ebb4caSwyllys encodedname->Length = extdata->bv_len; 1508*99ebb4caSwyllys 1509*99ebb4caSwyllys free(extdata); 1510*99ebb4caSwyllys 1511*99ebb4caSwyllys cleanup: 1512*99ebb4caSwyllys if (asn1) 1513*99ebb4caSwyllys kmfber_free(asn1, 1); 1514*99ebb4caSwyllys 1515*99ebb4caSwyllys if (ret != KMF_OK) 1516*99ebb4caSwyllys KMF_FreeData(encodedname); 1517*99ebb4caSwyllys 1518*99ebb4caSwyllys return (ret); 1519*99ebb4caSwyllys } 1520*99ebb4caSwyllys 1521*99ebb4caSwyllys KMF_X509_EXTENSION * 1522*99ebb4caSwyllys FindExtn(KMF_X509_EXTENSIONS *exts, KMF_OID *oid) 1523*99ebb4caSwyllys { 1524*99ebb4caSwyllys KMF_X509_EXTENSION *foundextn = NULL; 1525*99ebb4caSwyllys int i; 1526*99ebb4caSwyllys 1527*99ebb4caSwyllys if (exts == NULL || oid == NULL) 1528*99ebb4caSwyllys return (NULL); 1529*99ebb4caSwyllys 1530*99ebb4caSwyllys for (i = 0; i < exts->numberOfExtensions; i++) { 1531*99ebb4caSwyllys if (IsEqualOid(oid, &exts->extensions[i].extnId)) { 1532*99ebb4caSwyllys foundextn = &exts->extensions[i]; 1533*99ebb4caSwyllys break; 1534*99ebb4caSwyllys } 1535*99ebb4caSwyllys } 1536*99ebb4caSwyllys return (foundextn); 1537*99ebb4caSwyllys } 1538*99ebb4caSwyllys 1539*99ebb4caSwyllys KMF_RETURN 1540*99ebb4caSwyllys GetSequenceContents(char *data, size_t len, 1541*99ebb4caSwyllys char **contents, size_t *outlen) 1542*99ebb4caSwyllys { 1543*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1544*99ebb4caSwyllys BerElement *exasn1 = NULL; 1545*99ebb4caSwyllys BerValue oldextn; 1546*99ebb4caSwyllys int tag; 1547*99ebb4caSwyllys size_t oldsize; 1548*99ebb4caSwyllys char *olddata = NULL; 1549*99ebb4caSwyllys 1550*99ebb4caSwyllys if (data == NULL || contents == NULL || outlen == NULL) 1551*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1552*99ebb4caSwyllys 1553*99ebb4caSwyllys /* 1554*99ebb4caSwyllys * Decode the sequence of general names 1555*99ebb4caSwyllys */ 1556*99ebb4caSwyllys oldextn.bv_val = data; 1557*99ebb4caSwyllys oldextn.bv_len = len; 1558*99ebb4caSwyllys 1559*99ebb4caSwyllys if ((exasn1 = kmfder_init(&oldextn)) == NULL) { 1560*99ebb4caSwyllys ret = KMF_ERR_MEMORY; 1561*99ebb4caSwyllys goto out; 1562*99ebb4caSwyllys } 1563*99ebb4caSwyllys 1564*99ebb4caSwyllys /* 1565*99ebb4caSwyllys * Unwrap the sequence to find the size of the block 1566*99ebb4caSwyllys * of GeneralName items in the set. 1567*99ebb4caSwyllys * 1568*99ebb4caSwyllys * Peek at the tag and length ("tl"), 1569*99ebb4caSwyllys * then consume them ("{"). 1570*99ebb4caSwyllys */ 1571*99ebb4caSwyllys if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT || 1572*99ebb4caSwyllys oldsize == 0) { 1573*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1574*99ebb4caSwyllys goto out; 1575*99ebb4caSwyllys } 1576*99ebb4caSwyllys 1577*99ebb4caSwyllys olddata = malloc(oldsize); 1578*99ebb4caSwyllys if (olddata == NULL) { 1579*99ebb4caSwyllys ret = KMF_ERR_MEMORY; 1580*99ebb4caSwyllys goto out; 1581*99ebb4caSwyllys } 1582*99ebb4caSwyllys (void) memset(olddata, 0, oldsize); 1583*99ebb4caSwyllys /* 1584*99ebb4caSwyllys * Read the entire blob of GeneralNames, we don't 1585*99ebb4caSwyllys * need to interpret them now. 1586*99ebb4caSwyllys */ 1587*99ebb4caSwyllys if (kmfber_read(exasn1, olddata, oldsize) != oldsize) { 1588*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1589*99ebb4caSwyllys goto out; 1590*99ebb4caSwyllys } 1591*99ebb4caSwyllys out: 1592*99ebb4caSwyllys if (exasn1 != NULL) 1593*99ebb4caSwyllys kmfber_free(exasn1, 1); 1594*99ebb4caSwyllys 1595*99ebb4caSwyllys if (ret != KMF_OK) { 1596*99ebb4caSwyllys *contents = NULL; 1597*99ebb4caSwyllys *outlen = 0; 1598*99ebb4caSwyllys if (olddata != NULL) 1599*99ebb4caSwyllys free(olddata); 1600*99ebb4caSwyllys } else { 1601*99ebb4caSwyllys *contents = olddata; 1602*99ebb4caSwyllys *outlen = oldsize; 1603*99ebb4caSwyllys } 1604*99ebb4caSwyllys return (ret); 1605*99ebb4caSwyllys } 1606*99ebb4caSwyllys 1607*99ebb4caSwyllys KMF_RETURN 1608*99ebb4caSwyllys add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) 1609*99ebb4caSwyllys { 1610*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1611*99ebb4caSwyllys KMF_X509_EXTENSION *extlist; 1612*99ebb4caSwyllys 1613*99ebb4caSwyllys if (exts == NULL || newextn == NULL) 1614*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1615*99ebb4caSwyllys 1616*99ebb4caSwyllys extlist = malloc(sizeof (KMF_X509_EXTENSION) * 1617*99ebb4caSwyllys (exts->numberOfExtensions + 1)); 1618*99ebb4caSwyllys if (extlist == NULL) 1619*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1620*99ebb4caSwyllys 1621*99ebb4caSwyllys (void) memcpy(extlist, exts->extensions, 1622*99ebb4caSwyllys exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION)); 1623*99ebb4caSwyllys 1624*99ebb4caSwyllys (void) memcpy(&extlist[exts->numberOfExtensions], newextn, 1625*99ebb4caSwyllys sizeof (KMF_X509_EXTENSION)); 1626*99ebb4caSwyllys 1627*99ebb4caSwyllys free(exts->extensions); 1628*99ebb4caSwyllys exts->numberOfExtensions++; 1629*99ebb4caSwyllys exts->extensions = extlist; 1630*99ebb4caSwyllys 1631*99ebb4caSwyllys return (ret); 1632*99ebb4caSwyllys } 1633*99ebb4caSwyllys 1634*99ebb4caSwyllys KMF_RETURN 1635*99ebb4caSwyllys KMF_SetAltName(KMF_X509_EXTENSIONS *extensions, 1636*99ebb4caSwyllys KMF_OID *oid, 1637*99ebb4caSwyllys int critical, 1638*99ebb4caSwyllys KMF_GENERALNAMECHOICES nametype, 1639*99ebb4caSwyllys char *namedata) 1640*99ebb4caSwyllys { 1641*99ebb4caSwyllys KMF_RETURN ret = KMF_OK; 1642*99ebb4caSwyllys KMF_X509_EXTENSION subjAltName; 1643*99ebb4caSwyllys KMF_DATA dername = { NULL, 0 }; 1644*99ebb4caSwyllys BerElement *asn1 = NULL; 1645*99ebb4caSwyllys BerValue *extdata; 1646*99ebb4caSwyllys char *olddata = NULL; 1647*99ebb4caSwyllys KMF_X509_EXTENSION *foundextn = NULL; 1648*99ebb4caSwyllys size_t oldsize = 0; 1649*99ebb4caSwyllys 1650*99ebb4caSwyllys if (extensions == NULL || oid == NULL || namedata == NULL) 1651*99ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 1652*99ebb4caSwyllys 1653*99ebb4caSwyllys ret = encode_altname(namedata, nametype, &dername); 1654*99ebb4caSwyllys 1655*99ebb4caSwyllys if (ret != KMF_OK) 1656*99ebb4caSwyllys return (ret); 1657*99ebb4caSwyllys 1658*99ebb4caSwyllys (void) memset(&subjAltName, 0, sizeof (subjAltName)); 1659*99ebb4caSwyllys 1660*99ebb4caSwyllys ret = copy_data(&subjAltName.extnId, oid); 1661*99ebb4caSwyllys if (ret != KMF_OK) 1662*99ebb4caSwyllys goto out; 1663*99ebb4caSwyllys /* 1664*99ebb4caSwyllys * Check to see if this cert already has a subjectAltName. 1665*99ebb4caSwyllys */ 1666*99ebb4caSwyllys foundextn = FindExtn(extensions, oid); 1667*99ebb4caSwyllys 1668*99ebb4caSwyllys if (foundextn != NULL) { 1669*99ebb4caSwyllys ret = GetSequenceContents( 1670*99ebb4caSwyllys (char *)foundextn->BERvalue.Data, 1671*99ebb4caSwyllys foundextn->BERvalue.Length, 1672*99ebb4caSwyllys &olddata, &oldsize); 1673*99ebb4caSwyllys if (ret != KMF_OK) 1674*99ebb4caSwyllys goto out; 1675*99ebb4caSwyllys } 1676*99ebb4caSwyllys 1677*99ebb4caSwyllys /* 1678*99ebb4caSwyllys * Assume (!!) that the namedata given is already properly encoded. 1679*99ebb4caSwyllys */ 1680*99ebb4caSwyllys if ((asn1 = kmfder_alloc()) == NULL) 1681*99ebb4caSwyllys return (KMF_ERR_MEMORY); 1682*99ebb4caSwyllys 1683*99ebb4caSwyllys if (kmfber_printf(asn1, "{") == -1) { 1684*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1685*99ebb4caSwyllys goto out; 1686*99ebb4caSwyllys } 1687*99ebb4caSwyllys 1688*99ebb4caSwyllys /* Write the old extension data first */ 1689*99ebb4caSwyllys if (olddata != NULL && oldsize > 0) { 1690*99ebb4caSwyllys if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 1691*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1692*99ebb4caSwyllys goto out; 1693*99ebb4caSwyllys } 1694*99ebb4caSwyllys } 1695*99ebb4caSwyllys 1696*99ebb4caSwyllys /* Now add the new name to the list */ 1697*99ebb4caSwyllys if (kmfber_write(asn1, (char *)dername.Data, dername.Length, 0) == -1) { 1698*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1699*99ebb4caSwyllys goto out; 1700*99ebb4caSwyllys } 1701*99ebb4caSwyllys 1702*99ebb4caSwyllys /* Now close the sequence */ 1703*99ebb4caSwyllys if (kmfber_printf(asn1, "}") == -1) { 1704*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1705*99ebb4caSwyllys goto out; 1706*99ebb4caSwyllys } 1707*99ebb4caSwyllys if (kmfber_flatten(asn1, &extdata) == -1) { 1708*99ebb4caSwyllys ret = KMF_ERR_ENCODING; 1709*99ebb4caSwyllys goto out; 1710*99ebb4caSwyllys } 1711*99ebb4caSwyllys 1712*99ebb4caSwyllys /* 1713*99ebb4caSwyllys * If we are just adding to an existing list of altNames, 1714*99ebb4caSwyllys * just replace the BER data associated with the found extension. 1715*99ebb4caSwyllys */ 1716*99ebb4caSwyllys if (foundextn != NULL) { 1717*99ebb4caSwyllys free(foundextn->BERvalue.Data); 1718*99ebb4caSwyllys foundextn->critical = critical; 1719*99ebb4caSwyllys foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 1720*99ebb4caSwyllys foundextn->BERvalue.Length = extdata->bv_len; 1721*99ebb4caSwyllys } else { 1722*99ebb4caSwyllys subjAltName.critical = critical; 1723*99ebb4caSwyllys subjAltName.format = KMF_X509_DATAFORMAT_ENCODED; 1724*99ebb4caSwyllys subjAltName.BERvalue.Data = (uchar_t *)extdata->bv_val; 1725*99ebb4caSwyllys subjAltName.BERvalue.Length = extdata->bv_len; 1726*99ebb4caSwyllys ret = add_an_extension(extensions, &subjAltName); 1727*99ebb4caSwyllys if (ret != KMF_OK) 1728*99ebb4caSwyllys free(subjAltName.BERvalue.Data); 1729*99ebb4caSwyllys } 1730*99ebb4caSwyllys 1731*99ebb4caSwyllys free(extdata); 1732*99ebb4caSwyllys out: 1733*99ebb4caSwyllys if (olddata != NULL) 1734*99ebb4caSwyllys free(olddata); 1735*99ebb4caSwyllys 1736*99ebb4caSwyllys KMF_FreeData(&dername); 1737*99ebb4caSwyllys if (ret != KMF_OK) 1738*99ebb4caSwyllys KMF_FreeData(&subjAltName.extnId); 1739*99ebb4caSwyllys if (asn1 != NULL) 1740*99ebb4caSwyllys kmfber_free(asn1, 1); 1741*99ebb4caSwyllys return (ret); 1742*99ebb4caSwyllys } 1743