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