cryptlib.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:21k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* crypto/cryptlib.c */
  2. /* ====================================================================
  3.  * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer. 
  11.  *
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in
  14.  *    the documentation and/or other materials provided with the
  15.  *    distribution.
  16.  *
  17.  * 3. All advertising materials mentioning features or use of this
  18.  *    software must display the following acknowledgment:
  19.  *    "This product includes software developed by the OpenSSL Project
  20.  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  21.  *
  22.  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  23.  *    endorse or promote products derived from this software without
  24.  *    prior written permission. For written permission, please contact
  25.  *    openssl-core@openssl.org.
  26.  *
  27.  * 5. Products derived from this software may not be called "OpenSSL"
  28.  *    nor may "OpenSSL" appear in their names without prior written
  29.  *    permission of the OpenSSL Project.
  30.  *
  31.  * 6. Redistributions of any form whatsoever must retain the following
  32.  *    acknowledgment:
  33.  *    "This product includes software developed by the OpenSSL Project
  34.  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  35.  *
  36.  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  37.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  38.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  39.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
  40.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  42.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  44.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  45.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  46.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  47.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  48.  * ====================================================================
  49.  *
  50.  * This product includes cryptographic software written by Eric Young
  51.  * (eay@cryptsoft.com).  This product includes software written by Tim
  52.  * Hudson (tjh@cryptsoft.com).
  53.  *
  54.  */
  55. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  56.  * All rights reserved.
  57.  *
  58.  * This package is an SSL implementation written
  59.  * by Eric Young (eay@cryptsoft.com).
  60.  * The implementation was written so as to conform with Netscapes SSL.
  61.  * 
  62.  * This library is free for commercial and non-commercial use as long as
  63.  * the following conditions are aheared to.  The following conditions
  64.  * apply to all code found in this distribution, be it the RC4, RSA,
  65.  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
  66.  * included with this distribution is covered by the same copyright terms
  67.  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  68.  * 
  69.  * Copyright remains Eric Young's, and as such any Copyright notices in
  70.  * the code are not to be removed.
  71.  * If this package is used in a product, Eric Young should be given attribution
  72.  * as the author of the parts of the library used.
  73.  * This can be in the form of a textual message at program startup or
  74.  * in documentation (online or textual) provided with the package.
  75.  * 
  76.  * Redistribution and use in source and binary forms, with or without
  77.  * modification, are permitted provided that the following conditions
  78.  * are met:
  79.  * 1. Redistributions of source code must retain the copyright
  80.  *    notice, this list of conditions and the following disclaimer.
  81.  * 2. Redistributions in binary form must reproduce the above copyright
  82.  *    notice, this list of conditions and the following disclaimer in the
  83.  *    documentation and/or other materials provided with the distribution.
  84.  * 3. All advertising materials mentioning features or use of this software
  85.  *    must display the following acknowledgement:
  86.  *    "This product includes cryptographic software written by
  87.  *     Eric Young (eay@cryptsoft.com)"
  88.  *    The word 'cryptographic' can be left out if the rouines from the library
  89.  *    being used are not cryptographic related :-).
  90.  * 4. If you include any Windows specific code (or a derivative thereof) from 
  91.  *    the apps directory (application code) you must include an acknowledgement:
  92.  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  93.  * 
  94.  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  95.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  96.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  97.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  98.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  99.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  100.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  101.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  102.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  103.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  104.  * SUCH DAMAGE.
  105.  * 
  106.  * The licence and distribution terms for any publically available version or
  107.  * derivative of this code cannot be changed.  i.e. this code cannot simply be
  108.  * copied and put under another distribution licence
  109.  * [including the GNU Public Licence.]
  110.  */
  111. /* ====================================================================
  112.  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  113.  * ECDH support in OpenSSL originally developed by 
  114.  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  115.  */
  116. #include "cryptlib.h"
  117. #include <openssl/safestack.h>
  118. #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
  119. static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
  120. #endif
  121. DECLARE_STACK_OF(CRYPTO_dynlock)
  122. IMPLEMENT_STACK_OF(CRYPTO_dynlock)
  123. /* real #defines in crypto.h, keep these upto date */
  124. static const char* lock_names[CRYPTO_NUM_LOCKS] =
  125. {
  126. "<<ERROR>>",
  127. "err",
  128. "ex_data",
  129. "x509",
  130. "x509_info",
  131. "x509_pkey",
  132. "x509_crl",
  133. "x509_req",
  134. "dsa",
  135. "rsa",
  136. "evp_pkey",
  137. "x509_store",
  138. "ssl_ctx",
  139. "ssl_cert",
  140. "ssl_session",
  141. "ssl_sess_cert",
  142. "ssl",
  143. "ssl_method",
  144. "rand",
  145. "rand2",
  146. "debug_malloc",
  147. "BIO",
  148. "gethostbyname",
  149. "getservbyname",
  150. "readdir",
  151. "RSA_blinding",
  152. "dh",
  153. "debug_malloc2",
  154. "dso",
  155. "dynlock",
  156. "engine",
  157. "ui",
  158. "ecdsa",
  159. "ec",
  160. "ecdh",
  161. "bn",
  162. "ec_pre_comp",
  163. "store",
  164. "comp",
  165. #if CRYPTO_NUM_LOCKS != 39
  166. # error "Inconsistency between crypto.h and cryptlib.c"
  167. #endif
  168. };
  169. /* This is for applications to allocate new type names in the non-dynamic
  170.    array of lock names.  These are numbered with positive numbers.  */
  171. static STACK *app_locks=NULL;
  172. /* For applications that want a more dynamic way of handling threads, the
  173.    following stack is used.  These are externally numbered with negative
  174.    numbers.  */
  175. static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
  176. static void (MS_FAR *locking_callback)(int mode,int type,
  177. const char *file,int line)=NULL;
  178. static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
  179. int type,const char *file,int line)=NULL;
  180. static unsigned long (MS_FAR *id_callback)(void)=NULL;
  181. static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
  182. (const char *file,int line)=NULL;
  183. static void (MS_FAR *dynlock_lock_callback)(int mode,
  184. struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
  185. static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
  186. const char *file,int line)=NULL;
  187. int CRYPTO_get_new_lockid(char *name)
  188. {
  189. char *str;
  190. int i;
  191. #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
  192. /* A hack to make Visual C++ 5.0 work correctly when linking as
  193.  * a DLL using /MT. Without this, the application cannot use
  194.  * and floating point printf's.
  195.  * It also seems to be needed for Visual C 1.5 (win16) */
  196. SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
  197. #endif
  198. if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
  199. {
  200. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
  201. return(0);
  202. }
  203. if ((str=BUF_strdup(name)) == NULL)
  204. {
  205. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
  206. return(0);
  207. }
  208. i=sk_push(app_locks,str);
  209. if (!i)
  210. OPENSSL_free(str);
  211. else
  212. i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
  213. return(i);
  214. }
  215. int CRYPTO_num_locks(void)
  216. {
  217. return CRYPTO_NUM_LOCKS;
  218. }
  219. int CRYPTO_get_new_dynlockid(void)
  220. {
  221. int i = 0;
  222. CRYPTO_dynlock *pointer = NULL;
  223. if (dynlock_create_callback == NULL)
  224. {
  225. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
  226. return(0);
  227. }
  228. CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
  229. if ((dyn_locks == NULL)
  230. && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
  231. {
  232. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  233. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
  234. return(0);
  235. }
  236. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  237. pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
  238. if (pointer == NULL)
  239. {
  240. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
  241. return(0);
  242. }
  243. pointer->references = 1;
  244. pointer->data = dynlock_create_callback(__FILE__,__LINE__);
  245. if (pointer->data == NULL)
  246. {
  247. OPENSSL_free(pointer);
  248. CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
  249. return(0);
  250. }
  251. CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
  252. /* First, try to find an existing empty slot */
  253. i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
  254. /* If there was none, push, thereby creating a new one */
  255. if (i == -1)
  256. /* Since sk_push() returns the number of items on the
  257.    stack, not the location of the pushed item, we need
  258.    to transform the returned number into a position,
  259.    by decreasing it.  */
  260. i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
  261. else
  262. /* If we found a place with a NULL pointer, put our pointer
  263.    in it.  */
  264. sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
  265. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  266. if (i == -1)
  267. {
  268. dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
  269. OPENSSL_free(pointer);
  270. }
  271. else
  272. i += 1; /* to avoid 0 */
  273. return -i;
  274. }
  275. void CRYPTO_destroy_dynlockid(int i)
  276. {
  277. CRYPTO_dynlock *pointer = NULL;
  278. if (i)
  279. i = -i-1;
  280. if (dynlock_destroy_callback == NULL)
  281. return;
  282. CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
  283. if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
  284. {
  285. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  286. return;
  287. }
  288. pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
  289. if (pointer != NULL)
  290. {
  291. --pointer->references;
  292. #ifdef REF_CHECK
  293. if (pointer->references < 0)
  294. {
  295. fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference countn");
  296. abort();
  297. }
  298. else
  299. #endif
  300. if (pointer->references <= 0)
  301. {
  302. sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
  303. }
  304. else
  305. pointer = NULL;
  306. }
  307. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  308. if (pointer)
  309. {
  310. dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
  311. OPENSSL_free(pointer);
  312. }
  313. }
  314. struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
  315. {
  316. CRYPTO_dynlock *pointer = NULL;
  317. if (i)
  318. i = -i-1;
  319. CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
  320. if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
  321. pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
  322. if (pointer)
  323. pointer->references++;
  324. CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
  325. if (pointer)
  326. return pointer->data;
  327. return NULL;
  328. }
  329. struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
  330. (const char *file,int line)
  331. {
  332. return(dynlock_create_callback);
  333. }
  334. void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
  335. struct CRYPTO_dynlock_value *l, const char *file,int line)
  336. {
  337. return(dynlock_lock_callback);
  338. }
  339. void (*CRYPTO_get_dynlock_destroy_callback(void))
  340. (struct CRYPTO_dynlock_value *l, const char *file,int line)
  341. {
  342. return(dynlock_destroy_callback);
  343. }
  344. void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
  345. (const char *file, int line))
  346. {
  347. dynlock_create_callback=func;
  348. }
  349. void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
  350. struct CRYPTO_dynlock_value *l, const char *file, int line))
  351. {
  352. dynlock_lock_callback=func;
  353. }
  354. void CRYPTO_set_dynlock_destroy_callback(void (*func)
  355. (struct CRYPTO_dynlock_value *l, const char *file, int line))
  356. {
  357. dynlock_destroy_callback=func;
  358. }
  359. void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
  360. int line)
  361. {
  362. return(locking_callback);
  363. }
  364. int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
  365.   const char *file,int line)
  366. {
  367. return(add_lock_callback);
  368. }
  369. void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
  370.       const char *file,int line))
  371. {
  372. locking_callback=func;
  373. }
  374. void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
  375.       const char *file,int line))
  376. {
  377. add_lock_callback=func;
  378. }
  379. unsigned long (*CRYPTO_get_id_callback(void))(void)
  380. {
  381. return(id_callback);
  382. }
  383. void CRYPTO_set_id_callback(unsigned long (*func)(void))
  384. {
  385. id_callback=func;
  386. }
  387. unsigned long CRYPTO_thread_id(void)
  388. {
  389. unsigned long ret=0;
  390. if (id_callback == NULL)
  391. {
  392. #ifdef OPENSSL_SYS_WIN16
  393. ret=(unsigned long)GetCurrentTask();
  394. #elif defined(OPENSSL_SYS_WIN32)
  395. ret=(unsigned long)GetCurrentThreadId();
  396. #elif defined(GETPID_IS_MEANINGLESS)
  397. ret=1L;
  398. #else
  399. ret=(unsigned long)getpid();
  400. #endif
  401. }
  402. else
  403. ret=id_callback();
  404. return(ret);
  405. }
  406. void CRYPTO_lock(int mode, int type, const char *file, int line)
  407. {
  408. #ifdef LOCK_DEBUG
  409. {
  410. char *rw_text,*operation_text;
  411. if (mode & CRYPTO_LOCK)
  412. operation_text="lock  ";
  413. else if (mode & CRYPTO_UNLOCK)
  414. operation_text="unlock";
  415. else
  416. operation_text="ERROR ";
  417. if (mode & CRYPTO_READ)
  418. rw_text="r";
  419. else if (mode & CRYPTO_WRITE)
  420. rw_text="w";
  421. else
  422. rw_text="ERROR";
  423. fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%dn",
  424. CRYPTO_thread_id(), rw_text, operation_text,
  425. CRYPTO_get_lock_name(type), file, line);
  426. }
  427. #endif
  428. if (type < 0)
  429. {
  430. if (dynlock_lock_callback != NULL)
  431. {
  432. struct CRYPTO_dynlock_value *pointer
  433. = CRYPTO_get_dynlock_value(type);
  434. OPENSSL_assert(pointer != NULL);
  435. dynlock_lock_callback(mode, pointer, file, line);
  436. CRYPTO_destroy_dynlockid(type);
  437. }
  438. }
  439. else
  440. if (locking_callback != NULL)
  441. locking_callback(mode,type,file,line);
  442. }
  443. int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
  444.      int line)
  445. {
  446. int ret = 0;
  447. if (add_lock_callback != NULL)
  448. {
  449. #ifdef LOCK_DEBUG
  450. int before= *pointer;
  451. #endif
  452. ret=add_lock_callback(pointer,amount,type,file,line);
  453. #ifdef LOCK_DEBUG
  454. fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%dn",
  455. CRYPTO_thread_id(),
  456. before,amount,ret,
  457. CRYPTO_get_lock_name(type),
  458. file,line);
  459. #endif
  460. }
  461. else
  462. {
  463. CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line);
  464. ret= *pointer+amount;
  465. #ifdef LOCK_DEBUG
  466. fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%dn",
  467. CRYPTO_thread_id(),
  468. *pointer,amount,ret,
  469. CRYPTO_get_lock_name(type),
  470. file,line);
  471. #endif
  472. *pointer=ret;
  473. CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
  474. }
  475. return(ret);
  476. }
  477. const char *CRYPTO_get_lock_name(int type)
  478. {
  479. if (type < 0)
  480. return("dynamic");
  481. else if (type < CRYPTO_NUM_LOCKS)
  482. return(lock_names[type]);
  483. else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks))
  484. return("ERROR");
  485. else
  486. return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS));
  487. }
  488. #if defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || 
  489. defined(__INTEL__) || 
  490. defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64)
  491. unsigned long  OPENSSL_ia32cap_P=0;
  492. unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; }
  493. #if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
  494. #define OPENSSL_CPUID_SETUP
  495. void OPENSSL_cpuid_setup(void)
  496. { static int trigger=0;
  497.   unsigned long OPENSSL_ia32_cpuid(void);
  498.   char *env;
  499.     if (trigger) return;
  500.     trigger=1;
  501.     if ((env=getenv("OPENSSL_ia32cap")))
  502. OPENSSL_ia32cap_P = strtoul(env,NULL,0)|(1<<10);
  503.     else
  504. OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid()|(1<<10);
  505.     /*
  506.      * |(1<<10) sets a reserved bit to signal that variable
  507.      * was initialized already... This is to avoid interference
  508.      * with cpuid snippets in ELF .init segment.
  509.      */
  510. }
  511. #endif
  512. #else
  513. unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; }
  514. #endif
  515. int OPENSSL_NONPIC_relocated = 0;
  516. #if !defined(OPENSSL_CPUID_SETUP)
  517. void OPENSSL_cpuid_setup(void) {}
  518. #endif
  519. #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
  520. #ifdef __CYGWIN__
  521. /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
  522. #include <windows.h>
  523. #endif
  524. /* All we really need to do is remove the 'error' state when a thread
  525.  * detaches */
  526. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
  527.      LPVOID lpvReserved)
  528. {
  529. switch(fdwReason)
  530. {
  531. case DLL_PROCESS_ATTACH:
  532. OPENSSL_cpuid_setup();
  533. #if defined(_WIN32_WINNT)
  534. {
  535. IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *)hinstDLL;
  536. IMAGE_NT_HEADERS *nt_headers;
  537. if (dos_header->e_magic==IMAGE_DOS_SIGNATURE)
  538. {
  539. nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header
  540. + dos_header->e_lfanew);
  541. if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
  542.     hinstDLL!=(HINSTANCE)(nt_headers->OptionalHeader.ImageBase))
  543. OPENSSL_NONPIC_relocated=1;
  544. }
  545. }
  546. #endif
  547. break;
  548. case DLL_THREAD_ATTACH:
  549. break;
  550. case DLL_THREAD_DETACH:
  551. ERR_remove_state(0);
  552. break;
  553. case DLL_PROCESS_DETACH:
  554. break;
  555. }
  556. return(TRUE);
  557. }
  558. #endif
  559. #if defined(_WIN32) && !defined(__CYGWIN__)
  560. #include <tchar.h>
  561. #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
  562. int OPENSSL_isservice(void)
  563. { HWINSTA h;
  564.   DWORD len;
  565.   WCHAR *name;
  566.     (void)GetDesktopWindow(); /* return value is ignored */
  567.     h = GetProcessWindowStation();
  568.     if (h==NULL) return -1;
  569.     if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) ||
  570. GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  571. return -1;
  572.     if (len>512) return -1; /* paranoia */
  573.     len++,len&=~1; /* paranoia */
  574. #ifdef _MSC_VER
  575.     name=(WCHAR *)_alloca(len+sizeof(WCHAR));
  576. #else
  577.     name=(WCHAR *)alloca(len+sizeof(WCHAR));
  578. #endif
  579.     if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len))
  580. return -1;
  581.     len++,len&=~1; /* paranoia */
  582.     name[len/sizeof(WCHAR)]=L''; /* paranoia */
  583. #if 1
  584.     /* This doesn't cover "interactive" services [working with real
  585.      * WinSta0's] nor programs started non-interactively by Task
  586.      * Scheduler [those are working with SAWinSta]. */
  587.     if (wcsstr(name,L"Service-0x")) return 1;
  588. #else
  589.     /* This covers all non-interactive programs such as services. */
  590.     if (!wcsstr(name,L"WinSta0")) return 1;
  591. #endif
  592.     else return 0;
  593. }
  594. #else
  595. int OPENSSL_isservice(void) { return 0; }
  596. #endif
  597. void OPENSSL_showfatal (const char *fmta,...)
  598. { va_list ap;
  599.   TCHAR buf[256];
  600.   const TCHAR *fmt;
  601. #ifdef STD_ERROR_HANDLE /* what a dirty trick! */
  602.   HANDLE h;
  603.     if ((h=GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
  604. GetFileType(h)!=FILE_TYPE_UNKNOWN)
  605.     { /* must be console application */
  606. va_start (ap,fmta);
  607. vfprintf (stderr,fmta,ap);
  608. va_end (ap);
  609. return;
  610.     }
  611. #endif
  612.     if (sizeof(TCHAR)==sizeof(char))
  613. fmt=(const TCHAR *)fmta;
  614.     else do
  615.     { int    keepgoing;
  616.       size_t len_0=strlen(fmta)+1,i;
  617.       WCHAR *fmtw;
  618. #ifdef _MSC_VER
  619. fmtw = (WCHAR *)_alloca (len_0*sizeof(WCHAR));
  620. #else
  621. fmtw = (WCHAR *)alloca (len_0*sizeof(WCHAR));
  622. #endif
  623. if (fmtw == NULL) { fmt=(const TCHAR *)L"no stack?"; break; }
  624. #ifndef OPENSSL_NO_MULTIBYTE
  625. if (!MultiByteToWideChar(CP_ACP,0,fmta,len_0,fmtw,len_0))
  626. #endif
  627.     for (i=0;i<len_0;i++) fmtw[i]=(WCHAR)fmta[i];
  628. for (i=0;i<len_0;i++)
  629. {   if (fmtw[i]==L'%') do
  630.     { keepgoing=0;
  631. switch (fmtw[i+1])
  632. {   case L'0': case L'1': case L'2': case L'3': case L'4':
  633.     case L'5': case L'6': case L'7': case L'8': case L'9':
  634.     case L'.': case L'*':
  635.     case L'-': i++; keepgoing=1; break;
  636.     case L's': fmtw[i+1]=L'S';   break;
  637.     case L'S': fmtw[i+1]=L's';   break;
  638.     case L'c': fmtw[i+1]=L'C';   break;
  639.     case L'C': fmtw[i+1]=L'c';   break;
  640. }
  641.     } while (keepgoing);
  642. }
  643. fmt = (const TCHAR *)fmtw;
  644.     } while (0);
  645.     va_start (ap,fmta);
  646.     _vsntprintf (buf,sizeof(buf)/sizeof(TCHAR)-1,fmt,ap);
  647.     buf [sizeof(buf)/sizeof(TCHAR)-1] = _T('');
  648.     va_end (ap);
  649. #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
  650.     /* this -------------v--- guards NT-specific calls */
  651.     if (GetVersion() < 0x80000000 && OPENSSL_isservice())
  652.     { HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
  653. const TCHAR *pmsg=buf;
  654. ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
  655. DeregisterEventSource(h);
  656.     }
  657.     else
  658. #endif
  659. MessageBox (NULL,buf,_T("OpenSSL: FATAL"),MB_OK|MB_ICONSTOP);
  660. }
  661. #else
  662. void OPENSSL_showfatal (const char *fmta,...)
  663. { va_list ap;
  664.     va_start (ap,fmta);
  665.     vfprintf (stderr,fmta,ap);
  666.     va_end (ap);
  667. }
  668. int OPENSSL_isservice (void) { return 0; }
  669. #endif
  670. void OpenSSLDie(const char *file,int line,const char *assertion)
  671. {
  672. OPENSSL_showfatal(
  673. "%s(%d): OpenSSL internal error, assertion failed: %sn",
  674. file,line,assertion);
  675. abort();
  676. }
  677. void *OPENSSL_stderr(void) { return stderr; }