summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/cryptlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/cryptlib.c')
-rw-r--r--src/lib/libcrypto/cryptlib.c303
1 files changed, 245 insertions, 58 deletions
diff --git a/src/lib/libcrypto/cryptlib.c b/src/lib/libcrypto/cryptlib.c
index 9a7e80b7f8..612b3b93b4 100644
--- a/src/lib/libcrypto/cryptlib.c
+++ b/src/lib/libcrypto/cryptlib.c
@@ -59,19 +59,22 @@
59#include <stdio.h> 59#include <stdio.h>
60#include <string.h> 60#include <string.h>
61#include "cryptlib.h" 61#include "cryptlib.h"
62#include "crypto.h" 62#include <openssl/crypto.h>
63#include "date.h" 63#include <openssl/safestack.h>
64 64
65#if defined(WIN32) || defined(WIN16) 65#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
66static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ 66static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
67#endif 67#endif
68 68
69DECLARE_STACK_OF(CRYPTO_dynlock)
70IMPLEMENT_STACK_OF(CRYPTO_dynlock)
71
69/* real #defines in crypto.h, keep these upto date */ 72/* real #defines in crypto.h, keep these upto date */
70static char* lock_names[CRYPTO_NUM_LOCKS] = 73static const char* lock_names[CRYPTO_NUM_LOCKS] =
71 { 74 {
72 "<<ERROR>>", 75 "<<ERROR>>",
73 "err", 76 "err",
74 "err_hash", 77 "ex_data",
75 "x509", 78 "x509",
76 "x509_info", 79 "x509_info",
77 "x509_pkey", 80 "x509_pkey",
@@ -84,100 +87,283 @@ static char* lock_names[CRYPTO_NUM_LOCKS] =
84 "ssl_ctx", 87 "ssl_ctx",
85 "ssl_cert", 88 "ssl_cert",
86 "ssl_session", 89 "ssl_session",
90 "ssl_sess_cert",
87 "ssl", 91 "ssl",
88 "rand", 92 "rand",
93 "rand2",
89 "debug_malloc", 94 "debug_malloc",
90 "BIO", 95 "BIO",
91 "bio_gethostbyname", 96 "gethostbyname",
97 "getservbyname",
98 "readdir",
92 "RSA_blinding", 99 "RSA_blinding",
100 "dh",
101 "debug_malloc2",
102 "dso",
103 "dynlock",
104 "engine",
105 "ui",
106#if CRYPTO_NUM_LOCKS != 31
107# error "Inconsistency between crypto.h and cryptlib.c"
108#endif
93 }; 109 };
94 110
111/* This is for applications to allocate new type names in the non-dynamic
112 array of lock names. These are numbered with positive numbers. */
95static STACK *app_locks=NULL; 113static STACK *app_locks=NULL;
96 114
97#ifndef NOPROTO 115/* For applications that want a more dynamic way of handling threads, the
116 following stack is used. These are externally numbered with negative
117 numbers. */
118static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
119
120
98static void (MS_FAR *locking_callback)(int mode,int type, 121static void (MS_FAR *locking_callback)(int mode,int type,
99 char *file,int line)=NULL; 122 const char *file,int line)=NULL;
100static int (MS_FAR *add_lock_callback)(int *pointer,int amount, 123static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
101 int type,char *file,int line)=NULL; 124 int type,const char *file,int line)=NULL;
102static unsigned long (MS_FAR *id_callback)(void)=NULL; 125static unsigned long (MS_FAR *id_callback)(void)=NULL;
103#else 126static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
104static void (MS_FAR *locking_callback)()=NULL; 127 (const char *file,int line)=NULL;
105static int (MS_FAR *add_lock_callback)()=NULL; 128static void (MS_FAR *dynlock_lock_callback)(int mode,
106static unsigned long (MS_FAR *id_callback)()=NULL; 129 struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
107#endif 130static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
131 const char *file,int line)=NULL;
108 132
109int CRYPTO_get_new_lockid(name) 133int CRYPTO_get_new_lockid(char *name)
110char *name;
111 { 134 {
112 char *str; 135 char *str;
113 int i; 136 int i;
114 137
138#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
115 /* A hack to make Visual C++ 5.0 work correctly when linking as 139 /* A hack to make Visual C++ 5.0 work correctly when linking as
116 * a DLL using /MT. Without this, the application cannot use 140 * a DLL using /MT. Without this, the application cannot use
117 * and floating point printf's. 141 * and floating point printf's.
118 * It also seems to be needed for Visual C 1.5 (win16) */ 142 * It also seems to be needed for Visual C 1.5 (win16) */
119#if defined(WIN32) || defined(WIN16)
120 SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; 143 SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
121#endif 144#endif
122 145
123 if (app_locks == NULL) 146 if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
124 if ((app_locks=sk_new_null()) == NULL) 147 {
125 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); 148 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
126 return(0); 149 return(0);
150 }
127 if ((str=BUF_strdup(name)) == NULL) 151 if ((str=BUF_strdup(name)) == NULL)
152 {
153 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
128 return(0); 154 return(0);
155 }
129 i=sk_push(app_locks,str); 156 i=sk_push(app_locks,str);
130 if (!i) 157 if (!i)
131 Free(str); 158 OPENSSL_free(str);
132 else 159 else
133 i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ 160 i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
134 return(i); 161 return(i);
135 } 162 }
136 163
137void (*CRYPTO_get_locking_callback(P_V))(P_I_I_P_I) 164int CRYPTO_num_locks(void)
165 {
166 return CRYPTO_NUM_LOCKS;
167 }
168
169int CRYPTO_get_new_dynlockid(void)
170 {
171 int i = 0;
172 CRYPTO_dynlock *pointer = NULL;
173
174 if (dynlock_create_callback == NULL)
175 {
176 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
177 return(0);
178 }
179 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
180 if ((dyn_locks == NULL)
181 && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
182 {
183 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
184 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
185 return(0);
186 }
187 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
188
189 pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
190 if (pointer == NULL)
191 {
192 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
193 return(0);
194 }
195 pointer->references = 1;
196 pointer->data = dynlock_create_callback(__FILE__,__LINE__);
197 if (pointer->data == NULL)
198 {
199 OPENSSL_free(pointer);
200 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
201 return(0);
202 }
203
204 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
205 /* First, try to find an existing empty slot */
206 i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
207 /* If there was none, push, thereby creating a new one */
208 if (i == -1)
209 i=sk_CRYPTO_dynlock_push(dyn_locks,pointer);
210 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
211
212 if (!i)
213 {
214 dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
215 OPENSSL_free(pointer);
216 }
217 else
218 i += 1; /* to avoid 0 */
219 return -i;
220 }
221
222void CRYPTO_destroy_dynlockid(int i)
223 {
224 CRYPTO_dynlock *pointer = NULL;
225 if (i)
226 i = -i-1;
227 if (dynlock_destroy_callback == NULL)
228 return;
229
230 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
231
232 if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
233 {
234 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
235 return;
236 }
237 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
238 if (pointer != NULL)
239 {
240 --pointer->references;
241#ifdef REF_CHECK
242 if (pointer->references < 0)
243 {
244 fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
245 abort();
246 }
247 else
248#endif
249 if (pointer->references <= 0)
250 {
251 sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
252 }
253 else
254 pointer = NULL;
255 }
256 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
257
258 if (pointer)
259 {
260 dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
261 OPENSSL_free(pointer);
262 }
263 }
264
265struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
266 {
267 CRYPTO_dynlock *pointer = NULL;
268 if (i)
269 i = -i-1;
270
271 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
272
273 if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
274 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
275 if (pointer)
276 pointer->references++;
277
278 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
279
280 if (pointer)
281 return pointer->data;
282 return NULL;
283 }
284
285struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
286 (const char *file,int line)
287 {
288 return(dynlock_create_callback);
289 }
290
291void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
292 struct CRYPTO_dynlock_value *l, const char *file,int line)
293 {
294 return(dynlock_lock_callback);
295 }
296
297void (*CRYPTO_get_dynlock_destroy_callback(void))
298 (struct CRYPTO_dynlock_value *l, const char *file,int line)
299 {
300 return(dynlock_destroy_callback);
301 }
302
303void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
304 (const char *file, int line))
305 {
306 dynlock_create_callback=func;
307 }
308
309void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
310 struct CRYPTO_dynlock_value *l, const char *file, int line))
311 {
312 dynlock_lock_callback=func;
313 }
314
315void CRYPTO_set_dynlock_destroy_callback(void (*func)
316 (struct CRYPTO_dynlock_value *l, const char *file, int line))
317 {
318 dynlock_destroy_callback=func;
319 }
320
321
322void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
323 int line)
138 { 324 {
139 return(locking_callback); 325 return(locking_callback);
140 } 326 }
141 327
142int (*CRYPTO_get_add_lock_callback(P_V))(P_IP_I_I_P_I) 328int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
329 const char *file,int line)
143 { 330 {
144 return(add_lock_callback); 331 return(add_lock_callback);
145 } 332 }
146 333
147void CRYPTO_set_locking_callback(func) 334void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
148void (*func)(P_I_I_P_I); 335 const char *file,int line))
149 { 336 {
150 locking_callback=func; 337 locking_callback=func;
151 } 338 }
152 339
153void CRYPTO_set_add_lock_callback(func) 340void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
154int (*func)(P_IP_I_I_P_I); 341 const char *file,int line))
155 { 342 {
156 add_lock_callback=func; 343 add_lock_callback=func;
157 } 344 }
158 345
159unsigned long (*CRYPTO_get_id_callback(P_V))(P_V) 346unsigned long (*CRYPTO_get_id_callback(void))(void)
160 { 347 {
161 return(id_callback); 348 return(id_callback);
162 } 349 }
163 350
164void CRYPTO_set_id_callback(func) 351void CRYPTO_set_id_callback(unsigned long (*func)(void))
165unsigned long (*func)(P_V);
166 { 352 {
167 id_callback=func; 353 id_callback=func;
168 } 354 }
169 355
170unsigned long CRYPTO_thread_id() 356unsigned long CRYPTO_thread_id(void)
171 { 357 {
172 unsigned long ret=0; 358 unsigned long ret=0;
173 359
174 if (id_callback == NULL) 360 if (id_callback == NULL)
175 { 361 {
176#ifdef WIN16 362#ifdef OPENSSL_SYS_WIN16
177 ret=(unsigned long)GetCurrentTask(); 363 ret=(unsigned long)GetCurrentTask();
178#elif defined(WIN32) 364#elif defined(OPENSSL_SYS_WIN32)
179 ret=(unsigned long)GetCurrentThreadId(); 365 ret=(unsigned long)GetCurrentThreadId();
180#elif defined(MSDOS) 366#elif defined(GETPID_IS_MEANINGLESS)
181 ret=1L; 367 ret=1L;
182#else 368#else
183 ret=(unsigned long)getpid(); 369 ret=(unsigned long)getpid();
@@ -188,11 +374,7 @@ unsigned long CRYPTO_thread_id()
188 return(ret); 374 return(ret);
189 } 375 }
190 376
191void CRYPTO_lock(mode,type,file,line) 377void CRYPTO_lock(int mode, int type, const char *file, int line)
192int mode;
193int type;
194char *file;
195int line;
196 { 378 {
197#ifdef LOCK_DEBUG 379#ifdef LOCK_DEBUG
198 { 380 {
@@ -217,18 +399,27 @@ int line;
217 CRYPTO_get_lock_name(type), file, line); 399 CRYPTO_get_lock_name(type), file, line);
218 } 400 }
219#endif 401#endif
220 if (locking_callback != NULL) 402 if (type < 0)
221 locking_callback(mode,type,file,line); 403 {
404 struct CRYPTO_dynlock_value *pointer
405 = CRYPTO_get_dynlock_value(type);
406
407 if (pointer && dynlock_lock_callback)
408 {
409 dynlock_lock_callback(mode, pointer, file, line);
410 }
411
412 CRYPTO_destroy_dynlockid(type);
413 }
414 else
415 if (locking_callback != NULL)
416 locking_callback(mode,type,file,line);
222 } 417 }
223 418
224int CRYPTO_add_lock(pointer,amount,type,file,line) 419int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
225int *pointer; 420 int line)
226int amount;
227int type;
228char *file;
229int line;
230 { 421 {
231 int ret; 422 int ret = 0;
232 423
233 if (add_lock_callback != NULL) 424 if (add_lock_callback != NULL)
234 { 425 {
@@ -244,7 +435,6 @@ int line;
244 CRYPTO_get_lock_name(type), 435 CRYPTO_get_lock_name(type),
245 file,line); 436 file,line);
246#endif 437#endif
247 *pointer=ret;
248 } 438 }
249 else 439 else
250 { 440 {
@@ -264,11 +454,10 @@ int line;
264 return(ret); 454 return(ret);
265 } 455 }
266 456
267char *CRYPTO_get_lock_name(type) 457const char *CRYPTO_get_lock_name(int type)
268int type;
269 { 458 {
270 if (type < 0) 459 if (type < 0)
271 return("ERROR"); 460 return("dynamic");
272 else if (type < CRYPTO_NUM_LOCKS) 461 else if (type < CRYPTO_NUM_LOCKS)
273 return(lock_names[type]); 462 return(lock_names[type]);
274 else if (type-CRYPTO_NUM_LOCKS >= sk_num(app_locks)) 463 else if (type-CRYPTO_NUM_LOCKS >= sk_num(app_locks))
@@ -278,15 +467,13 @@ int type;
278 } 467 }
279 468
280#ifdef _DLL 469#ifdef _DLL
281#ifdef WIN32 470#ifdef OPENSSL_SYS_WIN32
282 471
283/* All we really need to do is remove the 'error' state when a thread 472/* All we really need to do is remove the 'error' state when a thread
284 * detaches */ 473 * detaches */
285 474
286BOOL WINAPI DLLEntryPoint(hinstDLL,fdwReason,lpvReserved) 475BOOL WINAPI DLLEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason,
287HINSTANCE hinstDLL; 476 LPVOID lpvReserved)
288DWORD fdwReason;
289LPVOID lpvReserved;
290 { 477 {
291 switch(fdwReason) 478 switch(fdwReason)
292 { 479 {