1 /* crypto/cryptlib.c */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59 #include <stdio.h> 60 #include <string.h> 61 #include "cryptlib.h" 62 #include <openssl/crypto.h> 63 64 #if defined(WIN32) || defined(WIN16) 65 static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ 66 #endif 67 68 /* real #defines in crypto.h, keep these upto date */ 69 static const char* lock_names[CRYPTO_NUM_LOCKS] = 70 { 71 "<<ERROR>>", 72 "err", 73 "err_hash", 74 "x509", 75 "x509_info", 76 "x509_pkey", 77 "x509_crl", 78 "x509_req", 79 "dsa", 80 "rsa", 81 "evp_pkey", 82 "x509_store", 83 "ssl_ctx", 84 "ssl_cert", 85 "ssl_session", 86 "ssl_sess_cert", 87 "ssl", 88 "rand", 89 "debug_malloc", 90 "BIO", 91 "gethostbyname", 92 "getservbyname", 93 "readdir", 94 "RSA_blinding", 95 #if CRYPTO_NUM_LOCKS != 24 96 # error "Inconsistency between crypto.h and cryptlib.c" 97 #endif 98 }; 99 100 static STACK *app_locks=NULL; 101 102 static void (MS_FAR *locking_callback)(int mode,int type, 103 const char *file,int line)=NULL; 104 static int (MS_FAR *add_lock_callback)(int *pointer,int amount, 105 int type,const char *file,int line)=NULL; 106 static unsigned long (MS_FAR *id_callback)(void)=NULL; 107 int CRYPTO_get_new_lockid(char *name) 108 { 109 char *str; 110 int i; 111 112 /* A hack to make Visual C++ 5.0 work correctly when linking as 113 * a DLL using /MT. Without this, the application cannot use 114 * and floating point printf's. 115 * It also seems to be needed for Visual C 1.5 (win16) */ 116 #if defined(WIN32) || defined(WIN16) 117 SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; 118 #endif 119 120 if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL)) 121 { 122 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); 123 return(0); 124 } 125 if ((str=BUF_strdup(name)) == NULL) 126 return(0); 127 i=sk_push(app_locks,str); 128 if (!i) 129 Free(str); 130 else 131 i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ 132 return(i); 133 } 134 135 int CRYPTO_num_locks(void) 136 { 137 return CRYPTO_NUM_LOCKS; 138 } 139 140 void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, 141 int line) 142 { 143 return(locking_callback); 144 } 145 146 int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, 147 const char *file,int line) 148 { 149 return(add_lock_callback); 150 } 151 152 void CRYPTO_set_locking_callback(void (*func)(int mode,int type, 153 const char *file,int line)) 154 { 155 locking_callback=func; 156 } 157 158 void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, 159 const char *file,int line)) 160 { 161 add_lock_callback=func; 162 } 163 164 unsigned long (*CRYPTO_get_id_callback(void))(void) 165 { 166 return(id_callback); 167 } 168 169 void CRYPTO_set_id_callback(unsigned long (*func)(void)) 170 { 171 id_callback=func; 172 } 173 174 unsigned long CRYPTO_thread_id(void) 175 { 176 unsigned long ret=0; 177 178 if (id_callback == NULL) 179 { 180 #ifdef WIN16 181 ret=(unsigned long)GetCurrentTask(); 182 #elif defined(WIN32) 183 ret=(unsigned long)GetCurrentThreadId(); 184 #elif defined(MSDOS) 185 ret=1L; 186 #else 187 ret=(unsigned long)getpid(); 188 #endif 189 } 190 else 191 ret=id_callback(); 192 return(ret); 193 } 194 195 void CRYPTO_lock(int mode, int type, const char *file, int line) 196 { 197 #ifdef LOCK_DEBUG 198 { 199 char *rw_text,*operation_text; 200 201 if (mode & CRYPTO_LOCK) 202 operation_text="lock "; 203 else if (mode & CRYPTO_UNLOCK) 204 operation_text="unlock"; 205 else 206 operation_text="ERROR "; 207 208 if (mode & CRYPTO_READ) 209 rw_text="r"; 210 else if (mode & CRYPTO_WRITE) 211 rw_text="w"; 212 else 213 rw_text="ERROR"; 214 215 fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n", 216 CRYPTO_thread_id(), rw_text, operation_text, 217 CRYPTO_get_lock_name(type), file, line); 218 } 219 #endif 220 if (locking_callback != NULL) 221 locking_callback(mode,type,file,line); 222 } 223 224 int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, 225 int line) 226 { 227 int ret; 228 229 if (add_lock_callback != NULL) 230 { 231 #ifdef LOCK_DEBUG 232 int before= *pointer; 233 #endif 234 235 ret=add_lock_callback(pointer,amount,type,file,line); 236 #ifdef LOCK_DEBUG 237 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", 238 CRYPTO_thread_id(), 239 before,amount,ret, 240 CRYPTO_get_lock_name(type), 241 file,line); 242 #endif 243 *pointer=ret; 244 } 245 else 246 { 247 CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line); 248 249 ret= *pointer+amount; 250 #ifdef LOCK_DEBUG 251 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", 252 CRYPTO_thread_id(), 253 *pointer,amount,ret, 254 CRYPTO_get_lock_name(type), 255 file,line); 256 #endif 257 *pointer=ret; 258 CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line); 259 } 260 return(ret); 261 } 262 263 const char *CRYPTO_get_lock_name(int type) 264 { 265 if (type < 0) 266 return("ERROR"); 267 else if (type < CRYPTO_NUM_LOCKS) 268 return(lock_names[type]); 269 else if (type-CRYPTO_NUM_LOCKS >= sk_num(app_locks)) 270 return("ERROR"); 271 else 272 return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS)); 273 } 274 275 #ifdef _DLL 276 #ifdef WIN32 277 278 /* All we really need to do is remove the 'error' state when a thread 279 * detaches */ 280 281 BOOL WINAPI DLLEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, 282 LPVOID lpvReserved) 283 { 284 switch(fdwReason) 285 { 286 case DLL_PROCESS_ATTACH: 287 break; 288 case DLL_THREAD_ATTACH: 289 break; 290 case DLL_THREAD_DETACH: 291 ERR_remove_state(0); 292 break; 293 case DLL_PROCESS_DETACH: 294 break; 295 } 296 return(TRUE); 297 } 298 #endif 299 300 #endif 301