~ubuntu-branches/ubuntu/lucid/openssl/lucid-proposed

« back to all changes in this revision

Viewing changes to crypto/cryptlib.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2009-06-13 18:15:46 UTC
  • mto: (11.1.5 squeeze)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: james.westby@ubuntu.com-20090613181546-vbfntai3b009dl1u
Tags: upstream-0.9.8k
ImportĀ upstreamĀ versionĀ 0.9.8k

Show diffs side-by-side

added added

removed removed

Lines of Context:
121
121
static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
122
122
#endif
123
123
 
124
 
DECLARE_STACK_OF(CRYPTO_dynlock)
125
 
IMPLEMENT_STACK_OF(CRYPTO_dynlock)
126
 
 
127
 
/* real #defines in crypto.h, keep these upto date */
128
 
static const char* const lock_names[CRYPTO_NUM_LOCKS] =
129
 
        {
130
 
        "<<ERROR>>",
131
 
        "err",
132
 
        "ex_data",
133
 
        "x509",
134
 
        "x509_info",
135
 
        "x509_pkey",
136
 
        "x509_crl",
137
 
        "x509_req",
138
 
        "dsa",
139
 
        "rsa",
140
 
        "evp_pkey",
141
 
        "x509_store",
142
 
        "ssl_ctx",
143
 
        "ssl_cert",
144
 
        "ssl_session",
145
 
        "ssl_sess_cert",
146
 
        "ssl",
147
 
        "ssl_method",
148
 
        "rand",
149
 
        "rand2",
150
 
        "debug_malloc",
151
 
        "BIO",
152
 
        "gethostbyname",
153
 
        "getservbyname",
154
 
        "readdir",
155
 
        "RSA_blinding",
156
 
        "dh",
157
 
        "debug_malloc2",
158
 
        "dso",
159
 
        "dynlock",
160
 
        "engine",
161
 
        "ui",
162
 
        "ecdsa",
163
 
        "ec",
164
 
        "ecdh",
165
 
        "bn",
166
 
        "ec_pre_comp",
167
 
        "store",
168
 
        "comp",
169
 
#if CRYPTO_NUM_LOCKS != 39
170
 
# error "Inconsistency between crypto.h and cryptlib.c"
171
 
#endif
172
 
        };
173
 
 
174
 
/* This is for applications to allocate new type names in the non-dynamic
175
 
   array of lock names.  These are numbered with positive numbers.  */
176
 
static STACK *app_locks=NULL;
177
 
 
178
 
/* For applications that want a more dynamic way of handling threads, the
179
 
   following stack is used.  These are externally numbered with negative
180
 
   numbers.  */
181
 
static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
182
 
 
183
 
 
184
124
static void (MS_FAR *locking_callback)(int mode,int type,
185
125
        const char *file,int line)=NULL;
186
126
static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
187
127
        int type,const char *file,int line)=NULL;
188
128
static unsigned long (MS_FAR *id_callback)(void)=NULL;
189
 
static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
190
 
        (const char *file,int line)=NULL;
191
 
static void (MS_FAR *dynlock_lock_callback)(int mode,
192
 
        struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
193
 
static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
194
 
        const char *file,int line)=NULL;
195
 
 
196
 
int CRYPTO_get_new_lockid(char *name)
197
 
        {
198
 
        char *str;
199
 
        int i;
200
 
 
201
 
#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
202
 
        /* A hack to make Visual C++ 5.0 work correctly when linking as
203
 
         * a DLL using /MT. Without this, the application cannot use
204
 
         * and floating point printf's.
205
 
         * It also seems to be needed for Visual C 1.5 (win16) */
206
 
        SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
207
 
#endif
208
 
 
209
 
        if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
210
 
                {
211
 
                CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
212
 
                return(0);
213
 
                }
214
 
        if ((str=BUF_strdup(name)) == NULL)
215
 
                {
216
 
                CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
217
 
                return(0);
218
 
                }
219
 
        i=sk_push(app_locks,str);
220
 
        if (!i)
221
 
                OPENSSL_free(str);
222
 
        else
223
 
                i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
224
 
        return(i);
225
 
        }
226
129
 
227
130
int CRYPTO_num_locks(void)
228
131
        {
229
132
        return CRYPTO_NUM_LOCKS;
230
133
        }
231
134
 
232
 
int CRYPTO_get_new_dynlockid(void)
233
 
        {
234
 
        int i = 0;
235
 
        CRYPTO_dynlock *pointer = NULL;
236
 
 
237
 
        if (dynlock_create_callback == NULL)
238
 
                {
239
 
                CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
240
 
                return(0);
241
 
                }
242
 
        CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
243
 
        if ((dyn_locks == NULL)
244
 
                && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
245
 
                {
246
 
                CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
247
 
                CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
248
 
                return(0);
249
 
                }
250
 
        CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
251
 
 
252
 
        pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
253
 
        if (pointer == NULL)
254
 
                {
255
 
                CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
256
 
                return(0);
257
 
                }
258
 
        pointer->references = 1;
259
 
        pointer->data = dynlock_create_callback(__FILE__,__LINE__);
260
 
        if (pointer->data == NULL)
261
 
                {
262
 
                OPENSSL_free(pointer);
263
 
                CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
264
 
                return(0);
265
 
                }
266
 
 
267
 
        CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
268
 
        /* First, try to find an existing empty slot */
269
 
        i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
270
 
        /* If there was none, push, thereby creating a new one */
271
 
        if (i == -1)
272
 
                /* Since sk_push() returns the number of items on the
273
 
                   stack, not the location of the pushed item, we need
274
 
                   to transform the returned number into a position,
275
 
                   by decreasing it.  */
276
 
                i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
277
 
        else
278
 
                /* If we found a place with a NULL pointer, put our pointer
279
 
                   in it.  */
280
 
                (void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
281
 
        CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
282
 
 
283
 
        if (i == -1)
284
 
                {
285
 
                dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
286
 
                OPENSSL_free(pointer);
287
 
                }
288
 
        else
289
 
                i += 1; /* to avoid 0 */
290
 
        return -i;
291
 
        }
292
 
 
293
 
void CRYPTO_destroy_dynlockid(int i)
294
 
        {
295
 
        CRYPTO_dynlock *pointer = NULL;
296
 
        if (i)
297
 
                i = -i-1;
298
 
        if (dynlock_destroy_callback == NULL)
299
 
                return;
300
 
 
301
 
        CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
302
 
 
303
 
        if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
304
 
                {
305
 
                CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
306
 
                return;
307
 
                }
308
 
        pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
309
 
        if (pointer != NULL)
310
 
                {
311
 
                --pointer->references;
312
 
#ifdef REF_CHECK
313
 
                if (pointer->references < 0)
314
 
                        {
315
 
                        fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
316
 
                        abort();
317
 
                        }
318
 
                else
319
 
#endif
320
 
                        if (pointer->references <= 0)
321
 
                                {
322
 
                                (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
323
 
                                }
324
 
                        else
325
 
                                pointer = NULL;
326
 
                }
327
 
        CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
328
 
 
329
 
        if (pointer)
330
 
                {
331
 
                dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
332
 
                OPENSSL_free(pointer);
333
 
                }
334
 
        }
335
 
 
336
 
struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
337
 
        {
338
 
        CRYPTO_dynlock *pointer = NULL;
339
 
        if (i)
340
 
                i = -i-1;
341
 
 
342
 
        CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
343
 
 
344
 
        if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
345
 
                pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
346
 
        if (pointer)
347
 
                pointer->references++;
348
 
 
349
 
        CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
350
 
 
351
 
        if (pointer)
352
 
                return pointer->data;
353
 
        return NULL;
354
 
        }
355
 
 
356
 
struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
357
 
        (const char *file,int line)
358
 
        {
359
 
        return(dynlock_create_callback);
360
 
        }
361
 
 
362
 
void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
363
 
        struct CRYPTO_dynlock_value *l, const char *file,int line)
364
 
        {
365
 
        return(dynlock_lock_callback);
366
 
        }
367
 
 
368
 
void (*CRYPTO_get_dynlock_destroy_callback(void))
369
 
        (struct CRYPTO_dynlock_value *l, const char *file,int line)
370
 
        {
371
 
        return(dynlock_destroy_callback);
372
 
        }
373
 
 
374
 
void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
375
 
        (const char *file, int line))
376
 
        {
377
 
        dynlock_create_callback=func;
378
 
        }
379
 
 
380
 
void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
381
 
        struct CRYPTO_dynlock_value *l, const char *file, int line))
382
 
        {
383
 
        dynlock_lock_callback=func;
384
 
        }
385
 
 
386
 
void CRYPTO_set_dynlock_destroy_callback(void (*func)
387
 
        (struct CRYPTO_dynlock_value *l, const char *file, int line))
388
 
        {
389
 
        dynlock_destroy_callback=func;
390
 
        }
391
 
 
392
 
 
393
135
void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
394
136
                int line)
395
137
        {
445
187
        return(ret);
446
188
        }
447
189
 
 
190
static void (*do_dynlock_cb)(int mode, int type, const char *file, int line);
 
191
 
 
192
void int_CRYPTO_set_do_dynlock_callback(
 
193
        void (*dyn_cb)(int mode, int type, const char *file, int line))
 
194
        {
 
195
        do_dynlock_cb = dyn_cb;
 
196
        }
 
197
 
448
198
void CRYPTO_lock(int mode, int type, const char *file, int line)
449
199
        {
450
200
#ifdef LOCK_DEBUG
472
222
#endif
473
223
        if (type < 0)
474
224
                {
475
 
                if (dynlock_lock_callback != NULL)
476
 
                        {
477
 
                        struct CRYPTO_dynlock_value *pointer
478
 
                                = CRYPTO_get_dynlock_value(type);
479
 
 
480
 
                        OPENSSL_assert(pointer != NULL);
481
 
 
482
 
                        dynlock_lock_callback(mode, pointer, file, line);
483
 
 
484
 
                        CRYPTO_destroy_dynlockid(type);
485
 
                        }
 
225
                if (do_dynlock_cb)
 
226
                        do_dynlock_cb(mode, type, file, line);
486
227
                }
487
228
        else
488
229
                if (locking_callback != NULL)
527
268
        return(ret);
528
269
        }
529
270
 
530
 
const char *CRYPTO_get_lock_name(int type)
531
 
        {
532
 
        if (type < 0)
533
 
                return("dynamic");
534
 
        else if (type < CRYPTO_NUM_LOCKS)
535
 
                return(lock_names[type]);
536
 
        else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks))
537
 
                return("ERROR");
538
 
        else
539
 
                return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS));
540
 
        }
541
 
 
542
271
#if     defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
543
272
        defined(__INTEL__) || \
544
 
        defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64)
 
273
        defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
545
274
 
546
275
unsigned long  OPENSSL_ia32cap_P=0;
547
276
unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; }
577
306
#endif
578
307
 
579
308
#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
 
309
 
 
310
#ifdef OPENSSL_FIPS
 
311
 
 
312
#include <tlhelp32.h>
 
313
#if defined(__GNUC__) && __GNUC__>=2
 
314
static int DllInit(void) __attribute__((constructor));
 
315
#elif defined(_MSC_VER)
 
316
static int DllInit(void);
 
317
# ifdef _WIN64
 
318
# pragma section(".CRT$XCU",read)
 
319
  __declspec(allocate(".CRT$XCU"))
 
320
# else
 
321
# pragma data_seg(".CRT$XCU")
 
322
# endif
 
323
  static int (*p)(void) = DllInit;
 
324
# pragma data_seg()
 
325
#endif
 
326
 
 
327
static int DllInit(void)
 
328
{
 
329
#if defined(_WIN32_WINNT)
 
330
        union   { int(*f)(void); BYTE *p; } t = { DllInit };
 
331
        HANDLE  hModuleSnap = INVALID_HANDLE_VALUE;
 
332
        IMAGE_DOS_HEADER *dos_header;
 
333
        IMAGE_NT_HEADERS *nt_headers;
 
334
        MODULEENTRY32 me32 = {sizeof(me32)};
 
335
 
 
336
        hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
 
337
        if (hModuleSnap != INVALID_HANDLE_VALUE &&
 
338
            Module32First(hModuleSnap,&me32)) do
 
339
                {
 
340
                if (t.p >= me32.modBaseAddr &&
 
341
                    t.p <  me32.modBaseAddr+me32.modBaseSize)
 
342
                        {
 
343
                        dos_header=(IMAGE_DOS_HEADER *)me32.modBaseAddr;
 
344
                        if (dos_header->e_magic==IMAGE_DOS_SIGNATURE)
 
345
                                {
 
346
                                nt_headers=(IMAGE_NT_HEADERS *)
 
347
                                        ((BYTE *)dos_header+dos_header->e_lfanew);
 
348
                                if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
 
349
                                    me32.modBaseAddr!=(BYTE*)nt_headers->OptionalHeader.ImageBase)
 
350
                                        OPENSSL_NONPIC_relocated=1;
 
351
                                }
 
352
                        break;
 
353
                        }
 
354
                } while (Module32Next(hModuleSnap,&me32));
 
355
 
 
356
        if (hModuleSnap != INVALID_HANDLE_VALUE)
 
357
                CloseHandle(hModuleSnap);
 
358
#endif
 
359
        OPENSSL_cpuid_setup();
 
360
        return 0;
 
361
}
 
362
 
 
363
#else
 
364
 
580
365
#ifdef __CYGWIN__
581
366
/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
582
367
#include <windows.h>
620
405
        }
621
406
#endif
622
407
 
 
408
#endif
 
409
 
623
410
#if defined(_WIN32) && !defined(__CYGWIN__)
624
411
#include <tchar.h>
625
412