1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26/*--------------------------------------------------------------------------- 27 * Module: k_setupssl.c 28 * Operating System: Linux, Win32 29 * 30 * Description: 31 * This is the C Implementation file for setting up OpenSSL muti-threading environment 32 * 33 *-------------------------------------------------------------------------*/ 34 35#ifndef WIN32 36#include <signal.h> 37#include <openssl/evp.h> /* UNIX */ 38#include <openssl/engine.h> 39#endif 40 41#include "k_setupssl.h" 42#include "stdsoap2.h" 43#include <openssl/crypto.h> 44 45#if defined(WIN32) 46 47#include <windows.h> 48#define MUTEX_TYPE HANDLE 49#define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL) 50#define MUTEX_CLEANUP(x) CloseHandle(x) 51#define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE) 52#define MUTEX_UNLOCK(x) ReleaseMutex(x) 53#define THREAD_ID GetCurrentThreadId() 54 55#else 56 57#include <pthread.h> 58 59# define MUTEX_TYPE pthread_mutex_t 60# define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) 61# define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) 62# define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) 63# define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) 64# define THREAD_ID pthread_self() 65 66#ifdef K_SOLARIS_PLATFORM 67MUTEX_TYPE init_ssl_mutex = PTHREAD_MUTEX_INITIALIZER; 68static int ssl_initialized = 0; 69#endif 70#endif 71 72struct CRYPTO_dynlock_value 73{ MUTEX_TYPE mutex; 74}; 75 76void sigpipe_handle(int x) 77{ 78} 79 80static MUTEX_TYPE *mutex_buf; 81 82static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line) 83{ struct CRYPTO_dynlock_value *value; 84 value = (struct CRYPTO_dynlock_value*)malloc(sizeof(struct CRYPTO_dynlock_value)); 85 if (value) 86 MUTEX_SETUP(value->mutex); 87 return value; 88} 89 90static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line) 91{ if (mode & CRYPTO_LOCK) 92 MUTEX_LOCK(l->mutex); 93 else 94 MUTEX_UNLOCK(l->mutex); 95} 96 97static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line) 98{ MUTEX_CLEANUP(l->mutex); 99 free(l); 100} 101 102void kms_locking_function(int mode, int n, const char *file, int line) 103{ if (mode & CRYPTO_LOCK) 104 MUTEX_LOCK(mutex_buf[n]); 105 else 106 MUTEX_UNLOCK(mutex_buf[n]); 107} 108 109 110unsigned long id_function(void ) 111{ return (unsigned long)THREAD_ID; 112} 113 114#ifdef WIN32 115void OpenSSL_add_all_ciphers(void); // UNIX 116void OpenSSL_add_all_digests(void); 117#endif 118 119#ifdef K_HPUX_PLATFORM 120extern void allow_unaligned_data_access(); 121#endif 122 123// gSOAP 2.7e: 124// The function ssl_init is defined in stdsoap2.cpp and is not exported by 125// default by gSOAP. 126// gSOAP 2.7.12: 127// The function soap_ssl_init is defined in stdsoap2.cpp. It replaces 128// ssl_init and is exported by gSOAP. gSOAP 2.7.13 also supports a new 129// SOAP_SSL_SKIP_HOST_CHECK flag. 130#ifndef SOAP_SSL_SKIP_HOST_CHECK 131extern int ssl_init(); 132#endif 133 134int K_SetupSSL() 135{ int i; 136#ifdef K_SOLARIS_PLATFORM 137 if (ssl_initialized) 138 return 1; 139 MUTEX_LOCK(init_ssl_mutex); 140#endif 141 mutex_buf = (MUTEX_TYPE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); 142 if (!mutex_buf) { 143#ifdef K_SOLARIS_PLATFORM 144 MUTEX_UNLOCK(init_ssl_mutex); 145#endif 146 return 0; 147 } 148 for (i = 0; i < CRYPTO_num_locks(); i++) 149 MUTEX_SETUP(mutex_buf[i]); 150 if (CRYPTO_get_id_callback() == NULL) 151 CRYPTO_set_id_callback(id_function); 152 if (CRYPTO_get_locking_callback() == NULL) 153 CRYPTO_set_locking_callback(kms_locking_function); 154 155 CRYPTO_set_dynlock_create_callback(dyn_create_function); 156 CRYPTO_set_dynlock_lock_callback(dyn_lock_function); 157 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); 158 159#ifndef WIN32 160 /* Need SIGPIPE handler on Unix/Linux systems to catch broken pipes: */ 161 signal(SIGPIPE, sigpipe_handle); 162#endif 163#ifdef K_HPUX_PLATFORM 164// signal(SIGBUS, sigpipe_handle); 165 allow_unaligned_data_access(); 166#endif 167 OpenSSL_add_all_ciphers(); 168 OpenSSL_add_all_digests(); 169 170 // call gSOAP's OpenSSL initialization, which initializes SSL algorithms and seeds RAND 171 172 // gSOAP 2.7e: 173 // The function ssl_init is defined in stdsoap2.cpp and is not exported by 174 // default by gSOAP. 175 // gSOAP 2.7.13: 176 // The function soap_ssl_init is defined in stdsoap2.cpp. It replaces 177 // ssl_init and is exported by gSOAP. gSOAP 2.7.13 also supports a new 178 // SOAP_SSL_SKIP_HOST_CHECK flag. 179#ifdef SOAP_SSL_SKIP_HOST_CHECK 180 soap_ssl_init(); 181#else 182 ssl_init(); 183#endif 184 185#ifdef K_SOLARIS_PLATFORM 186 ssl_initialized = 1; 187 MUTEX_UNLOCK(init_ssl_mutex); 188#endif 189 190 return 1; 191} 192 193void K_CleanupSSL() 194{ int i; 195 if (!mutex_buf) 196 return; 197#ifdef K_SOLARIS_PLATFORM 198 { 199 unsigned long (*id_func)(); 200 201 if ((id_func = CRYPTO_get_id_callback()) == id_function) { 202 ENGINE_cleanup(); 203 /* EVP_cleanup(); */ 204 ERR_free_strings(); 205 CRYPTO_set_id_callback(NULL); 206 CRYPTO_set_locking_callback(NULL); 207 } 208 } 209#endif 210 CRYPTO_set_dynlock_create_callback(NULL); 211 CRYPTO_set_dynlock_lock_callback(NULL); 212 CRYPTO_set_dynlock_destroy_callback(NULL); 213 for (i = 0; i < CRYPTO_num_locks(); i++) 214 MUTEX_CLEANUP(mutex_buf[i]); 215 OPENSSL_free(mutex_buf); 216 mutex_buf = NULL; 217} 218 219// TODO: what should 'struct soap' really be? 220int K_SetupCallbacks( struct soap *i_pSoap ) 221{ 222 return 1; 223} 224