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 155*30a5e8faSwyllys 156*30a5e8faSwyllys 15799ebb4caSwyllys static void free_extensions(KMF_X509_EXTENSIONS *extns); 15899ebb4caSwyllys 1599b37d296Swyllys KMF_RETURN 1609b37d296Swyllys init_pk11() 16199ebb4caSwyllys { 1629b37d296Swyllys (void) mutex_lock(&init_lock); 1639b37d296Swyllys if (!pkcs11_initialized) { 1649b37d296Swyllys CK_RV rv = C_Initialize(NULL); 1659b37d296Swyllys if ((rv != CKR_OK) && 1669b37d296Swyllys (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 1679b37d296Swyllys (void) mutex_unlock(&init_lock); 1689b37d296Swyllys return (KMF_ERR_UNINITIALIZED); 1699b37d296Swyllys } else { 1709b37d296Swyllys pkcs11_initialized = 1; 1719b37d296Swyllys } 1729b37d296Swyllys } 1739b37d296Swyllys (void) mutex_unlock(&init_lock); 1749b37d296Swyllys return (KMF_OK); 17599ebb4caSwyllys } 17699ebb4caSwyllys 17799ebb4caSwyllys /* 17899ebb4caSwyllys * Private method for searching the plugin list for the correct 17999ebb4caSwyllys * Plugin to use. 18099ebb4caSwyllys */ 18199ebb4caSwyllys KMF_PLUGIN * 18299ebb4caSwyllys FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype) 18399ebb4caSwyllys { 18499ebb4caSwyllys KMF_PLUGIN_LIST *node; 18599ebb4caSwyllys 18699ebb4caSwyllys if (handle == NULL) 18799ebb4caSwyllys return (NULL); 18899ebb4caSwyllys 18999ebb4caSwyllys node = handle->plugins; 19099ebb4caSwyllys 19199ebb4caSwyllys while (node != NULL && node->plugin->type != kstype) 19299ebb4caSwyllys node = node->next; 19399ebb4caSwyllys 19499ebb4caSwyllys /* If it is NULL, that is indication enough of an error */ 19599ebb4caSwyllys return (node ? node->plugin : NULL); 19699ebb4caSwyllys } 19799ebb4caSwyllys 19899ebb4caSwyllys static KMF_RETURN 19999ebb4caSwyllys InitializePlugin(KMF_KEYSTORE_TYPE kstype, char *path, KMF_PLUGIN **plugin) 20099ebb4caSwyllys { 20199ebb4caSwyllys KMF_PLUGIN *p = NULL; 20299ebb4caSwyllys KMF_PLUGIN_FUNCLIST *(*sym)(); 20399ebb4caSwyllys 20499ebb4caSwyllys if (path == NULL || plugin == NULL) 20599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 20699ebb4caSwyllys 20799ebb4caSwyllys *plugin = NULL; 20899ebb4caSwyllys 20999ebb4caSwyllys p = (KMF_PLUGIN *)malloc(sizeof (KMF_PLUGIN)); 21099ebb4caSwyllys if (p == NULL) 21199ebb4caSwyllys return (KMF_ERR_MEMORY); 21299ebb4caSwyllys 21399ebb4caSwyllys p->type = kstype; 21499ebb4caSwyllys p->path = strdup(path); 21599ebb4caSwyllys if (p->path == NULL) { 21699ebb4caSwyllys free(p); 21799ebb4caSwyllys return (KMF_ERR_MEMORY); 21899ebb4caSwyllys } 21999ebb4caSwyllys p->dldesc = dlopen(path, RTLD_NOW | RTLD_GROUP | RTLD_PARENT); 22099ebb4caSwyllys if (p->dldesc == NULL) { 22199ebb4caSwyllys free(p->path); 22299ebb4caSwyllys free(p); 22399ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 22499ebb4caSwyllys } 22599ebb4caSwyllys 22699ebb4caSwyllys sym = (KMF_PLUGIN_FUNCLIST *(*)())dlsym(p->dldesc, 227*30a5e8faSwyllys KMF_PLUGIN_INIT_SYMBOL); 22899ebb4caSwyllys if (sym == NULL) { 22999ebb4caSwyllys (void) dlclose(p->dldesc); 23099ebb4caSwyllys free(p->path); 23199ebb4caSwyllys free(p); 23299ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 23399ebb4caSwyllys } 23499ebb4caSwyllys 23599ebb4caSwyllys /* Get the function list */ 23699ebb4caSwyllys if ((p->funclist = (*sym)()) == NULL) { 23799ebb4caSwyllys (void) dlclose(p->dldesc); 23899ebb4caSwyllys free(p->path); 23999ebb4caSwyllys free(p); 24099ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 24199ebb4caSwyllys } 24299ebb4caSwyllys 24399ebb4caSwyllys *plugin = p; 24499ebb4caSwyllys 24599ebb4caSwyllys return (KMF_OK); 24699ebb4caSwyllys } 24799ebb4caSwyllys 24899ebb4caSwyllys static KMF_RETURN 24999ebb4caSwyllys AddPlugin(KMF_HANDLE_T handle, KMF_PLUGIN *plugin) 25099ebb4caSwyllys { 25199ebb4caSwyllys KMF_PLUGIN_LIST *n; 25299ebb4caSwyllys 25399ebb4caSwyllys if (handle == NULL || plugin == NULL) 25499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 25599ebb4caSwyllys 25699ebb4caSwyllys /* If the head is NULL, create it */ 25799ebb4caSwyllys if (handle->plugins == NULL) { 25899ebb4caSwyllys handle->plugins = (KMF_PLUGIN_LIST *)malloc( 259*30a5e8faSwyllys sizeof (KMF_PLUGIN_LIST)); 26099ebb4caSwyllys if (handle->plugins == NULL) 26199ebb4caSwyllys return (KMF_ERR_MEMORY); 26299ebb4caSwyllys handle->plugins->plugin = plugin; 26399ebb4caSwyllys handle->plugins->next = NULL; 26499ebb4caSwyllys } else { 26599ebb4caSwyllys /* walk the list to find the tail */ 26699ebb4caSwyllys n = handle->plugins; 26799ebb4caSwyllys while (n->next != NULL) 26899ebb4caSwyllys n = n->next; 26999ebb4caSwyllys n->next = (KMF_PLUGIN_LIST *)malloc(sizeof (KMF_PLUGIN_LIST)); 27099ebb4caSwyllys if (n->next == NULL) 27199ebb4caSwyllys return (KMF_ERR_MEMORY); 27299ebb4caSwyllys 27399ebb4caSwyllys n->next->plugin = plugin; 27499ebb4caSwyllys n->next->next = NULL; 27599ebb4caSwyllys } 27699ebb4caSwyllys return (0); 27799ebb4caSwyllys } 27899ebb4caSwyllys 27999ebb4caSwyllys static void 28099ebb4caSwyllys DestroyPlugin(KMF_PLUGIN *plugin) 28199ebb4caSwyllys { 28299ebb4caSwyllys if (plugin) { 28399ebb4caSwyllys if (plugin->path) 28499ebb4caSwyllys free(plugin->path); 28599ebb4caSwyllys free(plugin); 28699ebb4caSwyllys } 28799ebb4caSwyllys } 28899ebb4caSwyllys 28999ebb4caSwyllys static void 29099ebb4caSwyllys Cleanup_KMF_Handle(KMF_HANDLE_T handle) 29199ebb4caSwyllys { 29299ebb4caSwyllys if (handle != NULL) { 29399ebb4caSwyllys while (handle->plugins != NULL) { 29499ebb4caSwyllys KMF_PLUGIN_LIST *next = handle->plugins->next; 29599ebb4caSwyllys 29699ebb4caSwyllys DestroyPlugin(handle->plugins->plugin); 29799ebb4caSwyllys 29899ebb4caSwyllys free(handle->plugins); 29999ebb4caSwyllys 30099ebb4caSwyllys handle->plugins = next; 30199ebb4caSwyllys } 30299ebb4caSwyllys 303*30a5e8faSwyllys kmf_free_policy_record(handle->policy); 30499ebb4caSwyllys free(handle->policy); 30599ebb4caSwyllys } 30699ebb4caSwyllys free(handle); 30799ebb4caSwyllys } 30899ebb4caSwyllys 30999ebb4caSwyllys void 31099ebb4caSwyllys Cleanup_PK11_Session(KMF_HANDLE_T handle) 31199ebb4caSwyllys { 31299ebb4caSwyllys if (handle != NULL) { 31399ebb4caSwyllys /* Close active session on a pkcs11 token */ 31499ebb4caSwyllys if (handle->pk11handle != NULL) { 31599ebb4caSwyllys (void) C_CloseSession(handle->pk11handle); 31699ebb4caSwyllys handle->pk11handle = NULL; 31799ebb4caSwyllys } 31899ebb4caSwyllys } 31999ebb4caSwyllys } 32099ebb4caSwyllys 32199ebb4caSwyllys KMF_RETURN 322*30a5e8faSwyllys kmf_initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 32399ebb4caSwyllys { 32499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 32599ebb4caSwyllys KMF_HANDLE *handle = NULL; 32699ebb4caSwyllys KMF_PLUGIN *pluginrec = NULL; 32785b65b39Swyllys int i, numitems; 32899ebb4caSwyllys 32999ebb4caSwyllys if (outhandle == NULL) 33099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 33199ebb4caSwyllys 33299ebb4caSwyllys *outhandle = NULL; 33399ebb4caSwyllys handle = (KMF_HANDLE *)malloc(sizeof (KMF_HANDLE)); 33499ebb4caSwyllys if (handle == NULL) 33599ebb4caSwyllys return (KMF_ERR_MEMORY); 33699ebb4caSwyllys 33799ebb4caSwyllys (void) memset(handle, 0, sizeof (KMF_HANDLE)); 33899ebb4caSwyllys handle->plugins = NULL; 33999ebb4caSwyllys 34099ebb4caSwyllys /* Initialize the handle with the policy */ 341*30a5e8faSwyllys ret = kmf_set_policy((void *)handle, 34299ebb4caSwyllys policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile, 34399ebb4caSwyllys policyname == NULL ? KMF_DEFAULT_POLICY_NAME : policyname); 34499ebb4caSwyllys if (ret != KMF_OK) 34599ebb4caSwyllys goto errout; 34699ebb4caSwyllys 34785b65b39Swyllys numitems = sizeof (plugin_list)/sizeof (KMF_PLUGIN_ITEM); 34885b65b39Swyllys for (i = 0; i < numitems; i++) { 34985b65b39Swyllys ret = InitializePlugin(plugin_list[i].kstype, 350*30a5e8faSwyllys plugin_list[i].path, &pluginrec); 35185b65b39Swyllys if (ret != KMF_OK) { 35285b65b39Swyllys cryptoerror( 35385b65b39Swyllys plugin_list[i].critical ? LOG_WARNING : LOG_DEBUG, 35485b65b39Swyllys "KMF was unable to load %s plugin module %s\n", 35585b65b39Swyllys plugin_list[i].critical ? "critical" : "optional", 35685b65b39Swyllys plugin_list[i].path); 35785b65b39Swyllys 35885b65b39Swyllys if (plugin_list[i].critical == FALSE) 35985b65b39Swyllys ret = KMF_OK; 36085b65b39Swyllys else 36185b65b39Swyllys goto errout; 36285b65b39Swyllys } 36385b65b39Swyllys if (pluginrec != NULL) { 36485b65b39Swyllys if ((ret = AddPlugin(handle, pluginrec))) 36585b65b39Swyllys goto errout; 36685b65b39Swyllys } 36799ebb4caSwyllys } 36899ebb4caSwyllys 36999ebb4caSwyllys CLEAR_ERROR(handle, ret); 37099ebb4caSwyllys errout: 37199ebb4caSwyllys if (ret != KMF_OK) { 37299ebb4caSwyllys Cleanup_KMF_Handle(handle); 37399ebb4caSwyllys handle = NULL; 37499ebb4caSwyllys } 37599ebb4caSwyllys 37699ebb4caSwyllys *outhandle = (KMF_HANDLE_T)handle; 37799ebb4caSwyllys return (ret); 37899ebb4caSwyllys } 37999ebb4caSwyllys 38099ebb4caSwyllys KMF_RETURN 381*30a5e8faSwyllys kmf_configure_keystore(KMF_HANDLE_T handle, 382*30a5e8faSwyllys int num_args, 383*30a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 38499ebb4caSwyllys { 385*30a5e8faSwyllys KMF_RETURN ret = KMF_OK; 38699ebb4caSwyllys KMF_PLUGIN *plugin; 387*30a5e8faSwyllys KMF_KEYSTORE_TYPE kstype; 388*30a5e8faSwyllys uint32_t len; 389*30a5e8faSwyllys 390*30a5e8faSwyllys KMF_ATTRIBUTE_TESTER required_attrs[] = { 391*30a5e8faSwyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 392*30a5e8faSwyllys }; 393*30a5e8faSwyllys 394*30a5e8faSwyllys int num_req_attrs = sizeof (required_attrs) / 395*30a5e8faSwyllys sizeof (KMF_ATTRIBUTE_TESTER); 396*30a5e8faSwyllys 397*30a5e8faSwyllys if (handle == NULL) 398*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 39999ebb4caSwyllys 40099ebb4caSwyllys CLEAR_ERROR(handle, ret); 401*30a5e8faSwyllys 402*30a5e8faSwyllys ret = test_attributes(num_req_attrs, required_attrs, 403*30a5e8faSwyllys 0, NULL, num_args, attrlist); 404*30a5e8faSwyllys 40599ebb4caSwyllys if (ret != KMF_OK) 40699ebb4caSwyllys return (ret); 40799ebb4caSwyllys 408*30a5e8faSwyllys len = sizeof (kstype); 409*30a5e8faSwyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, 410*30a5e8faSwyllys &kstype, &len); 411*30a5e8faSwyllys if (ret != KMF_OK) 412*30a5e8faSwyllys return (ret); 41399ebb4caSwyllys 414*30a5e8faSwyllys plugin = FindPlugin(handle, kstype); 415*30a5e8faSwyllys if (plugin != NULL && plugin->funclist->ConfigureKeystore != NULL) { 416*30a5e8faSwyllys return (plugin->funclist->ConfigureKeystore(handle, num_args, 417*30a5e8faSwyllys attrlist)); 418*30a5e8faSwyllys } else { 41999ebb4caSwyllys /* return KMF_OK, if the plugin does not have an entry */ 42099ebb4caSwyllys return (KMF_OK); 421*30a5e8faSwyllys } 42299ebb4caSwyllys } 42399ebb4caSwyllys 42499ebb4caSwyllys KMF_RETURN 425*30a5e8faSwyllys kmf_finalize(KMF_HANDLE_T handle) 42699ebb4caSwyllys { 42799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 42899ebb4caSwyllys 42999ebb4caSwyllys CLEAR_ERROR(handle, ret); 43099ebb4caSwyllys if (ret != KMF_OK) 43199ebb4caSwyllys return (ret); 43299ebb4caSwyllys 43399ebb4caSwyllys if (pkcs11_initialized) { 43499ebb4caSwyllys Cleanup_PK11_Session(handle); 43599ebb4caSwyllys } 43699ebb4caSwyllys Cleanup_KMF_Handle(handle); 43799ebb4caSwyllys 43899ebb4caSwyllys return (ret); 43999ebb4caSwyllys } 44099ebb4caSwyllys 44199ebb4caSwyllys KMF_RETURN 442*30a5e8faSwyllys kmf_get_kmf_error_str(KMF_RETURN errcode, char **errmsg) 44399ebb4caSwyllys { 44499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 44599ebb4caSwyllys int i, maxerr; 44699ebb4caSwyllys 44799ebb4caSwyllys if (errmsg == NULL) 44899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 44999ebb4caSwyllys 45099ebb4caSwyllys *errmsg = NULL; 45199ebb4caSwyllys maxerr = sizeof (kmf_errcodes) / sizeof (kmf_error_map); 45299ebb4caSwyllys 453*30a5e8faSwyllys for (i = 0; i < maxerr && errcode != kmf_errcodes[i].code; i++) 454*30a5e8faSwyllys /* empty body */ 455*30a5e8faSwyllys ; 45699ebb4caSwyllys 45799ebb4caSwyllys if (i == maxerr) 45899ebb4caSwyllys return (KMF_ERR_MISSING_ERRCODE); 45999ebb4caSwyllys else { 46099ebb4caSwyllys *errmsg = strdup(kmf_errcodes[i].message); 46199ebb4caSwyllys if ((*errmsg) == NULL) 46299ebb4caSwyllys return (KMF_ERR_MEMORY); 46399ebb4caSwyllys } 46499ebb4caSwyllys return (ret); 46599ebb4caSwyllys } 46699ebb4caSwyllys 46799ebb4caSwyllys KMF_RETURN 468*30a5e8faSwyllys kmf_get_plugin_error_str(KMF_HANDLE_T handle, char **msgstr) 46999ebb4caSwyllys { 47099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 47199ebb4caSwyllys KMF_PLUGIN *plugin; 47299ebb4caSwyllys 47399ebb4caSwyllys if (handle == NULL || msgstr == NULL) 47499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 47599ebb4caSwyllys 47699ebb4caSwyllys *msgstr = NULL; 47799ebb4caSwyllys 47899ebb4caSwyllys if (handle->lasterr.errcode == 0) { 47999ebb4caSwyllys return (KMF_ERR_MISSING_ERRCODE); 48099ebb4caSwyllys } 48199ebb4caSwyllys 48299ebb4caSwyllys if (handle->lasterr.kstype == -1) { /* System error */ 48399ebb4caSwyllys char *str = strerror(handle->lasterr.errcode); 48499ebb4caSwyllys if (str != NULL) { 48599ebb4caSwyllys *msgstr = strdup(str); 48699ebb4caSwyllys if ((*msgstr) == NULL) 48799ebb4caSwyllys return (KMF_ERR_MEMORY); 48899ebb4caSwyllys } 48999ebb4caSwyllys return (KMF_OK); 49099ebb4caSwyllys } 49199ebb4caSwyllys 49299ebb4caSwyllys plugin = FindPlugin(handle, handle->lasterr.kstype); 49399ebb4caSwyllys if (plugin == NULL) 49499ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 49599ebb4caSwyllys 49699ebb4caSwyllys if (plugin->funclist->GetErrorString != NULL) { 49799ebb4caSwyllys ret = plugin->funclist->GetErrorString(handle, msgstr); 49899ebb4caSwyllys } else { 49999ebb4caSwyllys return (KMF_ERR_FUNCTION_NOT_FOUND); 50099ebb4caSwyllys } 50199ebb4caSwyllys 50299ebb4caSwyllys return (ret); 50399ebb4caSwyllys } 50499ebb4caSwyllys 50599ebb4caSwyllys 5069b37d296Swyllys #define SET_SYS_ERROR(h, c) if (h) {\ 5079b37d296Swyllys h->lasterr.kstype = -1;\ 5089b37d296Swyllys h->lasterr.errcode = c;\ 5099b37d296Swyllys } 51099ebb4caSwyllys 51199ebb4caSwyllys KMF_RETURN 512*30a5e8faSwyllys kmf_read_input_file(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 51399ebb4caSwyllys { 51499ebb4caSwyllys struct stat s; 51599ebb4caSwyllys long nread, total = 0; 51699ebb4caSwyllys int fd; 51799ebb4caSwyllys unsigned char *buf = NULL; 51899ebb4caSwyllys KMF_RETURN ret; 51999ebb4caSwyllys 5209b37d296Swyllys if (handle) { 5219b37d296Swyllys CLEAR_ERROR(handle, ret); 5229b37d296Swyllys if (ret != KMF_OK) 5239b37d296Swyllys return (ret); 5249b37d296Swyllys } 52599ebb4caSwyllys 52699ebb4caSwyllys if (filename == NULL || pdata == NULL) { 52799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 52899ebb4caSwyllys } 52999ebb4caSwyllys 53099ebb4caSwyllys if ((fd = open(filename, O_RDONLY)) < 0) { 53199ebb4caSwyllys SET_SYS_ERROR(handle, errno); 53299ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 53399ebb4caSwyllys } 53499ebb4caSwyllys 53599ebb4caSwyllys if (fstat(fd, &s) < 0) { 53699ebb4caSwyllys SET_SYS_ERROR(handle, errno); 53799ebb4caSwyllys (void) close(fd); 53899ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 53999ebb4caSwyllys } 54099ebb4caSwyllys 54199ebb4caSwyllys if ((buf = (unsigned char *) malloc(s.st_size)) == NULL) { 54299ebb4caSwyllys (void) close(fd); 54399ebb4caSwyllys return (KMF_ERR_MEMORY); 54499ebb4caSwyllys } 54599ebb4caSwyllys 54699ebb4caSwyllys do { 54799ebb4caSwyllys nread = read(fd, buf+total, s.st_size-total); 54899ebb4caSwyllys if (nread < 0) { 54999ebb4caSwyllys SET_SYS_ERROR(handle, errno); 55099ebb4caSwyllys (void) close(fd); 55199ebb4caSwyllys free(buf); 55299ebb4caSwyllys return (KMF_ERR_INTERNAL); 55399ebb4caSwyllys } 55499ebb4caSwyllys total += nread; 55599ebb4caSwyllys } while (total < s.st_size); 55699ebb4caSwyllys 55799ebb4caSwyllys pdata->Data = buf; 55899ebb4caSwyllys pdata->Length = s.st_size; 55999ebb4caSwyllys (void) close(fd); 56099ebb4caSwyllys return (KMF_OK); 56199ebb4caSwyllys } 56299ebb4caSwyllys 56399ebb4caSwyllys /* 56499ebb4caSwyllys * 565*30a5e8faSwyllys * Name: kmf_der_to_pem 56699ebb4caSwyllys * 56799ebb4caSwyllys * Description: 56899ebb4caSwyllys * Function for converting DER encoded format to PEM encoded format 56999ebb4caSwyllys * 57099ebb4caSwyllys * Parameters: 57199ebb4caSwyllys * type(input) - CERTIFICATE or CSR 57299ebb4caSwyllys * data(input) - pointer to the DER encoded data 57399ebb4caSwyllys * len(input) - length of input data 57499ebb4caSwyllys * out(output) - contains the output buffer address to be returned 57599ebb4caSwyllys * outlen(output) - pointer to the returned output length 57699ebb4caSwyllys * 57799ebb4caSwyllys * Returns: 57899ebb4caSwyllys * A KMF_RETURN value indicating success or specifying a particular 57999ebb4caSwyllys * error condition. 58099ebb4caSwyllys * The value KMF_OK indicates success. All other values represent 58199ebb4caSwyllys * an error condition. 58299ebb4caSwyllys * 58399ebb4caSwyllys */ 58499ebb4caSwyllys KMF_RETURN 585*30a5e8faSwyllys kmf_der_to_pem(KMF_OBJECT_TYPE type, unsigned char *data, 58699ebb4caSwyllys int len, unsigned char **out, int *outlen) 58799ebb4caSwyllys { 58899ebb4caSwyllys 58999ebb4caSwyllys KMF_RETURN err; 59099ebb4caSwyllys if (data == NULL || out == NULL || outlen == NULL) 59199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 59299ebb4caSwyllys 59399ebb4caSwyllys err = Der2Pem(type, data, len, out, outlen); 59499ebb4caSwyllys return (err); 59599ebb4caSwyllys 59699ebb4caSwyllys } 59799ebb4caSwyllys 59899ebb4caSwyllys /* 59999ebb4caSwyllys * 600*30a5e8faSwyllys * Name: kmf_pem_to_der 60199ebb4caSwyllys * 60299ebb4caSwyllys * Description: 60399ebb4caSwyllys * Function for converting PEM encoded format to DER encoded format 60499ebb4caSwyllys * 60599ebb4caSwyllys * Parameters: 60699ebb4caSwyllys * in(input) - pointer to the PEM encoded data 60799ebb4caSwyllys * inlen(input) - length of input data 60899ebb4caSwyllys * out(output) - contains the output buffer address to be returned 60999ebb4caSwyllys * outlen(output) - pointer to the returned output length 61099ebb4caSwyllys * 61199ebb4caSwyllys * Returns: 61299ebb4caSwyllys * A KMF_RETURN value indicating success or specifying a particular 61399ebb4caSwyllys * error condition. 61499ebb4caSwyllys * The value KMF_OK indicates success. All other values represent 61599ebb4caSwyllys * an error condition. 61699ebb4caSwyllys * 61799ebb4caSwyllys */ 61899ebb4caSwyllys KMF_RETURN 619*30a5e8faSwyllys kmf_pem_to_der(unsigned char *in, int inlen, 62099ebb4caSwyllys unsigned char **out, int *outlen) 62199ebb4caSwyllys { 62299ebb4caSwyllys KMF_RETURN err; 62399ebb4caSwyllys if (in == NULL || out == NULL || outlen == NULL) 62499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 62599ebb4caSwyllys 62699ebb4caSwyllys err = Pem2Der(in, inlen, out, outlen); 62799ebb4caSwyllys return (err); 62899ebb4caSwyllys } 62999ebb4caSwyllys 63099ebb4caSwyllys char * 631*30a5e8faSwyllys kmf_oid_to_string(KMF_OID *oid) 63299ebb4caSwyllys { 63399ebb4caSwyllys char numstr[128]; 63499ebb4caSwyllys uint32_t number; 63599ebb4caSwyllys int numshift; 63699ebb4caSwyllys uint32_t i, string_length; 63799ebb4caSwyllys uchar_t *cp; 63899ebb4caSwyllys char *bp; 63999ebb4caSwyllys 64099ebb4caSwyllys /* First determine the size of the string */ 64199ebb4caSwyllys string_length = 0; 64299ebb4caSwyllys number = 0; 64399ebb4caSwyllys numshift = 0; 64499ebb4caSwyllys cp = (unsigned char *)oid->Data; 64599ebb4caSwyllys 64699ebb4caSwyllys number = (uint32_t)cp[0]; 64799ebb4caSwyllys (void) sprintf(numstr, "%d ", number/40); 64899ebb4caSwyllys 64999ebb4caSwyllys string_length += strlen(numstr); 65099ebb4caSwyllys (void) sprintf(numstr, "%d ", number%40); 65199ebb4caSwyllys 65299ebb4caSwyllys string_length += strlen(numstr); 65399ebb4caSwyllys 65499ebb4caSwyllys for (i = 1; i < oid->Length; i++) { 65599ebb4caSwyllys if ((uint32_t)(numshift+7) < (sizeof (uint32_t)*8)) { 65699ebb4caSwyllys number = (number << 7) | (cp[i] & 0x7f); 65799ebb4caSwyllys numshift += 7; 65899ebb4caSwyllys } else { 65999ebb4caSwyllys return (NULL); 66099ebb4caSwyllys } 66199ebb4caSwyllys 66299ebb4caSwyllys if ((cp[i] & 0x80) == 0) { 66399ebb4caSwyllys (void) sprintf(numstr, "%d ", number); 66499ebb4caSwyllys string_length += strlen(numstr); 66599ebb4caSwyllys number = 0; 66699ebb4caSwyllys numshift = 0; 66799ebb4caSwyllys } 66899ebb4caSwyllys } 66999ebb4caSwyllys /* 67099ebb4caSwyllys * If we get here, we've calculated the length of "n n n ... n ". Add 4 67199ebb4caSwyllys * here for "{ " and "}\0". 67299ebb4caSwyllys */ 67399ebb4caSwyllys string_length += 4; 67499ebb4caSwyllys if ((bp = (char *)malloc(string_length))) { 67599ebb4caSwyllys number = (uint32_t)cp[0]; 67699ebb4caSwyllys 67799ebb4caSwyllys (void) sprintf(numstr, "%d.", number/40); 67899ebb4caSwyllys (void) strcpy(bp, numstr); 67999ebb4caSwyllys 68099ebb4caSwyllys (void) sprintf(numstr, "%d.", number%40); 68199ebb4caSwyllys (void) strcat(bp, numstr); 68299ebb4caSwyllys 68399ebb4caSwyllys number = 0; 68499ebb4caSwyllys cp = (unsigned char *) oid->Data; 68599ebb4caSwyllys for (i = 1; i < oid->Length; i++) { 68699ebb4caSwyllys number = (number << 7) | (cp[i] & 0x7f); 68799ebb4caSwyllys if ((cp[i] & 0x80) == 0) { 68899ebb4caSwyllys (void) sprintf(numstr, "%d", number); 68999ebb4caSwyllys (void) strcat(bp, numstr); 69099ebb4caSwyllys number = 0; 69199ebb4caSwyllys if (i+1 < oid->Length) 69299ebb4caSwyllys (void) strcat(bp, "."); 69399ebb4caSwyllys } 69499ebb4caSwyllys } 69599ebb4caSwyllys } 69699ebb4caSwyllys return (bp); 69799ebb4caSwyllys } 69899ebb4caSwyllys 69902744e81Swyllys static boolean_t 70008ec4bd3Shylee check_for_pem(uchar_t *buf, KMF_ENCODE_FORMAT *fmt) 70102744e81Swyllys { 7029b37d296Swyllys char *p; 70302744e81Swyllys 70408ec4bd3Shylee if (buf == NULL) 70502744e81Swyllys return (FALSE); 70602744e81Swyllys 70708ec4bd3Shylee if (memcmp(buf, "Bag Attr", 8) == 0) { 70808ec4bd3Shylee *fmt = KMF_FORMAT_PEM_KEYPAIR; 70908ec4bd3Shylee return (TRUE); 71008ec4bd3Shylee } 71108ec4bd3Shylee 7129b37d296Swyllys /* Look for "-----BEGIN" right after a newline */ 71308ec4bd3Shylee p = strtok((char *)buf, "\n"); 7149b37d296Swyllys while (p != NULL) { 7159b37d296Swyllys if (strstr(p, "-----BEGIN") != NULL) { 71608ec4bd3Shylee *fmt = KMF_FORMAT_PEM; 7179b37d296Swyllys return (TRUE); 71802744e81Swyllys } 7199b37d296Swyllys p = strtok(NULL, "\n"); 72002744e81Swyllys } 72102744e81Swyllys return (FALSE); 72202744e81Swyllys } 72302744e81Swyllys 72408ec4bd3Shylee 72508ec4bd3Shylee static unsigned char pkcs12_version[3] = {0x02, 0x01, 0x03}; 72608ec4bd3Shylee static unsigned char pkcs12_oid[11] = 72708ec4bd3Shylee {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01}; 72808ec4bd3Shylee 72908ec4bd3Shylee /* 73008ec4bd3Shylee * This function takes a BER encoded string as input and checks the version 73108ec4bd3Shylee * and the oid in the the top-level ASN.1 structure to see if it complies to 73208ec4bd3Shylee * the PKCS#12 Syntax. 73308ec4bd3Shylee */ 73408ec4bd3Shylee static boolean_t 73508ec4bd3Shylee check_for_pkcs12(uchar_t *buf, int buf_len) 73608ec4bd3Shylee { 73708ec4bd3Shylee int index = 0; 73808ec4bd3Shylee int length_octets; 73908ec4bd3Shylee 74008ec4bd3Shylee if (buf == NULL || buf_len <= 0) 74108ec4bd3Shylee return (FALSE); 74208ec4bd3Shylee 74308ec4bd3Shylee /* 74408ec4bd3Shylee * The top level structure for a PKCS12 string: 74508ec4bd3Shylee * 74608ec4bd3Shylee * PFX ::= SEQUENCE { 74708ec4bd3Shylee * version INTEGER {v3(3)}(v3,...) 74808ec4bd3Shylee * authSafe ContentInfo 74908ec4bd3Shylee * macData MacData OPTIONAL 75008ec4bd3Shylee * } 75108ec4bd3Shylee * 75208ec4bd3Shylee * ContentInfo 75308ec4bd3Shylee * FROM PKCS-7 {iso(1) member-body(2) us(840) rsadsi(113549) 75408ec4bd3Shylee * pkcs(1) pkcs-7(7) modules(0) pkcs-7(1)} 75508ec4bd3Shylee * 75608ec4bd3Shylee * Therefore, the BER/DER dump of a PKCS#12 file for the first 2 75708ec4bd3Shylee * sequences up to the oid part is as following: 75808ec4bd3Shylee * 75908ec4bd3Shylee * SEQUENCE { 76008ec4bd3Shylee * INTEGER 3 76108ec4bd3Shylee * SEQUENCE { 76208ec4bd3Shylee * OBJECT IDENTIFIER data (1 2 840 113549 1 7 1) 76308ec4bd3Shylee */ 76408ec4bd3Shylee 76508ec4bd3Shylee /* 76608ec4bd3Shylee * Check the first sequence and calculate the number of bytes used 76708ec4bd3Shylee * to store the length. 76808ec4bd3Shylee */ 76908ec4bd3Shylee if (buf[index++] != 0x30) 77008ec4bd3Shylee return (FALSE); 77108ec4bd3Shylee 77208ec4bd3Shylee if (buf[index] & 0x80) { 77308ec4bd3Shylee length_octets = buf[index++] & 0x0F; /* long form */ 77408ec4bd3Shylee } else { 77508ec4bd3Shylee length_octets = 1; /* short form */ 77608ec4bd3Shylee } 77708ec4bd3Shylee 77808ec4bd3Shylee index += length_octets; 77908ec4bd3Shylee if (index >= buf_len) 78008ec4bd3Shylee return (FALSE); 78108ec4bd3Shylee 78208ec4bd3Shylee /* Skip the length octets and check the pkcs12 version */ 78308ec4bd3Shylee if (memcmp(buf + index, pkcs12_version, sizeof (pkcs12_version)) != 0) 78408ec4bd3Shylee return (FALSE); 78508ec4bd3Shylee 78608ec4bd3Shylee index += sizeof (pkcs12_version); 78708ec4bd3Shylee if (index >= buf_len) 78808ec4bd3Shylee return (FALSE); 78908ec4bd3Shylee 79008ec4bd3Shylee /* 79108ec4bd3Shylee * Check the 2nd sequence and calculate the number of bytes used 79208ec4bd3Shylee * to store the length. 79308ec4bd3Shylee */ 79408ec4bd3Shylee if ((buf[index++] & 0xFF) != 0x30) 79508ec4bd3Shylee return (FALSE); 79608ec4bd3Shylee 79708ec4bd3Shylee if (buf[index] & 0x80) { 79808ec4bd3Shylee length_octets = buf[index++] & 0x0F; 79908ec4bd3Shylee } else { 80008ec4bd3Shylee length_octets = 1; 80108ec4bd3Shylee } 80208ec4bd3Shylee 80308ec4bd3Shylee index += length_octets; 80408ec4bd3Shylee if (index + sizeof (pkcs12_oid) >= buf_len) 80508ec4bd3Shylee return (FALSE); 80608ec4bd3Shylee 80708ec4bd3Shylee /* Skip the length octets and check the oid */ 80808ec4bd3Shylee if (memcmp(buf + index, pkcs12_oid, sizeof (pkcs12_oid)) != 0) 80908ec4bd3Shylee return (FALSE); 81008ec4bd3Shylee else 81108ec4bd3Shylee return (TRUE); 81208ec4bd3Shylee } 81308ec4bd3Shylee 81499ebb4caSwyllys KMF_RETURN 815*30a5e8faSwyllys kmf_get_file_format(char *filename, KMF_ENCODE_FORMAT *fmt) 81699ebb4caSwyllys { 81799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 81808ec4bd3Shylee KMF_DATA filebuf = {NULL, 0}; 81908ec4bd3Shylee uchar_t *buf; 82099ebb4caSwyllys 82199ebb4caSwyllys if (filename == NULL || !strlen(filename) || fmt == NULL) 82299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 82399ebb4caSwyllys 82499ebb4caSwyllys *fmt = 0; 825*30a5e8faSwyllys ret = kmf_read_input_file(NULL, filename, &filebuf); 82608ec4bd3Shylee if (ret != KMF_OK) 82708ec4bd3Shylee return (ret); 82899ebb4caSwyllys 82908ec4bd3Shylee if (filebuf.Length < 8) { 83008ec4bd3Shylee ret = KMF_ERR_ENCODING; /* too small */ 83199ebb4caSwyllys goto end; 83299ebb4caSwyllys } 83399ebb4caSwyllys 83408ec4bd3Shylee buf = filebuf.Data; 83508ec4bd3Shylee if (check_for_pkcs12(buf, filebuf.Length) == TRUE) { 83608ec4bd3Shylee *fmt = KMF_FORMAT_PKCS12; 83708ec4bd3Shylee } else if (buf[0] == 0x30 && (buf[1] & 0x80)) { 83899ebb4caSwyllys /* It is most likely a generic ASN.1 encoded file */ 83908ec4bd3Shylee *fmt = KMF_FORMAT_ASN1; 84008ec4bd3Shylee } else if (check_for_pem(buf, fmt) == TRUE) { 84108ec4bd3Shylee goto end; 84299ebb4caSwyllys } else { 84308ec4bd3Shylee /* Cannot determine this file format */ 84408ec4bd3Shylee *fmt = 0; 84508ec4bd3Shylee ret = KMF_ERR_ENCODING; 84699ebb4caSwyllys } 84708ec4bd3Shylee 84899ebb4caSwyllys end: 849*30a5e8faSwyllys kmf_free_data(&filebuf); 85099ebb4caSwyllys return (ret); 85199ebb4caSwyllys } 85299ebb4caSwyllys 85399ebb4caSwyllys KMF_RETURN 854*30a5e8faSwyllys kmf_hexstr_to_bytes(unsigned char *hexstr, unsigned char **bytes, 85599ebb4caSwyllys size_t *outlen) 85699ebb4caSwyllys { 85799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 85899ebb4caSwyllys unsigned char *buf = NULL; 85999ebb4caSwyllys int len, stringlen; 86099ebb4caSwyllys int i; 86199ebb4caSwyllys unsigned char ch; 86299ebb4caSwyllys 86399ebb4caSwyllys if (hexstr == NULL) { 86499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 86599ebb4caSwyllys } 86699ebb4caSwyllys 867*30a5e8faSwyllys if (hexstr[0] == '0' && ((hexstr[1] == 'x') || (hexstr[1] == 'X'))) 86899ebb4caSwyllys hexstr += 2; 86999ebb4caSwyllys 870*30a5e8faSwyllys for (i = 0; i < strlen((char *)hexstr) && isxdigit(hexstr[i]); i++) 871*30a5e8faSwyllys /* empty body */ 872*30a5e8faSwyllys ; 87399ebb4caSwyllys /* 87499ebb4caSwyllys * If all the characters are not legitimate hex chars, 87599ebb4caSwyllys * return an error. 87699ebb4caSwyllys */ 87799ebb4caSwyllys if (i != strlen((char *)hexstr)) 87899ebb4caSwyllys return (KMF_ERR_BAD_HEX_STRING); 87999ebb4caSwyllys stringlen = i; 88099ebb4caSwyllys len = (i / 2) + (i % 2); 88199ebb4caSwyllys 88299ebb4caSwyllys buf = malloc(len); 88399ebb4caSwyllys if (buf == NULL) { 88499ebb4caSwyllys return (KMF_ERR_MEMORY); 88599ebb4caSwyllys } 88699ebb4caSwyllys (void) memset(buf, 0, len); 88799ebb4caSwyllys 88899ebb4caSwyllys for (i = 0; i < stringlen; i++) { 88999ebb4caSwyllys ch = (unsigned char) *hexstr; 89099ebb4caSwyllys hexstr++; 89199ebb4caSwyllys if ((ch >= '0') && (ch <= '9')) 89299ebb4caSwyllys ch -= '0'; 89399ebb4caSwyllys else if ((ch >= 'A') && (ch <= 'F')) 89499ebb4caSwyllys ch = ch - 'A' + 10; 89599ebb4caSwyllys else if ((ch >= 'a') && (ch <= 'f')) 89699ebb4caSwyllys ch = ch - 'a' + 10; 89799ebb4caSwyllys else { 89899ebb4caSwyllys ret = KMF_ERR_BAD_HEX_STRING; 89999ebb4caSwyllys goto out; 90099ebb4caSwyllys } 90199ebb4caSwyllys 90299ebb4caSwyllys if (i & 1) { 90399ebb4caSwyllys buf[i/2] |= ch; 90499ebb4caSwyllys } else { 90599ebb4caSwyllys buf[i/2] = (ch << 4); 90699ebb4caSwyllys } 90799ebb4caSwyllys } 90899ebb4caSwyllys 90999ebb4caSwyllys *bytes = buf; 91099ebb4caSwyllys *outlen = len; 91199ebb4caSwyllys out: 91299ebb4caSwyllys if (buf != NULL && ret != KMF_OK) { 91399ebb4caSwyllys free(buf); 91499ebb4caSwyllys } 91599ebb4caSwyllys return (ret); 91699ebb4caSwyllys } 91799ebb4caSwyllys 91899ebb4caSwyllys void 919*30a5e8faSwyllys kmf_free_dn(KMF_X509_NAME *name) 92099ebb4caSwyllys { 92199ebb4caSwyllys KMF_X509_RDN *newrdn = NULL; 92299ebb4caSwyllys KMF_X509_TYPE_VALUE_PAIR *av = NULL; 92399ebb4caSwyllys int i, j; 92499ebb4caSwyllys 92599ebb4caSwyllys if (name && name->numberOfRDNs) { 92699ebb4caSwyllys for (i = 0; i < name->numberOfRDNs; i++) { 92799ebb4caSwyllys newrdn = &name->RelativeDistinguishedName[i]; 92899ebb4caSwyllys for (j = 0; j < newrdn->numberOfPairs; j++) { 92999ebb4caSwyllys av = &newrdn->AttributeTypeAndValue[j]; 930*30a5e8faSwyllys kmf_free_data(&av->type); 931*30a5e8faSwyllys kmf_free_data(&av->value); 93299ebb4caSwyllys } 93399ebb4caSwyllys free(newrdn->AttributeTypeAndValue); 93499ebb4caSwyllys newrdn->numberOfPairs = 0; 93599ebb4caSwyllys newrdn->AttributeTypeAndValue = NULL; 93699ebb4caSwyllys } 93799ebb4caSwyllys free(name->RelativeDistinguishedName); 93899ebb4caSwyllys name->numberOfRDNs = 0; 93999ebb4caSwyllys name->RelativeDistinguishedName = NULL; 94099ebb4caSwyllys } 94199ebb4caSwyllys } 94299ebb4caSwyllys 94399ebb4caSwyllys void 944*30a5e8faSwyllys kmf_free_kmf_cert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 94599ebb4caSwyllys { 94699ebb4caSwyllys KMF_PLUGIN *plugin; 94799ebb4caSwyllys KMF_RETURN ret; 94899ebb4caSwyllys 94999ebb4caSwyllys CLEAR_ERROR(handle, ret); 95099ebb4caSwyllys if (ret != KMF_OK) 95199ebb4caSwyllys return; 95299ebb4caSwyllys 95399ebb4caSwyllys if (kmf_cert == NULL) 95499ebb4caSwyllys return; 95599ebb4caSwyllys 95699ebb4caSwyllys plugin = FindPlugin(handle, kmf_cert->kmf_private.keystore_type); 95799ebb4caSwyllys 95899ebb4caSwyllys if (plugin != NULL && plugin->funclist->FreeKMFCert != NULL) { 95999ebb4caSwyllys plugin->funclist->FreeKMFCert(handle, kmf_cert); 96099ebb4caSwyllys } 96199ebb4caSwyllys } 96299ebb4caSwyllys 96399ebb4caSwyllys void 964*30a5e8faSwyllys kmf_free_data(KMF_DATA *datablock) 96599ebb4caSwyllys { 96699ebb4caSwyllys if (datablock != NULL && datablock->Data != NULL) { 96799ebb4caSwyllys free(datablock->Data); 96899ebb4caSwyllys datablock->Data = NULL; 96999ebb4caSwyllys datablock->Length = 0; 97099ebb4caSwyllys } 97199ebb4caSwyllys } 97299ebb4caSwyllys 97399ebb4caSwyllys void 974*30a5e8faSwyllys kmf_free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *algoid) 97599ebb4caSwyllys { 97699ebb4caSwyllys if (algoid == NULL) 97799ebb4caSwyllys return; 978*30a5e8faSwyllys kmf_free_data(&algoid->algorithm); 979*30a5e8faSwyllys kmf_free_data(&algoid->parameters); 98099ebb4caSwyllys } 98199ebb4caSwyllys 98299ebb4caSwyllys void 983*30a5e8faSwyllys kmf_free_extn(KMF_X509_EXTENSION *exptr) 98499ebb4caSwyllys { 98599ebb4caSwyllys if (exptr == NULL) 98699ebb4caSwyllys return; 98799ebb4caSwyllys 988*30a5e8faSwyllys kmf_free_data((KMF_DATA *)&exptr->extnId); 989*30a5e8faSwyllys kmf_free_data(&exptr->BERvalue); 99099ebb4caSwyllys 99199ebb4caSwyllys if (exptr->value.tagAndValue) { 992*30a5e8faSwyllys kmf_free_data(&exptr->value.tagAndValue->value); 99399ebb4caSwyllys free(exptr->value.tagAndValue); 99499ebb4caSwyllys } 99599ebb4caSwyllys } 99699ebb4caSwyllys 99799ebb4caSwyllys void 998*30a5e8faSwyllys kmf_free_tbs_csr(KMF_TBS_CSR *tbscsr) 99999ebb4caSwyllys { 100099ebb4caSwyllys if (tbscsr) { 1001*30a5e8faSwyllys kmf_free_data(&tbscsr->version); 100299ebb4caSwyllys 1003*30a5e8faSwyllys kmf_free_dn(&tbscsr->subject); 100499ebb4caSwyllys 1005*30a5e8faSwyllys kmf_free_algoid(&tbscsr->subjectPublicKeyInfo.algorithm); 1006*30a5e8faSwyllys kmf_free_data(&tbscsr->subjectPublicKeyInfo.subjectPublicKey); 100799ebb4caSwyllys 100899ebb4caSwyllys free_extensions(&tbscsr->extensions); 100999ebb4caSwyllys } 101099ebb4caSwyllys } 101199ebb4caSwyllys 101299ebb4caSwyllys void 1013*30a5e8faSwyllys kmf_free_signed_csr(KMF_CSR_DATA *csr) 101499ebb4caSwyllys { 101599ebb4caSwyllys if (csr) { 1016*30a5e8faSwyllys kmf_free_tbs_csr(&csr->csr); 101799ebb4caSwyllys 1018*30a5e8faSwyllys kmf_free_algoid(&csr->signature.algorithmIdentifier); 1019*30a5e8faSwyllys kmf_free_data(&csr->signature.encrypted); 102099ebb4caSwyllys } 102199ebb4caSwyllys } 102299ebb4caSwyllys 102399ebb4caSwyllys static void 102499ebb4caSwyllys free_validity(KMF_X509_VALIDITY *validity) 102599ebb4caSwyllys { 102699ebb4caSwyllys if (validity == NULL) 102799ebb4caSwyllys return; 1028*30a5e8faSwyllys kmf_free_data(&validity->notBefore.time); 1029*30a5e8faSwyllys kmf_free_data(&validity->notAfter.time); 103099ebb4caSwyllys } 103199ebb4caSwyllys 103299ebb4caSwyllys static void 103399ebb4caSwyllys free_extensions(KMF_X509_EXTENSIONS *extns) 103499ebb4caSwyllys { 103599ebb4caSwyllys int i; 103699ebb4caSwyllys KMF_X509_EXTENSION *exptr; 103799ebb4caSwyllys 103899ebb4caSwyllys if (extns && extns->numberOfExtensions > 0) { 103999ebb4caSwyllys for (i = 0; i < extns->numberOfExtensions; i++) { 104099ebb4caSwyllys exptr = &extns->extensions[i]; 1041*30a5e8faSwyllys kmf_free_extn(exptr); 104299ebb4caSwyllys } 104399ebb4caSwyllys free(extns->extensions); 104499ebb4caSwyllys extns->numberOfExtensions = 0; 104599ebb4caSwyllys extns->extensions = NULL; 104699ebb4caSwyllys } 104799ebb4caSwyllys } 104899ebb4caSwyllys 104999ebb4caSwyllys void 1050*30a5e8faSwyllys kmf_free_tbs_cert(KMF_X509_TBS_CERT *tbscert) 105199ebb4caSwyllys { 105299ebb4caSwyllys if (tbscert) { 1053*30a5e8faSwyllys kmf_free_data(&tbscert->version); 1054*30a5e8faSwyllys kmf_free_bigint(&tbscert->serialNumber); 1055*30a5e8faSwyllys kmf_free_algoid(&tbscert->signature); 105699ebb4caSwyllys 1057*30a5e8faSwyllys kmf_free_dn(&tbscert->issuer); 1058*30a5e8faSwyllys kmf_free_dn(&tbscert->subject); 105999ebb4caSwyllys 106099ebb4caSwyllys free_validity(&tbscert->validity); 106199ebb4caSwyllys 1062*30a5e8faSwyllys kmf_free_data(&tbscert->issuerUniqueIdentifier); 1063*30a5e8faSwyllys kmf_free_data(&tbscert->subjectUniqueIdentifier); 106499ebb4caSwyllys 1065*30a5e8faSwyllys kmf_free_algoid(&tbscert->subjectPublicKeyInfo.algorithm); 1066*30a5e8faSwyllys kmf_free_data(&tbscert->subjectPublicKeyInfo.subjectPublicKey); 106799ebb4caSwyllys 106899ebb4caSwyllys free_extensions(&tbscert->extensions); 106999ebb4caSwyllys 1070*30a5e8faSwyllys kmf_free_data(&tbscert->issuerUniqueIdentifier); 1071*30a5e8faSwyllys kmf_free_data(&tbscert->subjectUniqueIdentifier); 107299ebb4caSwyllys } 107399ebb4caSwyllys } 107499ebb4caSwyllys 107599ebb4caSwyllys void 1076*30a5e8faSwyllys kmf_free_signed_cert(KMF_X509_CERTIFICATE *certptr) 107799ebb4caSwyllys { 107899ebb4caSwyllys if (!certptr) 107999ebb4caSwyllys return; 108099ebb4caSwyllys 1081*30a5e8faSwyllys kmf_free_tbs_cert(&certptr->certificate); 108299ebb4caSwyllys 1083*30a5e8faSwyllys kmf_free_algoid(&certptr->signature.algorithmIdentifier); 1084*30a5e8faSwyllys kmf_free_data(&certptr->signature.encrypted); 108599ebb4caSwyllys } 108699ebb4caSwyllys 108799ebb4caSwyllys void 1088*30a5e8faSwyllys kmf_free_str(char *pstr) 108999ebb4caSwyllys { 109099ebb4caSwyllys if (pstr != NULL) 109199ebb4caSwyllys free(pstr); 109299ebb4caSwyllys } 109399ebb4caSwyllys 109499ebb4caSwyllys void 109599ebb4caSwyllys free_keyidlist(KMF_OID *oidlist, int len) 109699ebb4caSwyllys { 109799ebb4caSwyllys int i; 109899ebb4caSwyllys for (i = 0; i < len; i++) { 1099*30a5e8faSwyllys kmf_free_data((KMF_DATA *)&oidlist[i]); 110099ebb4caSwyllys } 110199ebb4caSwyllys free(oidlist); 110299ebb4caSwyllys } 110399ebb4caSwyllys 110499ebb4caSwyllys void 1105*30a5e8faSwyllys kmf_free_eku(KMF_X509EXT_EKU *eptr) 110699ebb4caSwyllys { 1107*30a5e8faSwyllys if (eptr && eptr->nEKUs > 0 && eptr->keyPurposeIdList != NULL) 110899ebb4caSwyllys free_keyidlist(eptr->keyPurposeIdList, eptr->nEKUs); 110999ebb4caSwyllys } 111099ebb4caSwyllys 111199ebb4caSwyllys void 1112*30a5e8faSwyllys kmf_free_spki(KMF_X509_SPKI *spki) 111399ebb4caSwyllys { 111499ebb4caSwyllys if (spki != NULL) { 1115*30a5e8faSwyllys kmf_free_algoid(&spki->algorithm); 1116*30a5e8faSwyllys kmf_free_data(&spki->subjectPublicKey); 111799ebb4caSwyllys } 111899ebb4caSwyllys } 111999ebb4caSwyllys 112099ebb4caSwyllys void 1121*30a5e8faSwyllys kmf_free_kmf_key(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 112299ebb4caSwyllys { 112399ebb4caSwyllys KMF_PLUGIN *plugin; 112499ebb4caSwyllys KMF_RETURN ret; 1125*30a5e8faSwyllys KMF_ATTRIBUTE attlist[2]; /* only 2 attributes for DeleteKey op */ 1126*30a5e8faSwyllys int i = 0; 1127*30a5e8faSwyllys boolean_t token_destroy = B_FALSE; 1128*30a5e8faSwyllys 1129*30a5e8faSwyllys if (key == NULL) 1130*30a5e8faSwyllys return; 113199ebb4caSwyllys 113299ebb4caSwyllys CLEAR_ERROR(handle, ret); 113399ebb4caSwyllys if (ret != KMF_OK) 113499ebb4caSwyllys return; 113599ebb4caSwyllys 1136*30a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 1137*30a5e8faSwyllys KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); 1138*30a5e8faSwyllys i++; 1139*30a5e8faSwyllys 1140*30a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 1141*30a5e8faSwyllys KMF_DESTROY_BOOL_ATTR, &token_destroy, sizeof (boolean_t)); 1142*30a5e8faSwyllys i++; 114399ebb4caSwyllys 114499ebb4caSwyllys plugin = FindPlugin(handle, key->kstype); 114599ebb4caSwyllys if (plugin != NULL && plugin->funclist->DeleteKey != NULL) { 1146*30a5e8faSwyllys (void) plugin->funclist->DeleteKey(handle, i, attlist); 114799ebb4caSwyllys } 114899ebb4caSwyllys 114999ebb4caSwyllys if (key->keylabel) 115099ebb4caSwyllys free(key->keylabel); 115199ebb4caSwyllys 115299ebb4caSwyllys if (key->israw) { 1153*30a5e8faSwyllys kmf_free_raw_key(key->keyp); 115499ebb4caSwyllys free(key->keyp); 115599ebb4caSwyllys } 115699ebb4caSwyllys 115799ebb4caSwyllys (void) memset(key, 0, sizeof (KMF_KEY_HANDLE)); 115899ebb4caSwyllys } 115999ebb4caSwyllys 116099ebb4caSwyllys void 1161*30a5e8faSwyllys kmf_free_bigint(KMF_BIGINT *big) 116299ebb4caSwyllys { 116399ebb4caSwyllys if (big != NULL && big->val != NULL) { 116402744e81Swyllys /* Clear it out before returning it to the pool */ 116502744e81Swyllys (void) memset(big->val, 0x00, big->len); 116699ebb4caSwyllys free(big->val); 116799ebb4caSwyllys big->val = NULL; 116899ebb4caSwyllys big->len = 0; 116999ebb4caSwyllys } 117099ebb4caSwyllys } 117199ebb4caSwyllys 117299ebb4caSwyllys static void 117399ebb4caSwyllys free_raw_rsa(KMF_RAW_RSA_KEY *key) 117499ebb4caSwyllys { 117599ebb4caSwyllys if (key == NULL) 117699ebb4caSwyllys return; 1177*30a5e8faSwyllys kmf_free_bigint(&key->mod); 1178*30a5e8faSwyllys kmf_free_bigint(&key->pubexp); 1179*30a5e8faSwyllys kmf_free_bigint(&key->priexp); 1180*30a5e8faSwyllys kmf_free_bigint(&key->prime1); 1181*30a5e8faSwyllys kmf_free_bigint(&key->prime2); 1182*30a5e8faSwyllys kmf_free_bigint(&key->exp1); 1183*30a5e8faSwyllys kmf_free_bigint(&key->exp2); 1184*30a5e8faSwyllys kmf_free_bigint(&key->coef); 118599ebb4caSwyllys } 118699ebb4caSwyllys 118799ebb4caSwyllys static void 118899ebb4caSwyllys free_raw_dsa(KMF_RAW_DSA_KEY *key) 118999ebb4caSwyllys { 119099ebb4caSwyllys if (key == NULL) 119199ebb4caSwyllys return; 1192*30a5e8faSwyllys kmf_free_bigint(&key->prime); 1193*30a5e8faSwyllys kmf_free_bigint(&key->subprime); 1194*30a5e8faSwyllys kmf_free_bigint(&key->base); 1195*30a5e8faSwyllys kmf_free_bigint(&key->value); 119699ebb4caSwyllys } 119799ebb4caSwyllys 119899ebb4caSwyllys static void 119999ebb4caSwyllys free_raw_sym(KMF_RAW_SYM_KEY *key) 120099ebb4caSwyllys { 120199ebb4caSwyllys if (key == NULL) 120299ebb4caSwyllys return; 1203*30a5e8faSwyllys kmf_free_bigint(&key->keydata); 120499ebb4caSwyllys } 120599ebb4caSwyllys 120699ebb4caSwyllys void 1207*30a5e8faSwyllys kmf_free_raw_key(KMF_RAW_KEY_DATA *key) 120899ebb4caSwyllys { 120999ebb4caSwyllys if (key == NULL) 121099ebb4caSwyllys return; 121199ebb4caSwyllys 121299ebb4caSwyllys switch (key->keytype) { 121399ebb4caSwyllys case KMF_RSA: 121499ebb4caSwyllys free_raw_rsa(&key->rawdata.rsa); 121599ebb4caSwyllys break; 121699ebb4caSwyllys case KMF_DSA: 121799ebb4caSwyllys free_raw_dsa(&key->rawdata.dsa); 121899ebb4caSwyllys break; 121999ebb4caSwyllys case KMF_AES: 122099ebb4caSwyllys case KMF_RC4: 122199ebb4caSwyllys case KMF_DES: 122299ebb4caSwyllys case KMF_DES3: 122399ebb4caSwyllys free_raw_sym(&key->rawdata.sym); 122499ebb4caSwyllys break; 122599ebb4caSwyllys } 122699ebb4caSwyllys } 122799ebb4caSwyllys 122899ebb4caSwyllys void 1229*30a5e8faSwyllys kmf_free_raw_sym_key(KMF_RAW_SYM_KEY *key) 123099ebb4caSwyllys { 123199ebb4caSwyllys if (key == NULL) 123299ebb4caSwyllys return; 1233*30a5e8faSwyllys kmf_free_bigint(&key->keydata); 123499ebb4caSwyllys free(key); 123599ebb4caSwyllys } 123699ebb4caSwyllys 123799ebb4caSwyllys /* 123899ebb4caSwyllys * This function frees the space allocated for the name portion of a 123999ebb4caSwyllys * KMF_CRL_DIST_POINT. 124099ebb4caSwyllys */ 124199ebb4caSwyllys void 124299ebb4caSwyllys free_dp_name(KMF_CRL_DIST_POINT *dp) 124399ebb4caSwyllys { 124499ebb4caSwyllys KMF_GENERALNAMES *fullname; 124599ebb4caSwyllys KMF_DATA *urldata; 124699ebb4caSwyllys int i; 124799ebb4caSwyllys 124899ebb4caSwyllys if (dp == NULL) 124999ebb4caSwyllys return; 125099ebb4caSwyllys 125199ebb4caSwyllys /* For phase 1, we only need to free the fullname space. */ 125299ebb4caSwyllys fullname = &(dp->name.full_name); 125399ebb4caSwyllys if (fullname->number == 0) 125499ebb4caSwyllys return; 125599ebb4caSwyllys 125699ebb4caSwyllys for (i = 0; i < fullname->number; i++) { 125799ebb4caSwyllys urldata = &(fullname->namelist[fullname->number - 1].name); 1258*30a5e8faSwyllys kmf_free_data(urldata); 125999ebb4caSwyllys } 126099ebb4caSwyllys 126199ebb4caSwyllys free(fullname->namelist); 126299ebb4caSwyllys } 126399ebb4caSwyllys 126499ebb4caSwyllys /* 126599ebb4caSwyllys * This function frees the space allocated for a KMF_CRL_DIST_POINT. 126699ebb4caSwyllys */ 126799ebb4caSwyllys void 126899ebb4caSwyllys free_dp(KMF_CRL_DIST_POINT *dp) 126999ebb4caSwyllys { 127099ebb4caSwyllys if (dp == NULL) 127199ebb4caSwyllys return; 127299ebb4caSwyllys 127399ebb4caSwyllys free_dp_name(dp); 1274*30a5e8faSwyllys kmf_free_data(&(dp->reasons)); 127599ebb4caSwyllys /* Need not to free crl_issuer space at phase 1 */ 127699ebb4caSwyllys } 127799ebb4caSwyllys 127899ebb4caSwyllys /* 127999ebb4caSwyllys * This function frees space for a KMF_X509EXT_CRLDISTPOINTS internally. 128099ebb4caSwyllys */ 128199ebb4caSwyllys void 1282*30a5e8faSwyllys kmf_free_crl_dist_pts(KMF_X509EXT_CRLDISTPOINTS *crl_dps) 128399ebb4caSwyllys { 128499ebb4caSwyllys int i; 128599ebb4caSwyllys 128699ebb4caSwyllys if (crl_dps == NULL) 128799ebb4caSwyllys return; 128899ebb4caSwyllys 128999ebb4caSwyllys for (i = 0; i < crl_dps->number; i++) 129099ebb4caSwyllys free_dp(&(crl_dps->dplist[i])); 129199ebb4caSwyllys 129299ebb4caSwyllys free(crl_dps->dplist); 129399ebb4caSwyllys } 129499ebb4caSwyllys 129599ebb4caSwyllys KMF_RETURN 1296*30a5e8faSwyllys kmf_create_ocsp_request(KMF_HANDLE_T handle, 1297*30a5e8faSwyllys int num_args, 1298*30a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 129999ebb4caSwyllys { 1300*30a5e8faSwyllys KMF_RETURN ret = KMF_OK; 130199ebb4caSwyllys KMF_PLUGIN *plugin; 1302*30a5e8faSwyllys KMF_RETURN (*createReqFn)(void *, int num_args, 1303*30a5e8faSwyllys KMF_ATTRIBUTE *attrlist); 130499ebb4caSwyllys 1305*30a5e8faSwyllys KMF_ATTRIBUTE_TESTER required_attrs[] = { 1306*30a5e8faSwyllys {KMF_OCSP_REQUEST_FILENAME_ATTR, FALSE, 1, 0}, 1307*30a5e8faSwyllys {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1308*30a5e8faSwyllys sizeof (KMF_DATA)}, 1309*30a5e8faSwyllys {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1310*30a5e8faSwyllys sizeof (KMF_DATA)}, 1311*30a5e8faSwyllys }; 131299ebb4caSwyllys 1313*30a5e8faSwyllys int num_req_attrs = sizeof (required_attrs) / 1314*30a5e8faSwyllys sizeof (KMF_ATTRIBUTE_TESTER); 131599ebb4caSwyllys 1316*30a5e8faSwyllys if (handle == NULL) 131799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 131899ebb4caSwyllys 1319*30a5e8faSwyllys CLEAR_ERROR(handle, ret); 1320*30a5e8faSwyllys 1321*30a5e8faSwyllys ret = test_attributes(num_req_attrs, required_attrs, 1322*30a5e8faSwyllys 0, NULL, num_args, attrlist); 1323*30a5e8faSwyllys 1324*30a5e8faSwyllys if (ret != KMF_OK) 1325*30a5e8faSwyllys return (ret); 1326*30a5e8faSwyllys 132799ebb4caSwyllys /* 132899ebb4caSwyllys * This framework function is actually implemented in the openssl 132999ebb4caSwyllys * plugin library, so we find the function address and call it. 133099ebb4caSwyllys */ 133199ebb4caSwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 133299ebb4caSwyllys if (plugin == NULL || plugin->dldesc == NULL) { 133399ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 133499ebb4caSwyllys } 133599ebb4caSwyllys 133699ebb4caSwyllys createReqFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 133799ebb4caSwyllys "OpenSSL_CreateOCSPRequest"); 133899ebb4caSwyllys if (createReqFn == NULL) { 133999ebb4caSwyllys return (KMF_ERR_FUNCTION_NOT_FOUND); 134099ebb4caSwyllys } 134199ebb4caSwyllys 1342*30a5e8faSwyllys return (createReqFn(handle, num_args, attrlist)); 1343*30a5e8faSwyllys 134499ebb4caSwyllys } 134599ebb4caSwyllys 134699ebb4caSwyllys KMF_RETURN 1347*30a5e8faSwyllys kmf_get_ocsp_status_for_cert(KMF_HANDLE_T handle, 1348*30a5e8faSwyllys int num_args, 1349*30a5e8faSwyllys KMF_ATTRIBUTE *attrlist) 135099ebb4caSwyllys { 1351*30a5e8faSwyllys KMF_RETURN ret = KMF_OK; 135299ebb4caSwyllys KMF_PLUGIN *plugin; 1353*30a5e8faSwyllys KMF_RETURN (*getCertStatusFn)(void *, int num_args, 1354*30a5e8faSwyllys KMF_ATTRIBUTE *attrlist); 1355*30a5e8faSwyllys 1356*30a5e8faSwyllys KMF_ATTRIBUTE_TESTER required_attrs[] = { 1357*30a5e8faSwyllys {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1358*30a5e8faSwyllys sizeof (KMF_DATA)}, 1359*30a5e8faSwyllys {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1360*30a5e8faSwyllys sizeof (KMF_DATA)}, 1361*30a5e8faSwyllys {KMF_OCSP_RESPONSE_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1362*30a5e8faSwyllys sizeof (KMF_DATA)}, 1363*30a5e8faSwyllys {KMF_OCSP_RESPONSE_STATUS_ATTR, FALSE, sizeof (int), 1364*30a5e8faSwyllys sizeof (uint32_t)}, 1365*30a5e8faSwyllys {KMF_OCSP_RESPONSE_REASON_ATTR, FALSE, sizeof (int), 1366*30a5e8faSwyllys sizeof (uint32_t)}, 1367*30a5e8faSwyllys {KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, FALSE, sizeof (int), 1368*30a5e8faSwyllys sizeof (uint32_t)}, 1369*30a5e8faSwyllys }; 1370*30a5e8faSwyllys 1371*30a5e8faSwyllys int num_req_attrs = sizeof (required_attrs) / 1372*30a5e8faSwyllys sizeof (KMF_ATTRIBUTE_TESTER); 1373*30a5e8faSwyllys 1374*30a5e8faSwyllys if (handle == NULL) 1375*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 137699ebb4caSwyllys 137799ebb4caSwyllys CLEAR_ERROR(handle, ret); 137899ebb4caSwyllys 1379*30a5e8faSwyllys ret = test_attributes(num_req_attrs, required_attrs, 1380*30a5e8faSwyllys 0, NULL, num_args, attrlist); 138199ebb4caSwyllys 1382*30a5e8faSwyllys if (ret != KMF_OK) 1383*30a5e8faSwyllys return (ret); 138499ebb4caSwyllys 138599ebb4caSwyllys /* 138699ebb4caSwyllys * This framework function is actually implemented in the openssl 138799ebb4caSwyllys * plugin library, so we find the function address and call it. 138899ebb4caSwyllys */ 138999ebb4caSwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 139099ebb4caSwyllys if (plugin == NULL || plugin->dldesc == NULL) { 139199ebb4caSwyllys return (KMF_ERR_INTERNAL); 139299ebb4caSwyllys } 139399ebb4caSwyllys 139499ebb4caSwyllys getCertStatusFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 139599ebb4caSwyllys "OpenSSL_GetOCSPStatusForCert"); 139699ebb4caSwyllys if (getCertStatusFn == NULL) { 139799ebb4caSwyllys return (KMF_ERR_INTERNAL); 139899ebb4caSwyllys } 139999ebb4caSwyllys 1400*30a5e8faSwyllys return (getCertStatusFn(handle, num_args, attrlist)); 1401*30a5e8faSwyllys 140299ebb4caSwyllys } 140399ebb4caSwyllys 140499ebb4caSwyllys KMF_RETURN 1405*30a5e8faSwyllys kmf_string_to_oid(char *oidstring, KMF_OID *oid) 140699ebb4caSwyllys { 140799ebb4caSwyllys KMF_RETURN rv = KMF_OK; 140899ebb4caSwyllys char *cp, *bp, *startp; 140999ebb4caSwyllys int numbuf; 141099ebb4caSwyllys int onumbuf; 141199ebb4caSwyllys int nbytes, index; 141299ebb4caSwyllys int len; 141399ebb4caSwyllys unsigned char *op; 141499ebb4caSwyllys 141599ebb4caSwyllys if (oidstring == NULL || oid == NULL) 141699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 141799ebb4caSwyllys 141899ebb4caSwyllys len = strlen(oidstring); 141999ebb4caSwyllys 142099ebb4caSwyllys bp = oidstring; 142199ebb4caSwyllys cp = bp; 142299ebb4caSwyllys /* Skip over leading space */ 142399ebb4caSwyllys while ((bp < &cp[len]) && isspace(*bp)) 142499ebb4caSwyllys bp++; 142599ebb4caSwyllys 142699ebb4caSwyllys startp = bp; 142799ebb4caSwyllys nbytes = 0; 142899ebb4caSwyllys 142999ebb4caSwyllys /* 143099ebb4caSwyllys * The first two numbers are chewed up by the first octet. 143199ebb4caSwyllys */ 143299ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 143399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 143499ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 143599ebb4caSwyllys bp++; 143699ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 143799ebb4caSwyllys bp++; 143899ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 143999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 144099ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 144199ebb4caSwyllys bp++; 144299ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 144399ebb4caSwyllys bp++; 144499ebb4caSwyllys nbytes++; 144599ebb4caSwyllys 144699ebb4caSwyllys while (isdigit(*bp)) { 144799ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 144899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 144999ebb4caSwyllys while (numbuf) { 145099ebb4caSwyllys nbytes++; 145199ebb4caSwyllys numbuf >>= 7; 145299ebb4caSwyllys } 145399ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 145499ebb4caSwyllys bp++; 145599ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 145699ebb4caSwyllys bp++; 145799ebb4caSwyllys } 145899ebb4caSwyllys 145999ebb4caSwyllys oid->Length = nbytes; 146099ebb4caSwyllys oid->Data = malloc(oid->Length); 146199ebb4caSwyllys if (oid->Data == NULL) { 146299ebb4caSwyllys return (KMF_ERR_MEMORY); 146399ebb4caSwyllys } 146499ebb4caSwyllys (void) memset(oid->Data, 0, oid->Length); 146599ebb4caSwyllys 146699ebb4caSwyllys op = oid->Data; 146799ebb4caSwyllys 146899ebb4caSwyllys bp = startp; 146999ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 147099ebb4caSwyllys 147199ebb4caSwyllys while (isdigit(*bp)) bp++; 147299ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 147399ebb4caSwyllys 147499ebb4caSwyllys onumbuf = 40 * numbuf; 147599ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 147699ebb4caSwyllys onumbuf += numbuf; 147799ebb4caSwyllys *op = (unsigned char) onumbuf; 147899ebb4caSwyllys op++; 147999ebb4caSwyllys 148099ebb4caSwyllys while (isdigit(*bp)) bp++; 148199ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 148299ebb4caSwyllys while (isdigit(*bp)) { 148399ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 148499ebb4caSwyllys nbytes = 0; 148599ebb4caSwyllys /* Have to fill in the bytes msb-first */ 148699ebb4caSwyllys onumbuf = numbuf; 148799ebb4caSwyllys while (numbuf) { 148899ebb4caSwyllys nbytes++; 148999ebb4caSwyllys numbuf >>= 7; 149099ebb4caSwyllys } 149199ebb4caSwyllys numbuf = onumbuf; 149299ebb4caSwyllys op += nbytes; 149399ebb4caSwyllys index = -1; 149499ebb4caSwyllys while (numbuf) { 149599ebb4caSwyllys op[index] = (unsigned char)numbuf & 0x7f; 149699ebb4caSwyllys if (index != -1) 149799ebb4caSwyllys op[index] |= 0x80; 149899ebb4caSwyllys index--; 149999ebb4caSwyllys numbuf >>= 7; 150099ebb4caSwyllys } 150199ebb4caSwyllys while (isdigit(*bp)) bp++; 150299ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 150399ebb4caSwyllys } 150499ebb4caSwyllys 150599ebb4caSwyllys return (rv); 150699ebb4caSwyllys } 150799ebb4caSwyllys 150899ebb4caSwyllys static KMF_RETURN 150999ebb4caSwyllys encode_rid(char *name, KMF_DATA *derdata) 151099ebb4caSwyllys { 151199ebb4caSwyllys KMF_RETURN rv = KMF_OK; 151299ebb4caSwyllys 151399ebb4caSwyllys if (name == NULL || derdata == NULL) 151499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 151599ebb4caSwyllys 1516*30a5e8faSwyllys rv = kmf_string_to_oid(name, (KMF_OID *)derdata); 151799ebb4caSwyllys 151899ebb4caSwyllys return (rv); 151999ebb4caSwyllys } 152099ebb4caSwyllys 152199ebb4caSwyllys static KMF_RETURN 152299ebb4caSwyllys encode_ipaddr(char *name, KMF_DATA *derdata) 152399ebb4caSwyllys { 152499ebb4caSwyllys KMF_RETURN rv = KMF_OK; 152599ebb4caSwyllys size_t len; 152699ebb4caSwyllys in_addr_t v4; 152799ebb4caSwyllys in6_addr_t v6; 152899ebb4caSwyllys uint8_t *ptr; 152999ebb4caSwyllys 153099ebb4caSwyllys if (name == NULL || derdata == NULL) 153199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 153299ebb4caSwyllys 153399ebb4caSwyllys v4 = inet_addr(name); 153499ebb4caSwyllys if (v4 == (in_addr_t)-1) { 153599ebb4caSwyllys ptr = (uint8_t *)&v6; 153699ebb4caSwyllys if (inet_pton(AF_INET6, name, ptr) != 1) 153799ebb4caSwyllys return (KMF_ERR_ENCODING); 153899ebb4caSwyllys len = sizeof (v6); 153999ebb4caSwyllys } else { 154099ebb4caSwyllys ptr = (uint8_t *)&v4; 154199ebb4caSwyllys len = sizeof (v4); 154299ebb4caSwyllys } 154399ebb4caSwyllys 154499ebb4caSwyllys derdata->Data = malloc(len); 154599ebb4caSwyllys if (derdata->Data == NULL) 154699ebb4caSwyllys return (KMF_ERR_MEMORY); 154799ebb4caSwyllys (void) memcpy(derdata->Data, ptr, len); 154899ebb4caSwyllys derdata->Length = len; 154999ebb4caSwyllys 155099ebb4caSwyllys return (rv); 155199ebb4caSwyllys } 155299ebb4caSwyllys 155399ebb4caSwyllys static KMF_RETURN 155499ebb4caSwyllys verify_uri_format(char *uristring) 155599ebb4caSwyllys { 155699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 155799ebb4caSwyllys xmlURIPtr uriptr = NULL; 155899ebb4caSwyllys 155999ebb4caSwyllys /* Parse the URI string; get the hostname and port */ 156099ebb4caSwyllys uriptr = xmlParseURI(uristring); 156199ebb4caSwyllys if (uriptr == NULL) { 156299ebb4caSwyllys ret = KMF_ERR_BAD_URI; 156399ebb4caSwyllys goto out; 156499ebb4caSwyllys } 156599ebb4caSwyllys 156699ebb4caSwyllys if (uriptr->scheme == NULL || !strlen(uriptr->scheme)) { 156799ebb4caSwyllys ret = KMF_ERR_BAD_URI; 156899ebb4caSwyllys goto out; 156999ebb4caSwyllys } 157099ebb4caSwyllys 157199ebb4caSwyllys if (uriptr->server == NULL || !strlen(uriptr->server)) { 157299ebb4caSwyllys ret = KMF_ERR_BAD_URI; 157399ebb4caSwyllys goto out; 157499ebb4caSwyllys } 157599ebb4caSwyllys out: 157699ebb4caSwyllys if (uriptr != NULL) 157799ebb4caSwyllys xmlFreeURI(uriptr); 157899ebb4caSwyllys return (ret); 157999ebb4caSwyllys } 158099ebb4caSwyllys 158199ebb4caSwyllys static KMF_RETURN 158299ebb4caSwyllys encode_altname(char *namedata, 158399ebb4caSwyllys KMF_GENERALNAMECHOICES nametype, KMF_DATA *encodedname) 158499ebb4caSwyllys { 158599ebb4caSwyllys KMF_RETURN ret = KMF_OK; 158699ebb4caSwyllys KMF_X509_NAME dnname; 158799ebb4caSwyllys uchar_t tagval; 158899ebb4caSwyllys BerElement *asn1 = NULL; 158999ebb4caSwyllys BerValue *extdata; 159099ebb4caSwyllys 159199ebb4caSwyllys if (namedata == NULL || encodedname == NULL) 159299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 159399ebb4caSwyllys 159499ebb4caSwyllys /* 159599ebb4caSwyllys * Encode the namedata according to rules in RFC 3280 for GeneralName. 159699ebb4caSwyllys * The input "namedata" is assumed to be an ASCII string representation 159799ebb4caSwyllys * of the AltName, we need to convert it to correct ASN.1 here before 159899ebb4caSwyllys * adding it to the cert. 159999ebb4caSwyllys */ 160099ebb4caSwyllys switch (nametype) { 160199ebb4caSwyllys case GENNAME_RFC822NAME: /* rfc 822 */ 160299ebb4caSwyllys /* IA5String, no encoding needed */ 160399ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 160499ebb4caSwyllys if (encodedname->Data == NULL) 160599ebb4caSwyllys return (KMF_ERR_MEMORY); 160699ebb4caSwyllys encodedname->Length = strlen(namedata); 160799ebb4caSwyllys tagval = (0x80 | nametype); 160899ebb4caSwyllys break; 160999ebb4caSwyllys case GENNAME_DNSNAME: /* rfc 1034 */ 161099ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 161199ebb4caSwyllys if (encodedname->Data == NULL) 161299ebb4caSwyllys return (KMF_ERR_MEMORY); 161399ebb4caSwyllys encodedname->Length = strlen(namedata); 161499ebb4caSwyllys tagval = (0x80 | nametype); 161599ebb4caSwyllys break; 161699ebb4caSwyllys case GENNAME_URI: /* rfc 1738 */ 161799ebb4caSwyllys ret = verify_uri_format(namedata); 161899ebb4caSwyllys if (ret != KMF_OK) 161999ebb4caSwyllys return (ret); 162099ebb4caSwyllys /* IA5String, no encoding needed */ 162199ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 162299ebb4caSwyllys if (encodedname->Data == NULL) 162399ebb4caSwyllys return (KMF_ERR_MEMORY); 162499ebb4caSwyllys encodedname->Length = strlen(namedata); 162599ebb4caSwyllys tagval = (0x80 | nametype); 162699ebb4caSwyllys break; 162799ebb4caSwyllys case GENNAME_IPADDRESS: 162899ebb4caSwyllys ret = encode_ipaddr(namedata, encodedname); 162999ebb4caSwyllys tagval = (0x80 | nametype); 163099ebb4caSwyllys break; 163199ebb4caSwyllys case GENNAME_REGISTEREDID: 163299ebb4caSwyllys ret = encode_rid(namedata, encodedname); 163399ebb4caSwyllys tagval = (0x80 | nametype); 163499ebb4caSwyllys break; 163599ebb4caSwyllys case GENNAME_DIRECTORYNAME: 1636*30a5e8faSwyllys ret = kmf_dn_parser(namedata, &dnname); 163799ebb4caSwyllys if (ret == KMF_OK) { 1638*30a5e8faSwyllys ret = DerEncodeName(&dnname, encodedname); 163999ebb4caSwyllys } 1640*30a5e8faSwyllys (void) kmf_free_dn(&dnname); 164199ebb4caSwyllys tagval = (0xA0 | nametype); 164299ebb4caSwyllys break; 164399ebb4caSwyllys default: 164499ebb4caSwyllys /* unsupported */ 164599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 164699ebb4caSwyllys 164799ebb4caSwyllys } 164899ebb4caSwyllys if (ret != KMF_OK) { 1649*30a5e8faSwyllys kmf_free_data(encodedname); 165099ebb4caSwyllys return (ret); 165199ebb4caSwyllys } 165299ebb4caSwyllys 165399ebb4caSwyllys if ((asn1 = kmfder_alloc()) == NULL) 165499ebb4caSwyllys return (KMF_ERR_MEMORY); 165599ebb4caSwyllys 1656*30a5e8faSwyllys if (kmfber_printf(asn1, "Tl", tagval, encodedname->Length) == -1) 165799ebb4caSwyllys goto cleanup; 165899ebb4caSwyllys 165999ebb4caSwyllys if (kmfber_write(asn1, (char *)encodedname->Data, 1660*30a5e8faSwyllys encodedname->Length, 0) == -1) { 166199ebb4caSwyllys ret = KMF_ERR_ENCODING; 166299ebb4caSwyllys goto cleanup; 166399ebb4caSwyllys } 166499ebb4caSwyllys if (kmfber_flatten(asn1, &extdata) == -1) { 166599ebb4caSwyllys ret = KMF_ERR_ENCODING; 166699ebb4caSwyllys goto cleanup; 166799ebb4caSwyllys } 166899ebb4caSwyllys 1669*30a5e8faSwyllys kmf_free_data(encodedname); 167099ebb4caSwyllys encodedname->Data = (uchar_t *)extdata->bv_val; 167199ebb4caSwyllys encodedname->Length = extdata->bv_len; 167299ebb4caSwyllys 167399ebb4caSwyllys free(extdata); 167499ebb4caSwyllys 167599ebb4caSwyllys cleanup: 167699ebb4caSwyllys if (asn1) 167799ebb4caSwyllys kmfber_free(asn1, 1); 167899ebb4caSwyllys 167999ebb4caSwyllys if (ret != KMF_OK) 1680*30a5e8faSwyllys kmf_free_data(encodedname); 168199ebb4caSwyllys 168299ebb4caSwyllys return (ret); 168399ebb4caSwyllys } 168499ebb4caSwyllys 168599ebb4caSwyllys KMF_X509_EXTENSION * 168699ebb4caSwyllys FindExtn(KMF_X509_EXTENSIONS *exts, KMF_OID *oid) 168799ebb4caSwyllys { 168899ebb4caSwyllys KMF_X509_EXTENSION *foundextn = NULL; 168999ebb4caSwyllys int i; 169099ebb4caSwyllys 169199ebb4caSwyllys if (exts == NULL || oid == NULL) 169299ebb4caSwyllys return (NULL); 169399ebb4caSwyllys 169499ebb4caSwyllys for (i = 0; i < exts->numberOfExtensions; i++) { 169599ebb4caSwyllys if (IsEqualOid(oid, &exts->extensions[i].extnId)) { 169699ebb4caSwyllys foundextn = &exts->extensions[i]; 169799ebb4caSwyllys break; 169899ebb4caSwyllys } 169999ebb4caSwyllys } 170099ebb4caSwyllys return (foundextn); 170199ebb4caSwyllys } 170299ebb4caSwyllys 170399ebb4caSwyllys KMF_RETURN 170499ebb4caSwyllys GetSequenceContents(char *data, size_t len, 170599ebb4caSwyllys char **contents, size_t *outlen) 170699ebb4caSwyllys { 170799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 170899ebb4caSwyllys BerElement *exasn1 = NULL; 170999ebb4caSwyllys BerValue oldextn; 171099ebb4caSwyllys int tag; 171199ebb4caSwyllys size_t oldsize; 171299ebb4caSwyllys char *olddata = NULL; 171399ebb4caSwyllys 171499ebb4caSwyllys if (data == NULL || contents == NULL || outlen == NULL) 171599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 171699ebb4caSwyllys 171799ebb4caSwyllys /* 171899ebb4caSwyllys * Decode the sequence of general names 171999ebb4caSwyllys */ 172099ebb4caSwyllys oldextn.bv_val = data; 172199ebb4caSwyllys oldextn.bv_len = len; 172299ebb4caSwyllys 172399ebb4caSwyllys if ((exasn1 = kmfder_init(&oldextn)) == NULL) { 172499ebb4caSwyllys ret = KMF_ERR_MEMORY; 172599ebb4caSwyllys goto out; 172699ebb4caSwyllys } 172799ebb4caSwyllys 172899ebb4caSwyllys /* 172999ebb4caSwyllys * Unwrap the sequence to find the size of the block 173099ebb4caSwyllys * of GeneralName items in the set. 173199ebb4caSwyllys * 173299ebb4caSwyllys * Peek at the tag and length ("tl"), 173399ebb4caSwyllys * then consume them ("{"). 173499ebb4caSwyllys */ 173599ebb4caSwyllys if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT || 1736*30a5e8faSwyllys oldsize == 0) { 173799ebb4caSwyllys ret = KMF_ERR_ENCODING; 173899ebb4caSwyllys goto out; 173999ebb4caSwyllys } 174099ebb4caSwyllys 174199ebb4caSwyllys olddata = malloc(oldsize); 174299ebb4caSwyllys if (olddata == NULL) { 174399ebb4caSwyllys ret = KMF_ERR_MEMORY; 174499ebb4caSwyllys goto out; 174599ebb4caSwyllys } 174699ebb4caSwyllys (void) memset(olddata, 0, oldsize); 174799ebb4caSwyllys /* 174899ebb4caSwyllys * Read the entire blob of GeneralNames, we don't 174999ebb4caSwyllys * need to interpret them now. 175099ebb4caSwyllys */ 175199ebb4caSwyllys if (kmfber_read(exasn1, olddata, oldsize) != oldsize) { 175299ebb4caSwyllys ret = KMF_ERR_ENCODING; 175399ebb4caSwyllys goto out; 175499ebb4caSwyllys } 175599ebb4caSwyllys out: 175699ebb4caSwyllys if (exasn1 != NULL) 175799ebb4caSwyllys kmfber_free(exasn1, 1); 175899ebb4caSwyllys 175999ebb4caSwyllys if (ret != KMF_OK) { 176099ebb4caSwyllys *contents = NULL; 176199ebb4caSwyllys *outlen = 0; 176299ebb4caSwyllys if (olddata != NULL) 176399ebb4caSwyllys free(olddata); 176499ebb4caSwyllys } else { 176599ebb4caSwyllys *contents = olddata; 176699ebb4caSwyllys *outlen = oldsize; 176799ebb4caSwyllys } 176899ebb4caSwyllys return (ret); 176999ebb4caSwyllys } 177099ebb4caSwyllys 177199ebb4caSwyllys KMF_RETURN 177299ebb4caSwyllys add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) 177399ebb4caSwyllys { 177499ebb4caSwyllys KMF_RETURN ret = KMF_OK; 177599ebb4caSwyllys KMF_X509_EXTENSION *extlist; 177699ebb4caSwyllys 177799ebb4caSwyllys if (exts == NULL || newextn == NULL) 177899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 177999ebb4caSwyllys 178099ebb4caSwyllys extlist = malloc(sizeof (KMF_X509_EXTENSION) * 1781*30a5e8faSwyllys (exts->numberOfExtensions + 1)); 178299ebb4caSwyllys if (extlist == NULL) 178399ebb4caSwyllys return (KMF_ERR_MEMORY); 178499ebb4caSwyllys 178599ebb4caSwyllys (void) memcpy(extlist, exts->extensions, 178699ebb4caSwyllys exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION)); 178799ebb4caSwyllys 178899ebb4caSwyllys (void) memcpy(&extlist[exts->numberOfExtensions], newextn, 1789*30a5e8faSwyllys sizeof (KMF_X509_EXTENSION)); 179099ebb4caSwyllys 179199ebb4caSwyllys free(exts->extensions); 179299ebb4caSwyllys exts->numberOfExtensions++; 179399ebb4caSwyllys exts->extensions = extlist; 179499ebb4caSwyllys 179599ebb4caSwyllys return (ret); 179699ebb4caSwyllys } 179799ebb4caSwyllys 179899ebb4caSwyllys KMF_RETURN 1799*30a5e8faSwyllys kmf_set_altname(KMF_X509_EXTENSIONS *extensions, 180099ebb4caSwyllys KMF_OID *oid, 180199ebb4caSwyllys int critical, 180299ebb4caSwyllys KMF_GENERALNAMECHOICES nametype, 180399ebb4caSwyllys char *namedata) 180499ebb4caSwyllys { 180599ebb4caSwyllys KMF_RETURN ret = KMF_OK; 180699ebb4caSwyllys KMF_X509_EXTENSION subjAltName; 180799ebb4caSwyllys KMF_DATA dername = { NULL, 0 }; 180899ebb4caSwyllys BerElement *asn1 = NULL; 180999ebb4caSwyllys BerValue *extdata; 181099ebb4caSwyllys char *olddata = NULL; 181199ebb4caSwyllys KMF_X509_EXTENSION *foundextn = NULL; 181299ebb4caSwyllys size_t oldsize = 0; 181399ebb4caSwyllys 181499ebb4caSwyllys if (extensions == NULL || oid == NULL || namedata == NULL) 181599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 181699ebb4caSwyllys 181799ebb4caSwyllys ret = encode_altname(namedata, nametype, &dername); 181899ebb4caSwyllys 181999ebb4caSwyllys if (ret != KMF_OK) 182099ebb4caSwyllys return (ret); 182199ebb4caSwyllys 182299ebb4caSwyllys (void) memset(&subjAltName, 0, sizeof (subjAltName)); 182399ebb4caSwyllys 182499ebb4caSwyllys ret = copy_data(&subjAltName.extnId, oid); 182599ebb4caSwyllys if (ret != KMF_OK) 182699ebb4caSwyllys goto out; 182799ebb4caSwyllys /* 182899ebb4caSwyllys * Check to see if this cert already has a subjectAltName. 182999ebb4caSwyllys */ 183099ebb4caSwyllys foundextn = FindExtn(extensions, oid); 183199ebb4caSwyllys 183299ebb4caSwyllys if (foundextn != NULL) { 183399ebb4caSwyllys ret = GetSequenceContents( 1834*30a5e8faSwyllys (char *)foundextn->BERvalue.Data, 1835*30a5e8faSwyllys foundextn->BERvalue.Length, 1836*30a5e8faSwyllys &olddata, &oldsize); 183799ebb4caSwyllys if (ret != KMF_OK) 183899ebb4caSwyllys goto out; 183999ebb4caSwyllys } 184099ebb4caSwyllys 184199ebb4caSwyllys /* 184299ebb4caSwyllys * Assume (!!) that the namedata given is already properly encoded. 184399ebb4caSwyllys */ 184499ebb4caSwyllys if ((asn1 = kmfder_alloc()) == NULL) 184599ebb4caSwyllys return (KMF_ERR_MEMORY); 184699ebb4caSwyllys 184799ebb4caSwyllys if (kmfber_printf(asn1, "{") == -1) { 184899ebb4caSwyllys ret = KMF_ERR_ENCODING; 184999ebb4caSwyllys goto out; 185099ebb4caSwyllys } 185199ebb4caSwyllys 185299ebb4caSwyllys /* Write the old extension data first */ 185399ebb4caSwyllys if (olddata != NULL && oldsize > 0) { 185499ebb4caSwyllys if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 185599ebb4caSwyllys ret = KMF_ERR_ENCODING; 185699ebb4caSwyllys goto out; 185799ebb4caSwyllys } 185899ebb4caSwyllys } 185999ebb4caSwyllys 186099ebb4caSwyllys /* Now add the new name to the list */ 186199ebb4caSwyllys if (kmfber_write(asn1, (char *)dername.Data, dername.Length, 0) == -1) { 186299ebb4caSwyllys ret = KMF_ERR_ENCODING; 186399ebb4caSwyllys goto out; 186499ebb4caSwyllys } 186599ebb4caSwyllys 186699ebb4caSwyllys /* Now close the sequence */ 186799ebb4caSwyllys if (kmfber_printf(asn1, "}") == -1) { 186899ebb4caSwyllys ret = KMF_ERR_ENCODING; 186999ebb4caSwyllys goto out; 187099ebb4caSwyllys } 187199ebb4caSwyllys if (kmfber_flatten(asn1, &extdata) == -1) { 187299ebb4caSwyllys ret = KMF_ERR_ENCODING; 187399ebb4caSwyllys goto out; 187499ebb4caSwyllys } 187599ebb4caSwyllys 187699ebb4caSwyllys /* 187799ebb4caSwyllys * If we are just adding to an existing list of altNames, 187899ebb4caSwyllys * just replace the BER data associated with the found extension. 187999ebb4caSwyllys */ 188099ebb4caSwyllys if (foundextn != NULL) { 188199ebb4caSwyllys free(foundextn->BERvalue.Data); 188299ebb4caSwyllys foundextn->critical = critical; 188399ebb4caSwyllys foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 188499ebb4caSwyllys foundextn->BERvalue.Length = extdata->bv_len; 188599ebb4caSwyllys } else { 188699ebb4caSwyllys subjAltName.critical = critical; 188799ebb4caSwyllys subjAltName.format = KMF_X509_DATAFORMAT_ENCODED; 188899ebb4caSwyllys subjAltName.BERvalue.Data = (uchar_t *)extdata->bv_val; 188999ebb4caSwyllys subjAltName.BERvalue.Length = extdata->bv_len; 189099ebb4caSwyllys ret = add_an_extension(extensions, &subjAltName); 189199ebb4caSwyllys if (ret != KMF_OK) 189299ebb4caSwyllys free(subjAltName.BERvalue.Data); 189399ebb4caSwyllys } 189499ebb4caSwyllys 189599ebb4caSwyllys free(extdata); 189699ebb4caSwyllys out: 189799ebb4caSwyllys if (olddata != NULL) 189899ebb4caSwyllys free(olddata); 189999ebb4caSwyllys 1900*30a5e8faSwyllys kmf_free_data(&dername); 190199ebb4caSwyllys if (ret != KMF_OK) 1902*30a5e8faSwyllys kmf_free_data(&subjAltName.extnId); 190399ebb4caSwyllys if (asn1 != NULL) 190499ebb4caSwyllys kmfber_free(asn1, 1); 190599ebb4caSwyllys return (ret); 190699ebb4caSwyllys } 1907*30a5e8faSwyllys 1908*30a5e8faSwyllys /* 1909*30a5e8faSwyllys * Search a list of attributes for one that matches the given type. 1910*30a5e8faSwyllys * Return a pointer into the attribute list. This does not 1911*30a5e8faSwyllys * return a copy of the value, it returns a reference into the 1912*30a5e8faSwyllys * given list. 1913*30a5e8faSwyllys */ 1914*30a5e8faSwyllys int 1915*30a5e8faSwyllys kmf_find_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, int numattrs) 1916*30a5e8faSwyllys { 1917*30a5e8faSwyllys int i; 1918*30a5e8faSwyllys for (i = 0; i < numattrs; i++) { 1919*30a5e8faSwyllys if (attlist[i].type == type) 1920*30a5e8faSwyllys return (i); 1921*30a5e8faSwyllys } 1922*30a5e8faSwyllys return (-1); 1923*30a5e8faSwyllys } 1924*30a5e8faSwyllys 1925*30a5e8faSwyllys /* 1926*30a5e8faSwyllys * Verify that a given attribute is consistent with the 1927*30a5e8faSwyllys * "test" attribute. 1928*30a5e8faSwyllys */ 1929*30a5e8faSwyllys static KMF_RETURN 1930*30a5e8faSwyllys verify_attribute(KMF_ATTRIBUTE *givenattr, 1931*30a5e8faSwyllys KMF_ATTRIBUTE_TESTER *testattr) 1932*30a5e8faSwyllys { 1933*30a5e8faSwyllys /* A NULL pValue was found where one is required */ 1934*30a5e8faSwyllys if (testattr->null_value_ok == FALSE && 1935*30a5e8faSwyllys givenattr->pValue == NULL) 1936*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 1937*30a5e8faSwyllys 1938*30a5e8faSwyllys /* If the given valueLen is too small, return error */ 1939*30a5e8faSwyllys if (givenattr->pValue != NULL && 1940*30a5e8faSwyllys testattr->minlen > 0 && 1941*30a5e8faSwyllys (givenattr->valueLen < testattr->minlen)) 1942*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 1943*30a5e8faSwyllys 1944*30a5e8faSwyllys /* If the given valueLen is too big, return error */ 1945*30a5e8faSwyllys if (givenattr->pValue != NULL && 1946*30a5e8faSwyllys testattr->maxlen > 0 && 1947*30a5e8faSwyllys (givenattr->valueLen > testattr->maxlen)) 1948*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 1949*30a5e8faSwyllys 1950*30a5e8faSwyllys return (KMF_OK); 1951*30a5e8faSwyllys } 1952*30a5e8faSwyllys 1953*30a5e8faSwyllys /* 1954*30a5e8faSwyllys * Given a set of required attribute tests and optional 1955*30a5e8faSwyllys * attributes, make sure that the actual attributes 1956*30a5e8faSwyllys * being tested (attrlist below) are allowed and are 1957*30a5e8faSwyllys * properly specified. 1958*30a5e8faSwyllys */ 1959*30a5e8faSwyllys KMF_RETURN 1960*30a5e8faSwyllys test_attributes(int reqnum, KMF_ATTRIBUTE_TESTER *reqattrs, 1961*30a5e8faSwyllys int optnum, KMF_ATTRIBUTE_TESTER *optattrs, 1962*30a5e8faSwyllys int numattrs, KMF_ATTRIBUTE *attrlist) 1963*30a5e8faSwyllys { 1964*30a5e8faSwyllys KMF_RETURN ret = KMF_OK; 1965*30a5e8faSwyllys int i, idx; 1966*30a5e8faSwyllys 1967*30a5e8faSwyllys /* 1968*30a5e8faSwyllys * If the caller didn't supply enough attributes, 1969*30a5e8faSwyllys * return an error. 1970*30a5e8faSwyllys */ 1971*30a5e8faSwyllys if (numattrs < reqnum || attrlist == NULL) 1972*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 1973*30a5e8faSwyllys 1974*30a5e8faSwyllys /* 1975*30a5e8faSwyllys * Make sure all required attrs are present and 1976*30a5e8faSwyllys * correct. 1977*30a5e8faSwyllys */ 1978*30a5e8faSwyllys for (i = 0; i < reqnum && ret == KMF_OK; i++) { 1979*30a5e8faSwyllys idx = kmf_find_attr(reqattrs[i].type, attrlist, numattrs); 1980*30a5e8faSwyllys /* If a required attr is not found, return error */ 1981*30a5e8faSwyllys if (idx == -1) { 1982*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 1983*30a5e8faSwyllys } 1984*30a5e8faSwyllys 1985*30a5e8faSwyllys ret = verify_attribute(&attrlist[idx], &reqattrs[i]); 1986*30a5e8faSwyllys } 1987*30a5e8faSwyllys /* 1988*30a5e8faSwyllys * Now test the optional parameters. 1989*30a5e8faSwyllys */ 1990*30a5e8faSwyllys for (i = 0; i < optnum && ret == KMF_OK; i++) { 1991*30a5e8faSwyllys idx = kmf_find_attr(optattrs[i].type, attrlist, numattrs); 1992*30a5e8faSwyllys /* If a optional attr is not found, continue. */ 1993*30a5e8faSwyllys if (idx == -1) { 1994*30a5e8faSwyllys continue; 1995*30a5e8faSwyllys } 1996*30a5e8faSwyllys 1997*30a5e8faSwyllys ret = verify_attribute(&attrlist[idx], &optattrs[i]); 1998*30a5e8faSwyllys } 1999*30a5e8faSwyllys 2000*30a5e8faSwyllys return (ret); 2001*30a5e8faSwyllys } 2002*30a5e8faSwyllys 2003*30a5e8faSwyllys /* 2004*30a5e8faSwyllys * Given an already allocated attribute list, insert 2005*30a5e8faSwyllys * the given attribute information at a specific index 2006*30a5e8faSwyllys * in the list. 2007*30a5e8faSwyllys */ 2008*30a5e8faSwyllys void 2009*30a5e8faSwyllys kmf_set_attr_at_index(KMF_ATTRIBUTE *attlist, int index, 2010*30a5e8faSwyllys KMF_ATTR_TYPE type, void *pValue, uint32_t len) 2011*30a5e8faSwyllys { 2012*30a5e8faSwyllys if (attlist == NULL) 2013*30a5e8faSwyllys return; 2014*30a5e8faSwyllys 2015*30a5e8faSwyllys attlist[index].type = type; 2016*30a5e8faSwyllys attlist[index].pValue = pValue; 2017*30a5e8faSwyllys attlist[index].valueLen = len; 2018*30a5e8faSwyllys } 2019*30a5e8faSwyllys 2020*30a5e8faSwyllys /* 2021*30a5e8faSwyllys * Find an attribute matching a particular type and set 2022*30a5e8faSwyllys * the pValue and length fields to the given values. 2023*30a5e8faSwyllys */ 2024*30a5e8faSwyllys KMF_RETURN 2025*30a5e8faSwyllys kmf_set_attr(KMF_ATTRIBUTE *attlist, int numattr, 2026*30a5e8faSwyllys KMF_ATTR_TYPE type, void *pValue, uint32_t len) 2027*30a5e8faSwyllys { 2028*30a5e8faSwyllys int idx; 2029*30a5e8faSwyllys if (attlist == NULL) 2030*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2031*30a5e8faSwyllys 2032*30a5e8faSwyllys idx = kmf_find_attr(type, attlist, numattr); 2033*30a5e8faSwyllys if (idx == -1) 2034*30a5e8faSwyllys return (KMF_ERR_ATTR_NOT_FOUND); 2035*30a5e8faSwyllys 2036*30a5e8faSwyllys attlist[idx].type = type; 2037*30a5e8faSwyllys /* Assumes the attribute pValue can hold the result */ 2038*30a5e8faSwyllys if (attlist[idx].pValue != NULL) { 2039*30a5e8faSwyllys if (attlist[idx].valueLen >= len) 2040*30a5e8faSwyllys (void) memcpy(attlist[idx].pValue, pValue, len); 2041*30a5e8faSwyllys else 2042*30a5e8faSwyllys return (KMF_ERR_BUFFER_SIZE); 2043*30a5e8faSwyllys } 2044*30a5e8faSwyllys attlist[idx].valueLen = len; 2045*30a5e8faSwyllys return (KMF_OK); 2046*30a5e8faSwyllys } 2047*30a5e8faSwyllys 2048*30a5e8faSwyllys /* 2049*30a5e8faSwyllys * Find a particular attribute in a list and return 2050*30a5e8faSwyllys * a pointer to its value. 2051*30a5e8faSwyllys */ 2052*30a5e8faSwyllys void * 2053*30a5e8faSwyllys kmf_get_attr_ptr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 2054*30a5e8faSwyllys int numattrs) 2055*30a5e8faSwyllys { 2056*30a5e8faSwyllys int i; 2057*30a5e8faSwyllys 2058*30a5e8faSwyllys i = kmf_find_attr(type, attlist, numattrs); 2059*30a5e8faSwyllys if (i == -1) 2060*30a5e8faSwyllys return (NULL); 2061*30a5e8faSwyllys 2062*30a5e8faSwyllys return (attlist[i].pValue); 2063*30a5e8faSwyllys } 2064*30a5e8faSwyllys 2065*30a5e8faSwyllys /* 2066*30a5e8faSwyllys * Find a particular attribute in a list and return 2067*30a5e8faSwyllys * the value and length values. Value and length 2068*30a5e8faSwyllys * may be NULL if the caller doesn't want their values 2069*30a5e8faSwyllys * to be filled in. 2070*30a5e8faSwyllys */ 2071*30a5e8faSwyllys KMF_RETURN 2072*30a5e8faSwyllys kmf_get_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 2073*30a5e8faSwyllys int numattrs, void *outValue, uint32_t *outlen) 2074*30a5e8faSwyllys { 2075*30a5e8faSwyllys int i; 2076*30a5e8faSwyllys uint32_t len = 0; 2077*30a5e8faSwyllys uint32_t *lenptr = outlen; 2078*30a5e8faSwyllys 2079*30a5e8faSwyllys if (lenptr == NULL) 2080*30a5e8faSwyllys lenptr = &len; 2081*30a5e8faSwyllys 2082*30a5e8faSwyllys i = kmf_find_attr(type, attlist, numattrs); 2083*30a5e8faSwyllys if (i == -1) 2084*30a5e8faSwyllys return (KMF_ERR_ATTR_NOT_FOUND); 2085*30a5e8faSwyllys 2086*30a5e8faSwyllys /* This assumes that the ptr passed in is pre-allocated space */ 2087*30a5e8faSwyllys if (attlist[i].pValue != NULL && outValue != NULL) { 2088*30a5e8faSwyllys /* 2089*30a5e8faSwyllys * If the caller did not specify a length, 2090*30a5e8faSwyllys * assume "outValue" is big enough. 2091*30a5e8faSwyllys */ 2092*30a5e8faSwyllys if (outlen != NULL) { 2093*30a5e8faSwyllys if (*outlen >= attlist[i].valueLen) 2094*30a5e8faSwyllys (void) memcpy(outValue, attlist[i].pValue, 2095*30a5e8faSwyllys attlist[i].valueLen); 2096*30a5e8faSwyllys else 2097*30a5e8faSwyllys return (KMF_ERR_BUFFER_SIZE); 2098*30a5e8faSwyllys } else { 2099*30a5e8faSwyllys (void) memcpy(outValue, attlist[i].pValue, 2100*30a5e8faSwyllys attlist[i].valueLen); 2101*30a5e8faSwyllys } 2102*30a5e8faSwyllys } 2103*30a5e8faSwyllys 2104*30a5e8faSwyllys if (outlen != NULL) 2105*30a5e8faSwyllys *outlen = attlist[i].valueLen; 2106*30a5e8faSwyllys return (KMF_OK); 2107*30a5e8faSwyllys } 2108*30a5e8faSwyllys 2109*30a5e8faSwyllys /* 2110*30a5e8faSwyllys * Utility routine to find a string type attribute, allocate it 2111*30a5e8faSwyllys * and return the value to the caller. This simplifies the 2112*30a5e8faSwyllys * operation by doing both "kmf_get_attr" calls and avoids 2113*30a5e8faSwyllys * duplicating this block of code in lots of places. 2114*30a5e8faSwyllys */ 2115*30a5e8faSwyllys KMF_RETURN 2116*30a5e8faSwyllys kmf_get_string_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attrlist, 2117*30a5e8faSwyllys int numattrs, char **outstr) 2118*30a5e8faSwyllys { 2119*30a5e8faSwyllys KMF_RETURN rv; 2120*30a5e8faSwyllys uint32_t len; 2121*30a5e8faSwyllys 2122*30a5e8faSwyllys if (outstr == NULL) 2123*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2124*30a5e8faSwyllys 2125*30a5e8faSwyllys if ((rv = kmf_get_attr(type, attrlist, numattrs, NULL, &len)) == 2126*30a5e8faSwyllys KMF_OK) { 2127*30a5e8faSwyllys *outstr = malloc(len + 1); 2128*30a5e8faSwyllys if ((*outstr) == NULL) 2129*30a5e8faSwyllys return (KMF_ERR_MEMORY); 2130*30a5e8faSwyllys (void) memset((*outstr), 0, len + 1); 2131*30a5e8faSwyllys rv = kmf_get_attr(type, attrlist, numattrs, (*outstr), &len); 2132*30a5e8faSwyllys if (rv != KMF_OK) { 2133*30a5e8faSwyllys free(*outstr); 2134*30a5e8faSwyllys *outstr = NULL; 2135*30a5e8faSwyllys } 2136*30a5e8faSwyllys } 2137*30a5e8faSwyllys 2138*30a5e8faSwyllys return (rv); 2139*30a5e8faSwyllys } 2140*30a5e8faSwyllys 2141*30a5e8faSwyllys /* 2142*30a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 2143*30a5e8faSwyllys */ 2144*30a5e8faSwyllys KMF_RETURN 2145*30a5e8faSwyllys KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 2146*30a5e8faSwyllys { 2147*30a5e8faSwyllys 2148*30a5e8faSwyllys KMF_ATTRIBUTE attlist[32]; 2149*30a5e8faSwyllys int i = 0; 2150*30a5e8faSwyllys 2151*30a5e8faSwyllys if (params == NULL) 2152*30a5e8faSwyllys return (KMF_ERR_BAD_PARAMETER); 2153*30a5e8faSwyllys 2154*30a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 2155*30a5e8faSwyllys KMF_KEYSTORE_TYPE_ATTR, ¶ms->kstype, sizeof (params->kstype)); 2156*30a5e8faSwyllys i++; 2157*30a5e8faSwyllys 2158*30a5e8faSwyllys if (params->kstype == KMF_KEYSTORE_NSS) { 2159*30a5e8faSwyllys if (params->nssconfig.configdir != NULL) { 2160*30a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 2161*30a5e8faSwyllys KMF_DIRPATH_ATTR, 2162*30a5e8faSwyllys params->nssconfig.configdir, 2163*30a5e8faSwyllys strlen(params->nssconfig.configdir)); 2164*30a5e8faSwyllys i++; 2165*30a5e8faSwyllys } 2166*30a5e8faSwyllys if (params->nssconfig.certPrefix != NULL) { 2167*30a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 2168*30a5e8faSwyllys KMF_CERTPREFIX_ATTR, 2169*30a5e8faSwyllys params->nssconfig.certPrefix, 2170*30a5e8faSwyllys strlen(params->nssconfig.certPrefix)); 2171*30a5e8faSwyllys i++; 2172*30a5e8faSwyllys } 2173*30a5e8faSwyllys if (params->nssconfig.keyPrefix != NULL) { 2174*30a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 2175*30a5e8faSwyllys KMF_KEYPREFIX_ATTR, 2176*30a5e8faSwyllys params->nssconfig.keyPrefix, 2177*30a5e8faSwyllys strlen(params->nssconfig.keyPrefix)); 2178*30a5e8faSwyllys i++; 2179*30a5e8faSwyllys } 2180*30a5e8faSwyllys if (params->nssconfig.secModName != NULL) { 2181*30a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 2182*30a5e8faSwyllys KMF_SECMODNAME_ATTR, 2183*30a5e8faSwyllys params->nssconfig.secModName, 2184*30a5e8faSwyllys strlen(params->nssconfig.secModName)); 2185*30a5e8faSwyllys i++; 2186*30a5e8faSwyllys } 2187*30a5e8faSwyllys } else if (params->kstype == KMF_KEYSTORE_PK11TOKEN) { 2188*30a5e8faSwyllys if (params->pkcs11config.label != NULL) { 2189*30a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 2190*30a5e8faSwyllys KMF_TOKEN_LABEL_ATTR, 2191*30a5e8faSwyllys params->pkcs11config.label, 2192*30a5e8faSwyllys strlen(params->pkcs11config.label)); 2193*30a5e8faSwyllys i++; 2194*30a5e8faSwyllys } 2195*30a5e8faSwyllys kmf_set_attr_at_index(attlist, i, 2196*30a5e8faSwyllys KMF_READONLY_ATTR, 2197*30a5e8faSwyllys ¶ms->pkcs11config.readonly, 2198*30a5e8faSwyllys sizeof (params->pkcs11config.readonly)); 2199*30a5e8faSwyllys i++; 2200*30a5e8faSwyllys } 2201*30a5e8faSwyllys 2202*30a5e8faSwyllys return (kmf_configure_keystore(handle, i, attlist)); 2203*30a5e8faSwyllys } 2204*30a5e8faSwyllys 2205*30a5e8faSwyllys /* 2206*30a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 2207*30a5e8faSwyllys */ 2208*30a5e8faSwyllys KMF_RETURN 2209*30a5e8faSwyllys KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 2210*30a5e8faSwyllys { 2211*30a5e8faSwyllys return (kmf_initialize(outhandle, policyfile, policyname)); 2212*30a5e8faSwyllys } 2213*30a5e8faSwyllys 2214*30a5e8faSwyllys /* 2215*30a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 2216*30a5e8faSwyllys */ 2217*30a5e8faSwyllys KMF_RETURN 2218*30a5e8faSwyllys KMF_Finalize(KMF_HANDLE_T handle) 2219*30a5e8faSwyllys { 2220*30a5e8faSwyllys return (kmf_finalize(handle)); 2221*30a5e8faSwyllys } 2222*30a5e8faSwyllys 2223*30a5e8faSwyllys /* 2224*30a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 2225*30a5e8faSwyllys */ 2226*30a5e8faSwyllys KMF_RETURN 2227*30a5e8faSwyllys KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) 2228*30a5e8faSwyllys { 2229*30a5e8faSwyllys return (kmf_get_kmf_error_str(errcode, errmsg)); 2230*30a5e8faSwyllys } 2231*30a5e8faSwyllys 2232*30a5e8faSwyllys /* 2233*30a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 2234*30a5e8faSwyllys */ 2235*30a5e8faSwyllys KMF_RETURN 2236*30a5e8faSwyllys KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 2237*30a5e8faSwyllys { 2238*30a5e8faSwyllys return (kmf_read_input_file(handle, filename, pdata)); 2239*30a5e8faSwyllys } 2240*30a5e8faSwyllys 2241*30a5e8faSwyllys 2242*30a5e8faSwyllys /* 2243*30a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 2244*30a5e8faSwyllys */ 2245*30a5e8faSwyllys void 2246*30a5e8faSwyllys KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 2247*30a5e8faSwyllys { 2248*30a5e8faSwyllys kmf_free_kmf_cert(handle, kmf_cert); 2249*30a5e8faSwyllys } 2250*30a5e8faSwyllys 2251*30a5e8faSwyllys /* 2252*30a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 2253*30a5e8faSwyllys */ 2254*30a5e8faSwyllys void 2255*30a5e8faSwyllys KMF_FreeData(KMF_DATA *datablock) 2256*30a5e8faSwyllys { 2257*30a5e8faSwyllys kmf_free_data(datablock); 2258*30a5e8faSwyllys } 2259*30a5e8faSwyllys 2260*30a5e8faSwyllys /* 2261*30a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 2262*30a5e8faSwyllys */ 2263*30a5e8faSwyllys void 2264*30a5e8faSwyllys KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 2265*30a5e8faSwyllys { 2266*30a5e8faSwyllys kmf_free_kmf_key(handle, key); 2267*30a5e8faSwyllys } 2268*30a5e8faSwyllys 2269*30a5e8faSwyllys /* 2270*30a5e8faSwyllys * This API is used by elfsign. We must keep it in old API form. 2271*30a5e8faSwyllys */ 2272*30a5e8faSwyllys void 2273*30a5e8faSwyllys KMF_FreeSignedCSR(KMF_CSR_DATA *csr) 2274*30a5e8faSwyllys { 2275*30a5e8faSwyllys kmf_free_signed_csr(csr); 2276*30a5e8faSwyllys } 2277