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