199ebb4caSwyllys /* 299ebb4caSwyllys * CDDL HEADER START 399ebb4caSwyllys * 499ebb4caSwyllys * The contents of this file are subject to the terms of the 599ebb4caSwyllys * Common Development and Distribution License (the "License"). 699ebb4caSwyllys * You may not use this file except in compliance with the License. 799ebb4caSwyllys * 899ebb4caSwyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 999ebb4caSwyllys * or http://www.opensolaris.org/os/licensing. 1099ebb4caSwyllys * See the License for the specific language governing permissions 1199ebb4caSwyllys * and limitations under the License. 1299ebb4caSwyllys * 1399ebb4caSwyllys * When distributing Covered Code, include this CDDL HEADER in each 1499ebb4caSwyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1599ebb4caSwyllys * If applicable, add the following below this CDDL HEADER, with the 1699ebb4caSwyllys * fields enclosed by brackets "[]" replaced with your own identifying 1799ebb4caSwyllys * information: Portions Copyright [yyyy] [name of copyright owner] 1899ebb4caSwyllys * 1999ebb4caSwyllys * CDDL HEADER END 2099ebb4caSwyllys */ 2199ebb4caSwyllys /* 2271593db2Swyllys * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 2399ebb4caSwyllys * Use is subject to license terms. 2499ebb4caSwyllys * 2599ebb4caSwyllys */ 2699ebb4caSwyllys 2799ebb4caSwyllys #pragma ident "%Z%%M% %I% %E% SMI" 2899ebb4caSwyllys 2999ebb4caSwyllys #include <stdio.h> 3099ebb4caSwyllys #include <dlfcn.h> 3199ebb4caSwyllys #include <link.h> 3299ebb4caSwyllys #include <fcntl.h> 3399ebb4caSwyllys #include <ctype.h> 3499ebb4caSwyllys #include <sys/param.h> 3599ebb4caSwyllys #include <sys/types.h> 3699ebb4caSwyllys #include <sys/stat.h> 3799ebb4caSwyllys #include <errno.h> 3899ebb4caSwyllys #include <sys/socket.h> 3999ebb4caSwyllys #include <netinet/in.h> 4099ebb4caSwyllys #include <arpa/inet.h> 4199ebb4caSwyllys #include <thread.h> 4299ebb4caSwyllys 4399ebb4caSwyllys #include <ber_der.h> 4499ebb4caSwyllys #include <kmfapiP.h> 4599ebb4caSwyllys 4699ebb4caSwyllys #include <pem_encode.h> 4799ebb4caSwyllys #include <rdn_parser.h> 4899ebb4caSwyllys #include <libxml2/libxml/uri.h> 4999ebb4caSwyllys #include <libgen.h> 5099ebb4caSwyllys #include <cryptoutil.h> 5199ebb4caSwyllys 5299ebb4caSwyllys static uchar_t pkcs11_initialized = 0; 5399ebb4caSwyllys mutex_t init_lock = DEFAULTMUTEX; 5499ebb4caSwyllys extern int errno; 5599ebb4caSwyllys 5699ebb4caSwyllys typedef struct { 5799ebb4caSwyllys KMF_RETURN code; 5899ebb4caSwyllys char *message; 5999ebb4caSwyllys } kmf_error_map; 6099ebb4caSwyllys 6199ebb4caSwyllys static kmf_error_map kmf_errcodes[] = { 6299ebb4caSwyllys {KMF_OK, "KMF_OK"}, 6399ebb4caSwyllys {KMF_ERR_BAD_PARAMETER, "KMF_ERR_BAD_PARAMETER"}, 6499ebb4caSwyllys {KMF_ERR_BAD_KEY_FORMAT, "KMF_ERR_BAD_KEY_FORMAT"}, 6599ebb4caSwyllys {KMF_ERR_BAD_ALGORITHM, "KMF_ERR_BAD_ALGORITHM"}, 6699ebb4caSwyllys {KMF_ERR_MEMORY, "KMF_ERR_MEMORY"}, 6799ebb4caSwyllys {KMF_ERR_ENCODING, "KMF_ERR_ENCODING"}, 6899ebb4caSwyllys {KMF_ERR_PLUGIN_INIT, "KMF_ERR_PLUGIN_INIT"}, 6999ebb4caSwyllys {KMF_ERR_PLUGIN_NOTFOUND, "KMF_ERR_PLUGIN_NOTFOUND"}, 7099ebb4caSwyllys {KMF_ERR_INTERNAL, "KMF_ERR_INTERNAL"}, 7199ebb4caSwyllys {KMF_ERR_BAD_CERT_FORMAT, "KMF_ERR_BAD_CERT_FORMAT"}, 7299ebb4caSwyllys {KMF_ERR_KEYGEN_FAILED, "KMF_ERR_KEYGEN_FAILED"}, 7399ebb4caSwyllys {KMF_ERR_UNINITIALIZED, "KMF_ERR_UNINITIALIZED"}, 7499ebb4caSwyllys {KMF_ERR_ISSUER, "KMF_ERR_ISSUER"}, 7599ebb4caSwyllys {KMF_ERR_NOT_REVOKED, "KMF_ERR_NOT_REVOKED"}, 7699ebb4caSwyllys {KMF_ERR_CERT_NOT_FOUND, "KMF_ERR_CERT_NOT_FOUND"}, 7799ebb4caSwyllys {KMF_ERR_CRL_NOT_FOUND, "KMF_ERR_CRL_NOT_FOUND"}, 7899ebb4caSwyllys {KMF_ERR_RDN_PARSER, "KMF_ERR_RDN_PARSER"}, 7999ebb4caSwyllys {KMF_ERR_RDN_ATTR, "KMF_ERR_RDN_ATTR"}, 8099ebb4caSwyllys {KMF_ERR_SLOTNAME, "KMF_ERR_SLOTNAME"}, 8199ebb4caSwyllys {KMF_ERR_EMPTY_CRL, "KMF_ERR_EMPTY_CRL"}, 8299ebb4caSwyllys {KMF_ERR_BUFFER_SIZE, "KMF_ERR_BUFFER_SIZE"}, 8399ebb4caSwyllys {KMF_ERR_AUTH_FAILED, "KMF_ERR_AUTH_FAILED"}, 8499ebb4caSwyllys {KMF_ERR_TOKEN_SELECTED, "KMF_ERR_TOKEN_SELECTED"}, 8599ebb4caSwyllys {KMF_ERR_NO_TOKEN_SELECTED, "KMF_ERR_NO_TOKEN_SELECTED"}, 8699ebb4caSwyllys {KMF_ERR_TOKEN_NOT_PRESENT, "KMF_ERR_TOKEN_NOT_PRESENT"}, 8799ebb4caSwyllys {KMF_ERR_EXTENSION_NOT_FOUND, "KMF_ERR_EXTENSION_NOT_FOUND"}, 8899ebb4caSwyllys {KMF_ERR_POLICY_ENGINE, "KMF_ERR_POLICY_ENGINE"}, 8999ebb4caSwyllys {KMF_ERR_POLICY_DB_FORMAT, "KMF_ERR_POLICY_DB_FORMAT"}, 9099ebb4caSwyllys {KMF_ERR_POLICY_NOT_FOUND, "KMF_ERR_POLICY_NOT_FOUND"}, 9199ebb4caSwyllys {KMF_ERR_POLICY_DB_FILE, "KMF_ERR_POLICY_DB_FILE"}, 9299ebb4caSwyllys {KMF_ERR_POLICY_NAME, "KMF_ERR_POLICY_NAME"}, 9399ebb4caSwyllys {KMF_ERR_OCSP_POLICY, "KMF_ERR_OCSP_POLICY"}, 9499ebb4caSwyllys {KMF_ERR_TA_POLICY, "KMF_ERR_TA_POLICY"}, 9599ebb4caSwyllys {KMF_ERR_KEY_NOT_FOUND, "KMF_ERR_KEY_NOT_FOUND"}, 9699ebb4caSwyllys {KMF_ERR_OPEN_FILE, "KMF_ERR_OPEN_FILE"}, 9799ebb4caSwyllys {KMF_ERR_OCSP_BAD_ISSUER, "KMF_ERR_OCSP_BAD_ISSUER"}, 9899ebb4caSwyllys {KMF_ERR_OCSP_BAD_CERT, "KMF_ERR_OCSP_BAD_CERT"}, 9999ebb4caSwyllys {KMF_ERR_OCSP_CREATE_REQUEST, "KMF_ERR_OCSP_CREATE_REQUEST"}, 10099ebb4caSwyllys {KMF_ERR_CONNECT_SERVER, "KMF_ERR_CONNECT_SERVER"}, 10199ebb4caSwyllys {KMF_ERR_SEND_REQUEST, "KMF_ERR_SEND_REQUEST"}, 10299ebb4caSwyllys {KMF_ERR_OCSP_CERTID, "KMF_ERR_OCSP_CERTID"}, 10399ebb4caSwyllys {KMF_ERR_OCSP_MALFORMED_RESPONSE, "KMF_ERR_OCSP_MALFORMED_RESPONSE"}, 10499ebb4caSwyllys {KMF_ERR_OCSP_RESPONSE_STATUS, "KMF_ERR_OCSP_RESPONSE_STATUS"}, 10599ebb4caSwyllys {KMF_ERR_OCSP_NO_BASIC_RESPONSE, "KMF_ERR_OCSP_NO_BASIC_RESPONSE"}, 10699ebb4caSwyllys {KMF_ERR_OCSP_BAD_SIGNER, "KMF_ERR_OCSP_BAD_SIGNER"}, 10799ebb4caSwyllys {KMF_ERR_OCSP_RESPONSE_SIGNATURE, "KMF_ERR_OCSP_RESPONSE_SIGNATURE"}, 10899ebb4caSwyllys {KMF_ERR_OCSP_UNKNOWN_CERT, "KMF_ERR_OCSP_UNKNOWN_CERT"}, 10999ebb4caSwyllys {KMF_ERR_OCSP_STATUS_TIME_INVALID, "KMF_ERR_OCSP_STATUS_TIME_INVALID"}, 11099ebb4caSwyllys {KMF_ERR_BAD_HTTP_RESPONSE, "KMF_ERR_BAD_HTTP_RESPONSE"}, 11199ebb4caSwyllys {KMF_ERR_RECV_RESPONSE, "KMF_ERR_RECV_RESPONSE"}, 11299ebb4caSwyllys {KMF_ERR_RECV_TIMEOUT, "KMF_ERR_RECV_TIMEOUT"}, 11399ebb4caSwyllys {KMF_ERR_DUPLICATE_KEYFILE, "KMF_ERR_DUPLICATE_KEYFILE"}, 11499ebb4caSwyllys {KMF_ERR_AMBIGUOUS_PATHNAME, "KMF_ERR_AMBIGUOUS_PATHNAME"}, 11599ebb4caSwyllys {KMF_ERR_FUNCTION_NOT_FOUND, "KMF_ERR_FUNCTION_NOT_FOUND"}, 11699ebb4caSwyllys {KMF_ERR_PKCS12_FORMAT, "KMF_ERR_PKCS12_FORMAT"}, 11799ebb4caSwyllys {KMF_ERR_BAD_KEY_TYPE, "KMF_ERR_BAD_KEY_TYPE"}, 11899ebb4caSwyllys {KMF_ERR_BAD_KEY_CLASS, "KMF_ERR_BAD_KEY_CLASS"}, 11999ebb4caSwyllys {KMF_ERR_BAD_KEY_SIZE, "KMF_ERR_BAD_KEY_SIZE"}, 12099ebb4caSwyllys {KMF_ERR_BAD_HEX_STRING, "KMF_ERR_BAD_HEX_STRING"}, 12199ebb4caSwyllys {KMF_ERR_KEYUSAGE, "KMF_ERR_KEYUSAGE"}, 12299ebb4caSwyllys {KMF_ERR_VALIDITY_PERIOD, "KMF_ERR_VALIDITY_PERIOD"}, 12399ebb4caSwyllys {KMF_ERR_OCSP_REVOKED, "KMF_ERR_OCSP_REVOKED"}, 12499ebb4caSwyllys {KMF_ERR_CERT_MULTIPLE_FOUND, "KMF_ERR_CERT_MULTIPLE_FOUND"}, 12599ebb4caSwyllys {KMF_ERR_WRITE_FILE, "KMF_ERR_WRITE_FILE"}, 12699ebb4caSwyllys {KMF_ERR_BAD_URI, "KMF_ERR_BAD_URI"}, 12799ebb4caSwyllys {KMF_ERR_BAD_CRLFILE, "KMF_ERR_BAD_CRLFILE"}, 12899ebb4caSwyllys {KMF_ERR_BAD_CERTFILE, "KMF_ERR_BAD_CERTFILE"}, 12999ebb4caSwyllys {KMF_ERR_GETKEYVALUE_FAILED, "KMF_ERR_GETKEYVALUE_FAILED"}, 13099ebb4caSwyllys {KMF_ERR_BAD_KEYHANDLE, "KMF_ERR_BAD_KEYHANDLE"}, 13199ebb4caSwyllys {KMF_ERR_BAD_OBJECT_TYPE, "KMF_ERR_BAD_OBJECT_TYPE"}, 13299ebb4caSwyllys {KMF_ERR_OCSP_RESPONSE_LIFETIME, "KMF_ERR_OCSP_RESPONSE_LIFETIME"}, 13399ebb4caSwyllys {KMF_ERR_UNKNOWN_CSR_ATTRIBUTE, "KMF_ERR_UNKNOWN_CSR_ATTRIBUTE"}, 13499ebb4caSwyllys {KMF_ERR_UNINITIALIZED_TOKEN, "KMF_ERR_UNINITIALIZED_TOKEN"}, 13599ebb4caSwyllys {KMF_ERR_INCOMPLETE_TBS_CERT, "KMF_ERR_INCOMPLETE_TBS_CERT"}, 13699ebb4caSwyllys {KMF_ERR_MISSING_ERRCODE, "KMF_ERR_MISSING_ERRCODE"}, 13771593db2Swyllys {KMF_KEYSTORE_ALREADY_INITIALIZED, "KMF_KEYSTORE_ALREADY_INITIALIZED"}, 13871593db2Swyllys {KMF_ERR_SENSITIVE_KEY, "KMF_ERR_SENSITIVE_KEY"}, 13971593db2Swyllys {KMF_ERR_UNEXTRACTABLE_KEY, "KMF_ERR_UNEXTRACTABLE_KEY"}, 14071593db2Swyllys {KMF_ERR_KEY_MISMATCH, "KMF_ERR_KEY_MISMATCH"} 14199ebb4caSwyllys }; 14299ebb4caSwyllys 14385b65b39Swyllys typedef struct { 14485b65b39Swyllys KMF_KEYSTORE_TYPE kstype; 14585b65b39Swyllys char *path; 14685b65b39Swyllys boolean_t critical; 14785b65b39Swyllys } KMF_PLUGIN_ITEM; 14885b65b39Swyllys 14985b65b39Swyllys KMF_PLUGIN_ITEM plugin_list[] = { 15085b65b39Swyllys {KMF_KEYSTORE_OPENSSL, KMF_PLUGIN_PATH "kmf_openssl.so.1", TRUE}, 15185b65b39Swyllys {KMF_KEYSTORE_PK11TOKEN, KMF_PLUGIN_PATH "kmf_pkcs11.so.1", TRUE}, 15285b65b39Swyllys {KMF_KEYSTORE_NSS, KMF_PLUGIN_PATH "kmf_nss.so.1", FALSE} 15385b65b39Swyllys }; 15499ebb4caSwyllys 15530a5e8faSwyllys 15630a5e8faSwyllys 15790c85bf8Swyllys static KMF_RETURN InitializePlugin(KMF_KEYSTORE_TYPE, char *, KMF_PLUGIN **); 15890c85bf8Swyllys static KMF_RETURN AddPlugin(KMF_HANDLE_T, KMF_PLUGIN *); 15999ebb4caSwyllys static void free_extensions(KMF_X509_EXTENSIONS *extns); 16090c85bf8Swyllys static void DestroyPlugin(KMF_PLUGIN *); 16199ebb4caSwyllys 162*431deaa0Shylee #if defined(__sparcv9) 163*431deaa0Shylee #define ISA_PATH "/sparcv9" 164*431deaa0Shylee #elif defined(__sparc) 165*431deaa0Shylee #define ISA_PATH "/" 166*431deaa0Shylee #elif defined(__i386) 167*431deaa0Shylee #define ISA_PATH "/" 168*431deaa0Shylee #elif defined(__amd64) 169*431deaa0Shylee #define ISA_PATH "/amd64" 170*431deaa0Shylee #endif 171*431deaa0Shylee 172*431deaa0Shylee #define DEFAULT_KEYSTORE_NUM 3 173*431deaa0Shylee static int kstore_num = DEFAULT_KEYSTORE_NUM; 174*431deaa0Shylee conf_entrylist_t *extra_plugin_list = NULL; 175*431deaa0Shylee static boolean_t check_extra_plugin = B_FALSE; 176*431deaa0Shylee mutex_t extra_plugin_lock = DEFAULTMUTEX; 177*431deaa0Shylee 1789b37d296Swyllys KMF_RETURN 1799b37d296Swyllys init_pk11() 18099ebb4caSwyllys { 1819b37d296Swyllys (void) mutex_lock(&init_lock); 1829b37d296Swyllys if (!pkcs11_initialized) { 1839b37d296Swyllys CK_RV rv = C_Initialize(NULL); 1849b37d296Swyllys if ((rv != CKR_OK) && 1859b37d296Swyllys (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 1869b37d296Swyllys (void) mutex_unlock(&init_lock); 1879b37d296Swyllys return (KMF_ERR_UNINITIALIZED); 1889b37d296Swyllys } else { 1899b37d296Swyllys pkcs11_initialized = 1; 1909b37d296Swyllys } 1919b37d296Swyllys } 1929b37d296Swyllys (void) mutex_unlock(&init_lock); 1939b37d296Swyllys return (KMF_OK); 19499ebb4caSwyllys } 19599ebb4caSwyllys 19699ebb4caSwyllys /* 19799ebb4caSwyllys * Private method for searching the plugin list for the correct 19899ebb4caSwyllys * Plugin to use. 19999ebb4caSwyllys */ 20099ebb4caSwyllys KMF_PLUGIN * 20199ebb4caSwyllys FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype) 20299ebb4caSwyllys { 20399ebb4caSwyllys KMF_PLUGIN_LIST *node; 20490c85bf8Swyllys KMF_RETURN ret = KMF_OK; 205*431deaa0Shylee KMF_PLUGIN *pluginrec = NULL; 20699ebb4caSwyllys 20799ebb4caSwyllys if (handle == NULL) 20899ebb4caSwyllys return (NULL); 20999ebb4caSwyllys 21099ebb4caSwyllys node = handle->plugins; 21199ebb4caSwyllys 21290c85bf8Swyllys /* See if the desired plugin was already initialized. */ 21399ebb4caSwyllys while (node != NULL && node->plugin->type != kstype) 21499ebb4caSwyllys node = node->next; 21599ebb4caSwyllys 216*431deaa0Shylee if (node != NULL) 217*431deaa0Shylee return (node->plugin); 218*431deaa0Shylee 219*431deaa0Shylee /* The plugin was not found, try to initialize it here. */ 220*431deaa0Shylee if (VALID_DEFAULT_KEYSTORE_TYPE(kstype)) { 22190c85bf8Swyllys int i; 22290c85bf8Swyllys int numitems = sizeof (plugin_list)/sizeof (KMF_PLUGIN_ITEM); 22390c85bf8Swyllys for (i = 0; i < numitems; i++) { 22490c85bf8Swyllys if (plugin_list[i].kstype == kstype) { 22590c85bf8Swyllys ret = InitializePlugin(plugin_list[i].kstype, 22690c85bf8Swyllys plugin_list[i].path, &pluginrec); 22790c85bf8Swyllys break; 22890c85bf8Swyllys } 22990c85bf8Swyllys } 23090c85bf8Swyllys 231*431deaa0Shylee goto out; 232*431deaa0Shylee 233*431deaa0Shylee } else { 234*431deaa0Shylee /* 235*431deaa0Shylee * Not a built-in plugin. Check if it is in the 236*431deaa0Shylee * extra_plugin_list. If it is, try to initialize it here. 237*431deaa0Shylee */ 238*431deaa0Shylee conf_entrylist_t *phead = extra_plugin_list; 239*431deaa0Shylee char realpath[MAXPATHLEN]; 240*431deaa0Shylee 241*431deaa0Shylee while (phead != NULL) { 242*431deaa0Shylee if (phead->entry->kstype == kstype) 243*431deaa0Shylee break; 244*431deaa0Shylee else 245*431deaa0Shylee phead = phead->next; 246*431deaa0Shylee } 247*431deaa0Shylee 248*431deaa0Shylee if (phead == NULL) 24990c85bf8Swyllys return (NULL); 25090c85bf8Swyllys 251*431deaa0Shylee /* 252*431deaa0Shylee * Get the absolute path of the module. 253*431deaa0Shylee * - If modulepath is not a full path, then prepend it 254*431deaa0Shylee * with KMF_PLUGIN_PATH. 255*431deaa0Shylee * - If modulepath is a full path and contain $ISA, then 256*431deaa0Shylee * subsitute the architecture dependent path. 257*431deaa0Shylee */ 258*431deaa0Shylee (void) memset(realpath, 0, sizeof (realpath)); 259*431deaa0Shylee if (strncmp(phead->entry->modulepath, "/", 1) != 0) { 260*431deaa0Shylee (void) snprintf(realpath, MAXPATHLEN, "%s%s", 261*431deaa0Shylee KMF_PLUGIN_PATH, phead->entry->modulepath); 262*431deaa0Shylee } else { 263*431deaa0Shylee char *buf = phead->entry->modulepath; 264*431deaa0Shylee char *isa; 265*431deaa0Shylee 266*431deaa0Shylee if ((isa = strstr(buf, PKCS11_ISA)) != NULL) { 267*431deaa0Shylee char *isa_str; 268*431deaa0Shylee 269*431deaa0Shylee (void) strncpy(realpath, buf, isa - buf); 270*431deaa0Shylee isa_str = strdup(ISA_PATH); 271*431deaa0Shylee if (isa_str == NULL) /* not enough memory */ 272*431deaa0Shylee return (NULL); 273*431deaa0Shylee 274*431deaa0Shylee (void) strncat(realpath, isa_str, 275*431deaa0Shylee strlen(isa_str)); 276*431deaa0Shylee free(isa_str); 277*431deaa0Shylee 278*431deaa0Shylee isa += strlen(PKCS11_ISA); 279*431deaa0Shylee (void) strlcat(realpath, isa, MAXPATHLEN); 280*431deaa0Shylee } else { 281*431deaa0Shylee (void) snprintf(realpath, MAXPATHLEN, "%s", 282*431deaa0Shylee phead->entry->modulepath); 283*431deaa0Shylee } 28490c85bf8Swyllys } 285*431deaa0Shylee 286*431deaa0Shylee ret = InitializePlugin(phead->entry->kstype, realpath, 287*431deaa0Shylee &pluginrec); 288*431deaa0Shylee goto out; 289*431deaa0Shylee } 290*431deaa0Shylee 291*431deaa0Shylee out: 292*431deaa0Shylee if (ret != KMF_OK || pluginrec == NULL) 293*431deaa0Shylee /* No matching plugins found in the built-in list */ 294*431deaa0Shylee return (NULL); 295*431deaa0Shylee 296*431deaa0Shylee ret = AddPlugin(handle, pluginrec); 297*431deaa0Shylee if (ret != KMF_OK) { 298*431deaa0Shylee DestroyPlugin(pluginrec); 299*431deaa0Shylee pluginrec = NULL; 30090c85bf8Swyllys } 301*431deaa0Shylee return (pluginrec); 30299ebb4caSwyllys } 30399ebb4caSwyllys 304*431deaa0Shylee 30599ebb4caSwyllys static KMF_RETURN 30699ebb4caSwyllys InitializePlugin(KMF_KEYSTORE_TYPE kstype, char *path, KMF_PLUGIN **plugin) 30799ebb4caSwyllys { 30899ebb4caSwyllys KMF_PLUGIN *p = NULL; 30999ebb4caSwyllys KMF_PLUGIN_FUNCLIST *(*sym)(); 31099ebb4caSwyllys 31199ebb4caSwyllys if (path == NULL || plugin == NULL) 31299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 31399ebb4caSwyllys 31499ebb4caSwyllys *plugin = NULL; 31599ebb4caSwyllys 31699ebb4caSwyllys p = (KMF_PLUGIN *)malloc(sizeof (KMF_PLUGIN)); 31799ebb4caSwyllys if (p == NULL) 31899ebb4caSwyllys return (KMF_ERR_MEMORY); 31999ebb4caSwyllys 32099ebb4caSwyllys p->type = kstype; 32199ebb4caSwyllys p->path = strdup(path); 32299ebb4caSwyllys if (p->path == NULL) { 32399ebb4caSwyllys free(p); 32499ebb4caSwyllys return (KMF_ERR_MEMORY); 32599ebb4caSwyllys } 32690c85bf8Swyllys p->dldesc = dlopen(path, RTLD_LAZY | RTLD_GROUP | RTLD_PARENT); 32799ebb4caSwyllys if (p->dldesc == NULL) { 32899ebb4caSwyllys free(p->path); 32999ebb4caSwyllys free(p); 33099ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 33199ebb4caSwyllys } 33299ebb4caSwyllys 33399ebb4caSwyllys sym = (KMF_PLUGIN_FUNCLIST *(*)())dlsym(p->dldesc, 33430a5e8faSwyllys KMF_PLUGIN_INIT_SYMBOL); 33599ebb4caSwyllys if (sym == NULL) { 33699ebb4caSwyllys (void) dlclose(p->dldesc); 33799ebb4caSwyllys free(p->path); 33899ebb4caSwyllys free(p); 33999ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 34099ebb4caSwyllys } 34199ebb4caSwyllys 34299ebb4caSwyllys /* Get the function list */ 34399ebb4caSwyllys if ((p->funclist = (*sym)()) == NULL) { 34499ebb4caSwyllys (void) dlclose(p->dldesc); 34599ebb4caSwyllys free(p->path); 34699ebb4caSwyllys free(p); 34799ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 34899ebb4caSwyllys } 34999ebb4caSwyllys 35099ebb4caSwyllys *plugin = p; 35199ebb4caSwyllys 35299ebb4caSwyllys return (KMF_OK); 35399ebb4caSwyllys } 35499ebb4caSwyllys 35599ebb4caSwyllys static KMF_RETURN 35699ebb4caSwyllys AddPlugin(KMF_HANDLE_T handle, KMF_PLUGIN *plugin) 35799ebb4caSwyllys { 35899ebb4caSwyllys KMF_PLUGIN_LIST *n; 35999ebb4caSwyllys 36099ebb4caSwyllys if (handle == NULL || plugin == NULL) 36199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 36299ebb4caSwyllys 36399ebb4caSwyllys /* If the head is NULL, create it */ 36499ebb4caSwyllys if (handle->plugins == NULL) { 36599ebb4caSwyllys handle->plugins = (KMF_PLUGIN_LIST *)malloc( 36630a5e8faSwyllys sizeof (KMF_PLUGIN_LIST)); 36799ebb4caSwyllys if (handle->plugins == NULL) 36899ebb4caSwyllys return (KMF_ERR_MEMORY); 36999ebb4caSwyllys handle->plugins->plugin = plugin; 37099ebb4caSwyllys handle->plugins->next = NULL; 37199ebb4caSwyllys } else { 37299ebb4caSwyllys /* walk the list to find the tail */ 37399ebb4caSwyllys n = handle->plugins; 37499ebb4caSwyllys while (n->next != NULL) 37599ebb4caSwyllys n = n->next; 37699ebb4caSwyllys n->next = (KMF_PLUGIN_LIST *)malloc(sizeof (KMF_PLUGIN_LIST)); 37799ebb4caSwyllys if (n->next == NULL) 37899ebb4caSwyllys return (KMF_ERR_MEMORY); 37999ebb4caSwyllys 38099ebb4caSwyllys n->next->plugin = plugin; 38199ebb4caSwyllys n->next->next = NULL; 38299ebb4caSwyllys } 38399ebb4caSwyllys return (0); 38499ebb4caSwyllys } 38599ebb4caSwyllys 38699ebb4caSwyllys static void 38799ebb4caSwyllys DestroyPlugin(KMF_PLUGIN *plugin) 38899ebb4caSwyllys { 38999ebb4caSwyllys if (plugin) { 39099ebb4caSwyllys if (plugin->path) 39199ebb4caSwyllys free(plugin->path); 39299ebb4caSwyllys free(plugin); 39399ebb4caSwyllys } 39499ebb4caSwyllys } 39599ebb4caSwyllys 39699ebb4caSwyllys static void 39799ebb4caSwyllys Cleanup_KMF_Handle(KMF_HANDLE_T handle) 39899ebb4caSwyllys { 39999ebb4caSwyllys if (handle != NULL) { 40099ebb4caSwyllys while (handle->plugins != NULL) { 40199ebb4caSwyllys KMF_PLUGIN_LIST *next = handle->plugins->next; 40299ebb4caSwyllys 40399ebb4caSwyllys DestroyPlugin(handle->plugins->plugin); 40499ebb4caSwyllys free(handle->plugins); 40599ebb4caSwyllys handle->plugins = next; 40699ebb4caSwyllys } 40730a5e8faSwyllys kmf_free_policy_record(handle->policy); 40899ebb4caSwyllys free(handle->policy); 40999ebb4caSwyllys } 41099ebb4caSwyllys free(handle); 41199ebb4caSwyllys } 41299ebb4caSwyllys 41399ebb4caSwyllys void 41499ebb4caSwyllys Cleanup_PK11_Session(KMF_HANDLE_T handle) 41599ebb4caSwyllys { 41699ebb4caSwyllys if (handle != NULL) { 41799ebb4caSwyllys /* Close active session on a pkcs11 token */ 41899ebb4caSwyllys if (handle->pk11handle != NULL) { 41999ebb4caSwyllys (void) C_CloseSession(handle->pk11handle); 42099ebb4caSwyllys handle->pk11handle = NULL; 42199ebb4caSwyllys } 42299ebb4caSwyllys } 42399ebb4caSwyllys } 42499ebb4caSwyllys 42599ebb4caSwyllys KMF_RETURN 42630a5e8faSwyllys kmf_initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 42799ebb4caSwyllys { 42899ebb4caSwyllys KMF_RETURN ret = KMF_OK; 42999ebb4caSwyllys KMF_HANDLE *handle = NULL; 43099ebb4caSwyllys 43199ebb4caSwyllys if (outhandle == NULL) 43299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 43399ebb4caSwyllys 43499ebb4caSwyllys *outhandle = NULL; 43599ebb4caSwyllys handle = (KMF_HANDLE *)malloc(sizeof (KMF_HANDLE)); 43699ebb4caSwyllys if (handle == NULL) 43799ebb4caSwyllys return (KMF_ERR_MEMORY); 43899ebb4caSwyllys 43999ebb4caSwyllys (void) memset(handle, 0, sizeof (KMF_HANDLE)); 44099ebb4caSwyllys handle->plugins = NULL; 44199ebb4caSwyllys 442*431deaa0Shylee /* 443*431deaa0Shylee * When this function is called the first time, get the additional 444*431deaa0Shylee * plugins from the config file. 445*431deaa0Shylee */ 446*431deaa0Shylee (void) mutex_lock(&extra_plugin_lock); 447*431deaa0Shylee if (!check_extra_plugin) { 448*431deaa0Shylee 449*431deaa0Shylee ret = get_entrylist(&extra_plugin_list); 450*431deaa0Shylee check_extra_plugin = B_TRUE; 451*431deaa0Shylee 452*431deaa0Shylee /* 453*431deaa0Shylee * Assign the kstype number to the additional plugins here. 454*431deaa0Shylee * The global kstore_num will be protected by the mutex lock. 455*431deaa0Shylee */ 456*431deaa0Shylee if (ret == KMF_OK) { 457*431deaa0Shylee conf_entrylist_t *phead = extra_plugin_list; 458*431deaa0Shylee while (phead != NULL) { 459*431deaa0Shylee phead->entry->kstype = ++kstore_num; 460*431deaa0Shylee phead = phead->next; 461*431deaa0Shylee } 462*431deaa0Shylee } 463*431deaa0Shylee 464*431deaa0Shylee /* 465*431deaa0Shylee * If the KMF configuration file does not exist or cannot be 466*431deaa0Shylee * parsed correctly, we will give a warning in syslog and 467*431deaa0Shylee * continue on as there is no extra plugins in the system. 468*431deaa0Shylee */ 469*431deaa0Shylee if (ret == KMF_ERR_KMF_CONF) { 470*431deaa0Shylee cryptoerror(LOG_WARNING, "KMF was unable to parse " 471*431deaa0Shylee "the private KMF config file.\n"); 472*431deaa0Shylee ret = KMF_OK; 473*431deaa0Shylee } 474*431deaa0Shylee 475*431deaa0Shylee if (ret != KMF_OK) { 476*431deaa0Shylee (void) mutex_unlock(&extra_plugin_lock); 477*431deaa0Shylee goto errout; 478*431deaa0Shylee } 479*431deaa0Shylee } 480*431deaa0Shylee (void) mutex_unlock(&extra_plugin_lock); 481*431deaa0Shylee 48299ebb4caSwyllys /* Initialize the handle with the policy */ 48330a5e8faSwyllys ret = kmf_set_policy((void *)handle, 48499ebb4caSwyllys policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile, 48599ebb4caSwyllys policyname == NULL ? KMF_DEFAULT_POLICY_NAME : policyname); 48699ebb4caSwyllys if (ret != KMF_OK) 48799ebb4caSwyllys goto errout; 48899ebb4caSwyllys 48999ebb4caSwyllys CLEAR_ERROR(handle, ret); 49099ebb4caSwyllys errout: 49199ebb4caSwyllys if (ret != KMF_OK) { 49299ebb4caSwyllys Cleanup_KMF_Handle(handle); 49399ebb4caSwyllys handle = NULL; 49499ebb4caSwyllys } 49599ebb4caSwyllys 49699ebb4caSwyllys *outhandle = (KMF_HANDLE_T)handle; 49799ebb4caSwyllys return (ret); 49899ebb4caSwyllys } 49999ebb4caSwyllys 50099ebb4caSwyllys KMF_RETURN 50130a5e8faSwyllys kmf_configure_keystore(KMF_HANDLE_T handle, 50230a5e8faSwyllys int num_args, 50330a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 50499ebb4caSwyllys { 50530a5e8faSwyllys KMF_RETURN ret = KMF_OK; 50699ebb4caSwyllys KMF_PLUGIN *plugin; 50730a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 50830a5e8faSwyllys uint32_t len; 50930a5e8faSwyllys 51030a5e8faSwyllys KMF_ATTRIBUTE_TESTER required_attrs[] = { 51130a5e8faSwyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 51230a5e8faSwyllys }; 51330a5e8faSwyllys 51430a5e8faSwyllys int num_req_attrs = sizeof (required_attrs) / 51530a5e8faSwyllys sizeof (KMF_ATTRIBUTE_TESTER); 51630a5e8faSwyllys 51730a5e8faSwyllys if (handle == NULL) 51830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 51999ebb4caSwyllys 52099ebb4caSwyllys CLEAR_ERROR(handle, ret); 52130a5e8faSwyllys 52230a5e8faSwyllys ret = test_attributes(num_req_attrs, required_attrs, 52330a5e8faSwyllys 0, NULL, num_args, attrlist); 52430a5e8faSwyllys 52599ebb4caSwyllys if (ret != KMF_OK) 52699ebb4caSwyllys return (ret); 52799ebb4caSwyllys 52830a5e8faSwyllys len = sizeof (kstype); 52930a5e8faSwyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, 53030a5e8faSwyllys &kstype, &len); 53130a5e8faSwyllys if (ret != KMF_OK) 53230a5e8faSwyllys return (ret); 53399ebb4caSwyllys 53430a5e8faSwyllys plugin = FindPlugin(handle, kstype); 53530a5e8faSwyllys if (plugin != NULL && plugin->funclist->ConfigureKeystore != NULL) { 53630a5e8faSwyllys return (plugin->funclist->ConfigureKeystore(handle, num_args, 53730a5e8faSwyllys attrlist)); 53830a5e8faSwyllys } else { 53999ebb4caSwyllys /* return KMF_OK, if the plugin does not have an entry */ 54099ebb4caSwyllys return (KMF_OK); 54130a5e8faSwyllys } 54299ebb4caSwyllys } 54399ebb4caSwyllys 54499ebb4caSwyllys KMF_RETURN 54530a5e8faSwyllys kmf_finalize(KMF_HANDLE_T handle) 54699ebb4caSwyllys { 54799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 54899ebb4caSwyllys 54999ebb4caSwyllys CLEAR_ERROR(handle, ret); 55099ebb4caSwyllys if (ret != KMF_OK) 55199ebb4caSwyllys return (ret); 55299ebb4caSwyllys 55399ebb4caSwyllys if (pkcs11_initialized) { 55499ebb4caSwyllys Cleanup_PK11_Session(handle); 55599ebb4caSwyllys } 55699ebb4caSwyllys Cleanup_KMF_Handle(handle); 55799ebb4caSwyllys 55899ebb4caSwyllys return (ret); 55999ebb4caSwyllys } 56099ebb4caSwyllys 56199ebb4caSwyllys KMF_RETURN 56230a5e8faSwyllys kmf_get_kmf_error_str(KMF_RETURN errcode, char **errmsg) 56399ebb4caSwyllys { 56499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 56599ebb4caSwyllys int i, maxerr; 56699ebb4caSwyllys 56799ebb4caSwyllys if (errmsg == NULL) 56899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 56999ebb4caSwyllys 57099ebb4caSwyllys *errmsg = NULL; 57199ebb4caSwyllys maxerr = sizeof (kmf_errcodes) / sizeof (kmf_error_map); 57299ebb4caSwyllys 57330a5e8faSwyllys for (i = 0; i < maxerr && errcode != kmf_errcodes[i].code; i++) 57430a5e8faSwyllys /* empty body */ 57530a5e8faSwyllys ; 57699ebb4caSwyllys 57799ebb4caSwyllys if (i == maxerr) 57899ebb4caSwyllys return (KMF_ERR_MISSING_ERRCODE); 57999ebb4caSwyllys else { 58099ebb4caSwyllys *errmsg = strdup(kmf_errcodes[i].message); 58199ebb4caSwyllys if ((*errmsg) == NULL) 58299ebb4caSwyllys return (KMF_ERR_MEMORY); 58399ebb4caSwyllys } 58499ebb4caSwyllys return (ret); 58599ebb4caSwyllys } 58699ebb4caSwyllys 58799ebb4caSwyllys KMF_RETURN 58830a5e8faSwyllys kmf_get_plugin_error_str(KMF_HANDLE_T handle, char **msgstr) 58999ebb4caSwyllys { 59099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 59199ebb4caSwyllys KMF_PLUGIN *plugin; 59299ebb4caSwyllys 59399ebb4caSwyllys if (handle == NULL || msgstr == NULL) 59499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 59599ebb4caSwyllys 59699ebb4caSwyllys *msgstr = NULL; 59799ebb4caSwyllys 59899ebb4caSwyllys if (handle->lasterr.errcode == 0) { 59999ebb4caSwyllys return (KMF_ERR_MISSING_ERRCODE); 60099ebb4caSwyllys } 60199ebb4caSwyllys 60299ebb4caSwyllys if (handle->lasterr.kstype == -1) { /* System error */ 60399ebb4caSwyllys char *str = strerror(handle->lasterr.errcode); 60499ebb4caSwyllys if (str != NULL) { 60599ebb4caSwyllys *msgstr = strdup(str); 60699ebb4caSwyllys if ((*msgstr) == NULL) 60799ebb4caSwyllys return (KMF_ERR_MEMORY); 60899ebb4caSwyllys } 60999ebb4caSwyllys return (KMF_OK); 61099ebb4caSwyllys } 61199ebb4caSwyllys 61299ebb4caSwyllys plugin = FindPlugin(handle, handle->lasterr.kstype); 61399ebb4caSwyllys if (plugin == NULL) 61499ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 61599ebb4caSwyllys 61699ebb4caSwyllys if (plugin->funclist->GetErrorString != NULL) { 61799ebb4caSwyllys ret = plugin->funclist->GetErrorString(handle, msgstr); 61899ebb4caSwyllys } else { 61999ebb4caSwyllys return (KMF_ERR_FUNCTION_NOT_FOUND); 62099ebb4caSwyllys } 62199ebb4caSwyllys 62299ebb4caSwyllys return (ret); 62399ebb4caSwyllys } 62499ebb4caSwyllys 62599ebb4caSwyllys 6269b37d296Swyllys #define SET_SYS_ERROR(h, c) if (h) {\ 6279b37d296Swyllys h->lasterr.kstype = -1;\ 6289b37d296Swyllys h->lasterr.errcode = c;\ 6299b37d296Swyllys } 63099ebb4caSwyllys 63199ebb4caSwyllys KMF_RETURN 63230a5e8faSwyllys kmf_read_input_file(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 63399ebb4caSwyllys { 63499ebb4caSwyllys struct stat s; 63599ebb4caSwyllys long nread, total = 0; 63699ebb4caSwyllys int fd; 63799ebb4caSwyllys unsigned char *buf = NULL; 63899ebb4caSwyllys KMF_RETURN ret; 63999ebb4caSwyllys 6409b37d296Swyllys if (handle) { 6419b37d296Swyllys CLEAR_ERROR(handle, ret); 6429b37d296Swyllys if (ret != KMF_OK) 6439b37d296Swyllys return (ret); 6449b37d296Swyllys } 64599ebb4caSwyllys 64699ebb4caSwyllys if (filename == NULL || pdata == NULL) { 64799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 64899ebb4caSwyllys } 64999ebb4caSwyllys 65099ebb4caSwyllys if ((fd = open(filename, O_RDONLY)) < 0) { 65199ebb4caSwyllys SET_SYS_ERROR(handle, errno); 65299ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 65399ebb4caSwyllys } 65499ebb4caSwyllys 65599ebb4caSwyllys if (fstat(fd, &s) < 0) { 65699ebb4caSwyllys SET_SYS_ERROR(handle, errno); 65799ebb4caSwyllys (void) close(fd); 65899ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 65999ebb4caSwyllys } 66099ebb4caSwyllys 66199ebb4caSwyllys if ((buf = (unsigned char *) malloc(s.st_size)) == NULL) { 66299ebb4caSwyllys (void) close(fd); 66399ebb4caSwyllys return (KMF_ERR_MEMORY); 66499ebb4caSwyllys } 66599ebb4caSwyllys 66699ebb4caSwyllys do { 66799ebb4caSwyllys nread = read(fd, buf+total, s.st_size-total); 66899ebb4caSwyllys if (nread < 0) { 66999ebb4caSwyllys SET_SYS_ERROR(handle, errno); 67099ebb4caSwyllys (void) close(fd); 67199ebb4caSwyllys free(buf); 67299ebb4caSwyllys return (KMF_ERR_INTERNAL); 67399ebb4caSwyllys } 67499ebb4caSwyllys total += nread; 67599ebb4caSwyllys } while (total < s.st_size); 67699ebb4caSwyllys 67799ebb4caSwyllys pdata->Data = buf; 67899ebb4caSwyllys pdata->Length = s.st_size; 67999ebb4caSwyllys (void) close(fd); 68099ebb4caSwyllys return (KMF_OK); 68199ebb4caSwyllys } 68299ebb4caSwyllys 68399ebb4caSwyllys /* 68499ebb4caSwyllys * 68530a5e8faSwyllys * Name: kmf_der_to_pem 68699ebb4caSwyllys * 68799ebb4caSwyllys * Description: 68899ebb4caSwyllys * Function for converting DER encoded format to PEM encoded format 68999ebb4caSwyllys * 69099ebb4caSwyllys * Parameters: 69199ebb4caSwyllys * type(input) - CERTIFICATE or CSR 69299ebb4caSwyllys * data(input) - pointer to the DER encoded data 69399ebb4caSwyllys * len(input) - length of input data 69499ebb4caSwyllys * out(output) - contains the output buffer address to be returned 69599ebb4caSwyllys * outlen(output) - pointer to the returned output length 69699ebb4caSwyllys * 69799ebb4caSwyllys * Returns: 69899ebb4caSwyllys * A KMF_RETURN value indicating success or specifying a particular 69999ebb4caSwyllys * error condition. 70099ebb4caSwyllys * The value KMF_OK indicates success. All other values represent 70199ebb4caSwyllys * an error condition. 70299ebb4caSwyllys * 70399ebb4caSwyllys */ 70499ebb4caSwyllys KMF_RETURN 70530a5e8faSwyllys kmf_der_to_pem(KMF_OBJECT_TYPE type, unsigned char *data, 70699ebb4caSwyllys int len, unsigned char **out, int *outlen) 70799ebb4caSwyllys { 70899ebb4caSwyllys 70999ebb4caSwyllys KMF_RETURN err; 71099ebb4caSwyllys if (data == NULL || out == NULL || outlen == NULL) 71199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 71299ebb4caSwyllys 71399ebb4caSwyllys err = Der2Pem(type, data, len, out, outlen); 71499ebb4caSwyllys return (err); 71599ebb4caSwyllys 71699ebb4caSwyllys } 71799ebb4caSwyllys 71899ebb4caSwyllys /* 71999ebb4caSwyllys * 72030a5e8faSwyllys * Name: kmf_pem_to_der 72199ebb4caSwyllys * 72299ebb4caSwyllys * Description: 72399ebb4caSwyllys * Function for converting PEM encoded format to DER encoded format 72499ebb4caSwyllys * 72599ebb4caSwyllys * Parameters: 72699ebb4caSwyllys * in(input) - pointer to the PEM encoded data 72799ebb4caSwyllys * inlen(input) - length of input data 72899ebb4caSwyllys * out(output) - contains the output buffer address to be returned 72999ebb4caSwyllys * outlen(output) - pointer to the returned output length 73099ebb4caSwyllys * 73199ebb4caSwyllys * Returns: 73299ebb4caSwyllys * A KMF_RETURN value indicating success or specifying a particular 73399ebb4caSwyllys * error condition. 73499ebb4caSwyllys * The value KMF_OK indicates success. All other values represent 73599ebb4caSwyllys * an error condition. 73699ebb4caSwyllys * 73799ebb4caSwyllys */ 73899ebb4caSwyllys KMF_RETURN 73930a5e8faSwyllys kmf_pem_to_der(unsigned char *in, int inlen, 74099ebb4caSwyllys unsigned char **out, int *outlen) 74199ebb4caSwyllys { 74299ebb4caSwyllys KMF_RETURN err; 74399ebb4caSwyllys if (in == NULL || out == NULL || outlen == NULL) 74499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 74599ebb4caSwyllys 74699ebb4caSwyllys err = Pem2Der(in, inlen, out, outlen); 74799ebb4caSwyllys return (err); 74899ebb4caSwyllys } 74999ebb4caSwyllys 75099ebb4caSwyllys char * 75130a5e8faSwyllys kmf_oid_to_string(KMF_OID *oid) 75299ebb4caSwyllys { 75399ebb4caSwyllys char numstr[128]; 75499ebb4caSwyllys uint32_t number; 75599ebb4caSwyllys int numshift; 75699ebb4caSwyllys uint32_t i, string_length; 75799ebb4caSwyllys uchar_t *cp; 75899ebb4caSwyllys char *bp; 75999ebb4caSwyllys 76099ebb4caSwyllys /* First determine the size of the string */ 76199ebb4caSwyllys string_length = 0; 76299ebb4caSwyllys number = 0; 76399ebb4caSwyllys numshift = 0; 76499ebb4caSwyllys cp = (unsigned char *)oid->Data; 76599ebb4caSwyllys 76699ebb4caSwyllys number = (uint32_t)cp[0]; 76799ebb4caSwyllys (void) sprintf(numstr, "%d ", number/40); 76899ebb4caSwyllys 76999ebb4caSwyllys string_length += strlen(numstr); 77099ebb4caSwyllys (void) sprintf(numstr, "%d ", number%40); 77199ebb4caSwyllys 77299ebb4caSwyllys string_length += strlen(numstr); 77399ebb4caSwyllys 77499ebb4caSwyllys for (i = 1; i < oid->Length; i++) { 77599ebb4caSwyllys if ((uint32_t)(numshift+7) < (sizeof (uint32_t)*8)) { 77699ebb4caSwyllys number = (number << 7) | (cp[i] & 0x7f); 77799ebb4caSwyllys numshift += 7; 77899ebb4caSwyllys } else { 77999ebb4caSwyllys return (NULL); 78099ebb4caSwyllys } 78199ebb4caSwyllys 78299ebb4caSwyllys if ((cp[i] & 0x80) == 0) { 78399ebb4caSwyllys (void) sprintf(numstr, "%d ", number); 78499ebb4caSwyllys string_length += strlen(numstr); 78599ebb4caSwyllys number = 0; 78699ebb4caSwyllys numshift = 0; 78799ebb4caSwyllys } 78899ebb4caSwyllys } 78999ebb4caSwyllys /* 79099ebb4caSwyllys * If we get here, we've calculated the length of "n n n ... n ". Add 4 79199ebb4caSwyllys * here for "{ " and "}\0". 79299ebb4caSwyllys */ 79399ebb4caSwyllys string_length += 4; 79499ebb4caSwyllys if ((bp = (char *)malloc(string_length))) { 79599ebb4caSwyllys number = (uint32_t)cp[0]; 79699ebb4caSwyllys 79799ebb4caSwyllys (void) sprintf(numstr, "%d.", number/40); 79899ebb4caSwyllys (void) strcpy(bp, numstr); 79999ebb4caSwyllys 80099ebb4caSwyllys (void) sprintf(numstr, "%d.", number%40); 80199ebb4caSwyllys (void) strcat(bp, numstr); 80299ebb4caSwyllys 80399ebb4caSwyllys number = 0; 80499ebb4caSwyllys cp = (unsigned char *) oid->Data; 80599ebb4caSwyllys for (i = 1; i < oid->Length; i++) { 80699ebb4caSwyllys number = (number << 7) | (cp[i] & 0x7f); 80799ebb4caSwyllys if ((cp[i] & 0x80) == 0) { 80899ebb4caSwyllys (void) sprintf(numstr, "%d", number); 80999ebb4caSwyllys (void) strcat(bp, numstr); 81099ebb4caSwyllys number = 0; 81199ebb4caSwyllys if (i+1 < oid->Length) 81299ebb4caSwyllys (void) strcat(bp, "."); 81399ebb4caSwyllys } 81499ebb4caSwyllys } 81599ebb4caSwyllys } 81699ebb4caSwyllys return (bp); 81799ebb4caSwyllys } 81899ebb4caSwyllys 81902744e81Swyllys static boolean_t 82008ec4bd3Shylee check_for_pem(uchar_t *buf, KMF_ENCODE_FORMAT *fmt) 82102744e81Swyllys { 8229b37d296Swyllys char *p; 82302744e81Swyllys 82408ec4bd3Shylee if (buf == NULL) 82502744e81Swyllys return (FALSE); 82602744e81Swyllys 82708ec4bd3Shylee if (memcmp(buf, "Bag Attr", 8) == 0) { 82808ec4bd3Shylee *fmt = KMF_FORMAT_PEM_KEYPAIR; 82908ec4bd3Shylee return (TRUE); 83008ec4bd3Shylee } 83108ec4bd3Shylee 8329b37d296Swyllys /* Look for "-----BEGIN" right after a newline */ 83308ec4bd3Shylee p = strtok((char *)buf, "\n"); 8349b37d296Swyllys while (p != NULL) { 8359b37d296Swyllys if (strstr(p, "-----BEGIN") != NULL) { 83608ec4bd3Shylee *fmt = KMF_FORMAT_PEM; 8379b37d296Swyllys return (TRUE); 83802744e81Swyllys } 8399b37d296Swyllys p = strtok(NULL, "\n"); 84002744e81Swyllys } 84102744e81Swyllys return (FALSE); 84202744e81Swyllys } 84302744e81Swyllys 84408ec4bd3Shylee 84508ec4bd3Shylee static unsigned char pkcs12_version[3] = {0x02, 0x01, 0x03}; 84608ec4bd3Shylee static unsigned char pkcs12_oid[11] = 84708ec4bd3Shylee {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01}; 84808ec4bd3Shylee 84908ec4bd3Shylee /* 85008ec4bd3Shylee * This function takes a BER encoded string as input and checks the version 85108ec4bd3Shylee * and the oid in the the top-level ASN.1 structure to see if it complies to 85208ec4bd3Shylee * the PKCS#12 Syntax. 85308ec4bd3Shylee */ 85408ec4bd3Shylee static boolean_t 85508ec4bd3Shylee check_for_pkcs12(uchar_t *buf, int buf_len) 85608ec4bd3Shylee { 85708ec4bd3Shylee int index = 0; 85808ec4bd3Shylee int length_octets; 85908ec4bd3Shylee 86008ec4bd3Shylee if (buf == NULL || buf_len <= 0) 86108ec4bd3Shylee return (FALSE); 86208ec4bd3Shylee 86308ec4bd3Shylee /* 86408ec4bd3Shylee * The top level structure for a PKCS12 string: 86508ec4bd3Shylee * 86608ec4bd3Shylee * PFX ::= SEQUENCE { 86708ec4bd3Shylee * version INTEGER {v3(3)}(v3,...) 86808ec4bd3Shylee * authSafe ContentInfo 86908ec4bd3Shylee * macData MacData OPTIONAL 87008ec4bd3Shylee * } 87108ec4bd3Shylee * 87208ec4bd3Shylee * ContentInfo 87308ec4bd3Shylee * FROM PKCS-7 {iso(1) member-body(2) us(840) rsadsi(113549) 87408ec4bd3Shylee * pkcs(1) pkcs-7(7) modules(0) pkcs-7(1)} 87508ec4bd3Shylee * 87608ec4bd3Shylee * Therefore, the BER/DER dump of a PKCS#12 file for the first 2 87708ec4bd3Shylee * sequences up to the oid part is as following: 87808ec4bd3Shylee * 87908ec4bd3Shylee * SEQUENCE { 88008ec4bd3Shylee * INTEGER 3 88108ec4bd3Shylee * SEQUENCE { 88208ec4bd3Shylee * OBJECT IDENTIFIER data (1 2 840 113549 1 7 1) 88308ec4bd3Shylee */ 88408ec4bd3Shylee 88508ec4bd3Shylee /* 88608ec4bd3Shylee * Check the first sequence and calculate the number of bytes used 88708ec4bd3Shylee * to store the length. 88808ec4bd3Shylee */ 88908ec4bd3Shylee if (buf[index++] != 0x30) 89008ec4bd3Shylee return (FALSE); 89108ec4bd3Shylee 89208ec4bd3Shylee if (buf[index] & 0x80) { 89308ec4bd3Shylee length_octets = buf[index++] & 0x0F; /* long form */ 89408ec4bd3Shylee } else { 89508ec4bd3Shylee length_octets = 1; /* short form */ 89608ec4bd3Shylee } 89708ec4bd3Shylee 89808ec4bd3Shylee index += length_octets; 89908ec4bd3Shylee if (index >= buf_len) 90008ec4bd3Shylee return (FALSE); 90108ec4bd3Shylee 90208ec4bd3Shylee /* Skip the length octets and check the pkcs12 version */ 90308ec4bd3Shylee if (memcmp(buf + index, pkcs12_version, sizeof (pkcs12_version)) != 0) 90408ec4bd3Shylee return (FALSE); 90508ec4bd3Shylee 90608ec4bd3Shylee index += sizeof (pkcs12_version); 90708ec4bd3Shylee if (index >= buf_len) 90808ec4bd3Shylee return (FALSE); 90908ec4bd3Shylee 91008ec4bd3Shylee /* 91108ec4bd3Shylee * Check the 2nd sequence and calculate the number of bytes used 91208ec4bd3Shylee * to store the length. 91308ec4bd3Shylee */ 91408ec4bd3Shylee if ((buf[index++] & 0xFF) != 0x30) 91508ec4bd3Shylee return (FALSE); 91608ec4bd3Shylee 91708ec4bd3Shylee if (buf[index] & 0x80) { 91808ec4bd3Shylee length_octets = buf[index++] & 0x0F; 91908ec4bd3Shylee } else { 92008ec4bd3Shylee length_octets = 1; 92108ec4bd3Shylee } 92208ec4bd3Shylee 92308ec4bd3Shylee index += length_octets; 92408ec4bd3Shylee if (index + sizeof (pkcs12_oid) >= buf_len) 92508ec4bd3Shylee return (FALSE); 92608ec4bd3Shylee 92708ec4bd3Shylee /* Skip the length octets and check the oid */ 92808ec4bd3Shylee if (memcmp(buf + index, pkcs12_oid, sizeof (pkcs12_oid)) != 0) 92908ec4bd3Shylee return (FALSE); 93008ec4bd3Shylee else 93108ec4bd3Shylee return (TRUE); 93208ec4bd3Shylee } 93308ec4bd3Shylee 93499ebb4caSwyllys KMF_RETURN 93530a5e8faSwyllys kmf_get_file_format(char *filename, KMF_ENCODE_FORMAT *fmt) 93699ebb4caSwyllys { 93799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 93808ec4bd3Shylee KMF_DATA filebuf = {NULL, 0}; 93908ec4bd3Shylee uchar_t *buf; 94099ebb4caSwyllys 94199ebb4caSwyllys if (filename == NULL || !strlen(filename) || fmt == NULL) 94299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 94399ebb4caSwyllys 94499ebb4caSwyllys *fmt = 0; 94530a5e8faSwyllys ret = kmf_read_input_file(NULL, filename, &filebuf); 94608ec4bd3Shylee if (ret != KMF_OK) 94708ec4bd3Shylee return (ret); 94899ebb4caSwyllys 94908ec4bd3Shylee if (filebuf.Length < 8) { 95008ec4bd3Shylee ret = KMF_ERR_ENCODING; /* too small */ 95199ebb4caSwyllys goto end; 95299ebb4caSwyllys } 95399ebb4caSwyllys 95408ec4bd3Shylee buf = filebuf.Data; 95508ec4bd3Shylee if (check_for_pkcs12(buf, filebuf.Length) == TRUE) { 95608ec4bd3Shylee *fmt = KMF_FORMAT_PKCS12; 95708ec4bd3Shylee } else if (buf[0] == 0x30 && (buf[1] & 0x80)) { 95899ebb4caSwyllys /* It is most likely a generic ASN.1 encoded file */ 95908ec4bd3Shylee *fmt = KMF_FORMAT_ASN1; 96008ec4bd3Shylee } else if (check_for_pem(buf, fmt) == TRUE) { 96108ec4bd3Shylee goto end; 96299ebb4caSwyllys } else { 96308ec4bd3Shylee /* Cannot determine this file format */ 96408ec4bd3Shylee *fmt = 0; 96508ec4bd3Shylee ret = KMF_ERR_ENCODING; 96699ebb4caSwyllys } 96708ec4bd3Shylee 96899ebb4caSwyllys end: 96930a5e8faSwyllys kmf_free_data(&filebuf); 97099ebb4caSwyllys return (ret); 97199ebb4caSwyllys } 97299ebb4caSwyllys 97399ebb4caSwyllys KMF_RETURN 97430a5e8faSwyllys kmf_hexstr_to_bytes(unsigned char *hexstr, unsigned char **bytes, 97599ebb4caSwyllys size_t *outlen) 97699ebb4caSwyllys { 97799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 97899ebb4caSwyllys unsigned char *buf = NULL; 97999ebb4caSwyllys int len, stringlen; 98099ebb4caSwyllys int i; 98199ebb4caSwyllys unsigned char ch; 98299ebb4caSwyllys 98399ebb4caSwyllys if (hexstr == NULL) { 98499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 98599ebb4caSwyllys } 98699ebb4caSwyllys 98730a5e8faSwyllys if (hexstr[0] == '0' && ((hexstr[1] == 'x') || (hexstr[1] == 'X'))) 98899ebb4caSwyllys hexstr += 2; 98999ebb4caSwyllys 99030a5e8faSwyllys for (i = 0; i < strlen((char *)hexstr) && isxdigit(hexstr[i]); i++) 99130a5e8faSwyllys /* empty body */ 99230a5e8faSwyllys ; 99399ebb4caSwyllys /* 99499ebb4caSwyllys * If all the characters are not legitimate hex chars, 99599ebb4caSwyllys * return an error. 99699ebb4caSwyllys */ 99799ebb4caSwyllys if (i != strlen((char *)hexstr)) 99899ebb4caSwyllys return (KMF_ERR_BAD_HEX_STRING); 99999ebb4caSwyllys stringlen = i; 100099ebb4caSwyllys len = (i / 2) + (i % 2); 100199ebb4caSwyllys 100299ebb4caSwyllys buf = malloc(len); 100399ebb4caSwyllys if (buf == NULL) { 100499ebb4caSwyllys return (KMF_ERR_MEMORY); 100599ebb4caSwyllys } 100699ebb4caSwyllys (void) memset(buf, 0, len); 100799ebb4caSwyllys 100899ebb4caSwyllys for (i = 0; i < stringlen; i++) { 100999ebb4caSwyllys ch = (unsigned char) *hexstr; 101099ebb4caSwyllys hexstr++; 101199ebb4caSwyllys if ((ch >= '0') && (ch <= '9')) 101299ebb4caSwyllys ch -= '0'; 101399ebb4caSwyllys else if ((ch >= 'A') && (ch <= 'F')) 101499ebb4caSwyllys ch = ch - 'A' + 10; 101599ebb4caSwyllys else if ((ch >= 'a') && (ch <= 'f')) 101699ebb4caSwyllys ch = ch - 'a' + 10; 101799ebb4caSwyllys else { 101899ebb4caSwyllys ret = KMF_ERR_BAD_HEX_STRING; 101999ebb4caSwyllys goto out; 102099ebb4caSwyllys } 102199ebb4caSwyllys 102299ebb4caSwyllys if (i & 1) { 102399ebb4caSwyllys buf[i/2] |= ch; 102499ebb4caSwyllys } else { 102599ebb4caSwyllys buf[i/2] = (ch << 4); 102699ebb4caSwyllys } 102799ebb4caSwyllys } 102899ebb4caSwyllys 102999ebb4caSwyllys *bytes = buf; 103099ebb4caSwyllys *outlen = len; 103199ebb4caSwyllys out: 103299ebb4caSwyllys if (buf != NULL && ret != KMF_OK) { 103399ebb4caSwyllys free(buf); 103499ebb4caSwyllys } 103599ebb4caSwyllys return (ret); 103699ebb4caSwyllys } 103799ebb4caSwyllys 103899ebb4caSwyllys void 103930a5e8faSwyllys kmf_free_dn(KMF_X509_NAME *name) 104099ebb4caSwyllys { 104199ebb4caSwyllys KMF_X509_RDN *newrdn = NULL; 104299ebb4caSwyllys KMF_X509_TYPE_VALUE_PAIR *av = NULL; 104399ebb4caSwyllys int i, j; 104499ebb4caSwyllys 104599ebb4caSwyllys if (name && name->numberOfRDNs) { 104699ebb4caSwyllys for (i = 0; i < name->numberOfRDNs; i++) { 104799ebb4caSwyllys newrdn = &name->RelativeDistinguishedName[i]; 104899ebb4caSwyllys for (j = 0; j < newrdn->numberOfPairs; j++) { 104999ebb4caSwyllys av = &newrdn->AttributeTypeAndValue[j]; 105030a5e8faSwyllys kmf_free_data(&av->type); 105130a5e8faSwyllys kmf_free_data(&av->value); 105299ebb4caSwyllys } 105399ebb4caSwyllys free(newrdn->AttributeTypeAndValue); 105499ebb4caSwyllys newrdn->numberOfPairs = 0; 105599ebb4caSwyllys newrdn->AttributeTypeAndValue = NULL; 105699ebb4caSwyllys } 105799ebb4caSwyllys free(name->RelativeDistinguishedName); 105899ebb4caSwyllys name->numberOfRDNs = 0; 105999ebb4caSwyllys name->RelativeDistinguishedName = NULL; 106099ebb4caSwyllys } 106199ebb4caSwyllys } 106299ebb4caSwyllys 106399ebb4caSwyllys void 106430a5e8faSwyllys kmf_free_kmf_cert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 106599ebb4caSwyllys { 106699ebb4caSwyllys KMF_PLUGIN *plugin; 106799ebb4caSwyllys KMF_RETURN ret; 106899ebb4caSwyllys 106999ebb4caSwyllys CLEAR_ERROR(handle, ret); 107099ebb4caSwyllys if (ret != KMF_OK) 107199ebb4caSwyllys return; 107299ebb4caSwyllys 107399ebb4caSwyllys if (kmf_cert == NULL) 107499ebb4caSwyllys return; 107599ebb4caSwyllys 107699ebb4caSwyllys plugin = FindPlugin(handle, kmf_cert->kmf_private.keystore_type); 107799ebb4caSwyllys 107899ebb4caSwyllys if (plugin != NULL && plugin->funclist->FreeKMFCert != NULL) { 107999ebb4caSwyllys plugin->funclist->FreeKMFCert(handle, kmf_cert); 108099ebb4caSwyllys } 108199ebb4caSwyllys } 108299ebb4caSwyllys 108399ebb4caSwyllys void 108430a5e8faSwyllys kmf_free_data(KMF_DATA *datablock) 108599ebb4caSwyllys { 108699ebb4caSwyllys if (datablock != NULL && datablock->Data != NULL) { 108799ebb4caSwyllys free(datablock->Data); 108899ebb4caSwyllys datablock->Data = NULL; 108999ebb4caSwyllys datablock->Length = 0; 109099ebb4caSwyllys } 109199ebb4caSwyllys } 109299ebb4caSwyllys 109399ebb4caSwyllys void 109430a5e8faSwyllys kmf_free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *algoid) 109599ebb4caSwyllys { 109699ebb4caSwyllys if (algoid == NULL) 109799ebb4caSwyllys return; 109830a5e8faSwyllys kmf_free_data(&algoid->algorithm); 109930a5e8faSwyllys kmf_free_data(&algoid->parameters); 110099ebb4caSwyllys } 110199ebb4caSwyllys 110299ebb4caSwyllys void 110330a5e8faSwyllys kmf_free_extn(KMF_X509_EXTENSION *exptr) 110499ebb4caSwyllys { 110599ebb4caSwyllys if (exptr == NULL) 110699ebb4caSwyllys return; 110799ebb4caSwyllys 110830a5e8faSwyllys kmf_free_data((KMF_DATA *)&exptr->extnId); 110930a5e8faSwyllys kmf_free_data(&exptr->BERvalue); 111099ebb4caSwyllys 111199ebb4caSwyllys if (exptr->value.tagAndValue) { 111230a5e8faSwyllys kmf_free_data(&exptr->value.tagAndValue->value); 111399ebb4caSwyllys free(exptr->value.tagAndValue); 111499ebb4caSwyllys } 111599ebb4caSwyllys } 111699ebb4caSwyllys 111799ebb4caSwyllys void 111830a5e8faSwyllys kmf_free_tbs_csr(KMF_TBS_CSR *tbscsr) 111999ebb4caSwyllys { 112099ebb4caSwyllys if (tbscsr) { 112130a5e8faSwyllys kmf_free_data(&tbscsr->version); 112299ebb4caSwyllys 112330a5e8faSwyllys kmf_free_dn(&tbscsr->subject); 112499ebb4caSwyllys 112530a5e8faSwyllys kmf_free_algoid(&tbscsr->subjectPublicKeyInfo.algorithm); 112630a5e8faSwyllys kmf_free_data(&tbscsr->subjectPublicKeyInfo.subjectPublicKey); 112799ebb4caSwyllys 112899ebb4caSwyllys free_extensions(&tbscsr->extensions); 112999ebb4caSwyllys } 113099ebb4caSwyllys } 113199ebb4caSwyllys 113299ebb4caSwyllys void 113330a5e8faSwyllys kmf_free_signed_csr(KMF_CSR_DATA *csr) 113499ebb4caSwyllys { 113599ebb4caSwyllys if (csr) { 113630a5e8faSwyllys kmf_free_tbs_csr(&csr->csr); 113799ebb4caSwyllys 113830a5e8faSwyllys kmf_free_algoid(&csr->signature.algorithmIdentifier); 113930a5e8faSwyllys kmf_free_data(&csr->signature.encrypted); 114099ebb4caSwyllys } 114199ebb4caSwyllys } 114299ebb4caSwyllys 114399ebb4caSwyllys static void 114499ebb4caSwyllys free_validity(KMF_X509_VALIDITY *validity) 114599ebb4caSwyllys { 114699ebb4caSwyllys if (validity == NULL) 114799ebb4caSwyllys return; 114830a5e8faSwyllys kmf_free_data(&validity->notBefore.time); 114930a5e8faSwyllys kmf_free_data(&validity->notAfter.time); 115099ebb4caSwyllys } 115199ebb4caSwyllys 115299ebb4caSwyllys static void 115399ebb4caSwyllys free_extensions(KMF_X509_EXTENSIONS *extns) 115499ebb4caSwyllys { 115599ebb4caSwyllys int i; 115699ebb4caSwyllys KMF_X509_EXTENSION *exptr; 115799ebb4caSwyllys 115899ebb4caSwyllys if (extns && extns->numberOfExtensions > 0) { 115999ebb4caSwyllys for (i = 0; i < extns->numberOfExtensions; i++) { 116099ebb4caSwyllys exptr = &extns->extensions[i]; 116130a5e8faSwyllys kmf_free_extn(exptr); 116299ebb4caSwyllys } 116399ebb4caSwyllys free(extns->extensions); 116499ebb4caSwyllys extns->numberOfExtensions = 0; 116599ebb4caSwyllys extns->extensions = NULL; 116699ebb4caSwyllys } 116799ebb4caSwyllys } 116899ebb4caSwyllys 116999ebb4caSwyllys void 117030a5e8faSwyllys kmf_free_tbs_cert(KMF_X509_TBS_CERT *tbscert) 117199ebb4caSwyllys { 117299ebb4caSwyllys if (tbscert) { 117330a5e8faSwyllys kmf_free_data(&tbscert->version); 117430a5e8faSwyllys kmf_free_bigint(&tbscert->serialNumber); 117530a5e8faSwyllys kmf_free_algoid(&tbscert->signature); 117699ebb4caSwyllys 117730a5e8faSwyllys kmf_free_dn(&tbscert->issuer); 117830a5e8faSwyllys kmf_free_dn(&tbscert->subject); 117999ebb4caSwyllys 118099ebb4caSwyllys free_validity(&tbscert->validity); 118199ebb4caSwyllys 118230a5e8faSwyllys kmf_free_data(&tbscert->issuerUniqueIdentifier); 118330a5e8faSwyllys kmf_free_data(&tbscert->subjectUniqueIdentifier); 118499ebb4caSwyllys 118530a5e8faSwyllys kmf_free_algoid(&tbscert->subjectPublicKeyInfo.algorithm); 118630a5e8faSwyllys kmf_free_data(&tbscert->subjectPublicKeyInfo.subjectPublicKey); 118799ebb4caSwyllys 118899ebb4caSwyllys free_extensions(&tbscert->extensions); 118999ebb4caSwyllys 119030a5e8faSwyllys kmf_free_data(&tbscert->issuerUniqueIdentifier); 119130a5e8faSwyllys kmf_free_data(&tbscert->subjectUniqueIdentifier); 119299ebb4caSwyllys } 119399ebb4caSwyllys } 119499ebb4caSwyllys 119599ebb4caSwyllys void 119630a5e8faSwyllys kmf_free_signed_cert(KMF_X509_CERTIFICATE *certptr) 119799ebb4caSwyllys { 119899ebb4caSwyllys if (!certptr) 119999ebb4caSwyllys return; 120099ebb4caSwyllys 120130a5e8faSwyllys kmf_free_tbs_cert(&certptr->certificate); 120299ebb4caSwyllys 120330a5e8faSwyllys kmf_free_algoid(&certptr->signature.algorithmIdentifier); 120430a5e8faSwyllys kmf_free_data(&certptr->signature.encrypted); 120599ebb4caSwyllys } 120699ebb4caSwyllys 120799ebb4caSwyllys void 120830a5e8faSwyllys kmf_free_str(char *pstr) 120999ebb4caSwyllys { 121099ebb4caSwyllys if (pstr != NULL) 121199ebb4caSwyllys free(pstr); 121299ebb4caSwyllys } 121399ebb4caSwyllys 121499ebb4caSwyllys void 121599ebb4caSwyllys free_keyidlist(KMF_OID *oidlist, int len) 121699ebb4caSwyllys { 121799ebb4caSwyllys int i; 121899ebb4caSwyllys for (i = 0; i < len; i++) { 121930a5e8faSwyllys kmf_free_data((KMF_DATA *)&oidlist[i]); 122099ebb4caSwyllys } 122199ebb4caSwyllys free(oidlist); 122299ebb4caSwyllys } 122399ebb4caSwyllys 122499ebb4caSwyllys void 122530a5e8faSwyllys kmf_free_eku(KMF_X509EXT_EKU *eptr) 122699ebb4caSwyllys { 122730a5e8faSwyllys if (eptr && eptr->nEKUs > 0 && eptr->keyPurposeIdList != NULL) 122899ebb4caSwyllys free_keyidlist(eptr->keyPurposeIdList, eptr->nEKUs); 122999ebb4caSwyllys } 123099ebb4caSwyllys 123199ebb4caSwyllys void 123230a5e8faSwyllys kmf_free_spki(KMF_X509_SPKI *spki) 123399ebb4caSwyllys { 123499ebb4caSwyllys if (spki != NULL) { 123530a5e8faSwyllys kmf_free_algoid(&spki->algorithm); 123630a5e8faSwyllys kmf_free_data(&spki->subjectPublicKey); 123799ebb4caSwyllys } 123899ebb4caSwyllys } 123999ebb4caSwyllys 124099ebb4caSwyllys void 124130a5e8faSwyllys kmf_free_kmf_key(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 124299ebb4caSwyllys { 124399ebb4caSwyllys KMF_PLUGIN *plugin; 124499ebb4caSwyllys KMF_RETURN ret; 124530a5e8faSwyllys KMF_ATTRIBUTE attlist[2]; /* only 2 attributes for DeleteKey op */ 124630a5e8faSwyllys int i = 0; 124730a5e8faSwyllys boolean_t token_destroy = B_FALSE; 124830a5e8faSwyllys 124930a5e8faSwyllys if (key == NULL) 125030a5e8faSwyllys return; 125199ebb4caSwyllys 125299ebb4caSwyllys CLEAR_ERROR(handle, ret); 125399ebb4caSwyllys if (ret != KMF_OK) 125499ebb4caSwyllys return; 125599ebb4caSwyllys 125630a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 125730a5e8faSwyllys KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); 125830a5e8faSwyllys i++; 125930a5e8faSwyllys 126030a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 126130a5e8faSwyllys KMF_DESTROY_BOOL_ATTR, &token_destroy, sizeof (boolean_t)); 126230a5e8faSwyllys i++; 126399ebb4caSwyllys 126499ebb4caSwyllys plugin = FindPlugin(handle, key->kstype); 126599ebb4caSwyllys if (plugin != NULL && plugin->funclist->DeleteKey != NULL) { 126630a5e8faSwyllys (void) plugin->funclist->DeleteKey(handle, i, attlist); 126799ebb4caSwyllys } 126899ebb4caSwyllys 126999ebb4caSwyllys if (key->keylabel) 127099ebb4caSwyllys free(key->keylabel); 127199ebb4caSwyllys 127299ebb4caSwyllys if (key->israw) { 127330a5e8faSwyllys kmf_free_raw_key(key->keyp); 127499ebb4caSwyllys free(key->keyp); 127599ebb4caSwyllys } 127699ebb4caSwyllys 127799ebb4caSwyllys (void) memset(key, 0, sizeof (KMF_KEY_HANDLE)); 127899ebb4caSwyllys } 127999ebb4caSwyllys 128099ebb4caSwyllys void 128130a5e8faSwyllys kmf_free_bigint(KMF_BIGINT *big) 128299ebb4caSwyllys { 128399ebb4caSwyllys if (big != NULL && big->val != NULL) { 128402744e81Swyllys /* Clear it out before returning it to the pool */ 128502744e81Swyllys (void) memset(big->val, 0x00, big->len); 128699ebb4caSwyllys free(big->val); 128799ebb4caSwyllys big->val = NULL; 128899ebb4caSwyllys big->len = 0; 128999ebb4caSwyllys } 129099ebb4caSwyllys } 129199ebb4caSwyllys 129299ebb4caSwyllys static void 129399ebb4caSwyllys free_raw_rsa(KMF_RAW_RSA_KEY *key) 129499ebb4caSwyllys { 129599ebb4caSwyllys if (key == NULL) 129699ebb4caSwyllys return; 129730a5e8faSwyllys kmf_free_bigint(&key->mod); 129830a5e8faSwyllys kmf_free_bigint(&key->pubexp); 129930a5e8faSwyllys kmf_free_bigint(&key->priexp); 130030a5e8faSwyllys kmf_free_bigint(&key->prime1); 130130a5e8faSwyllys kmf_free_bigint(&key->prime2); 130230a5e8faSwyllys kmf_free_bigint(&key->exp1); 130330a5e8faSwyllys kmf_free_bigint(&key->exp2); 130430a5e8faSwyllys kmf_free_bigint(&key->coef); 130599ebb4caSwyllys } 130699ebb4caSwyllys 130799ebb4caSwyllys static void 130899ebb4caSwyllys free_raw_dsa(KMF_RAW_DSA_KEY *key) 130999ebb4caSwyllys { 131099ebb4caSwyllys if (key == NULL) 131199ebb4caSwyllys return; 131230a5e8faSwyllys kmf_free_bigint(&key->prime); 131330a5e8faSwyllys kmf_free_bigint(&key->subprime); 131430a5e8faSwyllys kmf_free_bigint(&key->base); 131530a5e8faSwyllys kmf_free_bigint(&key->value); 131699ebb4caSwyllys } 131799ebb4caSwyllys 131899ebb4caSwyllys static void 131999ebb4caSwyllys free_raw_sym(KMF_RAW_SYM_KEY *key) 132099ebb4caSwyllys { 132199ebb4caSwyllys if (key == NULL) 132299ebb4caSwyllys return; 132330a5e8faSwyllys kmf_free_bigint(&key->keydata); 132499ebb4caSwyllys } 132599ebb4caSwyllys 132699ebb4caSwyllys void 132730a5e8faSwyllys kmf_free_raw_key(KMF_RAW_KEY_DATA *key) 132899ebb4caSwyllys { 132999ebb4caSwyllys if (key == NULL) 133099ebb4caSwyllys return; 133199ebb4caSwyllys 133299ebb4caSwyllys switch (key->keytype) { 133399ebb4caSwyllys case KMF_RSA: 133499ebb4caSwyllys free_raw_rsa(&key->rawdata.rsa); 133599ebb4caSwyllys break; 133699ebb4caSwyllys case KMF_DSA: 133799ebb4caSwyllys free_raw_dsa(&key->rawdata.dsa); 133899ebb4caSwyllys break; 133999ebb4caSwyllys case KMF_AES: 134099ebb4caSwyllys case KMF_RC4: 134199ebb4caSwyllys case KMF_DES: 134299ebb4caSwyllys case KMF_DES3: 134399ebb4caSwyllys free_raw_sym(&key->rawdata.sym); 134499ebb4caSwyllys break; 134599ebb4caSwyllys } 13465b3e1433Swyllys if (key->label) { 13475b3e1433Swyllys free(key->label); 13485b3e1433Swyllys key->label = NULL; 13495b3e1433Swyllys } 13505b3e1433Swyllys kmf_free_data(&key->id); 135199ebb4caSwyllys } 135299ebb4caSwyllys 135399ebb4caSwyllys void 135430a5e8faSwyllys kmf_free_raw_sym_key(KMF_RAW_SYM_KEY *key) 135599ebb4caSwyllys { 135699ebb4caSwyllys if (key == NULL) 135799ebb4caSwyllys return; 135830a5e8faSwyllys kmf_free_bigint(&key->keydata); 135999ebb4caSwyllys free(key); 136099ebb4caSwyllys } 136199ebb4caSwyllys 136299ebb4caSwyllys /* 136399ebb4caSwyllys * This function frees the space allocated for the name portion of a 136499ebb4caSwyllys * KMF_CRL_DIST_POINT. 136599ebb4caSwyllys */ 136699ebb4caSwyllys void 136799ebb4caSwyllys free_dp_name(KMF_CRL_DIST_POINT *dp) 136899ebb4caSwyllys { 136999ebb4caSwyllys KMF_GENERALNAMES *fullname; 137099ebb4caSwyllys KMF_DATA *urldata; 137199ebb4caSwyllys int i; 137299ebb4caSwyllys 137399ebb4caSwyllys if (dp == NULL) 137499ebb4caSwyllys return; 137599ebb4caSwyllys 137699ebb4caSwyllys /* For phase 1, we only need to free the fullname space. */ 137799ebb4caSwyllys fullname = &(dp->name.full_name); 137899ebb4caSwyllys if (fullname->number == 0) 137999ebb4caSwyllys return; 138099ebb4caSwyllys 138199ebb4caSwyllys for (i = 0; i < fullname->number; i++) { 138299ebb4caSwyllys urldata = &(fullname->namelist[fullname->number - 1].name); 138330a5e8faSwyllys kmf_free_data(urldata); 138499ebb4caSwyllys } 138599ebb4caSwyllys 138699ebb4caSwyllys free(fullname->namelist); 138799ebb4caSwyllys } 138899ebb4caSwyllys 138999ebb4caSwyllys /* 139099ebb4caSwyllys * This function frees the space allocated for a KMF_CRL_DIST_POINT. 139199ebb4caSwyllys */ 139299ebb4caSwyllys void 139399ebb4caSwyllys free_dp(KMF_CRL_DIST_POINT *dp) 139499ebb4caSwyllys { 139599ebb4caSwyllys if (dp == NULL) 139699ebb4caSwyllys return; 139799ebb4caSwyllys 139899ebb4caSwyllys free_dp_name(dp); 139930a5e8faSwyllys kmf_free_data(&(dp->reasons)); 140099ebb4caSwyllys /* Need not to free crl_issuer space at phase 1 */ 140199ebb4caSwyllys } 140299ebb4caSwyllys 140399ebb4caSwyllys /* 140499ebb4caSwyllys * This function frees space for a KMF_X509EXT_CRLDISTPOINTS internally. 140599ebb4caSwyllys */ 140699ebb4caSwyllys void 140730a5e8faSwyllys kmf_free_crl_dist_pts(KMF_X509EXT_CRLDISTPOINTS *crl_dps) 140899ebb4caSwyllys { 140999ebb4caSwyllys int i; 141099ebb4caSwyllys 141199ebb4caSwyllys if (crl_dps == NULL) 141299ebb4caSwyllys return; 141399ebb4caSwyllys 141499ebb4caSwyllys for (i = 0; i < crl_dps->number; i++) 141599ebb4caSwyllys free_dp(&(crl_dps->dplist[i])); 141699ebb4caSwyllys 141799ebb4caSwyllys free(crl_dps->dplist); 141899ebb4caSwyllys } 141999ebb4caSwyllys 142099ebb4caSwyllys KMF_RETURN 142130a5e8faSwyllys kmf_create_ocsp_request(KMF_HANDLE_T handle, 142230a5e8faSwyllys int num_args, 142330a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 142499ebb4caSwyllys { 142530a5e8faSwyllys KMF_RETURN ret = KMF_OK; 142699ebb4caSwyllys KMF_PLUGIN *plugin; 142730a5e8faSwyllys KMF_RETURN (*createReqFn)(void *, int num_args, 142830a5e8faSwyllys KMF_ATTRIBUTE *attrlist); 142999ebb4caSwyllys 143030a5e8faSwyllys KMF_ATTRIBUTE_TESTER required_attrs[] = { 143130a5e8faSwyllys {KMF_OCSP_REQUEST_FILENAME_ATTR, FALSE, 1, 0}, 143230a5e8faSwyllys {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 143330a5e8faSwyllys sizeof (KMF_DATA)}, 143430a5e8faSwyllys {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 143530a5e8faSwyllys sizeof (KMF_DATA)}, 143630a5e8faSwyllys }; 143799ebb4caSwyllys 143830a5e8faSwyllys int num_req_attrs = sizeof (required_attrs) / 143930a5e8faSwyllys sizeof (KMF_ATTRIBUTE_TESTER); 144099ebb4caSwyllys 144130a5e8faSwyllys if (handle == NULL) 144299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 144399ebb4caSwyllys 144430a5e8faSwyllys CLEAR_ERROR(handle, ret); 144530a5e8faSwyllys 144630a5e8faSwyllys ret = test_attributes(num_req_attrs, required_attrs, 144730a5e8faSwyllys 0, NULL, num_args, attrlist); 144830a5e8faSwyllys 144930a5e8faSwyllys if (ret != KMF_OK) 145030a5e8faSwyllys return (ret); 145130a5e8faSwyllys 145299ebb4caSwyllys /* 145399ebb4caSwyllys * This framework function is actually implemented in the openssl 145499ebb4caSwyllys * plugin library, so we find the function address and call it. 145599ebb4caSwyllys */ 145699ebb4caSwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 145799ebb4caSwyllys if (plugin == NULL || plugin->dldesc == NULL) { 145899ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 145999ebb4caSwyllys } 146099ebb4caSwyllys 146199ebb4caSwyllys createReqFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 146299ebb4caSwyllys "OpenSSL_CreateOCSPRequest"); 146399ebb4caSwyllys if (createReqFn == NULL) { 146499ebb4caSwyllys return (KMF_ERR_FUNCTION_NOT_FOUND); 146599ebb4caSwyllys } 146699ebb4caSwyllys 146730a5e8faSwyllys return (createReqFn(handle, num_args, attrlist)); 146830a5e8faSwyllys 146999ebb4caSwyllys } 147099ebb4caSwyllys 147199ebb4caSwyllys KMF_RETURN 147230a5e8faSwyllys kmf_get_ocsp_status_for_cert(KMF_HANDLE_T handle, 147330a5e8faSwyllys int num_args, 147430a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 147599ebb4caSwyllys { 147630a5e8faSwyllys KMF_RETURN ret = KMF_OK; 147799ebb4caSwyllys KMF_PLUGIN *plugin; 147830a5e8faSwyllys KMF_RETURN (*getCertStatusFn)(void *, int num_args, 147930a5e8faSwyllys KMF_ATTRIBUTE *attrlist); 148030a5e8faSwyllys 148130a5e8faSwyllys KMF_ATTRIBUTE_TESTER required_attrs[] = { 148230a5e8faSwyllys {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 148330a5e8faSwyllys sizeof (KMF_DATA)}, 148430a5e8faSwyllys {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 148530a5e8faSwyllys sizeof (KMF_DATA)}, 148630a5e8faSwyllys {KMF_OCSP_RESPONSE_DATA_ATTR, FALSE, sizeof (KMF_DATA), 148730a5e8faSwyllys sizeof (KMF_DATA)}, 148830a5e8faSwyllys {KMF_OCSP_RESPONSE_STATUS_ATTR, FALSE, sizeof (int), 148930a5e8faSwyllys sizeof (uint32_t)}, 149030a5e8faSwyllys {KMF_OCSP_RESPONSE_REASON_ATTR, FALSE, sizeof (int), 149130a5e8faSwyllys sizeof (uint32_t)}, 149230a5e8faSwyllys {KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, FALSE, sizeof (int), 149330a5e8faSwyllys sizeof (uint32_t)}, 149430a5e8faSwyllys }; 149530a5e8faSwyllys 149630a5e8faSwyllys int num_req_attrs = sizeof (required_attrs) / 149730a5e8faSwyllys sizeof (KMF_ATTRIBUTE_TESTER); 149830a5e8faSwyllys 149930a5e8faSwyllys if (handle == NULL) 150030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 150199ebb4caSwyllys 150299ebb4caSwyllys CLEAR_ERROR(handle, ret); 150399ebb4caSwyllys 150430a5e8faSwyllys ret = test_attributes(num_req_attrs, required_attrs, 150530a5e8faSwyllys 0, NULL, num_args, attrlist); 150699ebb4caSwyllys 150730a5e8faSwyllys if (ret != KMF_OK) 150830a5e8faSwyllys return (ret); 150999ebb4caSwyllys 151099ebb4caSwyllys /* 151199ebb4caSwyllys * This framework function is actually implemented in the openssl 151299ebb4caSwyllys * plugin library, so we find the function address and call it. 151399ebb4caSwyllys */ 151499ebb4caSwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 151599ebb4caSwyllys if (plugin == NULL || plugin->dldesc == NULL) { 151699ebb4caSwyllys return (KMF_ERR_INTERNAL); 151799ebb4caSwyllys } 151899ebb4caSwyllys 151999ebb4caSwyllys getCertStatusFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 152099ebb4caSwyllys "OpenSSL_GetOCSPStatusForCert"); 152199ebb4caSwyllys if (getCertStatusFn == NULL) { 152299ebb4caSwyllys return (KMF_ERR_INTERNAL); 152399ebb4caSwyllys } 152499ebb4caSwyllys 152530a5e8faSwyllys return (getCertStatusFn(handle, num_args, attrlist)); 152630a5e8faSwyllys 152799ebb4caSwyllys } 152899ebb4caSwyllys 152999ebb4caSwyllys KMF_RETURN 153030a5e8faSwyllys kmf_string_to_oid(char *oidstring, KMF_OID *oid) 153199ebb4caSwyllys { 153299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 153399ebb4caSwyllys char *cp, *bp, *startp; 153499ebb4caSwyllys int numbuf; 153599ebb4caSwyllys int onumbuf; 153699ebb4caSwyllys int nbytes, index; 153799ebb4caSwyllys int len; 153899ebb4caSwyllys unsigned char *op; 153999ebb4caSwyllys 154099ebb4caSwyllys if (oidstring == NULL || oid == NULL) 154199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 154299ebb4caSwyllys 154399ebb4caSwyllys len = strlen(oidstring); 154499ebb4caSwyllys 154599ebb4caSwyllys bp = oidstring; 154699ebb4caSwyllys cp = bp; 154799ebb4caSwyllys /* Skip over leading space */ 154899ebb4caSwyllys while ((bp < &cp[len]) && isspace(*bp)) 154999ebb4caSwyllys bp++; 155099ebb4caSwyllys 155199ebb4caSwyllys startp = bp; 155299ebb4caSwyllys nbytes = 0; 155399ebb4caSwyllys 155499ebb4caSwyllys /* 155599ebb4caSwyllys * The first two numbers are chewed up by the first octet. 155699ebb4caSwyllys */ 155799ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 155899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 155999ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 156099ebb4caSwyllys bp++; 156199ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 156299ebb4caSwyllys bp++; 156399ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 156499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 156599ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 156699ebb4caSwyllys bp++; 156799ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 156899ebb4caSwyllys bp++; 156999ebb4caSwyllys nbytes++; 157099ebb4caSwyllys 157199ebb4caSwyllys while (isdigit(*bp)) { 157299ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 157399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 157499ebb4caSwyllys while (numbuf) { 157599ebb4caSwyllys nbytes++; 157699ebb4caSwyllys numbuf >>= 7; 157799ebb4caSwyllys } 157899ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 157999ebb4caSwyllys bp++; 158099ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 158199ebb4caSwyllys bp++; 158299ebb4caSwyllys } 158399ebb4caSwyllys 158499ebb4caSwyllys oid->Length = nbytes; 158599ebb4caSwyllys oid->Data = malloc(oid->Length); 158699ebb4caSwyllys if (oid->Data == NULL) { 158799ebb4caSwyllys return (KMF_ERR_MEMORY); 158899ebb4caSwyllys } 158999ebb4caSwyllys (void) memset(oid->Data, 0, oid->Length); 159099ebb4caSwyllys 159199ebb4caSwyllys op = oid->Data; 159299ebb4caSwyllys 159399ebb4caSwyllys bp = startp; 159499ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 159599ebb4caSwyllys 159699ebb4caSwyllys while (isdigit(*bp)) bp++; 159799ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 159899ebb4caSwyllys 159999ebb4caSwyllys onumbuf = 40 * numbuf; 160099ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 160199ebb4caSwyllys onumbuf += numbuf; 160299ebb4caSwyllys *op = (unsigned char) onumbuf; 160399ebb4caSwyllys op++; 160499ebb4caSwyllys 160599ebb4caSwyllys while (isdigit(*bp)) bp++; 160699ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 160799ebb4caSwyllys while (isdigit(*bp)) { 160899ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 160999ebb4caSwyllys nbytes = 0; 161099ebb4caSwyllys /* Have to fill in the bytes msb-first */ 161199ebb4caSwyllys onumbuf = numbuf; 161299ebb4caSwyllys while (numbuf) { 161399ebb4caSwyllys nbytes++; 161499ebb4caSwyllys numbuf >>= 7; 161599ebb4caSwyllys } 161699ebb4caSwyllys numbuf = onumbuf; 161799ebb4caSwyllys op += nbytes; 161899ebb4caSwyllys index = -1; 161999ebb4caSwyllys while (numbuf) { 162099ebb4caSwyllys op[index] = (unsigned char)numbuf & 0x7f; 162199ebb4caSwyllys if (index != -1) 162299ebb4caSwyllys op[index] |= 0x80; 162399ebb4caSwyllys index--; 162499ebb4caSwyllys numbuf >>= 7; 162599ebb4caSwyllys } 162699ebb4caSwyllys while (isdigit(*bp)) bp++; 162799ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 162899ebb4caSwyllys } 162999ebb4caSwyllys 163099ebb4caSwyllys return (rv); 163199ebb4caSwyllys } 163299ebb4caSwyllys 163399ebb4caSwyllys static KMF_RETURN 163499ebb4caSwyllys encode_rid(char *name, KMF_DATA *derdata) 163599ebb4caSwyllys { 163699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 163799ebb4caSwyllys 163899ebb4caSwyllys if (name == NULL || derdata == NULL) 163999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 164099ebb4caSwyllys 164130a5e8faSwyllys rv = kmf_string_to_oid(name, (KMF_OID *)derdata); 164299ebb4caSwyllys 164399ebb4caSwyllys return (rv); 164499ebb4caSwyllys } 164599ebb4caSwyllys 164699ebb4caSwyllys static KMF_RETURN 164799ebb4caSwyllys encode_ipaddr(char *name, KMF_DATA *derdata) 164899ebb4caSwyllys { 164999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 165099ebb4caSwyllys size_t len; 165199ebb4caSwyllys in_addr_t v4; 165299ebb4caSwyllys in6_addr_t v6; 165399ebb4caSwyllys uint8_t *ptr; 165499ebb4caSwyllys 165599ebb4caSwyllys if (name == NULL || derdata == NULL) 165699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 165799ebb4caSwyllys 165899ebb4caSwyllys v4 = inet_addr(name); 165999ebb4caSwyllys if (v4 == (in_addr_t)-1) { 166099ebb4caSwyllys ptr = (uint8_t *)&v6; 166199ebb4caSwyllys if (inet_pton(AF_INET6, name, ptr) != 1) 166299ebb4caSwyllys return (KMF_ERR_ENCODING); 166399ebb4caSwyllys len = sizeof (v6); 166499ebb4caSwyllys } else { 166599ebb4caSwyllys ptr = (uint8_t *)&v4; 166699ebb4caSwyllys len = sizeof (v4); 166799ebb4caSwyllys } 166899ebb4caSwyllys 166999ebb4caSwyllys derdata->Data = malloc(len); 167099ebb4caSwyllys if (derdata->Data == NULL) 167199ebb4caSwyllys return (KMF_ERR_MEMORY); 167299ebb4caSwyllys (void) memcpy(derdata->Data, ptr, len); 167399ebb4caSwyllys derdata->Length = len; 167499ebb4caSwyllys 167599ebb4caSwyllys return (rv); 167699ebb4caSwyllys } 167799ebb4caSwyllys 167899ebb4caSwyllys static KMF_RETURN 167999ebb4caSwyllys verify_uri_format(char *uristring) 168099ebb4caSwyllys { 168199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 168299ebb4caSwyllys xmlURIPtr uriptr = NULL; 168399ebb4caSwyllys 168499ebb4caSwyllys /* Parse the URI string; get the hostname and port */ 168599ebb4caSwyllys uriptr = xmlParseURI(uristring); 168699ebb4caSwyllys if (uriptr == NULL) { 168799ebb4caSwyllys ret = KMF_ERR_BAD_URI; 168899ebb4caSwyllys goto out; 168999ebb4caSwyllys } 169099ebb4caSwyllys 169199ebb4caSwyllys if (uriptr->scheme == NULL || !strlen(uriptr->scheme)) { 169299ebb4caSwyllys ret = KMF_ERR_BAD_URI; 169399ebb4caSwyllys goto out; 169499ebb4caSwyllys } 169599ebb4caSwyllys 169699ebb4caSwyllys if (uriptr->server == NULL || !strlen(uriptr->server)) { 169799ebb4caSwyllys ret = KMF_ERR_BAD_URI; 169899ebb4caSwyllys goto out; 169999ebb4caSwyllys } 170099ebb4caSwyllys out: 170199ebb4caSwyllys if (uriptr != NULL) 170299ebb4caSwyllys xmlFreeURI(uriptr); 170399ebb4caSwyllys return (ret); 170499ebb4caSwyllys } 170599ebb4caSwyllys 170699ebb4caSwyllys static KMF_RETURN 170799ebb4caSwyllys encode_altname(char *namedata, 170899ebb4caSwyllys KMF_GENERALNAMECHOICES nametype, KMF_DATA *encodedname) 170999ebb4caSwyllys { 171099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 171199ebb4caSwyllys KMF_X509_NAME dnname; 171299ebb4caSwyllys uchar_t tagval; 171399ebb4caSwyllys BerElement *asn1 = NULL; 171499ebb4caSwyllys BerValue *extdata; 171599ebb4caSwyllys 171699ebb4caSwyllys if (namedata == NULL || encodedname == NULL) 171799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 171899ebb4caSwyllys 171999ebb4caSwyllys /* 172099ebb4caSwyllys * Encode the namedata according to rules in RFC 3280 for GeneralName. 172199ebb4caSwyllys * The input "namedata" is assumed to be an ASCII string representation 172299ebb4caSwyllys * of the AltName, we need to convert it to correct ASN.1 here before 172399ebb4caSwyllys * adding it to the cert. 172499ebb4caSwyllys */ 172599ebb4caSwyllys switch (nametype) { 172699ebb4caSwyllys case GENNAME_RFC822NAME: /* rfc 822 */ 172799ebb4caSwyllys /* IA5String, no encoding needed */ 172899ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 172999ebb4caSwyllys if (encodedname->Data == NULL) 173099ebb4caSwyllys return (KMF_ERR_MEMORY); 173199ebb4caSwyllys encodedname->Length = strlen(namedata); 173299ebb4caSwyllys tagval = (0x80 | nametype); 173399ebb4caSwyllys break; 173499ebb4caSwyllys case GENNAME_DNSNAME: /* rfc 1034 */ 173599ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 173699ebb4caSwyllys if (encodedname->Data == NULL) 173799ebb4caSwyllys return (KMF_ERR_MEMORY); 173899ebb4caSwyllys encodedname->Length = strlen(namedata); 173999ebb4caSwyllys tagval = (0x80 | nametype); 174099ebb4caSwyllys break; 174199ebb4caSwyllys case GENNAME_URI: /* rfc 1738 */ 174299ebb4caSwyllys ret = verify_uri_format(namedata); 174399ebb4caSwyllys if (ret != KMF_OK) 174499ebb4caSwyllys return (ret); 174599ebb4caSwyllys /* IA5String, no encoding needed */ 174699ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 174799ebb4caSwyllys if (encodedname->Data == NULL) 174899ebb4caSwyllys return (KMF_ERR_MEMORY); 174999ebb4caSwyllys encodedname->Length = strlen(namedata); 175099ebb4caSwyllys tagval = (0x80 | nametype); 175199ebb4caSwyllys break; 175299ebb4caSwyllys case GENNAME_IPADDRESS: 175399ebb4caSwyllys ret = encode_ipaddr(namedata, encodedname); 175499ebb4caSwyllys tagval = (0x80 | nametype); 175599ebb4caSwyllys break; 175699ebb4caSwyllys case GENNAME_REGISTEREDID: 175799ebb4caSwyllys ret = encode_rid(namedata, encodedname); 175899ebb4caSwyllys tagval = (0x80 | nametype); 175999ebb4caSwyllys break; 176099ebb4caSwyllys case GENNAME_DIRECTORYNAME: 176130a5e8faSwyllys ret = kmf_dn_parser(namedata, &dnname); 176299ebb4caSwyllys if (ret == KMF_OK) { 176330a5e8faSwyllys ret = DerEncodeName(&dnname, encodedname); 176499ebb4caSwyllys } 176530a5e8faSwyllys (void) kmf_free_dn(&dnname); 176699ebb4caSwyllys tagval = (0xA0 | nametype); 176799ebb4caSwyllys break; 176899ebb4caSwyllys default: 176999ebb4caSwyllys /* unsupported */ 177099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 177199ebb4caSwyllys 177299ebb4caSwyllys } 177399ebb4caSwyllys if (ret != KMF_OK) { 177430a5e8faSwyllys kmf_free_data(encodedname); 177599ebb4caSwyllys return (ret); 177699ebb4caSwyllys } 177799ebb4caSwyllys 177899ebb4caSwyllys if ((asn1 = kmfder_alloc()) == NULL) 177999ebb4caSwyllys return (KMF_ERR_MEMORY); 178099ebb4caSwyllys 178130a5e8faSwyllys if (kmfber_printf(asn1, "Tl", tagval, encodedname->Length) == -1) 178299ebb4caSwyllys goto cleanup; 178399ebb4caSwyllys 178499ebb4caSwyllys if (kmfber_write(asn1, (char *)encodedname->Data, 178530a5e8faSwyllys encodedname->Length, 0) == -1) { 178699ebb4caSwyllys ret = KMF_ERR_ENCODING; 178799ebb4caSwyllys goto cleanup; 178899ebb4caSwyllys } 178999ebb4caSwyllys if (kmfber_flatten(asn1, &extdata) == -1) { 179099ebb4caSwyllys ret = KMF_ERR_ENCODING; 179199ebb4caSwyllys goto cleanup; 179299ebb4caSwyllys } 179399ebb4caSwyllys 179430a5e8faSwyllys kmf_free_data(encodedname); 179599ebb4caSwyllys encodedname->Data = (uchar_t *)extdata->bv_val; 179699ebb4caSwyllys encodedname->Length = extdata->bv_len; 179799ebb4caSwyllys 179899ebb4caSwyllys free(extdata); 179999ebb4caSwyllys 180099ebb4caSwyllys cleanup: 180199ebb4caSwyllys if (asn1) 180299ebb4caSwyllys kmfber_free(asn1, 1); 180399ebb4caSwyllys 180499ebb4caSwyllys if (ret != KMF_OK) 180530a5e8faSwyllys kmf_free_data(encodedname); 180699ebb4caSwyllys 180799ebb4caSwyllys return (ret); 180899ebb4caSwyllys } 180999ebb4caSwyllys 181099ebb4caSwyllys KMF_X509_EXTENSION * 181199ebb4caSwyllys FindExtn(KMF_X509_EXTENSIONS *exts, KMF_OID *oid) 181299ebb4caSwyllys { 181399ebb4caSwyllys KMF_X509_EXTENSION *foundextn = NULL; 181499ebb4caSwyllys int i; 181599ebb4caSwyllys 181699ebb4caSwyllys if (exts == NULL || oid == NULL) 181799ebb4caSwyllys return (NULL); 181899ebb4caSwyllys 181999ebb4caSwyllys for (i = 0; i < exts->numberOfExtensions; i++) { 182099ebb4caSwyllys if (IsEqualOid(oid, &exts->extensions[i].extnId)) { 182199ebb4caSwyllys foundextn = &exts->extensions[i]; 182299ebb4caSwyllys break; 182399ebb4caSwyllys } 182499ebb4caSwyllys } 182599ebb4caSwyllys return (foundextn); 182699ebb4caSwyllys } 182799ebb4caSwyllys 182899ebb4caSwyllys KMF_RETURN 182999ebb4caSwyllys GetSequenceContents(char *data, size_t len, 183099ebb4caSwyllys char **contents, size_t *outlen) 183199ebb4caSwyllys { 183299ebb4caSwyllys KMF_RETURN ret = KMF_OK; 183399ebb4caSwyllys BerElement *exasn1 = NULL; 183499ebb4caSwyllys BerValue oldextn; 183599ebb4caSwyllys int tag; 183699ebb4caSwyllys size_t oldsize; 183799ebb4caSwyllys char *olddata = NULL; 183899ebb4caSwyllys 183999ebb4caSwyllys if (data == NULL || contents == NULL || outlen == NULL) 184099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 184199ebb4caSwyllys 184299ebb4caSwyllys /* 184399ebb4caSwyllys * Decode the sequence of general names 184499ebb4caSwyllys */ 184599ebb4caSwyllys oldextn.bv_val = data; 184699ebb4caSwyllys oldextn.bv_len = len; 184799ebb4caSwyllys 184899ebb4caSwyllys if ((exasn1 = kmfder_init(&oldextn)) == NULL) { 184999ebb4caSwyllys ret = KMF_ERR_MEMORY; 185099ebb4caSwyllys goto out; 185199ebb4caSwyllys } 185299ebb4caSwyllys 185399ebb4caSwyllys /* 185499ebb4caSwyllys * Unwrap the sequence to find the size of the block 185599ebb4caSwyllys * of GeneralName items in the set. 185699ebb4caSwyllys * 185799ebb4caSwyllys * Peek at the tag and length ("tl"), 185899ebb4caSwyllys * then consume them ("{"). 185999ebb4caSwyllys */ 186099ebb4caSwyllys if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT || 186130a5e8faSwyllys oldsize == 0) { 186299ebb4caSwyllys ret = KMF_ERR_ENCODING; 186399ebb4caSwyllys goto out; 186499ebb4caSwyllys } 186599ebb4caSwyllys 186699ebb4caSwyllys olddata = malloc(oldsize); 186799ebb4caSwyllys if (olddata == NULL) { 186899ebb4caSwyllys ret = KMF_ERR_MEMORY; 186999ebb4caSwyllys goto out; 187099ebb4caSwyllys } 187199ebb4caSwyllys (void) memset(olddata, 0, oldsize); 187299ebb4caSwyllys /* 187399ebb4caSwyllys * Read the entire blob of GeneralNames, we don't 187499ebb4caSwyllys * need to interpret them now. 187599ebb4caSwyllys */ 187699ebb4caSwyllys if (kmfber_read(exasn1, olddata, oldsize) != oldsize) { 187799ebb4caSwyllys ret = KMF_ERR_ENCODING; 187899ebb4caSwyllys goto out; 187999ebb4caSwyllys } 188099ebb4caSwyllys out: 188199ebb4caSwyllys if (exasn1 != NULL) 188299ebb4caSwyllys kmfber_free(exasn1, 1); 188399ebb4caSwyllys 188499ebb4caSwyllys if (ret != KMF_OK) { 188599ebb4caSwyllys *contents = NULL; 188699ebb4caSwyllys *outlen = 0; 188799ebb4caSwyllys if (olddata != NULL) 188899ebb4caSwyllys free(olddata); 188999ebb4caSwyllys } else { 189099ebb4caSwyllys *contents = olddata; 189199ebb4caSwyllys *outlen = oldsize; 189299ebb4caSwyllys } 189399ebb4caSwyllys return (ret); 189499ebb4caSwyllys } 189599ebb4caSwyllys 189699ebb4caSwyllys KMF_RETURN 189799ebb4caSwyllys add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) 189899ebb4caSwyllys { 189999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 190099ebb4caSwyllys KMF_X509_EXTENSION *extlist; 190199ebb4caSwyllys 190299ebb4caSwyllys if (exts == NULL || newextn == NULL) 190399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 190499ebb4caSwyllys 190599ebb4caSwyllys extlist = malloc(sizeof (KMF_X509_EXTENSION) * 190630a5e8faSwyllys (exts->numberOfExtensions + 1)); 190799ebb4caSwyllys if (extlist == NULL) 190899ebb4caSwyllys return (KMF_ERR_MEMORY); 190999ebb4caSwyllys 191099ebb4caSwyllys (void) memcpy(extlist, exts->extensions, 191199ebb4caSwyllys exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION)); 191299ebb4caSwyllys 191399ebb4caSwyllys (void) memcpy(&extlist[exts->numberOfExtensions], newextn, 191430a5e8faSwyllys sizeof (KMF_X509_EXTENSION)); 191599ebb4caSwyllys 191699ebb4caSwyllys free(exts->extensions); 191799ebb4caSwyllys exts->numberOfExtensions++; 191899ebb4caSwyllys exts->extensions = extlist; 191999ebb4caSwyllys 192099ebb4caSwyllys return (ret); 192199ebb4caSwyllys } 192299ebb4caSwyllys 192399ebb4caSwyllys KMF_RETURN 192430a5e8faSwyllys kmf_set_altname(KMF_X509_EXTENSIONS *extensions, 192599ebb4caSwyllys KMF_OID *oid, 192699ebb4caSwyllys int critical, 192799ebb4caSwyllys KMF_GENERALNAMECHOICES nametype, 192899ebb4caSwyllys char *namedata) 192999ebb4caSwyllys { 193099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 193199ebb4caSwyllys KMF_X509_EXTENSION subjAltName; 193299ebb4caSwyllys KMF_DATA dername = { NULL, 0 }; 193399ebb4caSwyllys BerElement *asn1 = NULL; 193499ebb4caSwyllys BerValue *extdata; 193599ebb4caSwyllys char *olddata = NULL; 193699ebb4caSwyllys KMF_X509_EXTENSION *foundextn = NULL; 193799ebb4caSwyllys size_t oldsize = 0; 193899ebb4caSwyllys 193999ebb4caSwyllys if (extensions == NULL || oid == NULL || namedata == NULL) 194099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 194199ebb4caSwyllys 194299ebb4caSwyllys ret = encode_altname(namedata, nametype, &dername); 194399ebb4caSwyllys 194499ebb4caSwyllys if (ret != KMF_OK) 194599ebb4caSwyllys return (ret); 194699ebb4caSwyllys 194799ebb4caSwyllys (void) memset(&subjAltName, 0, sizeof (subjAltName)); 194899ebb4caSwyllys 194999ebb4caSwyllys ret = copy_data(&subjAltName.extnId, oid); 195099ebb4caSwyllys if (ret != KMF_OK) 195199ebb4caSwyllys goto out; 195299ebb4caSwyllys /* 195399ebb4caSwyllys * Check to see if this cert already has a subjectAltName. 195499ebb4caSwyllys */ 195599ebb4caSwyllys foundextn = FindExtn(extensions, oid); 195699ebb4caSwyllys 195799ebb4caSwyllys if (foundextn != NULL) { 195899ebb4caSwyllys ret = GetSequenceContents( 195930a5e8faSwyllys (char *)foundextn->BERvalue.Data, 196030a5e8faSwyllys foundextn->BERvalue.Length, 196130a5e8faSwyllys &olddata, &oldsize); 196299ebb4caSwyllys if (ret != KMF_OK) 196399ebb4caSwyllys goto out; 196499ebb4caSwyllys } 196599ebb4caSwyllys 196699ebb4caSwyllys /* 196799ebb4caSwyllys * Assume (!!) that the namedata given is already properly encoded. 196899ebb4caSwyllys */ 196999ebb4caSwyllys if ((asn1 = kmfder_alloc()) == NULL) 197099ebb4caSwyllys return (KMF_ERR_MEMORY); 197199ebb4caSwyllys 197299ebb4caSwyllys if (kmfber_printf(asn1, "{") == -1) { 197399ebb4caSwyllys ret = KMF_ERR_ENCODING; 197499ebb4caSwyllys goto out; 197599ebb4caSwyllys } 197699ebb4caSwyllys 197799ebb4caSwyllys /* Write the old extension data first */ 197899ebb4caSwyllys if (olddata != NULL && oldsize > 0) { 197999ebb4caSwyllys if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 198099ebb4caSwyllys ret = KMF_ERR_ENCODING; 198199ebb4caSwyllys goto out; 198299ebb4caSwyllys } 198399ebb4caSwyllys } 198499ebb4caSwyllys 198599ebb4caSwyllys /* Now add the new name to the list */ 198699ebb4caSwyllys if (kmfber_write(asn1, (char *)dername.Data, dername.Length, 0) == -1) { 198799ebb4caSwyllys ret = KMF_ERR_ENCODING; 198899ebb4caSwyllys goto out; 198999ebb4caSwyllys } 199099ebb4caSwyllys 199199ebb4caSwyllys /* Now close the sequence */ 199299ebb4caSwyllys if (kmfber_printf(asn1, "}") == -1) { 199399ebb4caSwyllys ret = KMF_ERR_ENCODING; 199499ebb4caSwyllys goto out; 199599ebb4caSwyllys } 199699ebb4caSwyllys if (kmfber_flatten(asn1, &extdata) == -1) { 199799ebb4caSwyllys ret = KMF_ERR_ENCODING; 199899ebb4caSwyllys goto out; 199999ebb4caSwyllys } 200099ebb4caSwyllys 200199ebb4caSwyllys /* 200299ebb4caSwyllys * If we are just adding to an existing list of altNames, 200399ebb4caSwyllys * just replace the BER data associated with the found extension. 200499ebb4caSwyllys */ 200599ebb4caSwyllys if (foundextn != NULL) { 200699ebb4caSwyllys free(foundextn->BERvalue.Data); 200799ebb4caSwyllys foundextn->critical = critical; 200899ebb4caSwyllys foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 200999ebb4caSwyllys foundextn->BERvalue.Length = extdata->bv_len; 201099ebb4caSwyllys } else { 201199ebb4caSwyllys subjAltName.critical = critical; 201299ebb4caSwyllys subjAltName.format = KMF_X509_DATAFORMAT_ENCODED; 201399ebb4caSwyllys subjAltName.BERvalue.Data = (uchar_t *)extdata->bv_val; 201499ebb4caSwyllys subjAltName.BERvalue.Length = extdata->bv_len; 201599ebb4caSwyllys ret = add_an_extension(extensions, &subjAltName); 201699ebb4caSwyllys if (ret != KMF_OK) 201799ebb4caSwyllys free(subjAltName.BERvalue.Data); 201899ebb4caSwyllys } 201999ebb4caSwyllys 202099ebb4caSwyllys free(extdata); 202199ebb4caSwyllys out: 202299ebb4caSwyllys if (olddata != NULL) 202399ebb4caSwyllys free(olddata); 202499ebb4caSwyllys 202530a5e8faSwyllys kmf_free_data(&dername); 202699ebb4caSwyllys if (ret != KMF_OK) 202730a5e8faSwyllys kmf_free_data(&subjAltName.extnId); 202899ebb4caSwyllys if (asn1 != NULL) 202999ebb4caSwyllys kmfber_free(asn1, 1); 203099ebb4caSwyllys return (ret); 203199ebb4caSwyllys } 203230a5e8faSwyllys 203330a5e8faSwyllys /* 203430a5e8faSwyllys * Search a list of attributes for one that matches the given type. 203530a5e8faSwyllys * Return a pointer into the attribute list. This does not 203630a5e8faSwyllys * return a copy of the value, it returns a reference into the 203730a5e8faSwyllys * given list. 203830a5e8faSwyllys */ 203930a5e8faSwyllys int 204030a5e8faSwyllys kmf_find_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, int numattrs) 204130a5e8faSwyllys { 204230a5e8faSwyllys int i; 204330a5e8faSwyllys for (i = 0; i < numattrs; i++) { 204430a5e8faSwyllys if (attlist[i].type == type) 204530a5e8faSwyllys return (i); 204630a5e8faSwyllys } 204730a5e8faSwyllys return (-1); 204830a5e8faSwyllys } 204930a5e8faSwyllys 205030a5e8faSwyllys /* 205130a5e8faSwyllys * Verify that a given attribute is consistent with the 205230a5e8faSwyllys * "test" attribute. 205330a5e8faSwyllys */ 205430a5e8faSwyllys static KMF_RETURN 205530a5e8faSwyllys verify_attribute(KMF_ATTRIBUTE *givenattr, 205630a5e8faSwyllys KMF_ATTRIBUTE_TESTER *testattr) 205730a5e8faSwyllys { 205830a5e8faSwyllys /* A NULL pValue was found where one is required */ 205930a5e8faSwyllys if (testattr->null_value_ok == FALSE && 206030a5e8faSwyllys givenattr->pValue == NULL) 206130a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 206230a5e8faSwyllys 206330a5e8faSwyllys /* If the given valueLen is too small, return error */ 206430a5e8faSwyllys if (givenattr->pValue != NULL && 206530a5e8faSwyllys testattr->minlen > 0 && 206630a5e8faSwyllys (givenattr->valueLen < testattr->minlen)) 206730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 206830a5e8faSwyllys 206930a5e8faSwyllys /* If the given valueLen is too big, return error */ 207030a5e8faSwyllys if (givenattr->pValue != NULL && 207130a5e8faSwyllys testattr->maxlen > 0 && 207230a5e8faSwyllys (givenattr->valueLen > testattr->maxlen)) 207330a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 207430a5e8faSwyllys 207530a5e8faSwyllys return (KMF_OK); 207630a5e8faSwyllys } 207730a5e8faSwyllys 207830a5e8faSwyllys /* 207930a5e8faSwyllys * Given a set of required attribute tests and optional 208030a5e8faSwyllys * attributes, make sure that the actual attributes 208130a5e8faSwyllys * being tested (attrlist below) are allowed and are 208230a5e8faSwyllys * properly specified. 208330a5e8faSwyllys */ 208430a5e8faSwyllys KMF_RETURN 208530a5e8faSwyllys test_attributes(int reqnum, KMF_ATTRIBUTE_TESTER *reqattrs, 208630a5e8faSwyllys int optnum, KMF_ATTRIBUTE_TESTER *optattrs, 208730a5e8faSwyllys int numattrs, KMF_ATTRIBUTE *attrlist) 208830a5e8faSwyllys { 208930a5e8faSwyllys KMF_RETURN ret = KMF_OK; 209030a5e8faSwyllys int i, idx; 209130a5e8faSwyllys 209230a5e8faSwyllys /* 209330a5e8faSwyllys * If the caller didn't supply enough attributes, 209430a5e8faSwyllys * return an error. 209530a5e8faSwyllys */ 209630a5e8faSwyllys if (numattrs < reqnum || attrlist == NULL) 209730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 209830a5e8faSwyllys 209930a5e8faSwyllys /* 210030a5e8faSwyllys * Make sure all required attrs are present and 210130a5e8faSwyllys * correct. 210230a5e8faSwyllys */ 210330a5e8faSwyllys for (i = 0; i < reqnum && ret == KMF_OK; i++) { 210430a5e8faSwyllys idx = kmf_find_attr(reqattrs[i].type, attrlist, numattrs); 210530a5e8faSwyllys /* If a required attr is not found, return error */ 210630a5e8faSwyllys if (idx == -1) { 210730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 210830a5e8faSwyllys } 210930a5e8faSwyllys 211030a5e8faSwyllys ret = verify_attribute(&attrlist[idx], &reqattrs[i]); 211130a5e8faSwyllys } 211230a5e8faSwyllys /* 211330a5e8faSwyllys * Now test the optional parameters. 211430a5e8faSwyllys */ 211530a5e8faSwyllys for (i = 0; i < optnum && ret == KMF_OK; i++) { 211630a5e8faSwyllys idx = kmf_find_attr(optattrs[i].type, attrlist, numattrs); 211730a5e8faSwyllys /* If a optional attr is not found, continue. */ 211830a5e8faSwyllys if (idx == -1) { 211930a5e8faSwyllys continue; 212030a5e8faSwyllys } 212130a5e8faSwyllys 212230a5e8faSwyllys ret = verify_attribute(&attrlist[idx], &optattrs[i]); 212330a5e8faSwyllys } 212430a5e8faSwyllys 212530a5e8faSwyllys return (ret); 212630a5e8faSwyllys } 212730a5e8faSwyllys 212830a5e8faSwyllys /* 212930a5e8faSwyllys * Given an already allocated attribute list, insert 213030a5e8faSwyllys * the given attribute information at a specific index 213130a5e8faSwyllys * in the list. 213230a5e8faSwyllys */ 213330a5e8faSwyllys void 213430a5e8faSwyllys kmf_set_attr_at_index(KMF_ATTRIBUTE *attlist, int index, 213530a5e8faSwyllys KMF_ATTR_TYPE type, void *pValue, uint32_t len) 213630a5e8faSwyllys { 213730a5e8faSwyllys if (attlist == NULL) 213830a5e8faSwyllys return; 213930a5e8faSwyllys 214030a5e8faSwyllys attlist[index].type = type; 214130a5e8faSwyllys attlist[index].pValue = pValue; 214230a5e8faSwyllys attlist[index].valueLen = len; 214330a5e8faSwyllys } 214430a5e8faSwyllys 214530a5e8faSwyllys /* 214630a5e8faSwyllys * Find an attribute matching a particular type and set 214730a5e8faSwyllys * the pValue and length fields to the given values. 214830a5e8faSwyllys */ 214930a5e8faSwyllys KMF_RETURN 215030a5e8faSwyllys kmf_set_attr(KMF_ATTRIBUTE *attlist, int numattr, 215130a5e8faSwyllys KMF_ATTR_TYPE type, void *pValue, uint32_t len) 215230a5e8faSwyllys { 215330a5e8faSwyllys int idx; 215430a5e8faSwyllys if (attlist == NULL) 215530a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 215630a5e8faSwyllys 215730a5e8faSwyllys idx = kmf_find_attr(type, attlist, numattr); 215830a5e8faSwyllys if (idx == -1) 215930a5e8faSwyllys return (KMF_ERR_ATTR_NOT_FOUND); 216030a5e8faSwyllys 216130a5e8faSwyllys attlist[idx].type = type; 216230a5e8faSwyllys /* Assumes the attribute pValue can hold the result */ 216330a5e8faSwyllys if (attlist[idx].pValue != NULL) { 216430a5e8faSwyllys if (attlist[idx].valueLen >= len) 216530a5e8faSwyllys (void) memcpy(attlist[idx].pValue, pValue, len); 216630a5e8faSwyllys else 216730a5e8faSwyllys return (KMF_ERR_BUFFER_SIZE); 216830a5e8faSwyllys } 216930a5e8faSwyllys attlist[idx].valueLen = len; 217030a5e8faSwyllys return (KMF_OK); 217130a5e8faSwyllys } 217230a5e8faSwyllys 217330a5e8faSwyllys /* 217430a5e8faSwyllys * Find a particular attribute in a list and return 217530a5e8faSwyllys * a pointer to its value. 217630a5e8faSwyllys */ 217730a5e8faSwyllys void * 217830a5e8faSwyllys kmf_get_attr_ptr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 217930a5e8faSwyllys int numattrs) 218030a5e8faSwyllys { 218130a5e8faSwyllys int i; 218230a5e8faSwyllys 218330a5e8faSwyllys i = kmf_find_attr(type, attlist, numattrs); 218430a5e8faSwyllys if (i == -1) 218530a5e8faSwyllys return (NULL); 218630a5e8faSwyllys 218730a5e8faSwyllys return (attlist[i].pValue); 218830a5e8faSwyllys } 218930a5e8faSwyllys 219030a5e8faSwyllys /* 219130a5e8faSwyllys * Find a particular attribute in a list and return 219230a5e8faSwyllys * the value and length values. Value and length 219330a5e8faSwyllys * may be NULL if the caller doesn't want their values 219430a5e8faSwyllys * to be filled in. 219530a5e8faSwyllys */ 219630a5e8faSwyllys KMF_RETURN 219730a5e8faSwyllys kmf_get_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 219830a5e8faSwyllys int numattrs, void *outValue, uint32_t *outlen) 219930a5e8faSwyllys { 220030a5e8faSwyllys int i; 220130a5e8faSwyllys uint32_t len = 0; 220230a5e8faSwyllys uint32_t *lenptr = outlen; 220330a5e8faSwyllys 220430a5e8faSwyllys if (lenptr == NULL) 220530a5e8faSwyllys lenptr = &len; 220630a5e8faSwyllys 220730a5e8faSwyllys i = kmf_find_attr(type, attlist, numattrs); 220830a5e8faSwyllys if (i == -1) 220930a5e8faSwyllys return (KMF_ERR_ATTR_NOT_FOUND); 221030a5e8faSwyllys 221130a5e8faSwyllys /* This assumes that the ptr passed in is pre-allocated space */ 221230a5e8faSwyllys if (attlist[i].pValue != NULL && outValue != NULL) { 221330a5e8faSwyllys /* 221430a5e8faSwyllys * If the caller did not specify a length, 221530a5e8faSwyllys * assume "outValue" is big enough. 221630a5e8faSwyllys */ 221730a5e8faSwyllys if (outlen != NULL) { 221830a5e8faSwyllys if (*outlen >= attlist[i].valueLen) 221930a5e8faSwyllys (void) memcpy(outValue, attlist[i].pValue, 222030a5e8faSwyllys attlist[i].valueLen); 222130a5e8faSwyllys else 222230a5e8faSwyllys return (KMF_ERR_BUFFER_SIZE); 222330a5e8faSwyllys } else { 222430a5e8faSwyllys (void) memcpy(outValue, attlist[i].pValue, 222530a5e8faSwyllys attlist[i].valueLen); 222630a5e8faSwyllys } 222730a5e8faSwyllys } 222830a5e8faSwyllys 222930a5e8faSwyllys if (outlen != NULL) 223030a5e8faSwyllys *outlen = attlist[i].valueLen; 223130a5e8faSwyllys return (KMF_OK); 223230a5e8faSwyllys } 223330a5e8faSwyllys 223430a5e8faSwyllys /* 223530a5e8faSwyllys * Utility routine to find a string type attribute, allocate it 223630a5e8faSwyllys * and return the value to the caller. This simplifies the 223730a5e8faSwyllys * operation by doing both "kmf_get_attr" calls and avoids 223830a5e8faSwyllys * duplicating this block of code in lots of places. 223930a5e8faSwyllys */ 224030a5e8faSwyllys KMF_RETURN 224130a5e8faSwyllys kmf_get_string_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attrlist, 224230a5e8faSwyllys int numattrs, char **outstr) 224330a5e8faSwyllys { 224430a5e8faSwyllys KMF_RETURN rv; 224530a5e8faSwyllys uint32_t len; 224630a5e8faSwyllys 224730a5e8faSwyllys if (outstr == NULL) 224830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 224930a5e8faSwyllys 225030a5e8faSwyllys if ((rv = kmf_get_attr(type, attrlist, numattrs, NULL, &len)) == 225130a5e8faSwyllys KMF_OK) { 225230a5e8faSwyllys *outstr = malloc(len + 1); 225330a5e8faSwyllys if ((*outstr) == NULL) 225430a5e8faSwyllys return (KMF_ERR_MEMORY); 225530a5e8faSwyllys (void) memset((*outstr), 0, len + 1); 225630a5e8faSwyllys rv = kmf_get_attr(type, attrlist, numattrs, (*outstr), &len); 225730a5e8faSwyllys if (rv != KMF_OK) { 225830a5e8faSwyllys free(*outstr); 225930a5e8faSwyllys *outstr = NULL; 226030a5e8faSwyllys } 226130a5e8faSwyllys } 226230a5e8faSwyllys 226330a5e8faSwyllys return (rv); 226430a5e8faSwyllys } 226530a5e8faSwyllys 2266*431deaa0Shylee 2267*431deaa0Shylee void 2268*431deaa0Shylee free_entry(conf_entry_t *entry) 2269*431deaa0Shylee { 2270*431deaa0Shylee if (entry == NULL) 2271*431deaa0Shylee return; 2272*431deaa0Shylee free(entry->keystore); 2273*431deaa0Shylee free(entry->modulepath); 2274*431deaa0Shylee free(entry->option); 2275*431deaa0Shylee } 2276*431deaa0Shylee 2277*431deaa0Shylee void 2278*431deaa0Shylee free_entrylist(conf_entrylist_t *list) 2279*431deaa0Shylee { 2280*431deaa0Shylee conf_entrylist_t *next; 2281*431deaa0Shylee 2282*431deaa0Shylee while (list != NULL) { 2283*431deaa0Shylee next = list->next; 2284*431deaa0Shylee free_entry(list->entry); 2285*431deaa0Shylee free(list); 2286*431deaa0Shylee list = next; 2287*431deaa0Shylee } 2288*431deaa0Shylee } 2289*431deaa0Shylee 2290*431deaa0Shylee static KMF_RETURN 2291*431deaa0Shylee parse_entry(char *buf, conf_entry_t **entry) 2292*431deaa0Shylee { 2293*431deaa0Shylee KMF_RETURN ret = KMF_OK; 2294*431deaa0Shylee conf_entry_t *tmp = NULL; 2295*431deaa0Shylee char *token1; 2296*431deaa0Shylee char *token2; 2297*431deaa0Shylee char *token3; 2298*431deaa0Shylee char *lasts; 2299*431deaa0Shylee char *value; 2300*431deaa0Shylee 2301*431deaa0Shylee if ((token1 = strtok_r(buf, SEP_COLON, &lasts)) == NULL) 2302*431deaa0Shylee return (KMF_ERR_KMF_CONF); 2303*431deaa0Shylee 2304*431deaa0Shylee if ((tmp = calloc(sizeof (conf_entry_t), 1)) == NULL) 2305*431deaa0Shylee return (KMF_ERR_MEMORY); 2306*431deaa0Shylee 2307*431deaa0Shylee if ((tmp->keystore = strdup(token1)) == NULL) { 2308*431deaa0Shylee ret = KMF_ERR_MEMORY; 2309*431deaa0Shylee goto end; 2310*431deaa0Shylee } 2311*431deaa0Shylee 2312*431deaa0Shylee if ((token2 = strtok_r(NULL, SEP_SEMICOLON, &lasts)) == NULL) { 2313*431deaa0Shylee ret = KMF_ERR_KMF_CONF; 2314*431deaa0Shylee goto end; 2315*431deaa0Shylee } 2316*431deaa0Shylee 2317*431deaa0Shylee /* need to get token3 first to satisfy nested strtok invocations */ 2318*431deaa0Shylee token3 = strtok_r(NULL, SEP_SEMICOLON, &lasts); 2319*431deaa0Shylee 2320*431deaa0Shylee /* parse token2 */ 2321*431deaa0Shylee if (strncmp(token2, CONF_MODULEPATH, strlen(CONF_MODULEPATH)) != 0) { 2322*431deaa0Shylee ret = KMF_ERR_KMF_CONF; 2323*431deaa0Shylee goto end; 2324*431deaa0Shylee } 2325*431deaa0Shylee 2326*431deaa0Shylee if (value = strpbrk(token2, SEP_EQUAL)) { 2327*431deaa0Shylee value++; /* get rid of = */ 2328*431deaa0Shylee } else { 2329*431deaa0Shylee ret = KMF_ERR_KMF_CONF; 2330*431deaa0Shylee goto end; 2331*431deaa0Shylee } 2332*431deaa0Shylee 2333*431deaa0Shylee if ((tmp->modulepath = strdup(value)) == NULL) { 2334*431deaa0Shylee ret = KMF_ERR_MEMORY; 2335*431deaa0Shylee goto end; 2336*431deaa0Shylee } 2337*431deaa0Shylee 2338*431deaa0Shylee /* parse token3, if it exists */ 2339*431deaa0Shylee if (token3 != NULL) { 2340*431deaa0Shylee if (strncmp(token3, CONF_OPTION, strlen(CONF_OPTION)) 2341*431deaa0Shylee != 0) { 2342*431deaa0Shylee ret = KMF_ERR_KMF_CONF; 2343*431deaa0Shylee goto end; 2344*431deaa0Shylee } 2345*431deaa0Shylee 2346*431deaa0Shylee if (value = strpbrk(token3, SEP_EQUAL)) { 2347*431deaa0Shylee value++; /* get rid of = */ 2348*431deaa0Shylee } else { 2349*431deaa0Shylee ret = KMF_ERR_KMF_CONF; 2350*431deaa0Shylee goto end; 2351*431deaa0Shylee } 2352*431deaa0Shylee 2353*431deaa0Shylee if ((tmp->option = strdup(value)) == NULL) { 2354*431deaa0Shylee ret = KMF_ERR_MEMORY; 2355*431deaa0Shylee goto end; 2356*431deaa0Shylee } 2357*431deaa0Shylee } 2358*431deaa0Shylee 2359*431deaa0Shylee *entry = tmp; 2360*431deaa0Shylee 2361*431deaa0Shylee end: 2362*431deaa0Shylee if (ret != KMF_OK) { 2363*431deaa0Shylee free_entry(tmp); 2364*431deaa0Shylee free(tmp); 2365*431deaa0Shylee } 2366*431deaa0Shylee return (ret); 2367*431deaa0Shylee } 2368*431deaa0Shylee 2369*431deaa0Shylee 2370*431deaa0Shylee conf_entry_t * 2371*431deaa0Shylee dup_entry(conf_entry_t *entry) 2372*431deaa0Shylee { 2373*431deaa0Shylee conf_entry_t *rtn_entry; 2374*431deaa0Shylee 2375*431deaa0Shylee if (entry == NULL) 2376*431deaa0Shylee return (NULL); 2377*431deaa0Shylee 2378*431deaa0Shylee rtn_entry = malloc(sizeof (conf_entry_t)); 2379*431deaa0Shylee if (rtn_entry == NULL) 2380*431deaa0Shylee return (NULL); 2381*431deaa0Shylee 2382*431deaa0Shylee if ((rtn_entry->keystore = strdup(entry->keystore)) == NULL) 2383*431deaa0Shylee goto out; 2384*431deaa0Shylee 2385*431deaa0Shylee if ((rtn_entry->modulepath = strdup(entry->modulepath)) == NULL) 2386*431deaa0Shylee goto out; 2387*431deaa0Shylee 2388*431deaa0Shylee if (entry->option != NULL && 2389*431deaa0Shylee (rtn_entry->option = strdup(entry->modulepath)) == NULL) 2390*431deaa0Shylee goto out; 2391*431deaa0Shylee 2392*431deaa0Shylee return (rtn_entry); 2393*431deaa0Shylee 2394*431deaa0Shylee out: 2395*431deaa0Shylee free_entry(rtn_entry); 2396*431deaa0Shylee return (NULL); 2397*431deaa0Shylee } 2398*431deaa0Shylee 2399*431deaa0Shylee 2400*431deaa0Shylee /* 2401*431deaa0Shylee * This function takes a keystore_name as input and returns 2402*431deaa0Shylee * the KMF_KEYSTORE_TYPE value assigned to it. If the "option" 2403*431deaa0Shylee * argument is not NULL, this function also returns the option string 2404*431deaa0Shylee * if there is an option string for the plugin module. 2405*431deaa0Shylee */ 2406*431deaa0Shylee KMF_RETURN 2407*431deaa0Shylee kmf_get_plugin_info(KMF_HANDLE_T handle, char *keystore_name, 2408*431deaa0Shylee KMF_KEYSTORE_TYPE *kstype, char **option) 2409*431deaa0Shylee { 2410*431deaa0Shylee KMF_RETURN ret = KMF_OK; 2411*431deaa0Shylee conf_entrylist_t *phead = extra_plugin_list; 2412*431deaa0Shylee boolean_t is_default = B_TRUE; 2413*431deaa0Shylee 2414*431deaa0Shylee /* 2415*431deaa0Shylee * Although handle is not really used in the function, we will 2416*431deaa0Shylee * check the handle to make sure that kmf_intialize() is called 2417*431deaa0Shylee * before this function. 2418*431deaa0Shylee */ 2419*431deaa0Shylee if (handle == NULL || keystore_name == NULL || kstype == NULL) 2420*431deaa0Shylee return (KMF_ERR_BAD_PARAMETER); 2421*431deaa0Shylee 2422*431deaa0Shylee if (strcmp(keystore_name, "pkcs11") == 0) { 2423*431deaa0Shylee *kstype = KMF_KEYSTORE_PK11TOKEN; 2424*431deaa0Shylee } else if (strcmp(keystore_name, "file") == 0) { 2425*431deaa0Shylee *kstype = KMF_KEYSTORE_OPENSSL; 2426*431deaa0Shylee } else if (strcmp(keystore_name, "nss") == 0) { 2427*431deaa0Shylee *kstype = KMF_KEYSTORE_NSS; 2428*431deaa0Shylee } else { 2429*431deaa0Shylee is_default = B_FALSE; 2430*431deaa0Shylee } 2431*431deaa0Shylee 2432*431deaa0Shylee if (is_default) { 2433*431deaa0Shylee if (option != NULL) 2434*431deaa0Shylee *option = NULL; 2435*431deaa0Shylee goto out; 2436*431deaa0Shylee } 2437*431deaa0Shylee 2438*431deaa0Shylee /* Not a built-in plugin; check if it is in extra_plugin_list. */ 2439*431deaa0Shylee while (phead != NULL) { 2440*431deaa0Shylee if (strcmp(phead->entry->keystore, keystore_name) == 0) 2441*431deaa0Shylee break; 2442*431deaa0Shylee phead = phead->next; 2443*431deaa0Shylee } 2444*431deaa0Shylee 2445*431deaa0Shylee if (phead == NULL) { 2446*431deaa0Shylee ret = KMF_ERR_PLUGIN_NOTFOUND; 2447*431deaa0Shylee goto out; 2448*431deaa0Shylee } 2449*431deaa0Shylee 2450*431deaa0Shylee /* found it */ 2451*431deaa0Shylee *kstype = phead->entry->kstype; 2452*431deaa0Shylee if (option != NULL) { 2453*431deaa0Shylee if (phead->entry->option == NULL) 2454*431deaa0Shylee *option = NULL; 2455*431deaa0Shylee else { 2456*431deaa0Shylee *option = strdup(phead->entry->option); 2457*431deaa0Shylee if (*option == NULL) { 2458*431deaa0Shylee ret = KMF_ERR_MEMORY; 2459*431deaa0Shylee goto out; 2460*431deaa0Shylee } 2461*431deaa0Shylee } 2462*431deaa0Shylee } 2463*431deaa0Shylee 2464*431deaa0Shylee out: 2465*431deaa0Shylee return (ret); 2466*431deaa0Shylee } 2467*431deaa0Shylee 2468*431deaa0Shylee /* 2469*431deaa0Shylee * Retrieve the non-default plugin list from the kmf.conf file. 2470*431deaa0Shylee */ 2471*431deaa0Shylee KMF_RETURN 2472*431deaa0Shylee get_entrylist(conf_entrylist_t **entlist) 2473*431deaa0Shylee { 2474*431deaa0Shylee KMF_RETURN rv = KMF_OK; 2475*431deaa0Shylee FILE *pfile; 2476*431deaa0Shylee conf_entry_t *entry; 2477*431deaa0Shylee conf_entrylist_t *rtnlist = NULL; 2478*431deaa0Shylee conf_entrylist_t *ptmp; 2479*431deaa0Shylee conf_entrylist_t *pcur; 2480*431deaa0Shylee char buffer[MAXPATHLEN]; 2481*431deaa0Shylee size_t len; 2482*431deaa0Shylee 2483*431deaa0Shylee if ((pfile = fopen(_PATH_KMF_CONF, "rF")) == NULL) { 2484*431deaa0Shylee cryptoerror(LOG_ERR, "failed to open %s.\n", _PATH_KMF_CONF); 2485*431deaa0Shylee return (KMF_ERR_KMF_CONF); 2486*431deaa0Shylee } 2487*431deaa0Shylee 2488*431deaa0Shylee while (fgets(buffer, MAXPATHLEN, pfile) != NULL) { 2489*431deaa0Shylee if (buffer[0] == '#' || buffer[0] == ' ' || 2490*431deaa0Shylee buffer[0] == '\n'|| buffer[0] == '\t') { 2491*431deaa0Shylee continue; /* ignore comment lines */ 2492*431deaa0Shylee } 2493*431deaa0Shylee 2494*431deaa0Shylee len = strlen(buffer); 2495*431deaa0Shylee if (buffer[len-1] == '\n') { /* get rid of trailing '\n' */ 2496*431deaa0Shylee len--; 2497*431deaa0Shylee } 2498*431deaa0Shylee buffer[len] = '\0'; 2499*431deaa0Shylee 2500*431deaa0Shylee rv = parse_entry(buffer, &entry); 2501*431deaa0Shylee if (rv != KMF_OK) { 2502*431deaa0Shylee goto end; 2503*431deaa0Shylee } 2504*431deaa0Shylee 2505*431deaa0Shylee if ((ptmp = malloc(sizeof (conf_entrylist_t))) == NULL) { 2506*431deaa0Shylee rv = KMF_ERR_MEMORY; 2507*431deaa0Shylee goto end; 2508*431deaa0Shylee } 2509*431deaa0Shylee ptmp->entry = entry; 2510*431deaa0Shylee ptmp->next = NULL; 2511*431deaa0Shylee 2512*431deaa0Shylee if (rtnlist == NULL) { 2513*431deaa0Shylee rtnlist = pcur = ptmp; 2514*431deaa0Shylee } else { 2515*431deaa0Shylee pcur->next = ptmp; 2516*431deaa0Shylee pcur = ptmp; 2517*431deaa0Shylee } 2518*431deaa0Shylee } 2519*431deaa0Shylee 2520*431deaa0Shylee end: 2521*431deaa0Shylee (void) fclose(pfile); 2522*431deaa0Shylee 2523*431deaa0Shylee if (rv == KMF_OK) { 2524*431deaa0Shylee *entlist = rtnlist; 2525*431deaa0Shylee } else if (rtnlist != NULL) { 2526*431deaa0Shylee free_entrylist(rtnlist); 2527*431deaa0Shylee *entlist = NULL; 2528*431deaa0Shylee kstore_num = DEFAULT_KEYSTORE_NUM; 2529*431deaa0Shylee } 2530*431deaa0Shylee 2531*431deaa0Shylee return (rv); 2532*431deaa0Shylee } 2533*431deaa0Shylee 2534*431deaa0Shylee 2535*431deaa0Shylee boolean_t 2536*431deaa0Shylee is_valid_keystore_type(KMF_KEYSTORE_TYPE kstype) 2537*431deaa0Shylee { 2538*431deaa0Shylee 2539*431deaa0Shylee if (kstype > 0 && kstype <= kstore_num) 2540*431deaa0Shylee return (B_TRUE); 2541*431deaa0Shylee else 2542*431deaa0Shylee return (B_FALSE); 2543*431deaa0Shylee } 2544*431deaa0Shylee 2545*431deaa0Shylee 254630a5e8faSwyllys /* 254730a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 254830a5e8faSwyllys */ 254930a5e8faSwyllys KMF_RETURN 255030a5e8faSwyllys KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 255130a5e8faSwyllys { 255230a5e8faSwyllys 255330a5e8faSwyllys KMF_ATTRIBUTE attlist[32]; 255430a5e8faSwyllys int i = 0; 255530a5e8faSwyllys 255630a5e8faSwyllys if (params == NULL) 255730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 255830a5e8faSwyllys 255930a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 256030a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, ¶ms->kstype, sizeof (params->kstype)); 256130a5e8faSwyllys i++; 256230a5e8faSwyllys 256330a5e8faSwyllys if (params->kstype == KMF_KEYSTORE_NSS) { 256430a5e8faSwyllys if (params->nssconfig.configdir != NULL) { 256530a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 256630a5e8faSwyllys KMF_DIRPATH_ATTR, 256730a5e8faSwyllys params->nssconfig.configdir, 256830a5e8faSwyllys strlen(params->nssconfig.configdir)); 256930a5e8faSwyllys i++; 257030a5e8faSwyllys } 257130a5e8faSwyllys if (params->nssconfig.certPrefix != NULL) { 257230a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 257330a5e8faSwyllys KMF_CERTPREFIX_ATTR, 257430a5e8faSwyllys params->nssconfig.certPrefix, 257530a5e8faSwyllys strlen(params->nssconfig.certPrefix)); 257630a5e8faSwyllys i++; 257730a5e8faSwyllys } 257830a5e8faSwyllys if (params->nssconfig.keyPrefix != NULL) { 257930a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 258030a5e8faSwyllys KMF_KEYPREFIX_ATTR, 258130a5e8faSwyllys params->nssconfig.keyPrefix, 258230a5e8faSwyllys strlen(params->nssconfig.keyPrefix)); 258330a5e8faSwyllys i++; 258430a5e8faSwyllys } 258530a5e8faSwyllys if (params->nssconfig.secModName != NULL) { 258630a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 258730a5e8faSwyllys KMF_SECMODNAME_ATTR, 258830a5e8faSwyllys params->nssconfig.secModName, 258930a5e8faSwyllys strlen(params->nssconfig.secModName)); 259030a5e8faSwyllys i++; 259130a5e8faSwyllys } 259230a5e8faSwyllys } else if (params->kstype == KMF_KEYSTORE_PK11TOKEN) { 259330a5e8faSwyllys if (params->pkcs11config.label != NULL) { 259430a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 259530a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, 259630a5e8faSwyllys params->pkcs11config.label, 259730a5e8faSwyllys strlen(params->pkcs11config.label)); 259830a5e8faSwyllys i++; 259930a5e8faSwyllys } 260030a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 260130a5e8faSwyllys KMF_READONLY_ATTR, 260230a5e8faSwyllys ¶ms->pkcs11config.readonly, 260330a5e8faSwyllys sizeof (params->pkcs11config.readonly)); 260430a5e8faSwyllys i++; 260530a5e8faSwyllys } 260630a5e8faSwyllys 260730a5e8faSwyllys return (kmf_configure_keystore(handle, i, attlist)); 260830a5e8faSwyllys } 260930a5e8faSwyllys 261030a5e8faSwyllys /* 261130a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 261230a5e8faSwyllys */ 261330a5e8faSwyllys KMF_RETURN 261430a5e8faSwyllys KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 261530a5e8faSwyllys { 261630a5e8faSwyllys return (kmf_initialize(outhandle, policyfile, policyname)); 261730a5e8faSwyllys } 261830a5e8faSwyllys 261930a5e8faSwyllys /* 262030a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 262130a5e8faSwyllys */ 262230a5e8faSwyllys KMF_RETURN 262330a5e8faSwyllys KMF_Finalize(KMF_HANDLE_T handle) 262430a5e8faSwyllys { 262530a5e8faSwyllys return (kmf_finalize(handle)); 262630a5e8faSwyllys } 262730a5e8faSwyllys 262830a5e8faSwyllys /* 262930a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 263030a5e8faSwyllys */ 263130a5e8faSwyllys KMF_RETURN 263230a5e8faSwyllys KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) 263330a5e8faSwyllys { 263430a5e8faSwyllys return (kmf_get_kmf_error_str(errcode, errmsg)); 263530a5e8faSwyllys } 263630a5e8faSwyllys 263730a5e8faSwyllys /* 263830a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 263930a5e8faSwyllys */ 264030a5e8faSwyllys KMF_RETURN 264130a5e8faSwyllys KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 264230a5e8faSwyllys { 264330a5e8faSwyllys return (kmf_read_input_file(handle, filename, pdata)); 264430a5e8faSwyllys } 264530a5e8faSwyllys 264630a5e8faSwyllys 264730a5e8faSwyllys /* 264830a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 264930a5e8faSwyllys */ 265030a5e8faSwyllys void 265130a5e8faSwyllys KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 265230a5e8faSwyllys { 265330a5e8faSwyllys kmf_free_kmf_cert(handle, kmf_cert); 265430a5e8faSwyllys } 265530a5e8faSwyllys 265630a5e8faSwyllys /* 265730a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 265830a5e8faSwyllys */ 265930a5e8faSwyllys void 266030a5e8faSwyllys KMF_FreeData(KMF_DATA *datablock) 266130a5e8faSwyllys { 266230a5e8faSwyllys kmf_free_data(datablock); 266330a5e8faSwyllys } 266430a5e8faSwyllys 266530a5e8faSwyllys /* 266630a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 266730a5e8faSwyllys */ 266830a5e8faSwyllys void 266930a5e8faSwyllys KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 267030a5e8faSwyllys { 267130a5e8faSwyllys kmf_free_kmf_key(handle, key); 267230a5e8faSwyllys } 267330a5e8faSwyllys 267430a5e8faSwyllys /* 267530a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 267630a5e8faSwyllys */ 267730a5e8faSwyllys void 267830a5e8faSwyllys KMF_FreeSignedCSR(KMF_CSR_DATA *csr) 267930a5e8faSwyllys { 268030a5e8faSwyllys kmf_free_signed_csr(csr); 268130a5e8faSwyllys } 2682