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 157*90c85bf8Swyllys static KMF_RETURN InitializePlugin(KMF_KEYSTORE_TYPE, char *, KMF_PLUGIN **); 158*90c85bf8Swyllys static KMF_RETURN AddPlugin(KMF_HANDLE_T, KMF_PLUGIN *); 15999ebb4caSwyllys static void free_extensions(KMF_X509_EXTENSIONS *extns); 160*90c85bf8Swyllys static void DestroyPlugin(KMF_PLUGIN *); 16199ebb4caSwyllys 1629b37d296Swyllys KMF_RETURN 1639b37d296Swyllys init_pk11() 16499ebb4caSwyllys { 1659b37d296Swyllys (void) mutex_lock(&init_lock); 1669b37d296Swyllys if (!pkcs11_initialized) { 1679b37d296Swyllys CK_RV rv = C_Initialize(NULL); 1689b37d296Swyllys if ((rv != CKR_OK) && 1699b37d296Swyllys (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 1709b37d296Swyllys (void) mutex_unlock(&init_lock); 1719b37d296Swyllys return (KMF_ERR_UNINITIALIZED); 1729b37d296Swyllys } else { 1739b37d296Swyllys pkcs11_initialized = 1; 1749b37d296Swyllys } 1759b37d296Swyllys } 1769b37d296Swyllys (void) mutex_unlock(&init_lock); 1779b37d296Swyllys return (KMF_OK); 17899ebb4caSwyllys } 17999ebb4caSwyllys 18099ebb4caSwyllys /* 18199ebb4caSwyllys * Private method for searching the plugin list for the correct 18299ebb4caSwyllys * Plugin to use. 18399ebb4caSwyllys */ 18499ebb4caSwyllys KMF_PLUGIN * 18599ebb4caSwyllys FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype) 18699ebb4caSwyllys { 18799ebb4caSwyllys KMF_PLUGIN_LIST *node; 188*90c85bf8Swyllys KMF_RETURN ret = KMF_OK; 18999ebb4caSwyllys 19099ebb4caSwyllys if (handle == NULL) 19199ebb4caSwyllys return (NULL); 19299ebb4caSwyllys 19399ebb4caSwyllys node = handle->plugins; 19499ebb4caSwyllys 195*90c85bf8Swyllys /* See if the desired plugin was already initialized. */ 19699ebb4caSwyllys while (node != NULL && node->plugin->type != kstype) 19799ebb4caSwyllys node = node->next; 19899ebb4caSwyllys 199*90c85bf8Swyllys /* If the plugin was not found, try to initialize it here. */ 200*90c85bf8Swyllys if (node == NULL) { 201*90c85bf8Swyllys int i; 202*90c85bf8Swyllys KMF_PLUGIN *pluginrec = NULL; 203*90c85bf8Swyllys int numitems = sizeof (plugin_list)/sizeof (KMF_PLUGIN_ITEM); 204*90c85bf8Swyllys for (i = 0; i < numitems; i++) { 205*90c85bf8Swyllys if (plugin_list[i].kstype == kstype) { 206*90c85bf8Swyllys ret = InitializePlugin(plugin_list[i].kstype, 207*90c85bf8Swyllys plugin_list[i].path, &pluginrec); 208*90c85bf8Swyllys break; 209*90c85bf8Swyllys } 210*90c85bf8Swyllys } 211*90c85bf8Swyllys 212*90c85bf8Swyllys /* No matching plugins found in the available list */ 213*90c85bf8Swyllys if (ret != KMF_OK || pluginrec == NULL) 214*90c85bf8Swyllys return (NULL); 215*90c85bf8Swyllys 216*90c85bf8Swyllys ret = AddPlugin(handle, pluginrec); 217*90c85bf8Swyllys if (ret != KMF_OK) { 218*90c85bf8Swyllys DestroyPlugin(pluginrec); 219*90c85bf8Swyllys pluginrec = NULL; 220*90c85bf8Swyllys } 221*90c85bf8Swyllys return (pluginrec); 222*90c85bf8Swyllys } else { 223*90c85bf8Swyllys return (node->plugin); 224*90c85bf8Swyllys } 22599ebb4caSwyllys } 22699ebb4caSwyllys 22799ebb4caSwyllys static KMF_RETURN 22899ebb4caSwyllys InitializePlugin(KMF_KEYSTORE_TYPE kstype, char *path, KMF_PLUGIN **plugin) 22999ebb4caSwyllys { 23099ebb4caSwyllys KMF_PLUGIN *p = NULL; 23199ebb4caSwyllys KMF_PLUGIN_FUNCLIST *(*sym)(); 23299ebb4caSwyllys 23399ebb4caSwyllys if (path == NULL || plugin == NULL) 23499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 23599ebb4caSwyllys 23699ebb4caSwyllys *plugin = NULL; 23799ebb4caSwyllys 23899ebb4caSwyllys p = (KMF_PLUGIN *)malloc(sizeof (KMF_PLUGIN)); 23999ebb4caSwyllys if (p == NULL) 24099ebb4caSwyllys return (KMF_ERR_MEMORY); 24199ebb4caSwyllys 24299ebb4caSwyllys p->type = kstype; 24399ebb4caSwyllys p->path = strdup(path); 24499ebb4caSwyllys if (p->path == NULL) { 24599ebb4caSwyllys free(p); 24699ebb4caSwyllys return (KMF_ERR_MEMORY); 24799ebb4caSwyllys } 248*90c85bf8Swyllys p->dldesc = dlopen(path, RTLD_LAZY | RTLD_GROUP | RTLD_PARENT); 24999ebb4caSwyllys if (p->dldesc == NULL) { 25099ebb4caSwyllys free(p->path); 25199ebb4caSwyllys free(p); 25299ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 25399ebb4caSwyllys } 25499ebb4caSwyllys 25599ebb4caSwyllys sym = (KMF_PLUGIN_FUNCLIST *(*)())dlsym(p->dldesc, 25630a5e8faSwyllys KMF_PLUGIN_INIT_SYMBOL); 25799ebb4caSwyllys if (sym == NULL) { 25899ebb4caSwyllys (void) dlclose(p->dldesc); 25999ebb4caSwyllys free(p->path); 26099ebb4caSwyllys free(p); 26199ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 26299ebb4caSwyllys } 26399ebb4caSwyllys 26499ebb4caSwyllys /* Get the function list */ 26599ebb4caSwyllys if ((p->funclist = (*sym)()) == NULL) { 26699ebb4caSwyllys (void) dlclose(p->dldesc); 26799ebb4caSwyllys free(p->path); 26899ebb4caSwyllys free(p); 26999ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 27099ebb4caSwyllys } 27199ebb4caSwyllys 27299ebb4caSwyllys *plugin = p; 27399ebb4caSwyllys 27499ebb4caSwyllys return (KMF_OK); 27599ebb4caSwyllys } 27699ebb4caSwyllys 27799ebb4caSwyllys static KMF_RETURN 27899ebb4caSwyllys AddPlugin(KMF_HANDLE_T handle, KMF_PLUGIN *plugin) 27999ebb4caSwyllys { 28099ebb4caSwyllys KMF_PLUGIN_LIST *n; 28199ebb4caSwyllys 28299ebb4caSwyllys if (handle == NULL || plugin == NULL) 28399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 28499ebb4caSwyllys 28599ebb4caSwyllys /* If the head is NULL, create it */ 28699ebb4caSwyllys if (handle->plugins == NULL) { 28799ebb4caSwyllys handle->plugins = (KMF_PLUGIN_LIST *)malloc( 28830a5e8faSwyllys sizeof (KMF_PLUGIN_LIST)); 28999ebb4caSwyllys if (handle->plugins == NULL) 29099ebb4caSwyllys return (KMF_ERR_MEMORY); 29199ebb4caSwyllys handle->plugins->plugin = plugin; 29299ebb4caSwyllys handle->plugins->next = NULL; 29399ebb4caSwyllys } else { 29499ebb4caSwyllys /* walk the list to find the tail */ 29599ebb4caSwyllys n = handle->plugins; 29699ebb4caSwyllys while (n->next != NULL) 29799ebb4caSwyllys n = n->next; 29899ebb4caSwyllys n->next = (KMF_PLUGIN_LIST *)malloc(sizeof (KMF_PLUGIN_LIST)); 29999ebb4caSwyllys if (n->next == NULL) 30099ebb4caSwyllys return (KMF_ERR_MEMORY); 30199ebb4caSwyllys 30299ebb4caSwyllys n->next->plugin = plugin; 30399ebb4caSwyllys n->next->next = NULL; 30499ebb4caSwyllys } 30599ebb4caSwyllys return (0); 30699ebb4caSwyllys } 30799ebb4caSwyllys 30899ebb4caSwyllys static void 30999ebb4caSwyllys DestroyPlugin(KMF_PLUGIN *plugin) 31099ebb4caSwyllys { 31199ebb4caSwyllys if (plugin) { 31299ebb4caSwyllys if (plugin->path) 31399ebb4caSwyllys free(plugin->path); 31499ebb4caSwyllys free(plugin); 31599ebb4caSwyllys } 31699ebb4caSwyllys } 31799ebb4caSwyllys 31899ebb4caSwyllys static void 31999ebb4caSwyllys Cleanup_KMF_Handle(KMF_HANDLE_T handle) 32099ebb4caSwyllys { 32199ebb4caSwyllys if (handle != NULL) { 32299ebb4caSwyllys while (handle->plugins != NULL) { 32399ebb4caSwyllys KMF_PLUGIN_LIST *next = handle->plugins->next; 32499ebb4caSwyllys 32599ebb4caSwyllys DestroyPlugin(handle->plugins->plugin); 32699ebb4caSwyllys free(handle->plugins); 32799ebb4caSwyllys handle->plugins = next; 32899ebb4caSwyllys } 32930a5e8faSwyllys kmf_free_policy_record(handle->policy); 33099ebb4caSwyllys free(handle->policy); 33199ebb4caSwyllys } 33299ebb4caSwyllys free(handle); 33399ebb4caSwyllys } 33499ebb4caSwyllys 33599ebb4caSwyllys void 33699ebb4caSwyllys Cleanup_PK11_Session(KMF_HANDLE_T handle) 33799ebb4caSwyllys { 33899ebb4caSwyllys if (handle != NULL) { 33999ebb4caSwyllys /* Close active session on a pkcs11 token */ 34099ebb4caSwyllys if (handle->pk11handle != NULL) { 34199ebb4caSwyllys (void) C_CloseSession(handle->pk11handle); 34299ebb4caSwyllys handle->pk11handle = NULL; 34399ebb4caSwyllys } 34499ebb4caSwyllys } 34599ebb4caSwyllys } 34699ebb4caSwyllys 34799ebb4caSwyllys KMF_RETURN 34830a5e8faSwyllys kmf_initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 34999ebb4caSwyllys { 35099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 35199ebb4caSwyllys KMF_HANDLE *handle = NULL; 35299ebb4caSwyllys 35399ebb4caSwyllys if (outhandle == NULL) 35499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 35599ebb4caSwyllys 35699ebb4caSwyllys *outhandle = NULL; 35799ebb4caSwyllys handle = (KMF_HANDLE *)malloc(sizeof (KMF_HANDLE)); 35899ebb4caSwyllys if (handle == NULL) 35999ebb4caSwyllys return (KMF_ERR_MEMORY); 36099ebb4caSwyllys 36199ebb4caSwyllys (void) memset(handle, 0, sizeof (KMF_HANDLE)); 36299ebb4caSwyllys handle->plugins = NULL; 36399ebb4caSwyllys 36499ebb4caSwyllys /* Initialize the handle with the policy */ 36530a5e8faSwyllys ret = kmf_set_policy((void *)handle, 36699ebb4caSwyllys policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile, 36799ebb4caSwyllys policyname == NULL ? KMF_DEFAULT_POLICY_NAME : policyname); 36899ebb4caSwyllys if (ret != KMF_OK) 36999ebb4caSwyllys goto errout; 37099ebb4caSwyllys 37199ebb4caSwyllys CLEAR_ERROR(handle, ret); 37299ebb4caSwyllys errout: 37399ebb4caSwyllys if (ret != KMF_OK) { 37499ebb4caSwyllys Cleanup_KMF_Handle(handle); 37599ebb4caSwyllys handle = NULL; 37699ebb4caSwyllys } 37799ebb4caSwyllys 37899ebb4caSwyllys *outhandle = (KMF_HANDLE_T)handle; 37999ebb4caSwyllys return (ret); 38099ebb4caSwyllys } 38199ebb4caSwyllys 38299ebb4caSwyllys KMF_RETURN 38330a5e8faSwyllys kmf_configure_keystore(KMF_HANDLE_T handle, 38430a5e8faSwyllys int num_args, 38530a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 38699ebb4caSwyllys { 38730a5e8faSwyllys KMF_RETURN ret = KMF_OK; 38899ebb4caSwyllys KMF_PLUGIN *plugin; 38930a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 39030a5e8faSwyllys uint32_t len; 39130a5e8faSwyllys 39230a5e8faSwyllys KMF_ATTRIBUTE_TESTER required_attrs[] = { 39330a5e8faSwyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 39430a5e8faSwyllys }; 39530a5e8faSwyllys 39630a5e8faSwyllys int num_req_attrs = sizeof (required_attrs) / 39730a5e8faSwyllys sizeof (KMF_ATTRIBUTE_TESTER); 39830a5e8faSwyllys 39930a5e8faSwyllys if (handle == NULL) 40030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 40199ebb4caSwyllys 40299ebb4caSwyllys CLEAR_ERROR(handle, ret); 40330a5e8faSwyllys 40430a5e8faSwyllys ret = test_attributes(num_req_attrs, required_attrs, 40530a5e8faSwyllys 0, NULL, num_args, attrlist); 40630a5e8faSwyllys 40799ebb4caSwyllys if (ret != KMF_OK) 40899ebb4caSwyllys return (ret); 40999ebb4caSwyllys 41030a5e8faSwyllys len = sizeof (kstype); 41130a5e8faSwyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, 41230a5e8faSwyllys &kstype, &len); 41330a5e8faSwyllys if (ret != KMF_OK) 41430a5e8faSwyllys return (ret); 41599ebb4caSwyllys 41630a5e8faSwyllys plugin = FindPlugin(handle, kstype); 41730a5e8faSwyllys if (plugin != NULL && plugin->funclist->ConfigureKeystore != NULL) { 41830a5e8faSwyllys return (plugin->funclist->ConfigureKeystore(handle, num_args, 41930a5e8faSwyllys attrlist)); 42030a5e8faSwyllys } else { 42199ebb4caSwyllys /* return KMF_OK, if the plugin does not have an entry */ 42299ebb4caSwyllys return (KMF_OK); 42330a5e8faSwyllys } 42499ebb4caSwyllys } 42599ebb4caSwyllys 42699ebb4caSwyllys KMF_RETURN 42730a5e8faSwyllys kmf_finalize(KMF_HANDLE_T handle) 42899ebb4caSwyllys { 42999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 43099ebb4caSwyllys 43199ebb4caSwyllys CLEAR_ERROR(handle, ret); 43299ebb4caSwyllys if (ret != KMF_OK) 43399ebb4caSwyllys return (ret); 43499ebb4caSwyllys 43599ebb4caSwyllys if (pkcs11_initialized) { 43699ebb4caSwyllys Cleanup_PK11_Session(handle); 43799ebb4caSwyllys } 43899ebb4caSwyllys Cleanup_KMF_Handle(handle); 43999ebb4caSwyllys 44099ebb4caSwyllys return (ret); 44199ebb4caSwyllys } 44299ebb4caSwyllys 44399ebb4caSwyllys KMF_RETURN 44430a5e8faSwyllys kmf_get_kmf_error_str(KMF_RETURN errcode, char **errmsg) 44599ebb4caSwyllys { 44699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 44799ebb4caSwyllys int i, maxerr; 44899ebb4caSwyllys 44999ebb4caSwyllys if (errmsg == NULL) 45099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 45199ebb4caSwyllys 45299ebb4caSwyllys *errmsg = NULL; 45399ebb4caSwyllys maxerr = sizeof (kmf_errcodes) / sizeof (kmf_error_map); 45499ebb4caSwyllys 45530a5e8faSwyllys for (i = 0; i < maxerr && errcode != kmf_errcodes[i].code; i++) 45630a5e8faSwyllys /* empty body */ 45730a5e8faSwyllys ; 45899ebb4caSwyllys 45999ebb4caSwyllys if (i == maxerr) 46099ebb4caSwyllys return (KMF_ERR_MISSING_ERRCODE); 46199ebb4caSwyllys else { 46299ebb4caSwyllys *errmsg = strdup(kmf_errcodes[i].message); 46399ebb4caSwyllys if ((*errmsg) == NULL) 46499ebb4caSwyllys return (KMF_ERR_MEMORY); 46599ebb4caSwyllys } 46699ebb4caSwyllys return (ret); 46799ebb4caSwyllys } 46899ebb4caSwyllys 46999ebb4caSwyllys KMF_RETURN 47030a5e8faSwyllys kmf_get_plugin_error_str(KMF_HANDLE_T handle, char **msgstr) 47199ebb4caSwyllys { 47299ebb4caSwyllys KMF_RETURN ret = KMF_OK; 47399ebb4caSwyllys KMF_PLUGIN *plugin; 47499ebb4caSwyllys 47599ebb4caSwyllys if (handle == NULL || msgstr == NULL) 47699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 47799ebb4caSwyllys 47899ebb4caSwyllys *msgstr = NULL; 47999ebb4caSwyllys 48099ebb4caSwyllys if (handle->lasterr.errcode == 0) { 48199ebb4caSwyllys return (KMF_ERR_MISSING_ERRCODE); 48299ebb4caSwyllys } 48399ebb4caSwyllys 48499ebb4caSwyllys if (handle->lasterr.kstype == -1) { /* System error */ 48599ebb4caSwyllys char *str = strerror(handle->lasterr.errcode); 48699ebb4caSwyllys if (str != NULL) { 48799ebb4caSwyllys *msgstr = strdup(str); 48899ebb4caSwyllys if ((*msgstr) == NULL) 48999ebb4caSwyllys return (KMF_ERR_MEMORY); 49099ebb4caSwyllys } 49199ebb4caSwyllys return (KMF_OK); 49299ebb4caSwyllys } 49399ebb4caSwyllys 49499ebb4caSwyllys plugin = FindPlugin(handle, handle->lasterr.kstype); 49599ebb4caSwyllys if (plugin == NULL) 49699ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 49799ebb4caSwyllys 49899ebb4caSwyllys if (plugin->funclist->GetErrorString != NULL) { 49999ebb4caSwyllys ret = plugin->funclist->GetErrorString(handle, msgstr); 50099ebb4caSwyllys } else { 50199ebb4caSwyllys return (KMF_ERR_FUNCTION_NOT_FOUND); 50299ebb4caSwyllys } 50399ebb4caSwyllys 50499ebb4caSwyllys return (ret); 50599ebb4caSwyllys } 50699ebb4caSwyllys 50799ebb4caSwyllys 5089b37d296Swyllys #define SET_SYS_ERROR(h, c) if (h) {\ 5099b37d296Swyllys h->lasterr.kstype = -1;\ 5109b37d296Swyllys h->lasterr.errcode = c;\ 5119b37d296Swyllys } 51299ebb4caSwyllys 51399ebb4caSwyllys KMF_RETURN 51430a5e8faSwyllys kmf_read_input_file(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 51599ebb4caSwyllys { 51699ebb4caSwyllys struct stat s; 51799ebb4caSwyllys long nread, total = 0; 51899ebb4caSwyllys int fd; 51999ebb4caSwyllys unsigned char *buf = NULL; 52099ebb4caSwyllys KMF_RETURN ret; 52199ebb4caSwyllys 5229b37d296Swyllys if (handle) { 5239b37d296Swyllys CLEAR_ERROR(handle, ret); 5249b37d296Swyllys if (ret != KMF_OK) 5259b37d296Swyllys return (ret); 5269b37d296Swyllys } 52799ebb4caSwyllys 52899ebb4caSwyllys if (filename == NULL || pdata == NULL) { 52999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 53099ebb4caSwyllys } 53199ebb4caSwyllys 53299ebb4caSwyllys if ((fd = open(filename, O_RDONLY)) < 0) { 53399ebb4caSwyllys SET_SYS_ERROR(handle, errno); 53499ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 53599ebb4caSwyllys } 53699ebb4caSwyllys 53799ebb4caSwyllys if (fstat(fd, &s) < 0) { 53899ebb4caSwyllys SET_SYS_ERROR(handle, errno); 53999ebb4caSwyllys (void) close(fd); 54099ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 54199ebb4caSwyllys } 54299ebb4caSwyllys 54399ebb4caSwyllys if ((buf = (unsigned char *) malloc(s.st_size)) == NULL) { 54499ebb4caSwyllys (void) close(fd); 54599ebb4caSwyllys return (KMF_ERR_MEMORY); 54699ebb4caSwyllys } 54799ebb4caSwyllys 54899ebb4caSwyllys do { 54999ebb4caSwyllys nread = read(fd, buf+total, s.st_size-total); 55099ebb4caSwyllys if (nread < 0) { 55199ebb4caSwyllys SET_SYS_ERROR(handle, errno); 55299ebb4caSwyllys (void) close(fd); 55399ebb4caSwyllys free(buf); 55499ebb4caSwyllys return (KMF_ERR_INTERNAL); 55599ebb4caSwyllys } 55699ebb4caSwyllys total += nread; 55799ebb4caSwyllys } while (total < s.st_size); 55899ebb4caSwyllys 55999ebb4caSwyllys pdata->Data = buf; 56099ebb4caSwyllys pdata->Length = s.st_size; 56199ebb4caSwyllys (void) close(fd); 56299ebb4caSwyllys return (KMF_OK); 56399ebb4caSwyllys } 56499ebb4caSwyllys 56599ebb4caSwyllys /* 56699ebb4caSwyllys * 56730a5e8faSwyllys * Name: kmf_der_to_pem 56899ebb4caSwyllys * 56999ebb4caSwyllys * Description: 57099ebb4caSwyllys * Function for converting DER encoded format to PEM encoded format 57199ebb4caSwyllys * 57299ebb4caSwyllys * Parameters: 57399ebb4caSwyllys * type(input) - CERTIFICATE or CSR 57499ebb4caSwyllys * data(input) - pointer to the DER encoded data 57599ebb4caSwyllys * len(input) - length of input data 57699ebb4caSwyllys * out(output) - contains the output buffer address to be returned 57799ebb4caSwyllys * outlen(output) - pointer to the returned output length 57899ebb4caSwyllys * 57999ebb4caSwyllys * Returns: 58099ebb4caSwyllys * A KMF_RETURN value indicating success or specifying a particular 58199ebb4caSwyllys * error condition. 58299ebb4caSwyllys * The value KMF_OK indicates success. All other values represent 58399ebb4caSwyllys * an error condition. 58499ebb4caSwyllys * 58599ebb4caSwyllys */ 58699ebb4caSwyllys KMF_RETURN 58730a5e8faSwyllys kmf_der_to_pem(KMF_OBJECT_TYPE type, unsigned char *data, 58899ebb4caSwyllys int len, unsigned char **out, int *outlen) 58999ebb4caSwyllys { 59099ebb4caSwyllys 59199ebb4caSwyllys KMF_RETURN err; 59299ebb4caSwyllys if (data == NULL || out == NULL || outlen == NULL) 59399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 59499ebb4caSwyllys 59599ebb4caSwyllys err = Der2Pem(type, data, len, out, outlen); 59699ebb4caSwyllys return (err); 59799ebb4caSwyllys 59899ebb4caSwyllys } 59999ebb4caSwyllys 60099ebb4caSwyllys /* 60199ebb4caSwyllys * 60230a5e8faSwyllys * Name: kmf_pem_to_der 60399ebb4caSwyllys * 60499ebb4caSwyllys * Description: 60599ebb4caSwyllys * Function for converting PEM encoded format to DER encoded format 60699ebb4caSwyllys * 60799ebb4caSwyllys * Parameters: 60899ebb4caSwyllys * in(input) - pointer to the PEM encoded data 60999ebb4caSwyllys * inlen(input) - length of input data 61099ebb4caSwyllys * out(output) - contains the output buffer address to be returned 61199ebb4caSwyllys * outlen(output) - pointer to the returned output length 61299ebb4caSwyllys * 61399ebb4caSwyllys * Returns: 61499ebb4caSwyllys * A KMF_RETURN value indicating success or specifying a particular 61599ebb4caSwyllys * error condition. 61699ebb4caSwyllys * The value KMF_OK indicates success. All other values represent 61799ebb4caSwyllys * an error condition. 61899ebb4caSwyllys * 61999ebb4caSwyllys */ 62099ebb4caSwyllys KMF_RETURN 62130a5e8faSwyllys kmf_pem_to_der(unsigned char *in, int inlen, 62299ebb4caSwyllys unsigned char **out, int *outlen) 62399ebb4caSwyllys { 62499ebb4caSwyllys KMF_RETURN err; 62599ebb4caSwyllys if (in == NULL || out == NULL || outlen == NULL) 62699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 62799ebb4caSwyllys 62899ebb4caSwyllys err = Pem2Der(in, inlen, out, outlen); 62999ebb4caSwyllys return (err); 63099ebb4caSwyllys } 63199ebb4caSwyllys 63299ebb4caSwyllys char * 63330a5e8faSwyllys kmf_oid_to_string(KMF_OID *oid) 63499ebb4caSwyllys { 63599ebb4caSwyllys char numstr[128]; 63699ebb4caSwyllys uint32_t number; 63799ebb4caSwyllys int numshift; 63899ebb4caSwyllys uint32_t i, string_length; 63999ebb4caSwyllys uchar_t *cp; 64099ebb4caSwyllys char *bp; 64199ebb4caSwyllys 64299ebb4caSwyllys /* First determine the size of the string */ 64399ebb4caSwyllys string_length = 0; 64499ebb4caSwyllys number = 0; 64599ebb4caSwyllys numshift = 0; 64699ebb4caSwyllys cp = (unsigned char *)oid->Data; 64799ebb4caSwyllys 64899ebb4caSwyllys number = (uint32_t)cp[0]; 64999ebb4caSwyllys (void) sprintf(numstr, "%d ", number/40); 65099ebb4caSwyllys 65199ebb4caSwyllys string_length += strlen(numstr); 65299ebb4caSwyllys (void) sprintf(numstr, "%d ", number%40); 65399ebb4caSwyllys 65499ebb4caSwyllys string_length += strlen(numstr); 65599ebb4caSwyllys 65699ebb4caSwyllys for (i = 1; i < oid->Length; i++) { 65799ebb4caSwyllys if ((uint32_t)(numshift+7) < (sizeof (uint32_t)*8)) { 65899ebb4caSwyllys number = (number << 7) | (cp[i] & 0x7f); 65999ebb4caSwyllys numshift += 7; 66099ebb4caSwyllys } else { 66199ebb4caSwyllys return (NULL); 66299ebb4caSwyllys } 66399ebb4caSwyllys 66499ebb4caSwyllys if ((cp[i] & 0x80) == 0) { 66599ebb4caSwyllys (void) sprintf(numstr, "%d ", number); 66699ebb4caSwyllys string_length += strlen(numstr); 66799ebb4caSwyllys number = 0; 66899ebb4caSwyllys numshift = 0; 66999ebb4caSwyllys } 67099ebb4caSwyllys } 67199ebb4caSwyllys /* 67299ebb4caSwyllys * If we get here, we've calculated the length of "n n n ... n ". Add 4 67399ebb4caSwyllys * here for "{ " and "}\0". 67499ebb4caSwyllys */ 67599ebb4caSwyllys string_length += 4; 67699ebb4caSwyllys if ((bp = (char *)malloc(string_length))) { 67799ebb4caSwyllys number = (uint32_t)cp[0]; 67899ebb4caSwyllys 67999ebb4caSwyllys (void) sprintf(numstr, "%d.", number/40); 68099ebb4caSwyllys (void) strcpy(bp, numstr); 68199ebb4caSwyllys 68299ebb4caSwyllys (void) sprintf(numstr, "%d.", number%40); 68399ebb4caSwyllys (void) strcat(bp, numstr); 68499ebb4caSwyllys 68599ebb4caSwyllys number = 0; 68699ebb4caSwyllys cp = (unsigned char *) oid->Data; 68799ebb4caSwyllys for (i = 1; i < oid->Length; i++) { 68899ebb4caSwyllys number = (number << 7) | (cp[i] & 0x7f); 68999ebb4caSwyllys if ((cp[i] & 0x80) == 0) { 69099ebb4caSwyllys (void) sprintf(numstr, "%d", number); 69199ebb4caSwyllys (void) strcat(bp, numstr); 69299ebb4caSwyllys number = 0; 69399ebb4caSwyllys if (i+1 < oid->Length) 69499ebb4caSwyllys (void) strcat(bp, "."); 69599ebb4caSwyllys } 69699ebb4caSwyllys } 69799ebb4caSwyllys } 69899ebb4caSwyllys return (bp); 69999ebb4caSwyllys } 70099ebb4caSwyllys 70102744e81Swyllys static boolean_t 70208ec4bd3Shylee check_for_pem(uchar_t *buf, KMF_ENCODE_FORMAT *fmt) 70302744e81Swyllys { 7049b37d296Swyllys char *p; 70502744e81Swyllys 70608ec4bd3Shylee if (buf == NULL) 70702744e81Swyllys return (FALSE); 70802744e81Swyllys 70908ec4bd3Shylee if (memcmp(buf, "Bag Attr", 8) == 0) { 71008ec4bd3Shylee *fmt = KMF_FORMAT_PEM_KEYPAIR; 71108ec4bd3Shylee return (TRUE); 71208ec4bd3Shylee } 71308ec4bd3Shylee 7149b37d296Swyllys /* Look for "-----BEGIN" right after a newline */ 71508ec4bd3Shylee p = strtok((char *)buf, "\n"); 7169b37d296Swyllys while (p != NULL) { 7179b37d296Swyllys if (strstr(p, "-----BEGIN") != NULL) { 71808ec4bd3Shylee *fmt = KMF_FORMAT_PEM; 7199b37d296Swyllys return (TRUE); 72002744e81Swyllys } 7219b37d296Swyllys p = strtok(NULL, "\n"); 72202744e81Swyllys } 72302744e81Swyllys return (FALSE); 72402744e81Swyllys } 72502744e81Swyllys 72608ec4bd3Shylee 72708ec4bd3Shylee static unsigned char pkcs12_version[3] = {0x02, 0x01, 0x03}; 72808ec4bd3Shylee static unsigned char pkcs12_oid[11] = 72908ec4bd3Shylee {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01}; 73008ec4bd3Shylee 73108ec4bd3Shylee /* 73208ec4bd3Shylee * This function takes a BER encoded string as input and checks the version 73308ec4bd3Shylee * and the oid in the the top-level ASN.1 structure to see if it complies to 73408ec4bd3Shylee * the PKCS#12 Syntax. 73508ec4bd3Shylee */ 73608ec4bd3Shylee static boolean_t 73708ec4bd3Shylee check_for_pkcs12(uchar_t *buf, int buf_len) 73808ec4bd3Shylee { 73908ec4bd3Shylee int index = 0; 74008ec4bd3Shylee int length_octets; 74108ec4bd3Shylee 74208ec4bd3Shylee if (buf == NULL || buf_len <= 0) 74308ec4bd3Shylee return (FALSE); 74408ec4bd3Shylee 74508ec4bd3Shylee /* 74608ec4bd3Shylee * The top level structure for a PKCS12 string: 74708ec4bd3Shylee * 74808ec4bd3Shylee * PFX ::= SEQUENCE { 74908ec4bd3Shylee * version INTEGER {v3(3)}(v3,...) 75008ec4bd3Shylee * authSafe ContentInfo 75108ec4bd3Shylee * macData MacData OPTIONAL 75208ec4bd3Shylee * } 75308ec4bd3Shylee * 75408ec4bd3Shylee * ContentInfo 75508ec4bd3Shylee * FROM PKCS-7 {iso(1) member-body(2) us(840) rsadsi(113549) 75608ec4bd3Shylee * pkcs(1) pkcs-7(7) modules(0) pkcs-7(1)} 75708ec4bd3Shylee * 75808ec4bd3Shylee * Therefore, the BER/DER dump of a PKCS#12 file for the first 2 75908ec4bd3Shylee * sequences up to the oid part is as following: 76008ec4bd3Shylee * 76108ec4bd3Shylee * SEQUENCE { 76208ec4bd3Shylee * INTEGER 3 76308ec4bd3Shylee * SEQUENCE { 76408ec4bd3Shylee * OBJECT IDENTIFIER data (1 2 840 113549 1 7 1) 76508ec4bd3Shylee */ 76608ec4bd3Shylee 76708ec4bd3Shylee /* 76808ec4bd3Shylee * Check the first sequence and calculate the number of bytes used 76908ec4bd3Shylee * to store the length. 77008ec4bd3Shylee */ 77108ec4bd3Shylee if (buf[index++] != 0x30) 77208ec4bd3Shylee return (FALSE); 77308ec4bd3Shylee 77408ec4bd3Shylee if (buf[index] & 0x80) { 77508ec4bd3Shylee length_octets = buf[index++] & 0x0F; /* long form */ 77608ec4bd3Shylee } else { 77708ec4bd3Shylee length_octets = 1; /* short form */ 77808ec4bd3Shylee } 77908ec4bd3Shylee 78008ec4bd3Shylee index += length_octets; 78108ec4bd3Shylee if (index >= buf_len) 78208ec4bd3Shylee return (FALSE); 78308ec4bd3Shylee 78408ec4bd3Shylee /* Skip the length octets and check the pkcs12 version */ 78508ec4bd3Shylee if (memcmp(buf + index, pkcs12_version, sizeof (pkcs12_version)) != 0) 78608ec4bd3Shylee return (FALSE); 78708ec4bd3Shylee 78808ec4bd3Shylee index += sizeof (pkcs12_version); 78908ec4bd3Shylee if (index >= buf_len) 79008ec4bd3Shylee return (FALSE); 79108ec4bd3Shylee 79208ec4bd3Shylee /* 79308ec4bd3Shylee * Check the 2nd sequence and calculate the number of bytes used 79408ec4bd3Shylee * to store the length. 79508ec4bd3Shylee */ 79608ec4bd3Shylee if ((buf[index++] & 0xFF) != 0x30) 79708ec4bd3Shylee return (FALSE); 79808ec4bd3Shylee 79908ec4bd3Shylee if (buf[index] & 0x80) { 80008ec4bd3Shylee length_octets = buf[index++] & 0x0F; 80108ec4bd3Shylee } else { 80208ec4bd3Shylee length_octets = 1; 80308ec4bd3Shylee } 80408ec4bd3Shylee 80508ec4bd3Shylee index += length_octets; 80608ec4bd3Shylee if (index + sizeof (pkcs12_oid) >= buf_len) 80708ec4bd3Shylee return (FALSE); 80808ec4bd3Shylee 80908ec4bd3Shylee /* Skip the length octets and check the oid */ 81008ec4bd3Shylee if (memcmp(buf + index, pkcs12_oid, sizeof (pkcs12_oid)) != 0) 81108ec4bd3Shylee return (FALSE); 81208ec4bd3Shylee else 81308ec4bd3Shylee return (TRUE); 81408ec4bd3Shylee } 81508ec4bd3Shylee 81699ebb4caSwyllys KMF_RETURN 81730a5e8faSwyllys kmf_get_file_format(char *filename, KMF_ENCODE_FORMAT *fmt) 81899ebb4caSwyllys { 81999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 82008ec4bd3Shylee KMF_DATA filebuf = {NULL, 0}; 82108ec4bd3Shylee uchar_t *buf; 82299ebb4caSwyllys 82399ebb4caSwyllys if (filename == NULL || !strlen(filename) || fmt == NULL) 82499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 82599ebb4caSwyllys 82699ebb4caSwyllys *fmt = 0; 82730a5e8faSwyllys ret = kmf_read_input_file(NULL, filename, &filebuf); 82808ec4bd3Shylee if (ret != KMF_OK) 82908ec4bd3Shylee return (ret); 83099ebb4caSwyllys 83108ec4bd3Shylee if (filebuf.Length < 8) { 83208ec4bd3Shylee ret = KMF_ERR_ENCODING; /* too small */ 83399ebb4caSwyllys goto end; 83499ebb4caSwyllys } 83599ebb4caSwyllys 83608ec4bd3Shylee buf = filebuf.Data; 83708ec4bd3Shylee if (check_for_pkcs12(buf, filebuf.Length) == TRUE) { 83808ec4bd3Shylee *fmt = KMF_FORMAT_PKCS12; 83908ec4bd3Shylee } else if (buf[0] == 0x30 && (buf[1] & 0x80)) { 84099ebb4caSwyllys /* It is most likely a generic ASN.1 encoded file */ 84108ec4bd3Shylee *fmt = KMF_FORMAT_ASN1; 84208ec4bd3Shylee } else if (check_for_pem(buf, fmt) == TRUE) { 84308ec4bd3Shylee goto end; 84499ebb4caSwyllys } else { 84508ec4bd3Shylee /* Cannot determine this file format */ 84608ec4bd3Shylee *fmt = 0; 84708ec4bd3Shylee ret = KMF_ERR_ENCODING; 84899ebb4caSwyllys } 84908ec4bd3Shylee 85099ebb4caSwyllys end: 85130a5e8faSwyllys kmf_free_data(&filebuf); 85299ebb4caSwyllys return (ret); 85399ebb4caSwyllys } 85499ebb4caSwyllys 85599ebb4caSwyllys KMF_RETURN 85630a5e8faSwyllys kmf_hexstr_to_bytes(unsigned char *hexstr, unsigned char **bytes, 85799ebb4caSwyllys size_t *outlen) 85899ebb4caSwyllys { 85999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 86099ebb4caSwyllys unsigned char *buf = NULL; 86199ebb4caSwyllys int len, stringlen; 86299ebb4caSwyllys int i; 86399ebb4caSwyllys unsigned char ch; 86499ebb4caSwyllys 86599ebb4caSwyllys if (hexstr == NULL) { 86699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 86799ebb4caSwyllys } 86899ebb4caSwyllys 86930a5e8faSwyllys if (hexstr[0] == '0' && ((hexstr[1] == 'x') || (hexstr[1] == 'X'))) 87099ebb4caSwyllys hexstr += 2; 87199ebb4caSwyllys 87230a5e8faSwyllys for (i = 0; i < strlen((char *)hexstr) && isxdigit(hexstr[i]); i++) 87330a5e8faSwyllys /* empty body */ 87430a5e8faSwyllys ; 87599ebb4caSwyllys /* 87699ebb4caSwyllys * If all the characters are not legitimate hex chars, 87799ebb4caSwyllys * return an error. 87899ebb4caSwyllys */ 87999ebb4caSwyllys if (i != strlen((char *)hexstr)) 88099ebb4caSwyllys return (KMF_ERR_BAD_HEX_STRING); 88199ebb4caSwyllys stringlen = i; 88299ebb4caSwyllys len = (i / 2) + (i % 2); 88399ebb4caSwyllys 88499ebb4caSwyllys buf = malloc(len); 88599ebb4caSwyllys if (buf == NULL) { 88699ebb4caSwyllys return (KMF_ERR_MEMORY); 88799ebb4caSwyllys } 88899ebb4caSwyllys (void) memset(buf, 0, len); 88999ebb4caSwyllys 89099ebb4caSwyllys for (i = 0; i < stringlen; i++) { 89199ebb4caSwyllys ch = (unsigned char) *hexstr; 89299ebb4caSwyllys hexstr++; 89399ebb4caSwyllys if ((ch >= '0') && (ch <= '9')) 89499ebb4caSwyllys ch -= '0'; 89599ebb4caSwyllys else if ((ch >= 'A') && (ch <= 'F')) 89699ebb4caSwyllys ch = ch - 'A' + 10; 89799ebb4caSwyllys else if ((ch >= 'a') && (ch <= 'f')) 89899ebb4caSwyllys ch = ch - 'a' + 10; 89999ebb4caSwyllys else { 90099ebb4caSwyllys ret = KMF_ERR_BAD_HEX_STRING; 90199ebb4caSwyllys goto out; 90299ebb4caSwyllys } 90399ebb4caSwyllys 90499ebb4caSwyllys if (i & 1) { 90599ebb4caSwyllys buf[i/2] |= ch; 90699ebb4caSwyllys } else { 90799ebb4caSwyllys buf[i/2] = (ch << 4); 90899ebb4caSwyllys } 90999ebb4caSwyllys } 91099ebb4caSwyllys 91199ebb4caSwyllys *bytes = buf; 91299ebb4caSwyllys *outlen = len; 91399ebb4caSwyllys out: 91499ebb4caSwyllys if (buf != NULL && ret != KMF_OK) { 91599ebb4caSwyllys free(buf); 91699ebb4caSwyllys } 91799ebb4caSwyllys return (ret); 91899ebb4caSwyllys } 91999ebb4caSwyllys 92099ebb4caSwyllys void 92130a5e8faSwyllys kmf_free_dn(KMF_X509_NAME *name) 92299ebb4caSwyllys { 92399ebb4caSwyllys KMF_X509_RDN *newrdn = NULL; 92499ebb4caSwyllys KMF_X509_TYPE_VALUE_PAIR *av = NULL; 92599ebb4caSwyllys int i, j; 92699ebb4caSwyllys 92799ebb4caSwyllys if (name && name->numberOfRDNs) { 92899ebb4caSwyllys for (i = 0; i < name->numberOfRDNs; i++) { 92999ebb4caSwyllys newrdn = &name->RelativeDistinguishedName[i]; 93099ebb4caSwyllys for (j = 0; j < newrdn->numberOfPairs; j++) { 93199ebb4caSwyllys av = &newrdn->AttributeTypeAndValue[j]; 93230a5e8faSwyllys kmf_free_data(&av->type); 93330a5e8faSwyllys kmf_free_data(&av->value); 93499ebb4caSwyllys } 93599ebb4caSwyllys free(newrdn->AttributeTypeAndValue); 93699ebb4caSwyllys newrdn->numberOfPairs = 0; 93799ebb4caSwyllys newrdn->AttributeTypeAndValue = NULL; 93899ebb4caSwyllys } 93999ebb4caSwyllys free(name->RelativeDistinguishedName); 94099ebb4caSwyllys name->numberOfRDNs = 0; 94199ebb4caSwyllys name->RelativeDistinguishedName = NULL; 94299ebb4caSwyllys } 94399ebb4caSwyllys } 94499ebb4caSwyllys 94599ebb4caSwyllys void 94630a5e8faSwyllys kmf_free_kmf_cert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 94799ebb4caSwyllys { 94899ebb4caSwyllys KMF_PLUGIN *plugin; 94999ebb4caSwyllys KMF_RETURN ret; 95099ebb4caSwyllys 95199ebb4caSwyllys CLEAR_ERROR(handle, ret); 95299ebb4caSwyllys if (ret != KMF_OK) 95399ebb4caSwyllys return; 95499ebb4caSwyllys 95599ebb4caSwyllys if (kmf_cert == NULL) 95699ebb4caSwyllys return; 95799ebb4caSwyllys 95899ebb4caSwyllys plugin = FindPlugin(handle, kmf_cert->kmf_private.keystore_type); 95999ebb4caSwyllys 96099ebb4caSwyllys if (plugin != NULL && plugin->funclist->FreeKMFCert != NULL) { 96199ebb4caSwyllys plugin->funclist->FreeKMFCert(handle, kmf_cert); 96299ebb4caSwyllys } 96399ebb4caSwyllys } 96499ebb4caSwyllys 96599ebb4caSwyllys void 96630a5e8faSwyllys kmf_free_data(KMF_DATA *datablock) 96799ebb4caSwyllys { 96899ebb4caSwyllys if (datablock != NULL && datablock->Data != NULL) { 96999ebb4caSwyllys free(datablock->Data); 97099ebb4caSwyllys datablock->Data = NULL; 97199ebb4caSwyllys datablock->Length = 0; 97299ebb4caSwyllys } 97399ebb4caSwyllys } 97499ebb4caSwyllys 97599ebb4caSwyllys void 97630a5e8faSwyllys kmf_free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *algoid) 97799ebb4caSwyllys { 97899ebb4caSwyllys if (algoid == NULL) 97999ebb4caSwyllys return; 98030a5e8faSwyllys kmf_free_data(&algoid->algorithm); 98130a5e8faSwyllys kmf_free_data(&algoid->parameters); 98299ebb4caSwyllys } 98399ebb4caSwyllys 98499ebb4caSwyllys void 98530a5e8faSwyllys kmf_free_extn(KMF_X509_EXTENSION *exptr) 98699ebb4caSwyllys { 98799ebb4caSwyllys if (exptr == NULL) 98899ebb4caSwyllys return; 98999ebb4caSwyllys 99030a5e8faSwyllys kmf_free_data((KMF_DATA *)&exptr->extnId); 99130a5e8faSwyllys kmf_free_data(&exptr->BERvalue); 99299ebb4caSwyllys 99399ebb4caSwyllys if (exptr->value.tagAndValue) { 99430a5e8faSwyllys kmf_free_data(&exptr->value.tagAndValue->value); 99599ebb4caSwyllys free(exptr->value.tagAndValue); 99699ebb4caSwyllys } 99799ebb4caSwyllys } 99899ebb4caSwyllys 99999ebb4caSwyllys void 100030a5e8faSwyllys kmf_free_tbs_csr(KMF_TBS_CSR *tbscsr) 100199ebb4caSwyllys { 100299ebb4caSwyllys if (tbscsr) { 100330a5e8faSwyllys kmf_free_data(&tbscsr->version); 100499ebb4caSwyllys 100530a5e8faSwyllys kmf_free_dn(&tbscsr->subject); 100699ebb4caSwyllys 100730a5e8faSwyllys kmf_free_algoid(&tbscsr->subjectPublicKeyInfo.algorithm); 100830a5e8faSwyllys kmf_free_data(&tbscsr->subjectPublicKeyInfo.subjectPublicKey); 100999ebb4caSwyllys 101099ebb4caSwyllys free_extensions(&tbscsr->extensions); 101199ebb4caSwyllys } 101299ebb4caSwyllys } 101399ebb4caSwyllys 101499ebb4caSwyllys void 101530a5e8faSwyllys kmf_free_signed_csr(KMF_CSR_DATA *csr) 101699ebb4caSwyllys { 101799ebb4caSwyllys if (csr) { 101830a5e8faSwyllys kmf_free_tbs_csr(&csr->csr); 101999ebb4caSwyllys 102030a5e8faSwyllys kmf_free_algoid(&csr->signature.algorithmIdentifier); 102130a5e8faSwyllys kmf_free_data(&csr->signature.encrypted); 102299ebb4caSwyllys } 102399ebb4caSwyllys } 102499ebb4caSwyllys 102599ebb4caSwyllys static void 102699ebb4caSwyllys free_validity(KMF_X509_VALIDITY *validity) 102799ebb4caSwyllys { 102899ebb4caSwyllys if (validity == NULL) 102999ebb4caSwyllys return; 103030a5e8faSwyllys kmf_free_data(&validity->notBefore.time); 103130a5e8faSwyllys kmf_free_data(&validity->notAfter.time); 103299ebb4caSwyllys } 103399ebb4caSwyllys 103499ebb4caSwyllys static void 103599ebb4caSwyllys free_extensions(KMF_X509_EXTENSIONS *extns) 103699ebb4caSwyllys { 103799ebb4caSwyllys int i; 103899ebb4caSwyllys KMF_X509_EXTENSION *exptr; 103999ebb4caSwyllys 104099ebb4caSwyllys if (extns && extns->numberOfExtensions > 0) { 104199ebb4caSwyllys for (i = 0; i < extns->numberOfExtensions; i++) { 104299ebb4caSwyllys exptr = &extns->extensions[i]; 104330a5e8faSwyllys kmf_free_extn(exptr); 104499ebb4caSwyllys } 104599ebb4caSwyllys free(extns->extensions); 104699ebb4caSwyllys extns->numberOfExtensions = 0; 104799ebb4caSwyllys extns->extensions = NULL; 104899ebb4caSwyllys } 104999ebb4caSwyllys } 105099ebb4caSwyllys 105199ebb4caSwyllys void 105230a5e8faSwyllys kmf_free_tbs_cert(KMF_X509_TBS_CERT *tbscert) 105399ebb4caSwyllys { 105499ebb4caSwyllys if (tbscert) { 105530a5e8faSwyllys kmf_free_data(&tbscert->version); 105630a5e8faSwyllys kmf_free_bigint(&tbscert->serialNumber); 105730a5e8faSwyllys kmf_free_algoid(&tbscert->signature); 105899ebb4caSwyllys 105930a5e8faSwyllys kmf_free_dn(&tbscert->issuer); 106030a5e8faSwyllys kmf_free_dn(&tbscert->subject); 106199ebb4caSwyllys 106299ebb4caSwyllys free_validity(&tbscert->validity); 106399ebb4caSwyllys 106430a5e8faSwyllys kmf_free_data(&tbscert->issuerUniqueIdentifier); 106530a5e8faSwyllys kmf_free_data(&tbscert->subjectUniqueIdentifier); 106699ebb4caSwyllys 106730a5e8faSwyllys kmf_free_algoid(&tbscert->subjectPublicKeyInfo.algorithm); 106830a5e8faSwyllys kmf_free_data(&tbscert->subjectPublicKeyInfo.subjectPublicKey); 106999ebb4caSwyllys 107099ebb4caSwyllys free_extensions(&tbscert->extensions); 107199ebb4caSwyllys 107230a5e8faSwyllys kmf_free_data(&tbscert->issuerUniqueIdentifier); 107330a5e8faSwyllys kmf_free_data(&tbscert->subjectUniqueIdentifier); 107499ebb4caSwyllys } 107599ebb4caSwyllys } 107699ebb4caSwyllys 107799ebb4caSwyllys void 107830a5e8faSwyllys kmf_free_signed_cert(KMF_X509_CERTIFICATE *certptr) 107999ebb4caSwyllys { 108099ebb4caSwyllys if (!certptr) 108199ebb4caSwyllys return; 108299ebb4caSwyllys 108330a5e8faSwyllys kmf_free_tbs_cert(&certptr->certificate); 108499ebb4caSwyllys 108530a5e8faSwyllys kmf_free_algoid(&certptr->signature.algorithmIdentifier); 108630a5e8faSwyllys kmf_free_data(&certptr->signature.encrypted); 108799ebb4caSwyllys } 108899ebb4caSwyllys 108999ebb4caSwyllys void 109030a5e8faSwyllys kmf_free_str(char *pstr) 109199ebb4caSwyllys { 109299ebb4caSwyllys if (pstr != NULL) 109399ebb4caSwyllys free(pstr); 109499ebb4caSwyllys } 109599ebb4caSwyllys 109699ebb4caSwyllys void 109799ebb4caSwyllys free_keyidlist(KMF_OID *oidlist, int len) 109899ebb4caSwyllys { 109999ebb4caSwyllys int i; 110099ebb4caSwyllys for (i = 0; i < len; i++) { 110130a5e8faSwyllys kmf_free_data((KMF_DATA *)&oidlist[i]); 110299ebb4caSwyllys } 110399ebb4caSwyllys free(oidlist); 110499ebb4caSwyllys } 110599ebb4caSwyllys 110699ebb4caSwyllys void 110730a5e8faSwyllys kmf_free_eku(KMF_X509EXT_EKU *eptr) 110899ebb4caSwyllys { 110930a5e8faSwyllys if (eptr && eptr->nEKUs > 0 && eptr->keyPurposeIdList != NULL) 111099ebb4caSwyllys free_keyidlist(eptr->keyPurposeIdList, eptr->nEKUs); 111199ebb4caSwyllys } 111299ebb4caSwyllys 111399ebb4caSwyllys void 111430a5e8faSwyllys kmf_free_spki(KMF_X509_SPKI *spki) 111599ebb4caSwyllys { 111699ebb4caSwyllys if (spki != NULL) { 111730a5e8faSwyllys kmf_free_algoid(&spki->algorithm); 111830a5e8faSwyllys kmf_free_data(&spki->subjectPublicKey); 111999ebb4caSwyllys } 112099ebb4caSwyllys } 112199ebb4caSwyllys 112299ebb4caSwyllys void 112330a5e8faSwyllys kmf_free_kmf_key(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 112499ebb4caSwyllys { 112599ebb4caSwyllys KMF_PLUGIN *plugin; 112699ebb4caSwyllys KMF_RETURN ret; 112730a5e8faSwyllys KMF_ATTRIBUTE attlist[2]; /* only 2 attributes for DeleteKey op */ 112830a5e8faSwyllys int i = 0; 112930a5e8faSwyllys boolean_t token_destroy = B_FALSE; 113030a5e8faSwyllys 113130a5e8faSwyllys if (key == NULL) 113230a5e8faSwyllys return; 113399ebb4caSwyllys 113499ebb4caSwyllys CLEAR_ERROR(handle, ret); 113599ebb4caSwyllys if (ret != KMF_OK) 113699ebb4caSwyllys return; 113799ebb4caSwyllys 113830a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 113930a5e8faSwyllys KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); 114030a5e8faSwyllys i++; 114130a5e8faSwyllys 114230a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 114330a5e8faSwyllys KMF_DESTROY_BOOL_ATTR, &token_destroy, sizeof (boolean_t)); 114430a5e8faSwyllys i++; 114599ebb4caSwyllys 114699ebb4caSwyllys plugin = FindPlugin(handle, key->kstype); 114799ebb4caSwyllys if (plugin != NULL && plugin->funclist->DeleteKey != NULL) { 114830a5e8faSwyllys (void) plugin->funclist->DeleteKey(handle, i, attlist); 114999ebb4caSwyllys } 115099ebb4caSwyllys 115199ebb4caSwyllys if (key->keylabel) 115299ebb4caSwyllys free(key->keylabel); 115399ebb4caSwyllys 115499ebb4caSwyllys if (key->israw) { 115530a5e8faSwyllys kmf_free_raw_key(key->keyp); 115699ebb4caSwyllys free(key->keyp); 115799ebb4caSwyllys } 115899ebb4caSwyllys 115999ebb4caSwyllys (void) memset(key, 0, sizeof (KMF_KEY_HANDLE)); 116099ebb4caSwyllys } 116199ebb4caSwyllys 116299ebb4caSwyllys void 116330a5e8faSwyllys kmf_free_bigint(KMF_BIGINT *big) 116499ebb4caSwyllys { 116599ebb4caSwyllys if (big != NULL && big->val != NULL) { 116602744e81Swyllys /* Clear it out before returning it to the pool */ 116702744e81Swyllys (void) memset(big->val, 0x00, big->len); 116899ebb4caSwyllys free(big->val); 116999ebb4caSwyllys big->val = NULL; 117099ebb4caSwyllys big->len = 0; 117199ebb4caSwyllys } 117299ebb4caSwyllys } 117399ebb4caSwyllys 117499ebb4caSwyllys static void 117599ebb4caSwyllys free_raw_rsa(KMF_RAW_RSA_KEY *key) 117699ebb4caSwyllys { 117799ebb4caSwyllys if (key == NULL) 117899ebb4caSwyllys return; 117930a5e8faSwyllys kmf_free_bigint(&key->mod); 118030a5e8faSwyllys kmf_free_bigint(&key->pubexp); 118130a5e8faSwyllys kmf_free_bigint(&key->priexp); 118230a5e8faSwyllys kmf_free_bigint(&key->prime1); 118330a5e8faSwyllys kmf_free_bigint(&key->prime2); 118430a5e8faSwyllys kmf_free_bigint(&key->exp1); 118530a5e8faSwyllys kmf_free_bigint(&key->exp2); 118630a5e8faSwyllys kmf_free_bigint(&key->coef); 118799ebb4caSwyllys } 118899ebb4caSwyllys 118999ebb4caSwyllys static void 119099ebb4caSwyllys free_raw_dsa(KMF_RAW_DSA_KEY *key) 119199ebb4caSwyllys { 119299ebb4caSwyllys if (key == NULL) 119399ebb4caSwyllys return; 119430a5e8faSwyllys kmf_free_bigint(&key->prime); 119530a5e8faSwyllys kmf_free_bigint(&key->subprime); 119630a5e8faSwyllys kmf_free_bigint(&key->base); 119730a5e8faSwyllys kmf_free_bigint(&key->value); 119899ebb4caSwyllys } 119999ebb4caSwyllys 120099ebb4caSwyllys static void 120199ebb4caSwyllys free_raw_sym(KMF_RAW_SYM_KEY *key) 120299ebb4caSwyllys { 120399ebb4caSwyllys if (key == NULL) 120499ebb4caSwyllys return; 120530a5e8faSwyllys kmf_free_bigint(&key->keydata); 120699ebb4caSwyllys } 120799ebb4caSwyllys 120899ebb4caSwyllys void 120930a5e8faSwyllys kmf_free_raw_key(KMF_RAW_KEY_DATA *key) 121099ebb4caSwyllys { 121199ebb4caSwyllys if (key == NULL) 121299ebb4caSwyllys return; 121399ebb4caSwyllys 121499ebb4caSwyllys switch (key->keytype) { 121599ebb4caSwyllys case KMF_RSA: 121699ebb4caSwyllys free_raw_rsa(&key->rawdata.rsa); 121799ebb4caSwyllys break; 121899ebb4caSwyllys case KMF_DSA: 121999ebb4caSwyllys free_raw_dsa(&key->rawdata.dsa); 122099ebb4caSwyllys break; 122199ebb4caSwyllys case KMF_AES: 122299ebb4caSwyllys case KMF_RC4: 122399ebb4caSwyllys case KMF_DES: 122499ebb4caSwyllys case KMF_DES3: 122599ebb4caSwyllys free_raw_sym(&key->rawdata.sym); 122699ebb4caSwyllys break; 122799ebb4caSwyllys } 122899ebb4caSwyllys } 122999ebb4caSwyllys 123099ebb4caSwyllys void 123130a5e8faSwyllys kmf_free_raw_sym_key(KMF_RAW_SYM_KEY *key) 123299ebb4caSwyllys { 123399ebb4caSwyllys if (key == NULL) 123499ebb4caSwyllys return; 123530a5e8faSwyllys kmf_free_bigint(&key->keydata); 123699ebb4caSwyllys free(key); 123799ebb4caSwyllys } 123899ebb4caSwyllys 123999ebb4caSwyllys /* 124099ebb4caSwyllys * This function frees the space allocated for the name portion of a 124199ebb4caSwyllys * KMF_CRL_DIST_POINT. 124299ebb4caSwyllys */ 124399ebb4caSwyllys void 124499ebb4caSwyllys free_dp_name(KMF_CRL_DIST_POINT *dp) 124599ebb4caSwyllys { 124699ebb4caSwyllys KMF_GENERALNAMES *fullname; 124799ebb4caSwyllys KMF_DATA *urldata; 124899ebb4caSwyllys int i; 124999ebb4caSwyllys 125099ebb4caSwyllys if (dp == NULL) 125199ebb4caSwyllys return; 125299ebb4caSwyllys 125399ebb4caSwyllys /* For phase 1, we only need to free the fullname space. */ 125499ebb4caSwyllys fullname = &(dp->name.full_name); 125599ebb4caSwyllys if (fullname->number == 0) 125699ebb4caSwyllys return; 125799ebb4caSwyllys 125899ebb4caSwyllys for (i = 0; i < fullname->number; i++) { 125999ebb4caSwyllys urldata = &(fullname->namelist[fullname->number - 1].name); 126030a5e8faSwyllys kmf_free_data(urldata); 126199ebb4caSwyllys } 126299ebb4caSwyllys 126399ebb4caSwyllys free(fullname->namelist); 126499ebb4caSwyllys } 126599ebb4caSwyllys 126699ebb4caSwyllys /* 126799ebb4caSwyllys * This function frees the space allocated for a KMF_CRL_DIST_POINT. 126899ebb4caSwyllys */ 126999ebb4caSwyllys void 127099ebb4caSwyllys free_dp(KMF_CRL_DIST_POINT *dp) 127199ebb4caSwyllys { 127299ebb4caSwyllys if (dp == NULL) 127399ebb4caSwyllys return; 127499ebb4caSwyllys 127599ebb4caSwyllys free_dp_name(dp); 127630a5e8faSwyllys kmf_free_data(&(dp->reasons)); 127799ebb4caSwyllys /* Need not to free crl_issuer space at phase 1 */ 127899ebb4caSwyllys } 127999ebb4caSwyllys 128099ebb4caSwyllys /* 128199ebb4caSwyllys * This function frees space for a KMF_X509EXT_CRLDISTPOINTS internally. 128299ebb4caSwyllys */ 128399ebb4caSwyllys void 128430a5e8faSwyllys kmf_free_crl_dist_pts(KMF_X509EXT_CRLDISTPOINTS *crl_dps) 128599ebb4caSwyllys { 128699ebb4caSwyllys int i; 128799ebb4caSwyllys 128899ebb4caSwyllys if (crl_dps == NULL) 128999ebb4caSwyllys return; 129099ebb4caSwyllys 129199ebb4caSwyllys for (i = 0; i < crl_dps->number; i++) 129299ebb4caSwyllys free_dp(&(crl_dps->dplist[i])); 129399ebb4caSwyllys 129499ebb4caSwyllys free(crl_dps->dplist); 129599ebb4caSwyllys } 129699ebb4caSwyllys 129799ebb4caSwyllys KMF_RETURN 129830a5e8faSwyllys kmf_create_ocsp_request(KMF_HANDLE_T handle, 129930a5e8faSwyllys int num_args, 130030a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 130199ebb4caSwyllys { 130230a5e8faSwyllys KMF_RETURN ret = KMF_OK; 130399ebb4caSwyllys KMF_PLUGIN *plugin; 130430a5e8faSwyllys KMF_RETURN (*createReqFn)(void *, int num_args, 130530a5e8faSwyllys KMF_ATTRIBUTE *attrlist); 130699ebb4caSwyllys 130730a5e8faSwyllys KMF_ATTRIBUTE_TESTER required_attrs[] = { 130830a5e8faSwyllys {KMF_OCSP_REQUEST_FILENAME_ATTR, FALSE, 1, 0}, 130930a5e8faSwyllys {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 131030a5e8faSwyllys sizeof (KMF_DATA)}, 131130a5e8faSwyllys {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 131230a5e8faSwyllys sizeof (KMF_DATA)}, 131330a5e8faSwyllys }; 131499ebb4caSwyllys 131530a5e8faSwyllys int num_req_attrs = sizeof (required_attrs) / 131630a5e8faSwyllys sizeof (KMF_ATTRIBUTE_TESTER); 131799ebb4caSwyllys 131830a5e8faSwyllys if (handle == NULL) 131999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 132099ebb4caSwyllys 132130a5e8faSwyllys CLEAR_ERROR(handle, ret); 132230a5e8faSwyllys 132330a5e8faSwyllys ret = test_attributes(num_req_attrs, required_attrs, 132430a5e8faSwyllys 0, NULL, num_args, attrlist); 132530a5e8faSwyllys 132630a5e8faSwyllys if (ret != KMF_OK) 132730a5e8faSwyllys return (ret); 132830a5e8faSwyllys 132999ebb4caSwyllys /* 133099ebb4caSwyllys * This framework function is actually implemented in the openssl 133199ebb4caSwyllys * plugin library, so we find the function address and call it. 133299ebb4caSwyllys */ 133399ebb4caSwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 133499ebb4caSwyllys if (plugin == NULL || plugin->dldesc == NULL) { 133599ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 133699ebb4caSwyllys } 133799ebb4caSwyllys 133899ebb4caSwyllys createReqFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 133999ebb4caSwyllys "OpenSSL_CreateOCSPRequest"); 134099ebb4caSwyllys if (createReqFn == NULL) { 134199ebb4caSwyllys return (KMF_ERR_FUNCTION_NOT_FOUND); 134299ebb4caSwyllys } 134399ebb4caSwyllys 134430a5e8faSwyllys return (createReqFn(handle, num_args, attrlist)); 134530a5e8faSwyllys 134699ebb4caSwyllys } 134799ebb4caSwyllys 134899ebb4caSwyllys KMF_RETURN 134930a5e8faSwyllys kmf_get_ocsp_status_for_cert(KMF_HANDLE_T handle, 135030a5e8faSwyllys int num_args, 135130a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 135299ebb4caSwyllys { 135330a5e8faSwyllys KMF_RETURN ret = KMF_OK; 135499ebb4caSwyllys KMF_PLUGIN *plugin; 135530a5e8faSwyllys KMF_RETURN (*getCertStatusFn)(void *, int num_args, 135630a5e8faSwyllys KMF_ATTRIBUTE *attrlist); 135730a5e8faSwyllys 135830a5e8faSwyllys KMF_ATTRIBUTE_TESTER required_attrs[] = { 135930a5e8faSwyllys {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 136030a5e8faSwyllys sizeof (KMF_DATA)}, 136130a5e8faSwyllys {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 136230a5e8faSwyllys sizeof (KMF_DATA)}, 136330a5e8faSwyllys {KMF_OCSP_RESPONSE_DATA_ATTR, FALSE, sizeof (KMF_DATA), 136430a5e8faSwyllys sizeof (KMF_DATA)}, 136530a5e8faSwyllys {KMF_OCSP_RESPONSE_STATUS_ATTR, FALSE, sizeof (int), 136630a5e8faSwyllys sizeof (uint32_t)}, 136730a5e8faSwyllys {KMF_OCSP_RESPONSE_REASON_ATTR, FALSE, sizeof (int), 136830a5e8faSwyllys sizeof (uint32_t)}, 136930a5e8faSwyllys {KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, FALSE, sizeof (int), 137030a5e8faSwyllys sizeof (uint32_t)}, 137130a5e8faSwyllys }; 137230a5e8faSwyllys 137330a5e8faSwyllys int num_req_attrs = sizeof (required_attrs) / 137430a5e8faSwyllys sizeof (KMF_ATTRIBUTE_TESTER); 137530a5e8faSwyllys 137630a5e8faSwyllys if (handle == NULL) 137730a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 137899ebb4caSwyllys 137999ebb4caSwyllys CLEAR_ERROR(handle, ret); 138099ebb4caSwyllys 138130a5e8faSwyllys ret = test_attributes(num_req_attrs, required_attrs, 138230a5e8faSwyllys 0, NULL, num_args, attrlist); 138399ebb4caSwyllys 138430a5e8faSwyllys if (ret != KMF_OK) 138530a5e8faSwyllys return (ret); 138699ebb4caSwyllys 138799ebb4caSwyllys /* 138899ebb4caSwyllys * This framework function is actually implemented in the openssl 138999ebb4caSwyllys * plugin library, so we find the function address and call it. 139099ebb4caSwyllys */ 139199ebb4caSwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 139299ebb4caSwyllys if (plugin == NULL || plugin->dldesc == NULL) { 139399ebb4caSwyllys return (KMF_ERR_INTERNAL); 139499ebb4caSwyllys } 139599ebb4caSwyllys 139699ebb4caSwyllys getCertStatusFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 139799ebb4caSwyllys "OpenSSL_GetOCSPStatusForCert"); 139899ebb4caSwyllys if (getCertStatusFn == NULL) { 139999ebb4caSwyllys return (KMF_ERR_INTERNAL); 140099ebb4caSwyllys } 140199ebb4caSwyllys 140230a5e8faSwyllys return (getCertStatusFn(handle, num_args, attrlist)); 140330a5e8faSwyllys 140499ebb4caSwyllys } 140599ebb4caSwyllys 140699ebb4caSwyllys KMF_RETURN 140730a5e8faSwyllys kmf_string_to_oid(char *oidstring, KMF_OID *oid) 140899ebb4caSwyllys { 140999ebb4caSwyllys KMF_RETURN rv = KMF_OK; 141099ebb4caSwyllys char *cp, *bp, *startp; 141199ebb4caSwyllys int numbuf; 141299ebb4caSwyllys int onumbuf; 141399ebb4caSwyllys int nbytes, index; 141499ebb4caSwyllys int len; 141599ebb4caSwyllys unsigned char *op; 141699ebb4caSwyllys 141799ebb4caSwyllys if (oidstring == NULL || oid == NULL) 141899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 141999ebb4caSwyllys 142099ebb4caSwyllys len = strlen(oidstring); 142199ebb4caSwyllys 142299ebb4caSwyllys bp = oidstring; 142399ebb4caSwyllys cp = bp; 142499ebb4caSwyllys /* Skip over leading space */ 142599ebb4caSwyllys while ((bp < &cp[len]) && isspace(*bp)) 142699ebb4caSwyllys bp++; 142799ebb4caSwyllys 142899ebb4caSwyllys startp = bp; 142999ebb4caSwyllys nbytes = 0; 143099ebb4caSwyllys 143199ebb4caSwyllys /* 143299ebb4caSwyllys * The first two numbers are chewed up by the first octet. 143399ebb4caSwyllys */ 143499ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 143599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 143699ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 143799ebb4caSwyllys bp++; 143899ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 143999ebb4caSwyllys bp++; 144099ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 144199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 144299ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 144399ebb4caSwyllys bp++; 144499ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 144599ebb4caSwyllys bp++; 144699ebb4caSwyllys nbytes++; 144799ebb4caSwyllys 144899ebb4caSwyllys while (isdigit(*bp)) { 144999ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 145099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 145199ebb4caSwyllys while (numbuf) { 145299ebb4caSwyllys nbytes++; 145399ebb4caSwyllys numbuf >>= 7; 145499ebb4caSwyllys } 145599ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 145699ebb4caSwyllys bp++; 145799ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 145899ebb4caSwyllys bp++; 145999ebb4caSwyllys } 146099ebb4caSwyllys 146199ebb4caSwyllys oid->Length = nbytes; 146299ebb4caSwyllys oid->Data = malloc(oid->Length); 146399ebb4caSwyllys if (oid->Data == NULL) { 146499ebb4caSwyllys return (KMF_ERR_MEMORY); 146599ebb4caSwyllys } 146699ebb4caSwyllys (void) memset(oid->Data, 0, oid->Length); 146799ebb4caSwyllys 146899ebb4caSwyllys op = oid->Data; 146999ebb4caSwyllys 147099ebb4caSwyllys bp = startp; 147199ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 147299ebb4caSwyllys 147399ebb4caSwyllys while (isdigit(*bp)) bp++; 147499ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 147599ebb4caSwyllys 147699ebb4caSwyllys onumbuf = 40 * numbuf; 147799ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 147899ebb4caSwyllys onumbuf += numbuf; 147999ebb4caSwyllys *op = (unsigned char) onumbuf; 148099ebb4caSwyllys op++; 148199ebb4caSwyllys 148299ebb4caSwyllys while (isdigit(*bp)) bp++; 148399ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 148499ebb4caSwyllys while (isdigit(*bp)) { 148599ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 148699ebb4caSwyllys nbytes = 0; 148799ebb4caSwyllys /* Have to fill in the bytes msb-first */ 148899ebb4caSwyllys onumbuf = numbuf; 148999ebb4caSwyllys while (numbuf) { 149099ebb4caSwyllys nbytes++; 149199ebb4caSwyllys numbuf >>= 7; 149299ebb4caSwyllys } 149399ebb4caSwyllys numbuf = onumbuf; 149499ebb4caSwyllys op += nbytes; 149599ebb4caSwyllys index = -1; 149699ebb4caSwyllys while (numbuf) { 149799ebb4caSwyllys op[index] = (unsigned char)numbuf & 0x7f; 149899ebb4caSwyllys if (index != -1) 149999ebb4caSwyllys op[index] |= 0x80; 150099ebb4caSwyllys index--; 150199ebb4caSwyllys numbuf >>= 7; 150299ebb4caSwyllys } 150399ebb4caSwyllys while (isdigit(*bp)) bp++; 150499ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 150599ebb4caSwyllys } 150699ebb4caSwyllys 150799ebb4caSwyllys return (rv); 150899ebb4caSwyllys } 150999ebb4caSwyllys 151099ebb4caSwyllys static KMF_RETURN 151199ebb4caSwyllys encode_rid(char *name, KMF_DATA *derdata) 151299ebb4caSwyllys { 151399ebb4caSwyllys KMF_RETURN rv = KMF_OK; 151499ebb4caSwyllys 151599ebb4caSwyllys if (name == NULL || derdata == NULL) 151699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 151799ebb4caSwyllys 151830a5e8faSwyllys rv = kmf_string_to_oid(name, (KMF_OID *)derdata); 151999ebb4caSwyllys 152099ebb4caSwyllys return (rv); 152199ebb4caSwyllys } 152299ebb4caSwyllys 152399ebb4caSwyllys static KMF_RETURN 152499ebb4caSwyllys encode_ipaddr(char *name, KMF_DATA *derdata) 152599ebb4caSwyllys { 152699ebb4caSwyllys KMF_RETURN rv = KMF_OK; 152799ebb4caSwyllys size_t len; 152899ebb4caSwyllys in_addr_t v4; 152999ebb4caSwyllys in6_addr_t v6; 153099ebb4caSwyllys uint8_t *ptr; 153199ebb4caSwyllys 153299ebb4caSwyllys if (name == NULL || derdata == NULL) 153399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 153499ebb4caSwyllys 153599ebb4caSwyllys v4 = inet_addr(name); 153699ebb4caSwyllys if (v4 == (in_addr_t)-1) { 153799ebb4caSwyllys ptr = (uint8_t *)&v6; 153899ebb4caSwyllys if (inet_pton(AF_INET6, name, ptr) != 1) 153999ebb4caSwyllys return (KMF_ERR_ENCODING); 154099ebb4caSwyllys len = sizeof (v6); 154199ebb4caSwyllys } else { 154299ebb4caSwyllys ptr = (uint8_t *)&v4; 154399ebb4caSwyllys len = sizeof (v4); 154499ebb4caSwyllys } 154599ebb4caSwyllys 154699ebb4caSwyllys derdata->Data = malloc(len); 154799ebb4caSwyllys if (derdata->Data == NULL) 154899ebb4caSwyllys return (KMF_ERR_MEMORY); 154999ebb4caSwyllys (void) memcpy(derdata->Data, ptr, len); 155099ebb4caSwyllys derdata->Length = len; 155199ebb4caSwyllys 155299ebb4caSwyllys return (rv); 155399ebb4caSwyllys } 155499ebb4caSwyllys 155599ebb4caSwyllys static KMF_RETURN 155699ebb4caSwyllys verify_uri_format(char *uristring) 155799ebb4caSwyllys { 155899ebb4caSwyllys KMF_RETURN ret = KMF_OK; 155999ebb4caSwyllys xmlURIPtr uriptr = NULL; 156099ebb4caSwyllys 156199ebb4caSwyllys /* Parse the URI string; get the hostname and port */ 156299ebb4caSwyllys uriptr = xmlParseURI(uristring); 156399ebb4caSwyllys if (uriptr == NULL) { 156499ebb4caSwyllys ret = KMF_ERR_BAD_URI; 156599ebb4caSwyllys goto out; 156699ebb4caSwyllys } 156799ebb4caSwyllys 156899ebb4caSwyllys if (uriptr->scheme == NULL || !strlen(uriptr->scheme)) { 156999ebb4caSwyllys ret = KMF_ERR_BAD_URI; 157099ebb4caSwyllys goto out; 157199ebb4caSwyllys } 157299ebb4caSwyllys 157399ebb4caSwyllys if (uriptr->server == NULL || !strlen(uriptr->server)) { 157499ebb4caSwyllys ret = KMF_ERR_BAD_URI; 157599ebb4caSwyllys goto out; 157699ebb4caSwyllys } 157799ebb4caSwyllys out: 157899ebb4caSwyllys if (uriptr != NULL) 157999ebb4caSwyllys xmlFreeURI(uriptr); 158099ebb4caSwyllys return (ret); 158199ebb4caSwyllys } 158299ebb4caSwyllys 158399ebb4caSwyllys static KMF_RETURN 158499ebb4caSwyllys encode_altname(char *namedata, 158599ebb4caSwyllys KMF_GENERALNAMECHOICES nametype, KMF_DATA *encodedname) 158699ebb4caSwyllys { 158799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 158899ebb4caSwyllys KMF_X509_NAME dnname; 158999ebb4caSwyllys uchar_t tagval; 159099ebb4caSwyllys BerElement *asn1 = NULL; 159199ebb4caSwyllys BerValue *extdata; 159299ebb4caSwyllys 159399ebb4caSwyllys if (namedata == NULL || encodedname == NULL) 159499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 159599ebb4caSwyllys 159699ebb4caSwyllys /* 159799ebb4caSwyllys * Encode the namedata according to rules in RFC 3280 for GeneralName. 159899ebb4caSwyllys * The input "namedata" is assumed to be an ASCII string representation 159999ebb4caSwyllys * of the AltName, we need to convert it to correct ASN.1 here before 160099ebb4caSwyllys * adding it to the cert. 160199ebb4caSwyllys */ 160299ebb4caSwyllys switch (nametype) { 160399ebb4caSwyllys case GENNAME_RFC822NAME: /* rfc 822 */ 160499ebb4caSwyllys /* IA5String, no encoding needed */ 160599ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 160699ebb4caSwyllys if (encodedname->Data == NULL) 160799ebb4caSwyllys return (KMF_ERR_MEMORY); 160899ebb4caSwyllys encodedname->Length = strlen(namedata); 160999ebb4caSwyllys tagval = (0x80 | nametype); 161099ebb4caSwyllys break; 161199ebb4caSwyllys case GENNAME_DNSNAME: /* rfc 1034 */ 161299ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 161399ebb4caSwyllys if (encodedname->Data == NULL) 161499ebb4caSwyllys return (KMF_ERR_MEMORY); 161599ebb4caSwyllys encodedname->Length = strlen(namedata); 161699ebb4caSwyllys tagval = (0x80 | nametype); 161799ebb4caSwyllys break; 161899ebb4caSwyllys case GENNAME_URI: /* rfc 1738 */ 161999ebb4caSwyllys ret = verify_uri_format(namedata); 162099ebb4caSwyllys if (ret != KMF_OK) 162199ebb4caSwyllys return (ret); 162299ebb4caSwyllys /* IA5String, no encoding needed */ 162399ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 162499ebb4caSwyllys if (encodedname->Data == NULL) 162599ebb4caSwyllys return (KMF_ERR_MEMORY); 162699ebb4caSwyllys encodedname->Length = strlen(namedata); 162799ebb4caSwyllys tagval = (0x80 | nametype); 162899ebb4caSwyllys break; 162999ebb4caSwyllys case GENNAME_IPADDRESS: 163099ebb4caSwyllys ret = encode_ipaddr(namedata, encodedname); 163199ebb4caSwyllys tagval = (0x80 | nametype); 163299ebb4caSwyllys break; 163399ebb4caSwyllys case GENNAME_REGISTEREDID: 163499ebb4caSwyllys ret = encode_rid(namedata, encodedname); 163599ebb4caSwyllys tagval = (0x80 | nametype); 163699ebb4caSwyllys break; 163799ebb4caSwyllys case GENNAME_DIRECTORYNAME: 163830a5e8faSwyllys ret = kmf_dn_parser(namedata, &dnname); 163999ebb4caSwyllys if (ret == KMF_OK) { 164030a5e8faSwyllys ret = DerEncodeName(&dnname, encodedname); 164199ebb4caSwyllys } 164230a5e8faSwyllys (void) kmf_free_dn(&dnname); 164399ebb4caSwyllys tagval = (0xA0 | nametype); 164499ebb4caSwyllys break; 164599ebb4caSwyllys default: 164699ebb4caSwyllys /* unsupported */ 164799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 164899ebb4caSwyllys 164999ebb4caSwyllys } 165099ebb4caSwyllys if (ret != KMF_OK) { 165130a5e8faSwyllys kmf_free_data(encodedname); 165299ebb4caSwyllys return (ret); 165399ebb4caSwyllys } 165499ebb4caSwyllys 165599ebb4caSwyllys if ((asn1 = kmfder_alloc()) == NULL) 165699ebb4caSwyllys return (KMF_ERR_MEMORY); 165799ebb4caSwyllys 165830a5e8faSwyllys if (kmfber_printf(asn1, "Tl", tagval, encodedname->Length) == -1) 165999ebb4caSwyllys goto cleanup; 166099ebb4caSwyllys 166199ebb4caSwyllys if (kmfber_write(asn1, (char *)encodedname->Data, 166230a5e8faSwyllys encodedname->Length, 0) == -1) { 166399ebb4caSwyllys ret = KMF_ERR_ENCODING; 166499ebb4caSwyllys goto cleanup; 166599ebb4caSwyllys } 166699ebb4caSwyllys if (kmfber_flatten(asn1, &extdata) == -1) { 166799ebb4caSwyllys ret = KMF_ERR_ENCODING; 166899ebb4caSwyllys goto cleanup; 166999ebb4caSwyllys } 167099ebb4caSwyllys 167130a5e8faSwyllys kmf_free_data(encodedname); 167299ebb4caSwyllys encodedname->Data = (uchar_t *)extdata->bv_val; 167399ebb4caSwyllys encodedname->Length = extdata->bv_len; 167499ebb4caSwyllys 167599ebb4caSwyllys free(extdata); 167699ebb4caSwyllys 167799ebb4caSwyllys cleanup: 167899ebb4caSwyllys if (asn1) 167999ebb4caSwyllys kmfber_free(asn1, 1); 168099ebb4caSwyllys 168199ebb4caSwyllys if (ret != KMF_OK) 168230a5e8faSwyllys kmf_free_data(encodedname); 168399ebb4caSwyllys 168499ebb4caSwyllys return (ret); 168599ebb4caSwyllys } 168699ebb4caSwyllys 168799ebb4caSwyllys KMF_X509_EXTENSION * 168899ebb4caSwyllys FindExtn(KMF_X509_EXTENSIONS *exts, KMF_OID *oid) 168999ebb4caSwyllys { 169099ebb4caSwyllys KMF_X509_EXTENSION *foundextn = NULL; 169199ebb4caSwyllys int i; 169299ebb4caSwyllys 169399ebb4caSwyllys if (exts == NULL || oid == NULL) 169499ebb4caSwyllys return (NULL); 169599ebb4caSwyllys 169699ebb4caSwyllys for (i = 0; i < exts->numberOfExtensions; i++) { 169799ebb4caSwyllys if (IsEqualOid(oid, &exts->extensions[i].extnId)) { 169899ebb4caSwyllys foundextn = &exts->extensions[i]; 169999ebb4caSwyllys break; 170099ebb4caSwyllys } 170199ebb4caSwyllys } 170299ebb4caSwyllys return (foundextn); 170399ebb4caSwyllys } 170499ebb4caSwyllys 170599ebb4caSwyllys KMF_RETURN 170699ebb4caSwyllys GetSequenceContents(char *data, size_t len, 170799ebb4caSwyllys char **contents, size_t *outlen) 170899ebb4caSwyllys { 170999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 171099ebb4caSwyllys BerElement *exasn1 = NULL; 171199ebb4caSwyllys BerValue oldextn; 171299ebb4caSwyllys int tag; 171399ebb4caSwyllys size_t oldsize; 171499ebb4caSwyllys char *olddata = NULL; 171599ebb4caSwyllys 171699ebb4caSwyllys if (data == NULL || contents == NULL || outlen == NULL) 171799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 171899ebb4caSwyllys 171999ebb4caSwyllys /* 172099ebb4caSwyllys * Decode the sequence of general names 172199ebb4caSwyllys */ 172299ebb4caSwyllys oldextn.bv_val = data; 172399ebb4caSwyllys oldextn.bv_len = len; 172499ebb4caSwyllys 172599ebb4caSwyllys if ((exasn1 = kmfder_init(&oldextn)) == NULL) { 172699ebb4caSwyllys ret = KMF_ERR_MEMORY; 172799ebb4caSwyllys goto out; 172899ebb4caSwyllys } 172999ebb4caSwyllys 173099ebb4caSwyllys /* 173199ebb4caSwyllys * Unwrap the sequence to find the size of the block 173299ebb4caSwyllys * of GeneralName items in the set. 173399ebb4caSwyllys * 173499ebb4caSwyllys * Peek at the tag and length ("tl"), 173599ebb4caSwyllys * then consume them ("{"). 173699ebb4caSwyllys */ 173799ebb4caSwyllys if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT || 173830a5e8faSwyllys oldsize == 0) { 173999ebb4caSwyllys ret = KMF_ERR_ENCODING; 174099ebb4caSwyllys goto out; 174199ebb4caSwyllys } 174299ebb4caSwyllys 174399ebb4caSwyllys olddata = malloc(oldsize); 174499ebb4caSwyllys if (olddata == NULL) { 174599ebb4caSwyllys ret = KMF_ERR_MEMORY; 174699ebb4caSwyllys goto out; 174799ebb4caSwyllys } 174899ebb4caSwyllys (void) memset(olddata, 0, oldsize); 174999ebb4caSwyllys /* 175099ebb4caSwyllys * Read the entire blob of GeneralNames, we don't 175199ebb4caSwyllys * need to interpret them now. 175299ebb4caSwyllys */ 175399ebb4caSwyllys if (kmfber_read(exasn1, olddata, oldsize) != oldsize) { 175499ebb4caSwyllys ret = KMF_ERR_ENCODING; 175599ebb4caSwyllys goto out; 175699ebb4caSwyllys } 175799ebb4caSwyllys out: 175899ebb4caSwyllys if (exasn1 != NULL) 175999ebb4caSwyllys kmfber_free(exasn1, 1); 176099ebb4caSwyllys 176199ebb4caSwyllys if (ret != KMF_OK) { 176299ebb4caSwyllys *contents = NULL; 176399ebb4caSwyllys *outlen = 0; 176499ebb4caSwyllys if (olddata != NULL) 176599ebb4caSwyllys free(olddata); 176699ebb4caSwyllys } else { 176799ebb4caSwyllys *contents = olddata; 176899ebb4caSwyllys *outlen = oldsize; 176999ebb4caSwyllys } 177099ebb4caSwyllys return (ret); 177199ebb4caSwyllys } 177299ebb4caSwyllys 177399ebb4caSwyllys KMF_RETURN 177499ebb4caSwyllys add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) 177599ebb4caSwyllys { 177699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 177799ebb4caSwyllys KMF_X509_EXTENSION *extlist; 177899ebb4caSwyllys 177999ebb4caSwyllys if (exts == NULL || newextn == NULL) 178099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 178199ebb4caSwyllys 178299ebb4caSwyllys extlist = malloc(sizeof (KMF_X509_EXTENSION) * 178330a5e8faSwyllys (exts->numberOfExtensions + 1)); 178499ebb4caSwyllys if (extlist == NULL) 178599ebb4caSwyllys return (KMF_ERR_MEMORY); 178699ebb4caSwyllys 178799ebb4caSwyllys (void) memcpy(extlist, exts->extensions, 178899ebb4caSwyllys exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION)); 178999ebb4caSwyllys 179099ebb4caSwyllys (void) memcpy(&extlist[exts->numberOfExtensions], newextn, 179130a5e8faSwyllys sizeof (KMF_X509_EXTENSION)); 179299ebb4caSwyllys 179399ebb4caSwyllys free(exts->extensions); 179499ebb4caSwyllys exts->numberOfExtensions++; 179599ebb4caSwyllys exts->extensions = extlist; 179699ebb4caSwyllys 179799ebb4caSwyllys return (ret); 179899ebb4caSwyllys } 179999ebb4caSwyllys 180099ebb4caSwyllys KMF_RETURN 180130a5e8faSwyllys kmf_set_altname(KMF_X509_EXTENSIONS *extensions, 180299ebb4caSwyllys KMF_OID *oid, 180399ebb4caSwyllys int critical, 180499ebb4caSwyllys KMF_GENERALNAMECHOICES nametype, 180599ebb4caSwyllys char *namedata) 180699ebb4caSwyllys { 180799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 180899ebb4caSwyllys KMF_X509_EXTENSION subjAltName; 180999ebb4caSwyllys KMF_DATA dername = { NULL, 0 }; 181099ebb4caSwyllys BerElement *asn1 = NULL; 181199ebb4caSwyllys BerValue *extdata; 181299ebb4caSwyllys char *olddata = NULL; 181399ebb4caSwyllys KMF_X509_EXTENSION *foundextn = NULL; 181499ebb4caSwyllys size_t oldsize = 0; 181599ebb4caSwyllys 181699ebb4caSwyllys if (extensions == NULL || oid == NULL || namedata == NULL) 181799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 181899ebb4caSwyllys 181999ebb4caSwyllys ret = encode_altname(namedata, nametype, &dername); 182099ebb4caSwyllys 182199ebb4caSwyllys if (ret != KMF_OK) 182299ebb4caSwyllys return (ret); 182399ebb4caSwyllys 182499ebb4caSwyllys (void) memset(&subjAltName, 0, sizeof (subjAltName)); 182599ebb4caSwyllys 182699ebb4caSwyllys ret = copy_data(&subjAltName.extnId, oid); 182799ebb4caSwyllys if (ret != KMF_OK) 182899ebb4caSwyllys goto out; 182999ebb4caSwyllys /* 183099ebb4caSwyllys * Check to see if this cert already has a subjectAltName. 183199ebb4caSwyllys */ 183299ebb4caSwyllys foundextn = FindExtn(extensions, oid); 183399ebb4caSwyllys 183499ebb4caSwyllys if (foundextn != NULL) { 183599ebb4caSwyllys ret = GetSequenceContents( 183630a5e8faSwyllys (char *)foundextn->BERvalue.Data, 183730a5e8faSwyllys foundextn->BERvalue.Length, 183830a5e8faSwyllys &olddata, &oldsize); 183999ebb4caSwyllys if (ret != KMF_OK) 184099ebb4caSwyllys goto out; 184199ebb4caSwyllys } 184299ebb4caSwyllys 184399ebb4caSwyllys /* 184499ebb4caSwyllys * Assume (!!) that the namedata given is already properly encoded. 184599ebb4caSwyllys */ 184699ebb4caSwyllys if ((asn1 = kmfder_alloc()) == NULL) 184799ebb4caSwyllys return (KMF_ERR_MEMORY); 184899ebb4caSwyllys 184999ebb4caSwyllys if (kmfber_printf(asn1, "{") == -1) { 185099ebb4caSwyllys ret = KMF_ERR_ENCODING; 185199ebb4caSwyllys goto out; 185299ebb4caSwyllys } 185399ebb4caSwyllys 185499ebb4caSwyllys /* Write the old extension data first */ 185599ebb4caSwyllys if (olddata != NULL && oldsize > 0) { 185699ebb4caSwyllys if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 185799ebb4caSwyllys ret = KMF_ERR_ENCODING; 185899ebb4caSwyllys goto out; 185999ebb4caSwyllys } 186099ebb4caSwyllys } 186199ebb4caSwyllys 186299ebb4caSwyllys /* Now add the new name to the list */ 186399ebb4caSwyllys if (kmfber_write(asn1, (char *)dername.Data, dername.Length, 0) == -1) { 186499ebb4caSwyllys ret = KMF_ERR_ENCODING; 186599ebb4caSwyllys goto out; 186699ebb4caSwyllys } 186799ebb4caSwyllys 186899ebb4caSwyllys /* Now close the sequence */ 186999ebb4caSwyllys if (kmfber_printf(asn1, "}") == -1) { 187099ebb4caSwyllys ret = KMF_ERR_ENCODING; 187199ebb4caSwyllys goto out; 187299ebb4caSwyllys } 187399ebb4caSwyllys if (kmfber_flatten(asn1, &extdata) == -1) { 187499ebb4caSwyllys ret = KMF_ERR_ENCODING; 187599ebb4caSwyllys goto out; 187699ebb4caSwyllys } 187799ebb4caSwyllys 187899ebb4caSwyllys /* 187999ebb4caSwyllys * If we are just adding to an existing list of altNames, 188099ebb4caSwyllys * just replace the BER data associated with the found extension. 188199ebb4caSwyllys */ 188299ebb4caSwyllys if (foundextn != NULL) { 188399ebb4caSwyllys free(foundextn->BERvalue.Data); 188499ebb4caSwyllys foundextn->critical = critical; 188599ebb4caSwyllys foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 188699ebb4caSwyllys foundextn->BERvalue.Length = extdata->bv_len; 188799ebb4caSwyllys } else { 188899ebb4caSwyllys subjAltName.critical = critical; 188999ebb4caSwyllys subjAltName.format = KMF_X509_DATAFORMAT_ENCODED; 189099ebb4caSwyllys subjAltName.BERvalue.Data = (uchar_t *)extdata->bv_val; 189199ebb4caSwyllys subjAltName.BERvalue.Length = extdata->bv_len; 189299ebb4caSwyllys ret = add_an_extension(extensions, &subjAltName); 189399ebb4caSwyllys if (ret != KMF_OK) 189499ebb4caSwyllys free(subjAltName.BERvalue.Data); 189599ebb4caSwyllys } 189699ebb4caSwyllys 189799ebb4caSwyllys free(extdata); 189899ebb4caSwyllys out: 189999ebb4caSwyllys if (olddata != NULL) 190099ebb4caSwyllys free(olddata); 190199ebb4caSwyllys 190230a5e8faSwyllys kmf_free_data(&dername); 190399ebb4caSwyllys if (ret != KMF_OK) 190430a5e8faSwyllys kmf_free_data(&subjAltName.extnId); 190599ebb4caSwyllys if (asn1 != NULL) 190699ebb4caSwyllys kmfber_free(asn1, 1); 190799ebb4caSwyllys return (ret); 190899ebb4caSwyllys } 190930a5e8faSwyllys 191030a5e8faSwyllys /* 191130a5e8faSwyllys * Search a list of attributes for one that matches the given type. 191230a5e8faSwyllys * Return a pointer into the attribute list. This does not 191330a5e8faSwyllys * return a copy of the value, it returns a reference into the 191430a5e8faSwyllys * given list. 191530a5e8faSwyllys */ 191630a5e8faSwyllys int 191730a5e8faSwyllys kmf_find_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, int numattrs) 191830a5e8faSwyllys { 191930a5e8faSwyllys int i; 192030a5e8faSwyllys for (i = 0; i < numattrs; i++) { 192130a5e8faSwyllys if (attlist[i].type == type) 192230a5e8faSwyllys return (i); 192330a5e8faSwyllys } 192430a5e8faSwyllys return (-1); 192530a5e8faSwyllys } 192630a5e8faSwyllys 192730a5e8faSwyllys /* 192830a5e8faSwyllys * Verify that a given attribute is consistent with the 192930a5e8faSwyllys * "test" attribute. 193030a5e8faSwyllys */ 193130a5e8faSwyllys static KMF_RETURN 193230a5e8faSwyllys verify_attribute(KMF_ATTRIBUTE *givenattr, 193330a5e8faSwyllys KMF_ATTRIBUTE_TESTER *testattr) 193430a5e8faSwyllys { 193530a5e8faSwyllys /* A NULL pValue was found where one is required */ 193630a5e8faSwyllys if (testattr->null_value_ok == FALSE && 193730a5e8faSwyllys givenattr->pValue == NULL) 193830a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 193930a5e8faSwyllys 194030a5e8faSwyllys /* If the given valueLen is too small, return error */ 194130a5e8faSwyllys if (givenattr->pValue != NULL && 194230a5e8faSwyllys testattr->minlen > 0 && 194330a5e8faSwyllys (givenattr->valueLen < testattr->minlen)) 194430a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 194530a5e8faSwyllys 194630a5e8faSwyllys /* If the given valueLen is too big, return error */ 194730a5e8faSwyllys if (givenattr->pValue != NULL && 194830a5e8faSwyllys testattr->maxlen > 0 && 194930a5e8faSwyllys (givenattr->valueLen > testattr->maxlen)) 195030a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 195130a5e8faSwyllys 195230a5e8faSwyllys return (KMF_OK); 195330a5e8faSwyllys } 195430a5e8faSwyllys 195530a5e8faSwyllys /* 195630a5e8faSwyllys * Given a set of required attribute tests and optional 195730a5e8faSwyllys * attributes, make sure that the actual attributes 195830a5e8faSwyllys * being tested (attrlist below) are allowed and are 195930a5e8faSwyllys * properly specified. 196030a5e8faSwyllys */ 196130a5e8faSwyllys KMF_RETURN 196230a5e8faSwyllys test_attributes(int reqnum, KMF_ATTRIBUTE_TESTER *reqattrs, 196330a5e8faSwyllys int optnum, KMF_ATTRIBUTE_TESTER *optattrs, 196430a5e8faSwyllys int numattrs, KMF_ATTRIBUTE *attrlist) 196530a5e8faSwyllys { 196630a5e8faSwyllys KMF_RETURN ret = KMF_OK; 196730a5e8faSwyllys int i, idx; 196830a5e8faSwyllys 196930a5e8faSwyllys /* 197030a5e8faSwyllys * If the caller didn't supply enough attributes, 197130a5e8faSwyllys * return an error. 197230a5e8faSwyllys */ 197330a5e8faSwyllys if (numattrs < reqnum || attrlist == NULL) 197430a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 197530a5e8faSwyllys 197630a5e8faSwyllys /* 197730a5e8faSwyllys * Make sure all required attrs are present and 197830a5e8faSwyllys * correct. 197930a5e8faSwyllys */ 198030a5e8faSwyllys for (i = 0; i < reqnum && ret == KMF_OK; i++) { 198130a5e8faSwyllys idx = kmf_find_attr(reqattrs[i].type, attrlist, numattrs); 198230a5e8faSwyllys /* If a required attr is not found, return error */ 198330a5e8faSwyllys if (idx == -1) { 198430a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 198530a5e8faSwyllys } 198630a5e8faSwyllys 198730a5e8faSwyllys ret = verify_attribute(&attrlist[idx], &reqattrs[i]); 198830a5e8faSwyllys } 198930a5e8faSwyllys /* 199030a5e8faSwyllys * Now test the optional parameters. 199130a5e8faSwyllys */ 199230a5e8faSwyllys for (i = 0; i < optnum && ret == KMF_OK; i++) { 199330a5e8faSwyllys idx = kmf_find_attr(optattrs[i].type, attrlist, numattrs); 199430a5e8faSwyllys /* If a optional attr is not found, continue. */ 199530a5e8faSwyllys if (idx == -1) { 199630a5e8faSwyllys continue; 199730a5e8faSwyllys } 199830a5e8faSwyllys 199930a5e8faSwyllys ret = verify_attribute(&attrlist[idx], &optattrs[i]); 200030a5e8faSwyllys } 200130a5e8faSwyllys 200230a5e8faSwyllys return (ret); 200330a5e8faSwyllys } 200430a5e8faSwyllys 200530a5e8faSwyllys /* 200630a5e8faSwyllys * Given an already allocated attribute list, insert 200730a5e8faSwyllys * the given attribute information at a specific index 200830a5e8faSwyllys * in the list. 200930a5e8faSwyllys */ 201030a5e8faSwyllys void 201130a5e8faSwyllys kmf_set_attr_at_index(KMF_ATTRIBUTE *attlist, int index, 201230a5e8faSwyllys KMF_ATTR_TYPE type, void *pValue, uint32_t len) 201330a5e8faSwyllys { 201430a5e8faSwyllys if (attlist == NULL) 201530a5e8faSwyllys return; 201630a5e8faSwyllys 201730a5e8faSwyllys attlist[index].type = type; 201830a5e8faSwyllys attlist[index].pValue = pValue; 201930a5e8faSwyllys attlist[index].valueLen = len; 202030a5e8faSwyllys } 202130a5e8faSwyllys 202230a5e8faSwyllys /* 202330a5e8faSwyllys * Find an attribute matching a particular type and set 202430a5e8faSwyllys * the pValue and length fields to the given values. 202530a5e8faSwyllys */ 202630a5e8faSwyllys KMF_RETURN 202730a5e8faSwyllys kmf_set_attr(KMF_ATTRIBUTE *attlist, int numattr, 202830a5e8faSwyllys KMF_ATTR_TYPE type, void *pValue, uint32_t len) 202930a5e8faSwyllys { 203030a5e8faSwyllys int idx; 203130a5e8faSwyllys if (attlist == NULL) 203230a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 203330a5e8faSwyllys 203430a5e8faSwyllys idx = kmf_find_attr(type, attlist, numattr); 203530a5e8faSwyllys if (idx == -1) 203630a5e8faSwyllys return (KMF_ERR_ATTR_NOT_FOUND); 203730a5e8faSwyllys 203830a5e8faSwyllys attlist[idx].type = type; 203930a5e8faSwyllys /* Assumes the attribute pValue can hold the result */ 204030a5e8faSwyllys if (attlist[idx].pValue != NULL) { 204130a5e8faSwyllys if (attlist[idx].valueLen >= len) 204230a5e8faSwyllys (void) memcpy(attlist[idx].pValue, pValue, len); 204330a5e8faSwyllys else 204430a5e8faSwyllys return (KMF_ERR_BUFFER_SIZE); 204530a5e8faSwyllys } 204630a5e8faSwyllys attlist[idx].valueLen = len; 204730a5e8faSwyllys return (KMF_OK); 204830a5e8faSwyllys } 204930a5e8faSwyllys 205030a5e8faSwyllys /* 205130a5e8faSwyllys * Find a particular attribute in a list and return 205230a5e8faSwyllys * a pointer to its value. 205330a5e8faSwyllys */ 205430a5e8faSwyllys void * 205530a5e8faSwyllys kmf_get_attr_ptr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 205630a5e8faSwyllys int numattrs) 205730a5e8faSwyllys { 205830a5e8faSwyllys int i; 205930a5e8faSwyllys 206030a5e8faSwyllys i = kmf_find_attr(type, attlist, numattrs); 206130a5e8faSwyllys if (i == -1) 206230a5e8faSwyllys return (NULL); 206330a5e8faSwyllys 206430a5e8faSwyllys return (attlist[i].pValue); 206530a5e8faSwyllys } 206630a5e8faSwyllys 206730a5e8faSwyllys /* 206830a5e8faSwyllys * Find a particular attribute in a list and return 206930a5e8faSwyllys * the value and length values. Value and length 207030a5e8faSwyllys * may be NULL if the caller doesn't want their values 207130a5e8faSwyllys * to be filled in. 207230a5e8faSwyllys */ 207330a5e8faSwyllys KMF_RETURN 207430a5e8faSwyllys kmf_get_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 207530a5e8faSwyllys int numattrs, void *outValue, uint32_t *outlen) 207630a5e8faSwyllys { 207730a5e8faSwyllys int i; 207830a5e8faSwyllys uint32_t len = 0; 207930a5e8faSwyllys uint32_t *lenptr = outlen; 208030a5e8faSwyllys 208130a5e8faSwyllys if (lenptr == NULL) 208230a5e8faSwyllys lenptr = &len; 208330a5e8faSwyllys 208430a5e8faSwyllys i = kmf_find_attr(type, attlist, numattrs); 208530a5e8faSwyllys if (i == -1) 208630a5e8faSwyllys return (KMF_ERR_ATTR_NOT_FOUND); 208730a5e8faSwyllys 208830a5e8faSwyllys /* This assumes that the ptr passed in is pre-allocated space */ 208930a5e8faSwyllys if (attlist[i].pValue != NULL && outValue != NULL) { 209030a5e8faSwyllys /* 209130a5e8faSwyllys * If the caller did not specify a length, 209230a5e8faSwyllys * assume "outValue" is big enough. 209330a5e8faSwyllys */ 209430a5e8faSwyllys if (outlen != NULL) { 209530a5e8faSwyllys if (*outlen >= attlist[i].valueLen) 209630a5e8faSwyllys (void) memcpy(outValue, attlist[i].pValue, 209730a5e8faSwyllys attlist[i].valueLen); 209830a5e8faSwyllys else 209930a5e8faSwyllys return (KMF_ERR_BUFFER_SIZE); 210030a5e8faSwyllys } else { 210130a5e8faSwyllys (void) memcpy(outValue, attlist[i].pValue, 210230a5e8faSwyllys attlist[i].valueLen); 210330a5e8faSwyllys } 210430a5e8faSwyllys } 210530a5e8faSwyllys 210630a5e8faSwyllys if (outlen != NULL) 210730a5e8faSwyllys *outlen = attlist[i].valueLen; 210830a5e8faSwyllys return (KMF_OK); 210930a5e8faSwyllys } 211030a5e8faSwyllys 211130a5e8faSwyllys /* 211230a5e8faSwyllys * Utility routine to find a string type attribute, allocate it 211330a5e8faSwyllys * and return the value to the caller. This simplifies the 211430a5e8faSwyllys * operation by doing both "kmf_get_attr" calls and avoids 211530a5e8faSwyllys * duplicating this block of code in lots of places. 211630a5e8faSwyllys */ 211730a5e8faSwyllys KMF_RETURN 211830a5e8faSwyllys kmf_get_string_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attrlist, 211930a5e8faSwyllys int numattrs, char **outstr) 212030a5e8faSwyllys { 212130a5e8faSwyllys KMF_RETURN rv; 212230a5e8faSwyllys uint32_t len; 212330a5e8faSwyllys 212430a5e8faSwyllys if (outstr == NULL) 212530a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 212630a5e8faSwyllys 212730a5e8faSwyllys if ((rv = kmf_get_attr(type, attrlist, numattrs, NULL, &len)) == 212830a5e8faSwyllys KMF_OK) { 212930a5e8faSwyllys *outstr = malloc(len + 1); 213030a5e8faSwyllys if ((*outstr) == NULL) 213130a5e8faSwyllys return (KMF_ERR_MEMORY); 213230a5e8faSwyllys (void) memset((*outstr), 0, len + 1); 213330a5e8faSwyllys rv = kmf_get_attr(type, attrlist, numattrs, (*outstr), &len); 213430a5e8faSwyllys if (rv != KMF_OK) { 213530a5e8faSwyllys free(*outstr); 213630a5e8faSwyllys *outstr = NULL; 213730a5e8faSwyllys } 213830a5e8faSwyllys } 213930a5e8faSwyllys 214030a5e8faSwyllys return (rv); 214130a5e8faSwyllys } 214230a5e8faSwyllys 214330a5e8faSwyllys /* 214430a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 214530a5e8faSwyllys */ 214630a5e8faSwyllys KMF_RETURN 214730a5e8faSwyllys KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 214830a5e8faSwyllys { 214930a5e8faSwyllys 215030a5e8faSwyllys KMF_ATTRIBUTE attlist[32]; 215130a5e8faSwyllys int i = 0; 215230a5e8faSwyllys 215330a5e8faSwyllys if (params == NULL) 215430a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 215530a5e8faSwyllys 215630a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 215730a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, ¶ms->kstype, sizeof (params->kstype)); 215830a5e8faSwyllys i++; 215930a5e8faSwyllys 216030a5e8faSwyllys if (params->kstype == KMF_KEYSTORE_NSS) { 216130a5e8faSwyllys if (params->nssconfig.configdir != NULL) { 216230a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 216330a5e8faSwyllys KMF_DIRPATH_ATTR, 216430a5e8faSwyllys params->nssconfig.configdir, 216530a5e8faSwyllys strlen(params->nssconfig.configdir)); 216630a5e8faSwyllys i++; 216730a5e8faSwyllys } 216830a5e8faSwyllys if (params->nssconfig.certPrefix != NULL) { 216930a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 217030a5e8faSwyllys KMF_CERTPREFIX_ATTR, 217130a5e8faSwyllys params->nssconfig.certPrefix, 217230a5e8faSwyllys strlen(params->nssconfig.certPrefix)); 217330a5e8faSwyllys i++; 217430a5e8faSwyllys } 217530a5e8faSwyllys if (params->nssconfig.keyPrefix != NULL) { 217630a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 217730a5e8faSwyllys KMF_KEYPREFIX_ATTR, 217830a5e8faSwyllys params->nssconfig.keyPrefix, 217930a5e8faSwyllys strlen(params->nssconfig.keyPrefix)); 218030a5e8faSwyllys i++; 218130a5e8faSwyllys } 218230a5e8faSwyllys if (params->nssconfig.secModName != NULL) { 218330a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 218430a5e8faSwyllys KMF_SECMODNAME_ATTR, 218530a5e8faSwyllys params->nssconfig.secModName, 218630a5e8faSwyllys strlen(params->nssconfig.secModName)); 218730a5e8faSwyllys i++; 218830a5e8faSwyllys } 218930a5e8faSwyllys } else if (params->kstype == KMF_KEYSTORE_PK11TOKEN) { 219030a5e8faSwyllys if (params->pkcs11config.label != NULL) { 219130a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 219230a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, 219330a5e8faSwyllys params->pkcs11config.label, 219430a5e8faSwyllys strlen(params->pkcs11config.label)); 219530a5e8faSwyllys i++; 219630a5e8faSwyllys } 219730a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 219830a5e8faSwyllys KMF_READONLY_ATTR, 219930a5e8faSwyllys ¶ms->pkcs11config.readonly, 220030a5e8faSwyllys sizeof (params->pkcs11config.readonly)); 220130a5e8faSwyllys i++; 220230a5e8faSwyllys } 220330a5e8faSwyllys 220430a5e8faSwyllys return (kmf_configure_keystore(handle, i, attlist)); 220530a5e8faSwyllys } 220630a5e8faSwyllys 220730a5e8faSwyllys /* 220830a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 220930a5e8faSwyllys */ 221030a5e8faSwyllys KMF_RETURN 221130a5e8faSwyllys KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 221230a5e8faSwyllys { 221330a5e8faSwyllys return (kmf_initialize(outhandle, policyfile, policyname)); 221430a5e8faSwyllys } 221530a5e8faSwyllys 221630a5e8faSwyllys /* 221730a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 221830a5e8faSwyllys */ 221930a5e8faSwyllys KMF_RETURN 222030a5e8faSwyllys KMF_Finalize(KMF_HANDLE_T handle) 222130a5e8faSwyllys { 222230a5e8faSwyllys return (kmf_finalize(handle)); 222330a5e8faSwyllys } 222430a5e8faSwyllys 222530a5e8faSwyllys /* 222630a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 222730a5e8faSwyllys */ 222830a5e8faSwyllys KMF_RETURN 222930a5e8faSwyllys KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) 223030a5e8faSwyllys { 223130a5e8faSwyllys return (kmf_get_kmf_error_str(errcode, errmsg)); 223230a5e8faSwyllys } 223330a5e8faSwyllys 223430a5e8faSwyllys /* 223530a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 223630a5e8faSwyllys */ 223730a5e8faSwyllys KMF_RETURN 223830a5e8faSwyllys KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 223930a5e8faSwyllys { 224030a5e8faSwyllys return (kmf_read_input_file(handle, filename, pdata)); 224130a5e8faSwyllys } 224230a5e8faSwyllys 224330a5e8faSwyllys 224430a5e8faSwyllys /* 224530a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 224630a5e8faSwyllys */ 224730a5e8faSwyllys void 224830a5e8faSwyllys KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 224930a5e8faSwyllys { 225030a5e8faSwyllys kmf_free_kmf_cert(handle, kmf_cert); 225130a5e8faSwyllys } 225230a5e8faSwyllys 225330a5e8faSwyllys /* 225430a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 225530a5e8faSwyllys */ 225630a5e8faSwyllys void 225730a5e8faSwyllys KMF_FreeData(KMF_DATA *datablock) 225830a5e8faSwyllys { 225930a5e8faSwyllys kmf_free_data(datablock); 226030a5e8faSwyllys } 226130a5e8faSwyllys 226230a5e8faSwyllys /* 226330a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 226430a5e8faSwyllys */ 226530a5e8faSwyllys void 226630a5e8faSwyllys KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 226730a5e8faSwyllys { 226830a5e8faSwyllys kmf_free_kmf_key(handle, key); 226930a5e8faSwyllys } 227030a5e8faSwyllys 227130a5e8faSwyllys /* 227230a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 227330a5e8faSwyllys */ 227430a5e8faSwyllys void 227530a5e8faSwyllys KMF_FreeSignedCSR(KMF_CSR_DATA *csr) 227630a5e8faSwyllys { 227730a5e8faSwyllys kmf_free_signed_csr(csr); 227830a5e8faSwyllys } 2279