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 14399ebb4caSwyllys 14499ebb4caSwyllys static void free_extensions(KMF_X509_EXTENSIONS *extns); 14599ebb4caSwyllys 146*9b37d296Swyllys KMF_RETURN 147*9b37d296Swyllys init_pk11() 14899ebb4caSwyllys { 149*9b37d296Swyllys (void) mutex_lock(&init_lock); 150*9b37d296Swyllys if (!pkcs11_initialized) { 151*9b37d296Swyllys CK_RV rv = C_Initialize(NULL); 152*9b37d296Swyllys if ((rv != CKR_OK) && 153*9b37d296Swyllys (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 154*9b37d296Swyllys (void) mutex_unlock(&init_lock); 155*9b37d296Swyllys return (KMF_ERR_UNINITIALIZED); 156*9b37d296Swyllys } else { 157*9b37d296Swyllys pkcs11_initialized = 1; 158*9b37d296Swyllys } 159*9b37d296Swyllys } 160*9b37d296Swyllys (void) mutex_unlock(&init_lock); 161*9b37d296Swyllys return (KMF_OK); 16299ebb4caSwyllys } 16399ebb4caSwyllys 16499ebb4caSwyllys /* 16599ebb4caSwyllys * Private method for searching the plugin list for the correct 16699ebb4caSwyllys * Plugin to use. 16799ebb4caSwyllys */ 16899ebb4caSwyllys KMF_PLUGIN * 16999ebb4caSwyllys FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype) 17099ebb4caSwyllys { 17199ebb4caSwyllys KMF_PLUGIN_LIST *node; 17299ebb4caSwyllys 17399ebb4caSwyllys if (handle == NULL) 17499ebb4caSwyllys return (NULL); 17599ebb4caSwyllys 17699ebb4caSwyllys node = handle->plugins; 17799ebb4caSwyllys 17899ebb4caSwyllys while (node != NULL && node->plugin->type != kstype) 17999ebb4caSwyllys node = node->next; 18099ebb4caSwyllys 18199ebb4caSwyllys /* If it is NULL, that is indication enough of an error */ 18299ebb4caSwyllys return (node ? node->plugin : NULL); 18399ebb4caSwyllys } 18499ebb4caSwyllys 18599ebb4caSwyllys static KMF_RETURN 18699ebb4caSwyllys InitializePlugin(KMF_KEYSTORE_TYPE kstype, char *path, KMF_PLUGIN **plugin) 18799ebb4caSwyllys { 18899ebb4caSwyllys KMF_PLUGIN *p = NULL; 18999ebb4caSwyllys KMF_PLUGIN_FUNCLIST *(*sym)(); 19099ebb4caSwyllys 19199ebb4caSwyllys if (path == NULL || plugin == NULL) 19299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 19399ebb4caSwyllys 19499ebb4caSwyllys *plugin = NULL; 19599ebb4caSwyllys 19699ebb4caSwyllys p = (KMF_PLUGIN *)malloc(sizeof (KMF_PLUGIN)); 19799ebb4caSwyllys if (p == NULL) 19899ebb4caSwyllys return (KMF_ERR_MEMORY); 19999ebb4caSwyllys 20099ebb4caSwyllys p->type = kstype; 20199ebb4caSwyllys p->path = strdup(path); 20299ebb4caSwyllys if (p->path == NULL) { 20399ebb4caSwyllys free(p); 20499ebb4caSwyllys return (KMF_ERR_MEMORY); 20599ebb4caSwyllys } 20699ebb4caSwyllys p->dldesc = dlopen(path, RTLD_NOW | RTLD_GROUP | RTLD_PARENT); 20799ebb4caSwyllys if (p->dldesc == NULL) { 20899ebb4caSwyllys free(p->path); 20999ebb4caSwyllys free(p); 21099ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 21199ebb4caSwyllys } 21299ebb4caSwyllys 21399ebb4caSwyllys sym = (KMF_PLUGIN_FUNCLIST *(*)())dlsym(p->dldesc, 21499ebb4caSwyllys KMF_PLUGIN_INIT_SYMBOL); 21599ebb4caSwyllys if (sym == NULL) { 21699ebb4caSwyllys (void) dlclose(p->dldesc); 21799ebb4caSwyllys free(p->path); 21899ebb4caSwyllys free(p); 21999ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 22099ebb4caSwyllys } 22199ebb4caSwyllys 22299ebb4caSwyllys /* Get the function list */ 22399ebb4caSwyllys if ((p->funclist = (*sym)()) == NULL) { 22499ebb4caSwyllys (void) dlclose(p->dldesc); 22599ebb4caSwyllys free(p->path); 22699ebb4caSwyllys free(p); 22799ebb4caSwyllys return (KMF_ERR_PLUGIN_INIT); 22899ebb4caSwyllys } 22999ebb4caSwyllys 23099ebb4caSwyllys *plugin = p; 23199ebb4caSwyllys 23299ebb4caSwyllys return (KMF_OK); 23399ebb4caSwyllys } 23499ebb4caSwyllys 23599ebb4caSwyllys static KMF_RETURN 23699ebb4caSwyllys AddPlugin(KMF_HANDLE_T handle, KMF_PLUGIN *plugin) 23799ebb4caSwyllys { 23899ebb4caSwyllys KMF_PLUGIN_LIST *n; 23999ebb4caSwyllys 24099ebb4caSwyllys if (handle == NULL || plugin == NULL) 24199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 24299ebb4caSwyllys 24399ebb4caSwyllys /* If the head is NULL, create it */ 24499ebb4caSwyllys if (handle->plugins == NULL) { 24599ebb4caSwyllys handle->plugins = (KMF_PLUGIN_LIST *)malloc( 24699ebb4caSwyllys sizeof (KMF_PLUGIN_LIST)); 24799ebb4caSwyllys if (handle->plugins == NULL) 24899ebb4caSwyllys return (KMF_ERR_MEMORY); 24999ebb4caSwyllys handle->plugins->plugin = plugin; 25099ebb4caSwyllys handle->plugins->next = NULL; 25199ebb4caSwyllys } else { 25299ebb4caSwyllys /* walk the list to find the tail */ 25399ebb4caSwyllys n = handle->plugins; 25499ebb4caSwyllys while (n->next != NULL) 25599ebb4caSwyllys n = n->next; 25699ebb4caSwyllys n->next = (KMF_PLUGIN_LIST *)malloc(sizeof (KMF_PLUGIN_LIST)); 25799ebb4caSwyllys if (n->next == NULL) 25899ebb4caSwyllys return (KMF_ERR_MEMORY); 25999ebb4caSwyllys 26099ebb4caSwyllys n->next->plugin = plugin; 26199ebb4caSwyllys n->next->next = NULL; 26299ebb4caSwyllys } 26399ebb4caSwyllys return (0); 26499ebb4caSwyllys } 26599ebb4caSwyllys 26699ebb4caSwyllys static void 26799ebb4caSwyllys DestroyPlugin(KMF_PLUGIN *plugin) 26899ebb4caSwyllys { 26999ebb4caSwyllys if (plugin) { 27099ebb4caSwyllys if (plugin->path) 27199ebb4caSwyllys free(plugin->path); 27299ebb4caSwyllys free(plugin); 27399ebb4caSwyllys } 27499ebb4caSwyllys } 27599ebb4caSwyllys 27699ebb4caSwyllys static void 27799ebb4caSwyllys Cleanup_KMF_Handle(KMF_HANDLE_T handle) 27899ebb4caSwyllys { 27999ebb4caSwyllys if (handle != NULL) { 28099ebb4caSwyllys while (handle->plugins != NULL) { 28199ebb4caSwyllys KMF_PLUGIN_LIST *next = handle->plugins->next; 28299ebb4caSwyllys 28399ebb4caSwyllys DestroyPlugin(handle->plugins->plugin); 28499ebb4caSwyllys 28599ebb4caSwyllys free(handle->plugins); 28699ebb4caSwyllys 28799ebb4caSwyllys handle->plugins = next; 28899ebb4caSwyllys } 28999ebb4caSwyllys 29099ebb4caSwyllys KMF_FreePolicyRecord(handle->policy); 29199ebb4caSwyllys free(handle->policy); 29299ebb4caSwyllys } 29399ebb4caSwyllys free(handle); 29499ebb4caSwyllys } 29599ebb4caSwyllys 29699ebb4caSwyllys void 29799ebb4caSwyllys Cleanup_PK11_Session(KMF_HANDLE_T handle) 29899ebb4caSwyllys { 29999ebb4caSwyllys if (handle != NULL) { 30099ebb4caSwyllys /* Close active session on a pkcs11 token */ 30199ebb4caSwyllys if (handle->pk11handle != NULL) { 30299ebb4caSwyllys (void) C_CloseSession(handle->pk11handle); 30399ebb4caSwyllys handle->pk11handle = NULL; 30499ebb4caSwyllys } 30599ebb4caSwyllys } 30699ebb4caSwyllys } 30799ebb4caSwyllys 30899ebb4caSwyllys KMF_RETURN 30999ebb4caSwyllys KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 31099ebb4caSwyllys { 31199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 31299ebb4caSwyllys KMF_HANDLE *handle = NULL; 31399ebb4caSwyllys KMF_PLUGIN *pluginrec = NULL; 31499ebb4caSwyllys 31599ebb4caSwyllys if (outhandle == NULL) 31699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 31799ebb4caSwyllys 31899ebb4caSwyllys *outhandle = NULL; 31999ebb4caSwyllys handle = (KMF_HANDLE *)malloc(sizeof (KMF_HANDLE)); 32099ebb4caSwyllys if (handle == NULL) 32199ebb4caSwyllys return (KMF_ERR_MEMORY); 32299ebb4caSwyllys 32399ebb4caSwyllys (void) memset(handle, 0, sizeof (KMF_HANDLE)); 32499ebb4caSwyllys handle->plugins = NULL; 32599ebb4caSwyllys 32699ebb4caSwyllys 32799ebb4caSwyllys /* Initialize the handle with the policy */ 32899ebb4caSwyllys ret = KMF_SetPolicy((void *)handle, 32999ebb4caSwyllys policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile, 33099ebb4caSwyllys policyname == NULL ? KMF_DEFAULT_POLICY_NAME : policyname); 33199ebb4caSwyllys if (ret != KMF_OK) 33299ebb4caSwyllys goto errout; 33399ebb4caSwyllys 33499ebb4caSwyllys /* Create a record for the plugin */ 33599ebb4caSwyllys if ((ret = InitializePlugin(KMF_KEYSTORE_NSS, 33699ebb4caSwyllys KMF_PLUGIN_PATH "kmf_nss.so.1", &pluginrec)) != KMF_OK) 33799ebb4caSwyllys goto errout; 33899ebb4caSwyllys 33999ebb4caSwyllys /* Add it to the handle */ 34099ebb4caSwyllys if (pluginrec != NULL) { 34199ebb4caSwyllys if ((ret = AddPlugin(handle, pluginrec))) 34299ebb4caSwyllys goto errout; 34399ebb4caSwyllys } 34499ebb4caSwyllys if ((ret = InitializePlugin(KMF_KEYSTORE_OPENSSL, 34599ebb4caSwyllys KMF_PLUGIN_PATH "kmf_openssl.so.1", &pluginrec)) != KMF_OK) 34699ebb4caSwyllys goto errout; 34799ebb4caSwyllys 34899ebb4caSwyllys /* Add it to the handle */ 34999ebb4caSwyllys if (pluginrec != NULL) 35099ebb4caSwyllys if ((ret = AddPlugin(handle, pluginrec))) 35199ebb4caSwyllys goto errout; 35299ebb4caSwyllys 35399ebb4caSwyllys if ((ret = InitializePlugin(KMF_KEYSTORE_PK11TOKEN, 35499ebb4caSwyllys KMF_PLUGIN_PATH "kmf_pkcs11.so.1", &pluginrec)) != KMF_OK) 35599ebb4caSwyllys goto errout; 35699ebb4caSwyllys 35799ebb4caSwyllys /* Add it to the handle */ 35899ebb4caSwyllys if (pluginrec != NULL) 35999ebb4caSwyllys if ((ret = AddPlugin(handle, pluginrec))) 36099ebb4caSwyllys goto errout; 36199ebb4caSwyllys 36299ebb4caSwyllys CLEAR_ERROR(handle, ret); 36399ebb4caSwyllys errout: 36499ebb4caSwyllys if (ret != KMF_OK) { 36599ebb4caSwyllys Cleanup_KMF_Handle(handle); 36699ebb4caSwyllys handle = NULL; 36799ebb4caSwyllys } 36899ebb4caSwyllys 36999ebb4caSwyllys *outhandle = (KMF_HANDLE_T)handle; 37099ebb4caSwyllys return (ret); 37199ebb4caSwyllys } 37299ebb4caSwyllys 37399ebb4caSwyllys KMF_RETURN 37499ebb4caSwyllys KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 37599ebb4caSwyllys { 37699ebb4caSwyllys KMF_PLUGIN *plugin; 37799ebb4caSwyllys KMF_RETURN ret; 37899ebb4caSwyllys 37999ebb4caSwyllys CLEAR_ERROR(handle, ret); 38099ebb4caSwyllys if (ret != KMF_OK) 38199ebb4caSwyllys return (ret); 38299ebb4caSwyllys 38399ebb4caSwyllys if (params == NULL) 38499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 38599ebb4caSwyllys 38699ebb4caSwyllys plugin = FindPlugin(handle, params->kstype); 38799ebb4caSwyllys if (plugin == NULL) 38899ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 38999ebb4caSwyllys 39099ebb4caSwyllys if (plugin->funclist->ConfigureKeystore != NULL) 39199ebb4caSwyllys return (plugin->funclist->ConfigureKeystore(handle, params)); 39299ebb4caSwyllys else 39399ebb4caSwyllys /* return KMF_OK, if the plugin does not have an entry */ 39499ebb4caSwyllys return (KMF_OK); 39599ebb4caSwyllys } 39699ebb4caSwyllys 39799ebb4caSwyllys KMF_RETURN 39899ebb4caSwyllys KMF_Finalize(KMF_HANDLE_T handle) 39999ebb4caSwyllys { 40099ebb4caSwyllys KMF_RETURN ret = KMF_OK; 40199ebb4caSwyllys 40299ebb4caSwyllys CLEAR_ERROR(handle, ret); 40399ebb4caSwyllys if (ret != KMF_OK) 40499ebb4caSwyllys return (ret); 40599ebb4caSwyllys 40699ebb4caSwyllys if (pkcs11_initialized) { 40799ebb4caSwyllys Cleanup_PK11_Session(handle); 40899ebb4caSwyllys } 40999ebb4caSwyllys Cleanup_KMF_Handle(handle); 41099ebb4caSwyllys 41199ebb4caSwyllys return (ret); 41299ebb4caSwyllys } 41399ebb4caSwyllys 41499ebb4caSwyllys KMF_RETURN 41599ebb4caSwyllys KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) 41699ebb4caSwyllys { 41799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 41899ebb4caSwyllys int i, maxerr; 41999ebb4caSwyllys 42099ebb4caSwyllys if (errmsg == NULL) 42199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 42299ebb4caSwyllys 42399ebb4caSwyllys *errmsg = NULL; 42499ebb4caSwyllys maxerr = sizeof (kmf_errcodes) / sizeof (kmf_error_map); 42599ebb4caSwyllys 42699ebb4caSwyllys for (i = 0; i < maxerr && errcode != kmf_errcodes[i].code; i++); 42799ebb4caSwyllys 42899ebb4caSwyllys if (i == maxerr) 42999ebb4caSwyllys return (KMF_ERR_MISSING_ERRCODE); 43099ebb4caSwyllys else { 43199ebb4caSwyllys *errmsg = strdup(kmf_errcodes[i].message); 43299ebb4caSwyllys if ((*errmsg) == NULL) 43399ebb4caSwyllys return (KMF_ERR_MEMORY); 43499ebb4caSwyllys } 43599ebb4caSwyllys return (ret); 43699ebb4caSwyllys } 43799ebb4caSwyllys 43899ebb4caSwyllys KMF_RETURN 43999ebb4caSwyllys KMF_GetPluginErrorString(KMF_HANDLE_T handle, char **msgstr) 44099ebb4caSwyllys { 44199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 44299ebb4caSwyllys KMF_PLUGIN *plugin; 44399ebb4caSwyllys 44499ebb4caSwyllys if (handle == NULL || msgstr == NULL) 44599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 44699ebb4caSwyllys 44799ebb4caSwyllys *msgstr = NULL; 44899ebb4caSwyllys 44999ebb4caSwyllys if (handle->lasterr.errcode == 0) { 45099ebb4caSwyllys return (KMF_ERR_MISSING_ERRCODE); 45199ebb4caSwyllys } 45299ebb4caSwyllys 45399ebb4caSwyllys if (handle->lasterr.kstype == -1) { /* System error */ 45499ebb4caSwyllys char *str = strerror(handle->lasterr.errcode); 45599ebb4caSwyllys if (str != NULL) { 45699ebb4caSwyllys *msgstr = strdup(str); 45799ebb4caSwyllys if ((*msgstr) == NULL) 45899ebb4caSwyllys return (KMF_ERR_MEMORY); 45999ebb4caSwyllys } 46099ebb4caSwyllys return (KMF_OK); 46199ebb4caSwyllys } 46299ebb4caSwyllys 46399ebb4caSwyllys plugin = FindPlugin(handle, handle->lasterr.kstype); 46499ebb4caSwyllys if (plugin == NULL) 46599ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 46699ebb4caSwyllys 46799ebb4caSwyllys if (plugin->funclist->GetErrorString != NULL) { 46899ebb4caSwyllys ret = plugin->funclist->GetErrorString(handle, msgstr); 46999ebb4caSwyllys } else { 47099ebb4caSwyllys return (KMF_ERR_FUNCTION_NOT_FOUND); 47199ebb4caSwyllys } 47299ebb4caSwyllys 47399ebb4caSwyllys return (ret); 47499ebb4caSwyllys } 47599ebb4caSwyllys 47699ebb4caSwyllys KMF_RETURN 47799ebb4caSwyllys KMF_DNParser(char *string, KMF_X509_NAME *name) 47899ebb4caSwyllys { 47999ebb4caSwyllys KMF_RETURN err; 48099ebb4caSwyllys 48199ebb4caSwyllys if (string == NULL || name == NULL) 48299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 48399ebb4caSwyllys 48499ebb4caSwyllys err = ParseDistinguishedName(string, (int)strlen(string), name); 48599ebb4caSwyllys return (err); 48699ebb4caSwyllys } 48799ebb4caSwyllys 48899ebb4caSwyllys KMF_RETURN 48999ebb4caSwyllys KMF_DN2Der(KMF_X509_NAME *dn, KMF_DATA *der) 49099ebb4caSwyllys { 49199ebb4caSwyllys KMF_RETURN rv; 49299ebb4caSwyllys 49399ebb4caSwyllys if (dn == NULL || der == NULL) 49499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 49599ebb4caSwyllys 49699ebb4caSwyllys rv = DerEncodeName(dn, der); 49799ebb4caSwyllys return (rv); 49899ebb4caSwyllys } 49999ebb4caSwyllys 500*9b37d296Swyllys #define SET_SYS_ERROR(h, c) if (h) {\ 501*9b37d296Swyllys h->lasterr.kstype = -1;\ 502*9b37d296Swyllys h->lasterr.errcode = c;\ 503*9b37d296Swyllys } 50499ebb4caSwyllys 50599ebb4caSwyllys KMF_RETURN 50699ebb4caSwyllys KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 50799ebb4caSwyllys { 50899ebb4caSwyllys struct stat s; 50999ebb4caSwyllys long nread, total = 0; 51099ebb4caSwyllys int fd; 51199ebb4caSwyllys unsigned char *buf = NULL; 51299ebb4caSwyllys KMF_RETURN ret; 51399ebb4caSwyllys 514*9b37d296Swyllys if (handle) { 515*9b37d296Swyllys CLEAR_ERROR(handle, ret); 516*9b37d296Swyllys if (ret != KMF_OK) 517*9b37d296Swyllys return (ret); 518*9b37d296Swyllys } 51999ebb4caSwyllys 52099ebb4caSwyllys if (filename == NULL || pdata == NULL) { 52199ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 52299ebb4caSwyllys } 52399ebb4caSwyllys 52499ebb4caSwyllys if ((fd = open(filename, O_RDONLY)) < 0) { 52599ebb4caSwyllys SET_SYS_ERROR(handle, errno); 52699ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 52799ebb4caSwyllys } 52899ebb4caSwyllys 52999ebb4caSwyllys if (fstat(fd, &s) < 0) { 53099ebb4caSwyllys SET_SYS_ERROR(handle, errno); 53199ebb4caSwyllys (void) close(fd); 53299ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 53399ebb4caSwyllys } 53499ebb4caSwyllys 53599ebb4caSwyllys if ((buf = (unsigned char *) malloc(s.st_size)) == NULL) { 53699ebb4caSwyllys (void) close(fd); 53799ebb4caSwyllys return (KMF_ERR_MEMORY); 53899ebb4caSwyllys } 53999ebb4caSwyllys 54099ebb4caSwyllys do { 54199ebb4caSwyllys nread = read(fd, buf+total, s.st_size-total); 54299ebb4caSwyllys if (nread < 0) { 54399ebb4caSwyllys SET_SYS_ERROR(handle, errno); 54499ebb4caSwyllys (void) close(fd); 54599ebb4caSwyllys free(buf); 54699ebb4caSwyllys return (KMF_ERR_INTERNAL); 54799ebb4caSwyllys } 54899ebb4caSwyllys total += nread; 54999ebb4caSwyllys } while (total < s.st_size); 55099ebb4caSwyllys 55199ebb4caSwyllys pdata->Data = buf; 55299ebb4caSwyllys pdata->Length = s.st_size; 55399ebb4caSwyllys (void) close(fd); 55499ebb4caSwyllys return (KMF_OK); 55599ebb4caSwyllys } 55699ebb4caSwyllys 55799ebb4caSwyllys /* 55899ebb4caSwyllys * 55999ebb4caSwyllys * Name: KMF_Der2Pem 56099ebb4caSwyllys * 56199ebb4caSwyllys * Description: 56299ebb4caSwyllys * Function for converting DER encoded format to PEM encoded format 56399ebb4caSwyllys * 56499ebb4caSwyllys * Parameters: 56599ebb4caSwyllys * type(input) - CERTIFICATE or CSR 56699ebb4caSwyllys * data(input) - pointer to the DER encoded data 56799ebb4caSwyllys * len(input) - length of input data 56899ebb4caSwyllys * out(output) - contains the output buffer address to be returned 56999ebb4caSwyllys * outlen(output) - pointer to the returned output length 57099ebb4caSwyllys * 57199ebb4caSwyllys * Returns: 57299ebb4caSwyllys * A KMF_RETURN value indicating success or specifying a particular 57399ebb4caSwyllys * error condition. 57499ebb4caSwyllys * The value KMF_OK indicates success. All other values represent 57599ebb4caSwyllys * an error condition. 57699ebb4caSwyllys * 57799ebb4caSwyllys */ 57899ebb4caSwyllys KMF_RETURN 57999ebb4caSwyllys KMF_Der2Pem(KMF_OBJECT_TYPE type, unsigned char *data, 58099ebb4caSwyllys int len, unsigned char **out, int *outlen) 58199ebb4caSwyllys { 58299ebb4caSwyllys 58399ebb4caSwyllys KMF_RETURN err; 58499ebb4caSwyllys if (data == NULL || out == NULL || outlen == NULL) 58599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 58699ebb4caSwyllys 58799ebb4caSwyllys err = Der2Pem(type, data, len, out, outlen); 58899ebb4caSwyllys return (err); 58999ebb4caSwyllys 59099ebb4caSwyllys } 59199ebb4caSwyllys 59299ebb4caSwyllys /* 59399ebb4caSwyllys * 59499ebb4caSwyllys * Name: KMF_Pem2Der 59599ebb4caSwyllys * 59699ebb4caSwyllys * Description: 59799ebb4caSwyllys * Function for converting PEM encoded format to DER encoded format 59899ebb4caSwyllys * 59999ebb4caSwyllys * Parameters: 60099ebb4caSwyllys * in(input) - pointer to the PEM encoded data 60199ebb4caSwyllys * inlen(input) - length of input data 60299ebb4caSwyllys * out(output) - contains the output buffer address to be returned 60399ebb4caSwyllys * outlen(output) - pointer to the returned output length 60499ebb4caSwyllys * 60599ebb4caSwyllys * Returns: 60699ebb4caSwyllys * A KMF_RETURN value indicating success or specifying a particular 60799ebb4caSwyllys * error condition. 60899ebb4caSwyllys * The value KMF_OK indicates success. All other values represent 60999ebb4caSwyllys * an error condition. 61099ebb4caSwyllys * 61199ebb4caSwyllys */ 61299ebb4caSwyllys KMF_RETURN 61399ebb4caSwyllys KMF_Pem2Der(unsigned char *in, int inlen, 61499ebb4caSwyllys unsigned char **out, int *outlen) 61599ebb4caSwyllys { 61699ebb4caSwyllys KMF_RETURN err; 61799ebb4caSwyllys if (in == NULL || out == NULL || outlen == NULL) 61899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 61999ebb4caSwyllys 62099ebb4caSwyllys err = Pem2Der(in, inlen, out, outlen); 62199ebb4caSwyllys return (err); 62299ebb4caSwyllys } 62399ebb4caSwyllys 62499ebb4caSwyllys char * 62599ebb4caSwyllys KMF_OID2String(KMF_OID *oid) 62699ebb4caSwyllys { 62799ebb4caSwyllys char numstr[128]; 62899ebb4caSwyllys uint32_t number; 62999ebb4caSwyllys int numshift; 63099ebb4caSwyllys uint32_t i, string_length; 63199ebb4caSwyllys uchar_t *cp; 63299ebb4caSwyllys char *bp; 63399ebb4caSwyllys 63499ebb4caSwyllys /* First determine the size of the string */ 63599ebb4caSwyllys string_length = 0; 63699ebb4caSwyllys number = 0; 63799ebb4caSwyllys numshift = 0; 63899ebb4caSwyllys cp = (unsigned char *)oid->Data; 63999ebb4caSwyllys 64099ebb4caSwyllys number = (uint32_t)cp[0]; 64199ebb4caSwyllys (void) sprintf(numstr, "%d ", number/40); 64299ebb4caSwyllys 64399ebb4caSwyllys string_length += strlen(numstr); 64499ebb4caSwyllys (void) sprintf(numstr, "%d ", number%40); 64599ebb4caSwyllys 64699ebb4caSwyllys string_length += strlen(numstr); 64799ebb4caSwyllys 64899ebb4caSwyllys for (i = 1; i < oid->Length; i++) { 64999ebb4caSwyllys if ((uint32_t)(numshift+7) < (sizeof (uint32_t)*8)) { 65099ebb4caSwyllys number = (number << 7) | (cp[i] & 0x7f); 65199ebb4caSwyllys numshift += 7; 65299ebb4caSwyllys } else { 65399ebb4caSwyllys return (NULL); 65499ebb4caSwyllys } 65599ebb4caSwyllys 65699ebb4caSwyllys if ((cp[i] & 0x80) == 0) { 65799ebb4caSwyllys (void) sprintf(numstr, "%d ", number); 65899ebb4caSwyllys string_length += strlen(numstr); 65999ebb4caSwyllys number = 0; 66099ebb4caSwyllys numshift = 0; 66199ebb4caSwyllys } 66299ebb4caSwyllys } 66399ebb4caSwyllys /* 66499ebb4caSwyllys * If we get here, we've calculated the length of "n n n ... n ". Add 4 66599ebb4caSwyllys * here for "{ " and "}\0". 66699ebb4caSwyllys */ 66799ebb4caSwyllys string_length += 4; 66899ebb4caSwyllys if ((bp = (char *)malloc(string_length))) { 66999ebb4caSwyllys number = (uint32_t)cp[0]; 67099ebb4caSwyllys 67199ebb4caSwyllys (void) sprintf(numstr, "%d.", number/40); 67299ebb4caSwyllys (void) strcpy(bp, numstr); 67399ebb4caSwyllys 67499ebb4caSwyllys (void) sprintf(numstr, "%d.", number%40); 67599ebb4caSwyllys (void) strcat(bp, numstr); 67699ebb4caSwyllys 67799ebb4caSwyllys number = 0; 67899ebb4caSwyllys cp = (unsigned char *) oid->Data; 67999ebb4caSwyllys for (i = 1; i < oid->Length; i++) { 68099ebb4caSwyllys number = (number << 7) | (cp[i] & 0x7f); 68199ebb4caSwyllys if ((cp[i] & 0x80) == 0) { 68299ebb4caSwyllys (void) sprintf(numstr, "%d", number); 68399ebb4caSwyllys (void) strcat(bp, numstr); 68499ebb4caSwyllys number = 0; 68599ebb4caSwyllys if (i+1 < oid->Length) 68699ebb4caSwyllys (void) strcat(bp, "."); 68799ebb4caSwyllys } 68899ebb4caSwyllys } 68999ebb4caSwyllys } 69099ebb4caSwyllys return (bp); 69199ebb4caSwyllys } 69299ebb4caSwyllys 69302744e81Swyllys static boolean_t 69402744e81Swyllys check_for_pem(char *filename) 69502744e81Swyllys { 696*9b37d296Swyllys KMF_DATA filebuf; 697*9b37d296Swyllys KMF_RETURN rv; 698*9b37d296Swyllys char *p; 69902744e81Swyllys 700*9b37d296Swyllys rv = KMF_ReadInputFile(NULL, filename, &filebuf); 701*9b37d296Swyllys if (rv != KMF_OK) 70202744e81Swyllys return (FALSE); 70302744e81Swyllys 704*9b37d296Swyllys /* Look for "-----BEGIN" right after a newline */ 705*9b37d296Swyllys p = strtok((char *)filebuf.Data, "\n"); 706*9b37d296Swyllys while (p != NULL) { 707*9b37d296Swyllys if (strstr(p, "-----BEGIN") != NULL) { 708*9b37d296Swyllys free(filebuf.Data); 709*9b37d296Swyllys return (TRUE); 71002744e81Swyllys } 711*9b37d296Swyllys p = strtok(NULL, "\n"); 71202744e81Swyllys } 713*9b37d296Swyllys free(filebuf.Data); 71402744e81Swyllys return (FALSE); 71502744e81Swyllys } 71602744e81Swyllys 71799ebb4caSwyllys KMF_RETURN 71899ebb4caSwyllys KMF_GetFileFormat(char *filename, KMF_ENCODE_FORMAT *fmt) 71999ebb4caSwyllys { 72099ebb4caSwyllys int f; 72199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 72299ebb4caSwyllys uchar_t buf[16]; 72399ebb4caSwyllys 72499ebb4caSwyllys if (filename == NULL || !strlen(filename) || fmt == NULL) 72599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 72699ebb4caSwyllys 72799ebb4caSwyllys *fmt = 0; 72899ebb4caSwyllys if ((f = open(filename, O_RDONLY)) == -1) { 72999ebb4caSwyllys return (KMF_ERR_OPEN_FILE); 73099ebb4caSwyllys } 73199ebb4caSwyllys 73299ebb4caSwyllys if (read(f, buf, 8) != 8) { 73399ebb4caSwyllys ret = KMF_ERR_OPEN_FILE; 73499ebb4caSwyllys goto end; 73599ebb4caSwyllys } 73699ebb4caSwyllys 73702744e81Swyllys (void) close(f); 73802744e81Swyllys if (buf[0] == 0x30 && (buf[1] & 0x80)) { 73999ebb4caSwyllys if ((buf[1] & 0xFF) == 0x80 && 74099ebb4caSwyllys (buf[2] & 0xFF) == 0x02 && 74199ebb4caSwyllys (buf[5] & 0xFF) == 0x30) { 74299ebb4caSwyllys *fmt = KMF_FORMAT_PKCS12; 74399ebb4caSwyllys } else if ((buf[1] & 0xFF) == 0x82 && 74499ebb4caSwyllys (buf[4] & 0xFF) == 0x02 && 74599ebb4caSwyllys (buf[7] & 0xFF) == 0x30) { 74699ebb4caSwyllys *fmt = KMF_FORMAT_PKCS12; 74799ebb4caSwyllys /* It is most likely a generic ASN.1 encoded file */ 74899ebb4caSwyllys } else { 74999ebb4caSwyllys *fmt = KMF_FORMAT_ASN1; 75099ebb4caSwyllys } 75171593db2Swyllys } else if (memcmp(buf, "Bag Attr", 8) == 0) { 75271593db2Swyllys *fmt = KMF_FORMAT_PEM_KEYPAIR; 75399ebb4caSwyllys } else { 75402744e81Swyllys /* Try PEM */ 75502744e81Swyllys if (check_for_pem(filename) == TRUE) { 75602744e81Swyllys *fmt = KMF_FORMAT_PEM; 75702744e81Swyllys } else { 75802744e81Swyllys /* Cannot determine this file format */ 75902744e81Swyllys *fmt = 0; 76002744e81Swyllys ret = KMF_ERR_ENCODING; 76102744e81Swyllys } 76299ebb4caSwyllys } 76399ebb4caSwyllys end: 76499ebb4caSwyllys return (ret); 76599ebb4caSwyllys } 76699ebb4caSwyllys 76799ebb4caSwyllys KMF_RETURN 76899ebb4caSwyllys KMF_HexString2Bytes(unsigned char *hexstr, unsigned char **bytes, 76999ebb4caSwyllys size_t *outlen) 77099ebb4caSwyllys { 77199ebb4caSwyllys KMF_RETURN ret = KMF_OK; 77299ebb4caSwyllys unsigned char *buf = NULL; 77399ebb4caSwyllys int len, stringlen; 77499ebb4caSwyllys int i; 77599ebb4caSwyllys unsigned char ch; 77699ebb4caSwyllys 77799ebb4caSwyllys if (hexstr == NULL) { 77899ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 77999ebb4caSwyllys } 78099ebb4caSwyllys 78199ebb4caSwyllys if (hexstr[0] == '0' && 78299ebb4caSwyllys ((hexstr[1] == 'x') || (hexstr[1] == 'X'))) 78399ebb4caSwyllys hexstr += 2; 78499ebb4caSwyllys 78599ebb4caSwyllys for (i = 0; i < strlen((char *)hexstr) && isxdigit(hexstr[i]); i++); 78699ebb4caSwyllys /* 78799ebb4caSwyllys * If all the characters are not legitimate hex chars, 78899ebb4caSwyllys * return an error. 78999ebb4caSwyllys */ 79099ebb4caSwyllys if (i != strlen((char *)hexstr)) 79199ebb4caSwyllys return (KMF_ERR_BAD_HEX_STRING); 79299ebb4caSwyllys stringlen = i; 79399ebb4caSwyllys len = (i / 2) + (i % 2); 79499ebb4caSwyllys 79599ebb4caSwyllys buf = malloc(len); 79699ebb4caSwyllys if (buf == NULL) { 79799ebb4caSwyllys return (KMF_ERR_MEMORY); 79899ebb4caSwyllys } 79999ebb4caSwyllys (void) memset(buf, 0, len); 80099ebb4caSwyllys 80199ebb4caSwyllys for (i = 0; i < stringlen; i++) { 80299ebb4caSwyllys ch = (unsigned char) *hexstr; 80399ebb4caSwyllys hexstr++; 80499ebb4caSwyllys if ((ch >= '0') && (ch <= '9')) 80599ebb4caSwyllys ch -= '0'; 80699ebb4caSwyllys else if ((ch >= 'A') && (ch <= 'F')) 80799ebb4caSwyllys ch = ch - 'A' + 10; 80899ebb4caSwyllys else if ((ch >= 'a') && (ch <= 'f')) 80999ebb4caSwyllys ch = ch - 'a' + 10; 81099ebb4caSwyllys else { 81199ebb4caSwyllys ret = KMF_ERR_BAD_HEX_STRING; 81299ebb4caSwyllys goto out; 81399ebb4caSwyllys } 81499ebb4caSwyllys 81599ebb4caSwyllys if (i & 1) { 81699ebb4caSwyllys buf[i/2] |= ch; 81799ebb4caSwyllys } else { 81899ebb4caSwyllys buf[i/2] = (ch << 4); 81999ebb4caSwyllys } 82099ebb4caSwyllys } 82199ebb4caSwyllys 82299ebb4caSwyllys *bytes = buf; 82399ebb4caSwyllys *outlen = len; 82499ebb4caSwyllys out: 82599ebb4caSwyllys if (buf != NULL && ret != KMF_OK) { 82699ebb4caSwyllys free(buf); 82799ebb4caSwyllys } 82899ebb4caSwyllys return (ret); 82999ebb4caSwyllys } 83099ebb4caSwyllys 83199ebb4caSwyllys void 83299ebb4caSwyllys KMF_FreeDN(KMF_X509_NAME *name) 83399ebb4caSwyllys { 83499ebb4caSwyllys KMF_X509_RDN *newrdn = NULL; 83599ebb4caSwyllys KMF_X509_TYPE_VALUE_PAIR *av = NULL; 83699ebb4caSwyllys int i, j; 83799ebb4caSwyllys 83899ebb4caSwyllys if (name && name->numberOfRDNs) { 83999ebb4caSwyllys for (i = 0; i < name->numberOfRDNs; i++) { 84099ebb4caSwyllys newrdn = &name->RelativeDistinguishedName[i]; 84199ebb4caSwyllys for (j = 0; j < newrdn->numberOfPairs; j++) { 84299ebb4caSwyllys av = &newrdn->AttributeTypeAndValue[j]; 84399ebb4caSwyllys KMF_FreeData(&av->type); 84499ebb4caSwyllys KMF_FreeData(&av->value); 84599ebb4caSwyllys } 84699ebb4caSwyllys free(newrdn->AttributeTypeAndValue); 84799ebb4caSwyllys newrdn->numberOfPairs = 0; 84899ebb4caSwyllys newrdn->AttributeTypeAndValue = NULL; 84999ebb4caSwyllys } 85099ebb4caSwyllys free(name->RelativeDistinguishedName); 85199ebb4caSwyllys name->numberOfRDNs = 0; 85299ebb4caSwyllys name->RelativeDistinguishedName = NULL; 85399ebb4caSwyllys } 85499ebb4caSwyllys } 85599ebb4caSwyllys 85699ebb4caSwyllys void 85799ebb4caSwyllys KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 85899ebb4caSwyllys { 85999ebb4caSwyllys KMF_PLUGIN *plugin; 86099ebb4caSwyllys KMF_RETURN ret; 86199ebb4caSwyllys 86299ebb4caSwyllys CLEAR_ERROR(handle, ret); 86399ebb4caSwyllys if (ret != KMF_OK) 86499ebb4caSwyllys return; 86599ebb4caSwyllys 86699ebb4caSwyllys if (kmf_cert == NULL) 86799ebb4caSwyllys return; 86899ebb4caSwyllys 86999ebb4caSwyllys plugin = FindPlugin(handle, kmf_cert->kmf_private.keystore_type); 87099ebb4caSwyllys 87199ebb4caSwyllys if (plugin != NULL && plugin->funclist->FreeKMFCert != NULL) { 87299ebb4caSwyllys plugin->funclist->FreeKMFCert(handle, kmf_cert); 87399ebb4caSwyllys } 87499ebb4caSwyllys } 87599ebb4caSwyllys 87699ebb4caSwyllys void 87799ebb4caSwyllys KMF_FreeData(KMF_DATA *datablock) 87899ebb4caSwyllys { 87999ebb4caSwyllys if (datablock != NULL && datablock->Data != NULL) { 88099ebb4caSwyllys free(datablock->Data); 88199ebb4caSwyllys datablock->Data = NULL; 88299ebb4caSwyllys datablock->Length = 0; 88399ebb4caSwyllys } 88499ebb4caSwyllys } 88599ebb4caSwyllys 88699ebb4caSwyllys void 88799ebb4caSwyllys KMF_FreeAlgOID(KMF_X509_ALGORITHM_IDENTIFIER *algoid) 88899ebb4caSwyllys { 88999ebb4caSwyllys if (algoid == NULL) 89099ebb4caSwyllys return; 89199ebb4caSwyllys KMF_FreeData(&algoid->algorithm); 89299ebb4caSwyllys KMF_FreeData(&algoid->parameters); 89399ebb4caSwyllys } 89499ebb4caSwyllys 89599ebb4caSwyllys void 89699ebb4caSwyllys KMF_FreeExtension(KMF_X509_EXTENSION *exptr) 89799ebb4caSwyllys { 89899ebb4caSwyllys if (exptr == NULL) 89999ebb4caSwyllys return; 90099ebb4caSwyllys 90199ebb4caSwyllys KMF_FreeData((KMF_DATA *)&exptr->extnId); 90299ebb4caSwyllys KMF_FreeData(&exptr->BERvalue); 90399ebb4caSwyllys 90499ebb4caSwyllys if (exptr->value.tagAndValue) { 90599ebb4caSwyllys KMF_FreeData(&exptr->value.tagAndValue->value); 90699ebb4caSwyllys free(exptr->value.tagAndValue); 90799ebb4caSwyllys } 90899ebb4caSwyllys } 90999ebb4caSwyllys 91099ebb4caSwyllys void 91199ebb4caSwyllys KMF_FreeTBSCSR(KMF_TBS_CSR *tbscsr) 91299ebb4caSwyllys { 91399ebb4caSwyllys if (tbscsr) { 91499ebb4caSwyllys KMF_FreeData(&tbscsr->version); 91599ebb4caSwyllys 91699ebb4caSwyllys KMF_FreeDN(&tbscsr->subject); 91799ebb4caSwyllys 91899ebb4caSwyllys KMF_FreeAlgOID(&tbscsr->subjectPublicKeyInfo.algorithm); 91999ebb4caSwyllys KMF_FreeData(&tbscsr->subjectPublicKeyInfo.subjectPublicKey); 92099ebb4caSwyllys 92199ebb4caSwyllys free_extensions(&tbscsr->extensions); 92299ebb4caSwyllys } 92399ebb4caSwyllys } 92499ebb4caSwyllys 92599ebb4caSwyllys void 92699ebb4caSwyllys KMF_FreeSignedCSR(KMF_CSR_DATA *csr) 92799ebb4caSwyllys { 92899ebb4caSwyllys if (csr) { 92999ebb4caSwyllys KMF_FreeTBSCSR(&csr->csr); 93099ebb4caSwyllys 93199ebb4caSwyllys KMF_FreeAlgOID(&csr->signature.algorithmIdentifier); 93299ebb4caSwyllys KMF_FreeData(&csr->signature.encrypted); 93399ebb4caSwyllys } 93499ebb4caSwyllys } 93599ebb4caSwyllys 93699ebb4caSwyllys static void 93799ebb4caSwyllys free_validity(KMF_X509_VALIDITY *validity) 93899ebb4caSwyllys { 93999ebb4caSwyllys if (validity == NULL) 94099ebb4caSwyllys return; 94199ebb4caSwyllys KMF_FreeData(&validity->notBefore.time); 94299ebb4caSwyllys KMF_FreeData(&validity->notAfter.time); 94399ebb4caSwyllys } 94499ebb4caSwyllys 94599ebb4caSwyllys static void 94699ebb4caSwyllys free_extensions(KMF_X509_EXTENSIONS *extns) 94799ebb4caSwyllys { 94899ebb4caSwyllys int i; 94999ebb4caSwyllys KMF_X509_EXTENSION *exptr; 95099ebb4caSwyllys 95199ebb4caSwyllys if (extns && extns->numberOfExtensions > 0) { 95299ebb4caSwyllys for (i = 0; i < extns->numberOfExtensions; i++) { 95399ebb4caSwyllys exptr = &extns->extensions[i]; 95499ebb4caSwyllys KMF_FreeExtension(exptr); 95599ebb4caSwyllys } 95699ebb4caSwyllys free(extns->extensions); 95799ebb4caSwyllys extns->numberOfExtensions = 0; 95899ebb4caSwyllys extns->extensions = NULL; 95999ebb4caSwyllys } 96099ebb4caSwyllys } 96199ebb4caSwyllys 96299ebb4caSwyllys void 96399ebb4caSwyllys KMF_FreeTBSCert(KMF_X509_TBS_CERT *tbscert) 96499ebb4caSwyllys { 96599ebb4caSwyllys if (tbscert) { 96699ebb4caSwyllys KMF_FreeData(&tbscert->version); 96799ebb4caSwyllys KMF_FreeBigint(&tbscert->serialNumber); 96899ebb4caSwyllys KMF_FreeAlgOID(&tbscert->signature); 96999ebb4caSwyllys 97099ebb4caSwyllys KMF_FreeDN(&tbscert->issuer); 97199ebb4caSwyllys KMF_FreeDN(&tbscert->subject); 97299ebb4caSwyllys 97399ebb4caSwyllys free_validity(&tbscert->validity); 97499ebb4caSwyllys 97599ebb4caSwyllys KMF_FreeData(&tbscert->issuerUniqueIdentifier); 97699ebb4caSwyllys KMF_FreeData(&tbscert->subjectUniqueIdentifier); 97799ebb4caSwyllys 97899ebb4caSwyllys KMF_FreeAlgOID(&tbscert->subjectPublicKeyInfo.algorithm); 97999ebb4caSwyllys KMF_FreeData(&tbscert->subjectPublicKeyInfo.subjectPublicKey); 98099ebb4caSwyllys 98199ebb4caSwyllys free_extensions(&tbscert->extensions); 98299ebb4caSwyllys 98399ebb4caSwyllys KMF_FreeData(&tbscert->issuerUniqueIdentifier); 98499ebb4caSwyllys KMF_FreeData(&tbscert->subjectUniqueIdentifier); 98599ebb4caSwyllys } 98699ebb4caSwyllys } 98799ebb4caSwyllys 98899ebb4caSwyllys void 98999ebb4caSwyllys KMF_FreeSignedCert(KMF_X509_CERTIFICATE *certptr) 99099ebb4caSwyllys { 99199ebb4caSwyllys if (!certptr) 99299ebb4caSwyllys return; 99399ebb4caSwyllys 99499ebb4caSwyllys KMF_FreeTBSCert(&certptr->certificate); 99599ebb4caSwyllys 99699ebb4caSwyllys KMF_FreeAlgOID(&certptr->signature.algorithmIdentifier); 99799ebb4caSwyllys KMF_FreeData(&certptr->signature.encrypted); 99899ebb4caSwyllys } 99999ebb4caSwyllys 100099ebb4caSwyllys void 100199ebb4caSwyllys KMF_FreeString(char *pstr) 100299ebb4caSwyllys { 100399ebb4caSwyllys if (pstr != NULL) 100499ebb4caSwyllys free(pstr); 100599ebb4caSwyllys } 100699ebb4caSwyllys 100799ebb4caSwyllys void 100899ebb4caSwyllys free_keyidlist(KMF_OID *oidlist, int len) 100999ebb4caSwyllys { 101099ebb4caSwyllys int i; 101199ebb4caSwyllys for (i = 0; i < len; i++) { 101299ebb4caSwyllys KMF_FreeData((KMF_DATA *)&oidlist[i]); 101399ebb4caSwyllys } 101499ebb4caSwyllys free(oidlist); 101599ebb4caSwyllys } 101699ebb4caSwyllys 101799ebb4caSwyllys void 101899ebb4caSwyllys KMF_FreeEKU(KMF_X509EXT_EKU *eptr) 101999ebb4caSwyllys { 102099ebb4caSwyllys if (eptr && eptr->nEKUs > 0 && 102199ebb4caSwyllys eptr->keyPurposeIdList != NULL) 102299ebb4caSwyllys free_keyidlist(eptr->keyPurposeIdList, eptr->nEKUs); 102399ebb4caSwyllys } 102499ebb4caSwyllys 102599ebb4caSwyllys void 102699ebb4caSwyllys KMF_FreeSPKI(KMF_X509_SPKI *spki) 102799ebb4caSwyllys { 102899ebb4caSwyllys if (spki != NULL) { 102999ebb4caSwyllys KMF_FreeAlgOID(&spki->algorithm); 103099ebb4caSwyllys KMF_FreeData(&spki->subjectPublicKey); 103199ebb4caSwyllys } 103299ebb4caSwyllys } 103399ebb4caSwyllys 103499ebb4caSwyllys void 103599ebb4caSwyllys KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 103699ebb4caSwyllys { 103799ebb4caSwyllys KMF_PLUGIN *plugin; 103899ebb4caSwyllys KMF_RETURN ret; 103999ebb4caSwyllys 104099ebb4caSwyllys CLEAR_ERROR(handle, ret); 104199ebb4caSwyllys if (ret != KMF_OK) 104299ebb4caSwyllys return; 104399ebb4caSwyllys 104499ebb4caSwyllys if (key == NULL) 104599ebb4caSwyllys return; 104699ebb4caSwyllys 104799ebb4caSwyllys plugin = FindPlugin(handle, key->kstype); 104899ebb4caSwyllys if (plugin != NULL && plugin->funclist->DeleteKey != NULL) { 104999ebb4caSwyllys (void) plugin->funclist->DeleteKey(handle, NULL, key, FALSE); 105099ebb4caSwyllys } 105199ebb4caSwyllys 105299ebb4caSwyllys if (key == NULL) 105399ebb4caSwyllys return; 105499ebb4caSwyllys 105599ebb4caSwyllys if (key->keylabel) 105699ebb4caSwyllys free(key->keylabel); 105799ebb4caSwyllys 105899ebb4caSwyllys if (key->israw) { 105999ebb4caSwyllys KMF_FreeRawKey(key->keyp); 106099ebb4caSwyllys free(key->keyp); 106199ebb4caSwyllys } 106299ebb4caSwyllys 106399ebb4caSwyllys (void) memset(key, 0, sizeof (KMF_KEY_HANDLE)); 106499ebb4caSwyllys } 106599ebb4caSwyllys 106699ebb4caSwyllys void 106799ebb4caSwyllys KMF_FreeBigint(KMF_BIGINT *big) 106899ebb4caSwyllys { 106999ebb4caSwyllys if (big != NULL && big->val != NULL) { 107002744e81Swyllys /* Clear it out before returning it to the pool */ 107102744e81Swyllys (void) memset(big->val, 0x00, big->len); 107299ebb4caSwyllys free(big->val); 107399ebb4caSwyllys big->val = NULL; 107499ebb4caSwyllys big->len = 0; 107599ebb4caSwyllys } 107699ebb4caSwyllys } 107799ebb4caSwyllys 107899ebb4caSwyllys static void 107999ebb4caSwyllys free_raw_rsa(KMF_RAW_RSA_KEY *key) 108099ebb4caSwyllys { 108199ebb4caSwyllys if (key == NULL) 108299ebb4caSwyllys return; 108399ebb4caSwyllys KMF_FreeBigint(&key->mod); 108499ebb4caSwyllys KMF_FreeBigint(&key->pubexp); 108599ebb4caSwyllys KMF_FreeBigint(&key->priexp); 108699ebb4caSwyllys KMF_FreeBigint(&key->prime1); 108799ebb4caSwyllys KMF_FreeBigint(&key->prime2); 108899ebb4caSwyllys KMF_FreeBigint(&key->exp1); 108999ebb4caSwyllys KMF_FreeBigint(&key->exp2); 109099ebb4caSwyllys KMF_FreeBigint(&key->coef); 109199ebb4caSwyllys } 109299ebb4caSwyllys 109399ebb4caSwyllys static void 109499ebb4caSwyllys free_raw_dsa(KMF_RAW_DSA_KEY *key) 109599ebb4caSwyllys { 109699ebb4caSwyllys if (key == NULL) 109799ebb4caSwyllys return; 109899ebb4caSwyllys KMF_FreeBigint(&key->prime); 109999ebb4caSwyllys KMF_FreeBigint(&key->subprime); 110099ebb4caSwyllys KMF_FreeBigint(&key->base); 110199ebb4caSwyllys KMF_FreeBigint(&key->value); 110299ebb4caSwyllys } 110399ebb4caSwyllys 110499ebb4caSwyllys static void 110599ebb4caSwyllys free_raw_sym(KMF_RAW_SYM_KEY *key) 110699ebb4caSwyllys { 110799ebb4caSwyllys if (key == NULL) 110899ebb4caSwyllys return; 110999ebb4caSwyllys KMF_FreeBigint(&key->keydata); 111099ebb4caSwyllys } 111199ebb4caSwyllys 111299ebb4caSwyllys void 111399ebb4caSwyllys KMF_FreeRawKey(KMF_RAW_KEY_DATA *key) 111499ebb4caSwyllys { 111599ebb4caSwyllys if (key == NULL) 111699ebb4caSwyllys return; 111799ebb4caSwyllys 111899ebb4caSwyllys switch (key->keytype) { 111999ebb4caSwyllys case KMF_RSA: 112099ebb4caSwyllys free_raw_rsa(&key->rawdata.rsa); 112199ebb4caSwyllys break; 112299ebb4caSwyllys case KMF_DSA: 112399ebb4caSwyllys free_raw_dsa(&key->rawdata.dsa); 112499ebb4caSwyllys break; 112599ebb4caSwyllys case KMF_AES: 112699ebb4caSwyllys case KMF_RC4: 112799ebb4caSwyllys case KMF_DES: 112899ebb4caSwyllys case KMF_DES3: 112999ebb4caSwyllys free_raw_sym(&key->rawdata.sym); 113099ebb4caSwyllys break; 113199ebb4caSwyllys } 113299ebb4caSwyllys } 113399ebb4caSwyllys 113499ebb4caSwyllys void 113599ebb4caSwyllys KMF_FreeRawSymKey(KMF_RAW_SYM_KEY *key) 113699ebb4caSwyllys { 113799ebb4caSwyllys if (key == NULL) 113899ebb4caSwyllys return; 113999ebb4caSwyllys KMF_FreeBigint(&key->keydata); 114099ebb4caSwyllys free(key); 114199ebb4caSwyllys } 114299ebb4caSwyllys 114399ebb4caSwyllys /* 114499ebb4caSwyllys * This function frees the space allocated for the name portion of a 114599ebb4caSwyllys * KMF_CRL_DIST_POINT. 114699ebb4caSwyllys */ 114799ebb4caSwyllys void 114899ebb4caSwyllys free_dp_name(KMF_CRL_DIST_POINT *dp) 114999ebb4caSwyllys { 115099ebb4caSwyllys KMF_GENERALNAMES *fullname; 115199ebb4caSwyllys KMF_DATA *urldata; 115299ebb4caSwyllys int i; 115399ebb4caSwyllys 115499ebb4caSwyllys if (dp == NULL) 115599ebb4caSwyllys return; 115699ebb4caSwyllys 115799ebb4caSwyllys /* For phase 1, we only need to free the fullname space. */ 115899ebb4caSwyllys fullname = &(dp->name.full_name); 115999ebb4caSwyllys if (fullname->number == 0) 116099ebb4caSwyllys return; 116199ebb4caSwyllys 116299ebb4caSwyllys for (i = 0; i < fullname->number; i++) { 116399ebb4caSwyllys urldata = &(fullname->namelist[fullname->number - 1].name); 116499ebb4caSwyllys KMF_FreeData(urldata); 116599ebb4caSwyllys } 116699ebb4caSwyllys 116799ebb4caSwyllys free(fullname->namelist); 116899ebb4caSwyllys } 116999ebb4caSwyllys 117099ebb4caSwyllys /* 117199ebb4caSwyllys * This function frees the space allocated for a KMF_CRL_DIST_POINT. 117299ebb4caSwyllys */ 117399ebb4caSwyllys void 117499ebb4caSwyllys free_dp(KMF_CRL_DIST_POINT *dp) 117599ebb4caSwyllys { 117699ebb4caSwyllys if (dp == NULL) 117799ebb4caSwyllys return; 117899ebb4caSwyllys 117999ebb4caSwyllys free_dp_name(dp); 118099ebb4caSwyllys KMF_FreeData(&(dp->reasons)); 118199ebb4caSwyllys /* Need not to free crl_issuer space at phase 1 */ 118299ebb4caSwyllys } 118399ebb4caSwyllys 118499ebb4caSwyllys /* 118599ebb4caSwyllys * This function frees space for a KMF_X509EXT_CRLDISTPOINTS internally. 118699ebb4caSwyllys */ 118799ebb4caSwyllys void 118899ebb4caSwyllys KMF_FreeCRLDistributionPoints(KMF_X509EXT_CRLDISTPOINTS *crl_dps) 118999ebb4caSwyllys { 119099ebb4caSwyllys int i; 119199ebb4caSwyllys 119299ebb4caSwyllys if (crl_dps == NULL) 119399ebb4caSwyllys return; 119499ebb4caSwyllys 119599ebb4caSwyllys for (i = 0; i < crl_dps->number; i++) 119699ebb4caSwyllys free_dp(&(crl_dps->dplist[i])); 119799ebb4caSwyllys 119899ebb4caSwyllys free(crl_dps->dplist); 119999ebb4caSwyllys } 120099ebb4caSwyllys 120199ebb4caSwyllys KMF_RETURN 120299ebb4caSwyllys KMF_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, 120399ebb4caSwyllys char *reqfile) 120499ebb4caSwyllys { 120599ebb4caSwyllys KMF_PLUGIN *plugin; 120699ebb4caSwyllys KMF_RETURN (*createReqFn)(void *, KMF_OCSPREQUEST_PARAMS *params, 120799ebb4caSwyllys char *reqfile); 120899ebb4caSwyllys KMF_RETURN ret; 120999ebb4caSwyllys 121099ebb4caSwyllys CLEAR_ERROR(handle, ret); 121199ebb4caSwyllys if (ret != KMF_OK) 121299ebb4caSwyllys return (ret); 121399ebb4caSwyllys 121499ebb4caSwyllys 121599ebb4caSwyllys if (params == NULL || 121699ebb4caSwyllys reqfile == NULL) 121799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 121899ebb4caSwyllys 121999ebb4caSwyllys /* 122099ebb4caSwyllys * This framework function is actually implemented in the openssl 122199ebb4caSwyllys * plugin library, so we find the function address and call it. 122299ebb4caSwyllys */ 122399ebb4caSwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 122499ebb4caSwyllys if (plugin == NULL || plugin->dldesc == NULL) { 122599ebb4caSwyllys return (KMF_ERR_PLUGIN_NOTFOUND); 122699ebb4caSwyllys } 122799ebb4caSwyllys 122899ebb4caSwyllys createReqFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 122999ebb4caSwyllys "OpenSSL_CreateOCSPRequest"); 123099ebb4caSwyllys if (createReqFn == NULL) { 123199ebb4caSwyllys return (KMF_ERR_FUNCTION_NOT_FOUND); 123299ebb4caSwyllys } 123399ebb4caSwyllys 123499ebb4caSwyllys return (createReqFn(handle, params, reqfile)); 123599ebb4caSwyllys } 123699ebb4caSwyllys 123799ebb4caSwyllys KMF_RETURN 123899ebb4caSwyllys KMF_GetOCSPStatusForCert(KMF_HANDLE_T handle, 123999ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 124099ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) 124199ebb4caSwyllys { 124299ebb4caSwyllys KMF_PLUGIN *plugin; 124399ebb4caSwyllys KMF_RETURN (*getCertStatusFn)(void *, 124499ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 124599ebb4caSwyllys KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out); 124699ebb4caSwyllys KMF_RETURN ret; 124799ebb4caSwyllys 124899ebb4caSwyllys CLEAR_ERROR(handle, ret); 124999ebb4caSwyllys if (ret != KMF_OK) 125099ebb4caSwyllys return (ret); 125199ebb4caSwyllys 125299ebb4caSwyllys 125399ebb4caSwyllys if (params_in == NULL || 125499ebb4caSwyllys params_out == NULL) 125599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 125699ebb4caSwyllys 125799ebb4caSwyllys /* 125899ebb4caSwyllys * This framework function is actually implemented in the openssl 125999ebb4caSwyllys * plugin library, so we find the function address and call it. 126099ebb4caSwyllys */ 126199ebb4caSwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 126299ebb4caSwyllys if (plugin == NULL || plugin->dldesc == NULL) { 126399ebb4caSwyllys return (KMF_ERR_INTERNAL); 126499ebb4caSwyllys } 126599ebb4caSwyllys 126699ebb4caSwyllys getCertStatusFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 126799ebb4caSwyllys "OpenSSL_GetOCSPStatusForCert"); 126899ebb4caSwyllys if (getCertStatusFn == NULL) { 126999ebb4caSwyllys return (KMF_ERR_INTERNAL); 127099ebb4caSwyllys } 127199ebb4caSwyllys 127299ebb4caSwyllys return (getCertStatusFn(handle, params_in, params_out)); 127399ebb4caSwyllys } 127499ebb4caSwyllys 127599ebb4caSwyllys KMF_RETURN 127699ebb4caSwyllys KMF_String2OID(char *oidstring, KMF_OID *oid) 127799ebb4caSwyllys { 127899ebb4caSwyllys KMF_RETURN rv = KMF_OK; 127999ebb4caSwyllys char *cp, *bp, *startp; 128099ebb4caSwyllys int numbuf; 128199ebb4caSwyllys int onumbuf; 128299ebb4caSwyllys int nbytes, index; 128399ebb4caSwyllys int len; 128499ebb4caSwyllys unsigned char *op; 128599ebb4caSwyllys 128699ebb4caSwyllys if (oidstring == NULL || oid == NULL) 128799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 128899ebb4caSwyllys 128999ebb4caSwyllys len = strlen(oidstring); 129099ebb4caSwyllys 129199ebb4caSwyllys bp = oidstring; 129299ebb4caSwyllys cp = bp; 129399ebb4caSwyllys /* Skip over leading space */ 129499ebb4caSwyllys while ((bp < &cp[len]) && isspace(*bp)) 129599ebb4caSwyllys bp++; 129699ebb4caSwyllys 129799ebb4caSwyllys startp = bp; 129899ebb4caSwyllys nbytes = 0; 129999ebb4caSwyllys 130099ebb4caSwyllys /* 130199ebb4caSwyllys * The first two numbers are chewed up by the first octet. 130299ebb4caSwyllys */ 130399ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 130499ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 130599ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 130699ebb4caSwyllys bp++; 130799ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 130899ebb4caSwyllys bp++; 130999ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 131099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 131199ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 131299ebb4caSwyllys bp++; 131399ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 131499ebb4caSwyllys bp++; 131599ebb4caSwyllys nbytes++; 131699ebb4caSwyllys 131799ebb4caSwyllys while (isdigit(*bp)) { 131899ebb4caSwyllys if (sscanf(bp, "%d", &numbuf) != 1) 131999ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 132099ebb4caSwyllys while (numbuf) { 132199ebb4caSwyllys nbytes++; 132299ebb4caSwyllys numbuf >>= 7; 132399ebb4caSwyllys } 132499ebb4caSwyllys while ((bp < &cp[len]) && isdigit(*bp)) 132599ebb4caSwyllys bp++; 132699ebb4caSwyllys while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 132799ebb4caSwyllys bp++; 132899ebb4caSwyllys } 132999ebb4caSwyllys 133099ebb4caSwyllys oid->Length = nbytes; 133199ebb4caSwyllys oid->Data = malloc(oid->Length); 133299ebb4caSwyllys if (oid->Data == NULL) { 133399ebb4caSwyllys return (KMF_ERR_MEMORY); 133499ebb4caSwyllys } 133599ebb4caSwyllys (void) memset(oid->Data, 0, oid->Length); 133699ebb4caSwyllys 133799ebb4caSwyllys op = oid->Data; 133899ebb4caSwyllys 133999ebb4caSwyllys bp = startp; 134099ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 134199ebb4caSwyllys 134299ebb4caSwyllys while (isdigit(*bp)) bp++; 134399ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 134499ebb4caSwyllys 134599ebb4caSwyllys onumbuf = 40 * numbuf; 134699ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 134799ebb4caSwyllys onumbuf += numbuf; 134899ebb4caSwyllys *op = (unsigned char) onumbuf; 134999ebb4caSwyllys op++; 135099ebb4caSwyllys 135199ebb4caSwyllys while (isdigit(*bp)) bp++; 135299ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 135399ebb4caSwyllys while (isdigit(*bp)) { 135499ebb4caSwyllys (void) sscanf(bp, "%d", &numbuf); 135599ebb4caSwyllys nbytes = 0; 135699ebb4caSwyllys /* Have to fill in the bytes msb-first */ 135799ebb4caSwyllys onumbuf = numbuf; 135899ebb4caSwyllys while (numbuf) { 135999ebb4caSwyllys nbytes++; 136099ebb4caSwyllys numbuf >>= 7; 136199ebb4caSwyllys } 136299ebb4caSwyllys numbuf = onumbuf; 136399ebb4caSwyllys op += nbytes; 136499ebb4caSwyllys index = -1; 136599ebb4caSwyllys while (numbuf) { 136699ebb4caSwyllys op[index] = (unsigned char)numbuf & 0x7f; 136799ebb4caSwyllys if (index != -1) 136899ebb4caSwyllys op[index] |= 0x80; 136999ebb4caSwyllys index--; 137099ebb4caSwyllys numbuf >>= 7; 137199ebb4caSwyllys } 137299ebb4caSwyllys while (isdigit(*bp)) bp++; 137399ebb4caSwyllys while (isspace(*bp) || *bp == '.') bp++; 137499ebb4caSwyllys } 137599ebb4caSwyllys 137699ebb4caSwyllys return (rv); 137799ebb4caSwyllys } 137899ebb4caSwyllys 137999ebb4caSwyllys static KMF_RETURN 138099ebb4caSwyllys encode_rid(char *name, KMF_DATA *derdata) 138199ebb4caSwyllys { 138299ebb4caSwyllys KMF_RETURN rv = KMF_OK; 138399ebb4caSwyllys 138499ebb4caSwyllys if (name == NULL || derdata == NULL) 138599ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 138699ebb4caSwyllys 138799ebb4caSwyllys rv = KMF_String2OID(name, (KMF_OID *)derdata); 138899ebb4caSwyllys 138999ebb4caSwyllys return (rv); 139099ebb4caSwyllys } 139199ebb4caSwyllys 139299ebb4caSwyllys static KMF_RETURN 139399ebb4caSwyllys encode_ipaddr(char *name, KMF_DATA *derdata) 139499ebb4caSwyllys { 139599ebb4caSwyllys KMF_RETURN rv = KMF_OK; 139699ebb4caSwyllys size_t len; 139799ebb4caSwyllys in_addr_t v4; 139899ebb4caSwyllys in6_addr_t v6; 139999ebb4caSwyllys uint8_t *ptr; 140099ebb4caSwyllys 140199ebb4caSwyllys if (name == NULL || derdata == NULL) 140299ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 140399ebb4caSwyllys 140499ebb4caSwyllys v4 = inet_addr(name); 140599ebb4caSwyllys if (v4 == (in_addr_t)-1) { 140699ebb4caSwyllys ptr = (uint8_t *)&v6; 140799ebb4caSwyllys if (inet_pton(AF_INET6, name, ptr) != 1) 140899ebb4caSwyllys return (KMF_ERR_ENCODING); 140999ebb4caSwyllys len = sizeof (v6); 141099ebb4caSwyllys } else { 141199ebb4caSwyllys ptr = (uint8_t *)&v4; 141299ebb4caSwyllys len = sizeof (v4); 141399ebb4caSwyllys } 141499ebb4caSwyllys 141599ebb4caSwyllys derdata->Data = malloc(len); 141699ebb4caSwyllys if (derdata->Data == NULL) 141799ebb4caSwyllys return (KMF_ERR_MEMORY); 141899ebb4caSwyllys (void) memcpy(derdata->Data, ptr, len); 141999ebb4caSwyllys derdata->Length = len; 142099ebb4caSwyllys 142199ebb4caSwyllys return (rv); 142299ebb4caSwyllys } 142399ebb4caSwyllys 142499ebb4caSwyllys static KMF_RETURN 142599ebb4caSwyllys verify_uri_format(char *uristring) 142699ebb4caSwyllys { 142799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 142899ebb4caSwyllys xmlURIPtr uriptr = NULL; 142999ebb4caSwyllys 143099ebb4caSwyllys /* Parse the URI string; get the hostname and port */ 143199ebb4caSwyllys uriptr = xmlParseURI(uristring); 143299ebb4caSwyllys if (uriptr == NULL) { 143399ebb4caSwyllys ret = KMF_ERR_BAD_URI; 143499ebb4caSwyllys goto out; 143599ebb4caSwyllys } 143699ebb4caSwyllys 143799ebb4caSwyllys if (uriptr->scheme == NULL || !strlen(uriptr->scheme)) { 143899ebb4caSwyllys ret = KMF_ERR_BAD_URI; 143999ebb4caSwyllys goto out; 144099ebb4caSwyllys } 144199ebb4caSwyllys 144299ebb4caSwyllys if (uriptr->server == NULL || !strlen(uriptr->server)) { 144399ebb4caSwyllys ret = KMF_ERR_BAD_URI; 144499ebb4caSwyllys goto out; 144599ebb4caSwyllys } 144699ebb4caSwyllys out: 144799ebb4caSwyllys if (uriptr != NULL) 144899ebb4caSwyllys xmlFreeURI(uriptr); 144999ebb4caSwyllys return (ret); 145099ebb4caSwyllys } 145199ebb4caSwyllys 145299ebb4caSwyllys static KMF_RETURN 145399ebb4caSwyllys encode_altname(char *namedata, 145499ebb4caSwyllys KMF_GENERALNAMECHOICES nametype, KMF_DATA *encodedname) 145599ebb4caSwyllys { 145699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 145799ebb4caSwyllys KMF_X509_NAME dnname; 145899ebb4caSwyllys uchar_t tagval; 145999ebb4caSwyllys BerElement *asn1 = NULL; 146099ebb4caSwyllys BerValue *extdata; 146199ebb4caSwyllys 146299ebb4caSwyllys if (namedata == NULL || encodedname == NULL) 146399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 146499ebb4caSwyllys 146599ebb4caSwyllys /* 146699ebb4caSwyllys * Encode the namedata according to rules in RFC 3280 for GeneralName. 146799ebb4caSwyllys * The input "namedata" is assumed to be an ASCII string representation 146899ebb4caSwyllys * of the AltName, we need to convert it to correct ASN.1 here before 146999ebb4caSwyllys * adding it to the cert. 147099ebb4caSwyllys */ 147199ebb4caSwyllys switch (nametype) { 147299ebb4caSwyllys case GENNAME_RFC822NAME: /* rfc 822 */ 147399ebb4caSwyllys /* IA5String, no encoding needed */ 147499ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 147599ebb4caSwyllys if (encodedname->Data == NULL) 147699ebb4caSwyllys return (KMF_ERR_MEMORY); 147799ebb4caSwyllys encodedname->Length = strlen(namedata); 147899ebb4caSwyllys tagval = (0x80 | nametype); 147999ebb4caSwyllys break; 148099ebb4caSwyllys case GENNAME_DNSNAME: /* rfc 1034 */ 148199ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 148299ebb4caSwyllys if (encodedname->Data == NULL) 148399ebb4caSwyllys return (KMF_ERR_MEMORY); 148499ebb4caSwyllys encodedname->Length = strlen(namedata); 148599ebb4caSwyllys tagval = (0x80 | nametype); 148699ebb4caSwyllys break; 148799ebb4caSwyllys case GENNAME_URI: /* rfc 1738 */ 148899ebb4caSwyllys ret = verify_uri_format(namedata); 148999ebb4caSwyllys if (ret != KMF_OK) 149099ebb4caSwyllys return (ret); 149199ebb4caSwyllys /* IA5String, no encoding needed */ 149299ebb4caSwyllys encodedname->Data = (uchar_t *)strdup(namedata); 149399ebb4caSwyllys if (encodedname->Data == NULL) 149499ebb4caSwyllys return (KMF_ERR_MEMORY); 149599ebb4caSwyllys encodedname->Length = strlen(namedata); 149699ebb4caSwyllys tagval = (0x80 | nametype); 149799ebb4caSwyllys break; 149899ebb4caSwyllys case GENNAME_IPADDRESS: 149999ebb4caSwyllys ret = encode_ipaddr(namedata, encodedname); 150099ebb4caSwyllys tagval = (0x80 | nametype); 150199ebb4caSwyllys break; 150299ebb4caSwyllys case GENNAME_REGISTEREDID: 150399ebb4caSwyllys ret = encode_rid(namedata, encodedname); 150499ebb4caSwyllys tagval = (0x80 | nametype); 150599ebb4caSwyllys break; 150699ebb4caSwyllys case GENNAME_DIRECTORYNAME: 150799ebb4caSwyllys ret = KMF_DNParser(namedata, &dnname); 150899ebb4caSwyllys if (ret == KMF_OK) { 150999ebb4caSwyllys ret = KMF_DN2Der(&dnname, encodedname); 151099ebb4caSwyllys } 151199ebb4caSwyllys (void) KMF_FreeDN(&dnname); 151299ebb4caSwyllys tagval = (0xA0 | nametype); 151399ebb4caSwyllys break; 151499ebb4caSwyllys default: 151599ebb4caSwyllys /* unsupported */ 151699ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 151799ebb4caSwyllys 151899ebb4caSwyllys } 151999ebb4caSwyllys if (ret != KMF_OK) { 152099ebb4caSwyllys KMF_FreeData(encodedname); 152199ebb4caSwyllys return (ret); 152299ebb4caSwyllys } 152399ebb4caSwyllys 152499ebb4caSwyllys if ((asn1 = kmfder_alloc()) == NULL) 152599ebb4caSwyllys return (KMF_ERR_MEMORY); 152699ebb4caSwyllys 152799ebb4caSwyllys if (kmfber_printf(asn1, "Tl", 152899ebb4caSwyllys tagval, encodedname->Length) == -1) 152999ebb4caSwyllys goto cleanup; 153099ebb4caSwyllys 153199ebb4caSwyllys if (kmfber_write(asn1, (char *)encodedname->Data, 153299ebb4caSwyllys encodedname->Length, 0) == -1) { 153399ebb4caSwyllys ret = KMF_ERR_ENCODING; 153499ebb4caSwyllys goto cleanup; 153599ebb4caSwyllys } 153699ebb4caSwyllys if (kmfber_flatten(asn1, &extdata) == -1) { 153799ebb4caSwyllys ret = KMF_ERR_ENCODING; 153899ebb4caSwyllys goto cleanup; 153999ebb4caSwyllys } 154099ebb4caSwyllys 154199ebb4caSwyllys KMF_FreeData(encodedname); 154299ebb4caSwyllys encodedname->Data = (uchar_t *)extdata->bv_val; 154399ebb4caSwyllys encodedname->Length = extdata->bv_len; 154499ebb4caSwyllys 154599ebb4caSwyllys free(extdata); 154699ebb4caSwyllys 154799ebb4caSwyllys cleanup: 154899ebb4caSwyllys if (asn1) 154999ebb4caSwyllys kmfber_free(asn1, 1); 155099ebb4caSwyllys 155199ebb4caSwyllys if (ret != KMF_OK) 155299ebb4caSwyllys KMF_FreeData(encodedname); 155399ebb4caSwyllys 155499ebb4caSwyllys return (ret); 155599ebb4caSwyllys } 155699ebb4caSwyllys 155799ebb4caSwyllys KMF_X509_EXTENSION * 155899ebb4caSwyllys FindExtn(KMF_X509_EXTENSIONS *exts, KMF_OID *oid) 155999ebb4caSwyllys { 156099ebb4caSwyllys KMF_X509_EXTENSION *foundextn = NULL; 156199ebb4caSwyllys int i; 156299ebb4caSwyllys 156399ebb4caSwyllys if (exts == NULL || oid == NULL) 156499ebb4caSwyllys return (NULL); 156599ebb4caSwyllys 156699ebb4caSwyllys for (i = 0; i < exts->numberOfExtensions; i++) { 156799ebb4caSwyllys if (IsEqualOid(oid, &exts->extensions[i].extnId)) { 156899ebb4caSwyllys foundextn = &exts->extensions[i]; 156999ebb4caSwyllys break; 157099ebb4caSwyllys } 157199ebb4caSwyllys } 157299ebb4caSwyllys return (foundextn); 157399ebb4caSwyllys } 157499ebb4caSwyllys 157599ebb4caSwyllys KMF_RETURN 157699ebb4caSwyllys GetSequenceContents(char *data, size_t len, 157799ebb4caSwyllys char **contents, size_t *outlen) 157899ebb4caSwyllys { 157999ebb4caSwyllys KMF_RETURN ret = KMF_OK; 158099ebb4caSwyllys BerElement *exasn1 = NULL; 158199ebb4caSwyllys BerValue oldextn; 158299ebb4caSwyllys int tag; 158399ebb4caSwyllys size_t oldsize; 158499ebb4caSwyllys char *olddata = NULL; 158599ebb4caSwyllys 158699ebb4caSwyllys if (data == NULL || contents == NULL || outlen == NULL) 158799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 158899ebb4caSwyllys 158999ebb4caSwyllys /* 159099ebb4caSwyllys * Decode the sequence of general names 159199ebb4caSwyllys */ 159299ebb4caSwyllys oldextn.bv_val = data; 159399ebb4caSwyllys oldextn.bv_len = len; 159499ebb4caSwyllys 159599ebb4caSwyllys if ((exasn1 = kmfder_init(&oldextn)) == NULL) { 159699ebb4caSwyllys ret = KMF_ERR_MEMORY; 159799ebb4caSwyllys goto out; 159899ebb4caSwyllys } 159999ebb4caSwyllys 160099ebb4caSwyllys /* 160199ebb4caSwyllys * Unwrap the sequence to find the size of the block 160299ebb4caSwyllys * of GeneralName items in the set. 160399ebb4caSwyllys * 160499ebb4caSwyllys * Peek at the tag and length ("tl"), 160599ebb4caSwyllys * then consume them ("{"). 160699ebb4caSwyllys */ 160799ebb4caSwyllys if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT || 160899ebb4caSwyllys oldsize == 0) { 160999ebb4caSwyllys ret = KMF_ERR_ENCODING; 161099ebb4caSwyllys goto out; 161199ebb4caSwyllys } 161299ebb4caSwyllys 161399ebb4caSwyllys olddata = malloc(oldsize); 161499ebb4caSwyllys if (olddata == NULL) { 161599ebb4caSwyllys ret = KMF_ERR_MEMORY; 161699ebb4caSwyllys goto out; 161799ebb4caSwyllys } 161899ebb4caSwyllys (void) memset(olddata, 0, oldsize); 161999ebb4caSwyllys /* 162099ebb4caSwyllys * Read the entire blob of GeneralNames, we don't 162199ebb4caSwyllys * need to interpret them now. 162299ebb4caSwyllys */ 162399ebb4caSwyllys if (kmfber_read(exasn1, olddata, oldsize) != oldsize) { 162499ebb4caSwyllys ret = KMF_ERR_ENCODING; 162599ebb4caSwyllys goto out; 162699ebb4caSwyllys } 162799ebb4caSwyllys out: 162899ebb4caSwyllys if (exasn1 != NULL) 162999ebb4caSwyllys kmfber_free(exasn1, 1); 163099ebb4caSwyllys 163199ebb4caSwyllys if (ret != KMF_OK) { 163299ebb4caSwyllys *contents = NULL; 163399ebb4caSwyllys *outlen = 0; 163499ebb4caSwyllys if (olddata != NULL) 163599ebb4caSwyllys free(olddata); 163699ebb4caSwyllys } else { 163799ebb4caSwyllys *contents = olddata; 163899ebb4caSwyllys *outlen = oldsize; 163999ebb4caSwyllys } 164099ebb4caSwyllys return (ret); 164199ebb4caSwyllys } 164299ebb4caSwyllys 164399ebb4caSwyllys KMF_RETURN 164499ebb4caSwyllys add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) 164599ebb4caSwyllys { 164699ebb4caSwyllys KMF_RETURN ret = KMF_OK; 164799ebb4caSwyllys KMF_X509_EXTENSION *extlist; 164899ebb4caSwyllys 164999ebb4caSwyllys if (exts == NULL || newextn == NULL) 165099ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 165199ebb4caSwyllys 165299ebb4caSwyllys extlist = malloc(sizeof (KMF_X509_EXTENSION) * 165399ebb4caSwyllys (exts->numberOfExtensions + 1)); 165499ebb4caSwyllys if (extlist == NULL) 165599ebb4caSwyllys return (KMF_ERR_MEMORY); 165699ebb4caSwyllys 165799ebb4caSwyllys (void) memcpy(extlist, exts->extensions, 165899ebb4caSwyllys exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION)); 165999ebb4caSwyllys 166099ebb4caSwyllys (void) memcpy(&extlist[exts->numberOfExtensions], newextn, 166199ebb4caSwyllys sizeof (KMF_X509_EXTENSION)); 166299ebb4caSwyllys 166399ebb4caSwyllys free(exts->extensions); 166499ebb4caSwyllys exts->numberOfExtensions++; 166599ebb4caSwyllys exts->extensions = extlist; 166699ebb4caSwyllys 166799ebb4caSwyllys return (ret); 166899ebb4caSwyllys } 166999ebb4caSwyllys 167099ebb4caSwyllys KMF_RETURN 167199ebb4caSwyllys KMF_SetAltName(KMF_X509_EXTENSIONS *extensions, 167299ebb4caSwyllys KMF_OID *oid, 167399ebb4caSwyllys int critical, 167499ebb4caSwyllys KMF_GENERALNAMECHOICES nametype, 167599ebb4caSwyllys char *namedata) 167699ebb4caSwyllys { 167799ebb4caSwyllys KMF_RETURN ret = KMF_OK; 167899ebb4caSwyllys KMF_X509_EXTENSION subjAltName; 167999ebb4caSwyllys KMF_DATA dername = { NULL, 0 }; 168099ebb4caSwyllys BerElement *asn1 = NULL; 168199ebb4caSwyllys BerValue *extdata; 168299ebb4caSwyllys char *olddata = NULL; 168399ebb4caSwyllys KMF_X509_EXTENSION *foundextn = NULL; 168499ebb4caSwyllys size_t oldsize = 0; 168599ebb4caSwyllys 168699ebb4caSwyllys if (extensions == NULL || oid == NULL || namedata == NULL) 168799ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 168899ebb4caSwyllys 168999ebb4caSwyllys ret = encode_altname(namedata, nametype, &dername); 169099ebb4caSwyllys 169199ebb4caSwyllys if (ret != KMF_OK) 169299ebb4caSwyllys return (ret); 169399ebb4caSwyllys 169499ebb4caSwyllys (void) memset(&subjAltName, 0, sizeof (subjAltName)); 169599ebb4caSwyllys 169699ebb4caSwyllys ret = copy_data(&subjAltName.extnId, oid); 169799ebb4caSwyllys if (ret != KMF_OK) 169899ebb4caSwyllys goto out; 169999ebb4caSwyllys /* 170099ebb4caSwyllys * Check to see if this cert already has a subjectAltName. 170199ebb4caSwyllys */ 170299ebb4caSwyllys foundextn = FindExtn(extensions, oid); 170399ebb4caSwyllys 170499ebb4caSwyllys if (foundextn != NULL) { 170599ebb4caSwyllys ret = GetSequenceContents( 170699ebb4caSwyllys (char *)foundextn->BERvalue.Data, 170799ebb4caSwyllys foundextn->BERvalue.Length, 170899ebb4caSwyllys &olddata, &oldsize); 170999ebb4caSwyllys if (ret != KMF_OK) 171099ebb4caSwyllys goto out; 171199ebb4caSwyllys } 171299ebb4caSwyllys 171399ebb4caSwyllys /* 171499ebb4caSwyllys * Assume (!!) that the namedata given is already properly encoded. 171599ebb4caSwyllys */ 171699ebb4caSwyllys if ((asn1 = kmfder_alloc()) == NULL) 171799ebb4caSwyllys return (KMF_ERR_MEMORY); 171899ebb4caSwyllys 171999ebb4caSwyllys if (kmfber_printf(asn1, "{") == -1) { 172099ebb4caSwyllys ret = KMF_ERR_ENCODING; 172199ebb4caSwyllys goto out; 172299ebb4caSwyllys } 172399ebb4caSwyllys 172499ebb4caSwyllys /* Write the old extension data first */ 172599ebb4caSwyllys if (olddata != NULL && oldsize > 0) { 172699ebb4caSwyllys if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 172799ebb4caSwyllys ret = KMF_ERR_ENCODING; 172899ebb4caSwyllys goto out; 172999ebb4caSwyllys } 173099ebb4caSwyllys } 173199ebb4caSwyllys 173299ebb4caSwyllys /* Now add the new name to the list */ 173399ebb4caSwyllys if (kmfber_write(asn1, (char *)dername.Data, dername.Length, 0) == -1) { 173499ebb4caSwyllys ret = KMF_ERR_ENCODING; 173599ebb4caSwyllys goto out; 173699ebb4caSwyllys } 173799ebb4caSwyllys 173899ebb4caSwyllys /* Now close the sequence */ 173999ebb4caSwyllys if (kmfber_printf(asn1, "}") == -1) { 174099ebb4caSwyllys ret = KMF_ERR_ENCODING; 174199ebb4caSwyllys goto out; 174299ebb4caSwyllys } 174399ebb4caSwyllys if (kmfber_flatten(asn1, &extdata) == -1) { 174499ebb4caSwyllys ret = KMF_ERR_ENCODING; 174599ebb4caSwyllys goto out; 174699ebb4caSwyllys } 174799ebb4caSwyllys 174899ebb4caSwyllys /* 174999ebb4caSwyllys * If we are just adding to an existing list of altNames, 175099ebb4caSwyllys * just replace the BER data associated with the found extension. 175199ebb4caSwyllys */ 175299ebb4caSwyllys if (foundextn != NULL) { 175399ebb4caSwyllys free(foundextn->BERvalue.Data); 175499ebb4caSwyllys foundextn->critical = critical; 175599ebb4caSwyllys foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 175699ebb4caSwyllys foundextn->BERvalue.Length = extdata->bv_len; 175799ebb4caSwyllys } else { 175899ebb4caSwyllys subjAltName.critical = critical; 175999ebb4caSwyllys subjAltName.format = KMF_X509_DATAFORMAT_ENCODED; 176099ebb4caSwyllys subjAltName.BERvalue.Data = (uchar_t *)extdata->bv_val; 176199ebb4caSwyllys subjAltName.BERvalue.Length = extdata->bv_len; 176299ebb4caSwyllys ret = add_an_extension(extensions, &subjAltName); 176399ebb4caSwyllys if (ret != KMF_OK) 176499ebb4caSwyllys free(subjAltName.BERvalue.Data); 176599ebb4caSwyllys } 176699ebb4caSwyllys 176799ebb4caSwyllys free(extdata); 176899ebb4caSwyllys out: 176999ebb4caSwyllys if (olddata != NULL) 177099ebb4caSwyllys free(olddata); 177199ebb4caSwyllys 177299ebb4caSwyllys KMF_FreeData(&dername); 177399ebb4caSwyllys if (ret != KMF_OK) 177499ebb4caSwyllys KMF_FreeData(&subjAltName.extnId); 177599ebb4caSwyllys if (asn1 != NULL) 177699ebb4caSwyllys kmfber_free(asn1, 1); 177799ebb4caSwyllys return (ret); 177899ebb4caSwyllys } 1779