os/ossrv/ssl/libcrypto/src/crypto/cryptlib.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/cryptlib.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,834 @@
     1.4 +/* crypto/cryptlib.c */
     1.5 +/* ====================================================================
     1.6 + * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
     1.7 + *
     1.8 + * Redistribution and use in source and binary forms, with or without
     1.9 + * modification, are permitted provided that the following conditions
    1.10 + * are met:
    1.11 + *
    1.12 + * 1. Redistributions of source code must retain the above copyright
    1.13 + *    notice, this list of conditions and the following disclaimer. 
    1.14 + *
    1.15 + * 2. Redistributions in binary form must reproduce the above copyright
    1.16 + *    notice, this list of conditions and the following disclaimer in
    1.17 + *    the documentation and/or other materials provided with the
    1.18 + *    distribution.
    1.19 + *
    1.20 + * 3. All advertising materials mentioning features or use of this
    1.21 + *    software must display the following acknowledgment:
    1.22 + *    "This product includes software developed by the OpenSSL Project
    1.23 + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
    1.24 + *
    1.25 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
    1.26 + *    endorse or promote products derived from this software without
    1.27 + *    prior written permission. For written permission, please contact
    1.28 + *    openssl-core@openssl.org.
    1.29 + *
    1.30 + * 5. Products derived from this software may not be called "OpenSSL"
    1.31 + *    nor may "OpenSSL" appear in their names without prior written
    1.32 + *    permission of the OpenSSL Project.
    1.33 + *
    1.34 + * 6. Redistributions of any form whatsoever must retain the following
    1.35 + *    acknowledgment:
    1.36 + *    "This product includes software developed by the OpenSSL Project
    1.37 + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
    1.38 + *
    1.39 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
    1.40 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.41 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    1.42 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
    1.43 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.44 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    1.45 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    1.46 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.47 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    1.48 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.49 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    1.50 + * OF THE POSSIBILITY OF SUCH DAMAGE.
    1.51 + * ====================================================================
    1.52 + *
    1.53 + * This product includes cryptographic software written by Eric Young
    1.54 + * (eay@cryptsoft.com).  This product includes software written by Tim
    1.55 + * Hudson (tjh@cryptsoft.com).
    1.56 + *
    1.57 + */
    1.58 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
    1.59 + * All rights reserved.
    1.60 + *
    1.61 + * This package is an SSL implementation written
    1.62 + * by Eric Young (eay@cryptsoft.com).
    1.63 + * The implementation was written so as to conform with Netscapes SSL.
    1.64 + * 
    1.65 + * This library is free for commercial and non-commercial use as long as
    1.66 + * the following conditions are aheared to.  The following conditions
    1.67 + * apply to all code found in this distribution, be it the RC4, RSA,
    1.68 + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
    1.69 + * included with this distribution is covered by the same copyright terms
    1.70 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
    1.71 + * 
    1.72 + * Copyright remains Eric Young's, and as such any Copyright notices in
    1.73 + * the code are not to be removed.
    1.74 + * If this package is used in a product, Eric Young should be given attribution
    1.75 + * as the author of the parts of the library used.
    1.76 + * This can be in the form of a textual message at program startup or
    1.77 + * in documentation (online or textual) provided with the package.
    1.78 + * 
    1.79 + * Redistribution and use in source and binary forms, with or without
    1.80 + * modification, are permitted provided that the following conditions
    1.81 + * are met:
    1.82 + * 1. Redistributions of source code must retain the copyright
    1.83 + *    notice, this list of conditions and the following disclaimer.
    1.84 + * 2. Redistributions in binary form must reproduce the above copyright
    1.85 + *    notice, this list of conditions and the following disclaimer in the
    1.86 + *    documentation and/or other materials provided with the distribution.
    1.87 + * 3. All advertising materials mentioning features or use of this software
    1.88 + *    must display the following acknowledgement:
    1.89 + *    "This product includes cryptographic software written by
    1.90 + *     Eric Young (eay@cryptsoft.com)"
    1.91 + *    The word 'cryptographic' can be left out if the rouines from the library
    1.92 + *    being used are not cryptographic related :-).
    1.93 + * 4. If you include any Windows specific code (or a derivative thereof) from 
    1.94 + *    the apps directory (application code) you must include an acknowledgement:
    1.95 + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
    1.96 + * 
    1.97 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
    1.98 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.99 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   1.100 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   1.101 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   1.102 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   1.103 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   1.104 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   1.105 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   1.106 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   1.107 + * SUCH DAMAGE.
   1.108 + * 
   1.109 + * The licence and distribution terms for any publically available version or
   1.110 + * derivative of this code cannot be changed.  i.e. this code cannot simply be
   1.111 + * copied and put under another distribution licence
   1.112 + * [including the GNU Public Licence.]
   1.113 + */
   1.114 +/* ====================================================================
   1.115 + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
   1.116 + * ECDH support in OpenSSL originally developed by 
   1.117 + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
   1.118 + */
   1.119 + /*
   1.120 + © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
   1.121 + */
   1.122 +
   1.123 +#include "cryptlib.h"
   1.124 +#include <openssl/safestack.h>
   1.125 +
   1.126 +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
   1.127 +static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
   1.128 +#endif
   1.129 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
   1.130 +#include "libcrypto_wsd_macros.h"
   1.131 +#include "libcrypto_wsd.h"
   1.132 +#endif
   1.133 +
   1.134 +DECLARE_STACK_OF(CRYPTO_dynlock)
   1.135 +IMPLEMENT_STACK_OF(CRYPTO_dynlock)
   1.136 +
   1.137 +/* real #defines in crypto.h, keep these upto date */
   1.138 +#ifndef EMULATOR
   1.139 +static const char* lock_names[CRYPTO_NUM_LOCKS] =
   1.140 +	{
   1.141 +	"<<ERROR>>",
   1.142 +	"err",
   1.143 +	"ex_data",
   1.144 +	"x509",
   1.145 +	"x509_info",
   1.146 +	"x509_pkey",
   1.147 +	"x509_crl",
   1.148 +	"x509_req",
   1.149 +	"dsa",
   1.150 +	"rsa",
   1.151 +	"evp_pkey",
   1.152 +	"x509_store",
   1.153 +	"ssl_ctx",
   1.154 +	"ssl_cert",
   1.155 +	"ssl_session",
   1.156 +	"ssl_sess_cert",
   1.157 +	"ssl",
   1.158 +	"ssl_method",
   1.159 +	"rand",
   1.160 +	"rand2",
   1.161 +	"debug_malloc",
   1.162 +	"BIO",
   1.163 +	"gethostbyname",
   1.164 +	"getservbyname",
   1.165 +	"readdir",
   1.166 +	"RSA_blinding",
   1.167 +	"dh",
   1.168 +	"debug_malloc2",
   1.169 +	"dso",
   1.170 +	"dynlock",
   1.171 +	"engine",
   1.172 +	"ui",
   1.173 +	"ecdsa",
   1.174 +	"ec",
   1.175 +	"ecdh",
   1.176 +	"bn",
   1.177 +	"ec_pre_comp",
   1.178 +	"store",
   1.179 +	"comp",
   1.180 +#if CRYPTO_NUM_LOCKS != 39
   1.181 +# error "Inconsistency between crypto.h and cryptlib.c"
   1.182 +#endif
   1.183 +	};
   1.184 +#else
   1.185 +
   1.186 +static const char *const lock_names[CRYPTO_NUM_LOCKS] =
   1.187 +	{
   1.188 +	"<<ERROR>>",
   1.189 +	"err",
   1.190 +	"ex_data",
   1.191 +	"x509",
   1.192 +	"x509_info",
   1.193 +	"x509_pkey",
   1.194 +	"x509_crl",
   1.195 +	"x509_req",
   1.196 +	"dsa",
   1.197 +	"rsa",
   1.198 +	"evp_pkey",
   1.199 +	"x509_store",
   1.200 +	"ssl_ctx",
   1.201 +	"ssl_cert",
   1.202 +	"ssl_session",
   1.203 +	"ssl_sess_cert",
   1.204 +	"ssl",
   1.205 +	"ssl_method",
   1.206 +	"rand",
   1.207 +	"rand2",
   1.208 +	"debug_malloc",
   1.209 +	"BIO",
   1.210 +	"gethostbyname",
   1.211 +	"getservbyname",
   1.212 +	"readdir",
   1.213 +	"RSA_blinding",
   1.214 +	"dh",
   1.215 +	"debug_malloc2",
   1.216 +	"dso",
   1.217 +	"dynlock",
   1.218 +	"engine",
   1.219 +	"ui",
   1.220 +	"ecdsa",
   1.221 +	"ec",
   1.222 +	"ecdh",
   1.223 +	"bn",
   1.224 +	"ec_pre_comp",
   1.225 +	"store",
   1.226 +	"comp",
   1.227 +#if CRYPTO_NUM_LOCKS != 39
   1.228 +# error "Inconsistency between crypto.h and cryptlib.c"
   1.229 +#endif
   1.230 +	};
   1.231 +#endif //EMULATOR
   1.232 +
   1.233 +#ifndef EMULATOR
   1.234 +/* This is for applications to allocate new type names in the non-dynamic
   1.235 +   array of lock names.  These are numbered with positive numbers.  */
   1.236 +static STACK *app_locks=NULL;
   1.237 +/* For applications that want a more dynamic way of handling threads, the
   1.238 +   following stack is used.  These are externally numbered with negative
   1.239 +   numbers.  */
   1.240 +static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
   1.241 +
   1.242 +#else
   1.243 + GET_STATIC_VAR_FROM_TLS(app_locks,cryptlib,STACK *)
   1.244 + #define app_locks (*GET_WSD_VAR_NAME(app_locks,cryptlib,s)())
   1.245 + GET_STATIC_VAR_FROM_TLS(dyn_locks,cryptlib,STACK_OF(CRYPTO_dynlock)*)
   1.246 + #define dyn_locks (*GET_WSD_VAR_NAME(dyn_locks,cryptlib,s)())
   1.247 +#endif
   1.248 +
   1.249 +#ifndef EMULATOR
   1.250 +static void (MS_FAR *locking_callback)(int mode,int type,
   1.251 +	const char *file,int line)=NULL;
   1.252 +static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
   1.253 +	int type,const char *file,int line)=NULL;
   1.254 +static unsigned long (MS_FAR *id_callback)(void)=NULL;
   1.255 +static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
   1.256 +	(const char *file,int line)=NULL;
   1.257 +static void (MS_FAR *dynlock_lock_callback)(int mode,
   1.258 +	struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
   1.259 +static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
   1.260 +	const char *file,int line)=NULL;
   1.261 +#else
   1.262 +#define locking_callback libcrypto_ImpurePtr()->locking_callback
   1.263 +#define add_lock_callback libcrypto_ImpurePtr()->add_lock_callback
   1.264 +#define id_callback libcrypto_ImpurePtr()->id_callback
   1.265 +#define dynlock_create_callback libcrypto_ImpurePtr()->dynlock_create_callback
   1.266 +#define dynlock_lock_callback libcrypto_ImpurePtr()->dynlock_lock_callback
   1.267 +#define dynlock_destroy_callback libcrypto_ImpurePtr()->dynlock_destroy_callback
   1.268 +#endif	
   1.269 +
   1.270 +EXPORT_C int CRYPTO_get_new_lockid(char *name)
   1.271 +	{
   1.272 +	char *str;
   1.273 +	int i;
   1.274 +
   1.275 +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
   1.276 +	/* A hack to make Visual C++ 5.0 work correctly when linking as
   1.277 +	 * a DLL using /MT. Without this, the application cannot use
   1.278 +	 * and floating point printf's.
   1.279 +	 * It also seems to be needed for Visual C 1.5 (win16) */
   1.280 +	SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
   1.281 +#endif
   1.282 +
   1.283 +	if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
   1.284 +		{
   1.285 +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
   1.286 +		return(0);
   1.287 +		}
   1.288 +	if ((str=BUF_strdup(name)) == NULL)
   1.289 +		{
   1.290 +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
   1.291 +		return(0);
   1.292 +		}
   1.293 +	i=sk_push(app_locks,str);
   1.294 +	if (!i)
   1.295 +		OPENSSL_free(str);
   1.296 +	else
   1.297 +		i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
   1.298 +	return(i);
   1.299 +	}
   1.300 +
   1.301 +EXPORT_C int CRYPTO_num_locks(void)
   1.302 +	{
   1.303 +	return CRYPTO_NUM_LOCKS;
   1.304 +	}
   1.305 +
   1.306 +EXPORT_C int CRYPTO_get_new_dynlockid(void)
   1.307 +	{
   1.308 +	int i = 0;
   1.309 +	CRYPTO_dynlock *pointer = NULL;
   1.310 +
   1.311 +	if (dynlock_create_callback == NULL)
   1.312 +		{
   1.313 +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
   1.314 +		return(0);
   1.315 +		}
   1.316 +	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
   1.317 +	if ((dyn_locks == NULL)&&((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
   1.318 +		{
   1.319 +		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
   1.320 +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
   1.321 +		return(0);
   1.322 +		}
   1.323 +	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
   1.324 +
   1.325 +	pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
   1.326 +	if (pointer == NULL)
   1.327 +		{
   1.328 +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
   1.329 +		return(0);
   1.330 +		}
   1.331 +	pointer->references = 1;
   1.332 +	pointer->data = dynlock_create_callback(__FILE__,__LINE__);
   1.333 +	if (pointer->data == NULL)
   1.334 +		{
   1.335 +		OPENSSL_free(pointer);
   1.336 +		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
   1.337 +		return(0);
   1.338 +		}
   1.339 +
   1.340 +	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
   1.341 +	/* First, try to find an existing empty slot */
   1.342 +	i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
   1.343 +	/* If there was none, push, thereby creating a new one */
   1.344 +	if (i == -1)
   1.345 +		/* Since sk_push() returns the number of items on the
   1.346 +		   stack, not the location of the pushed item, we need
   1.347 +		   to transform the returned number into a position,
   1.348 +		   by decreasing it.  */
   1.349 +		i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
   1.350 +	else
   1.351 +		/* If we found a place with a NULL pointer, put our pointer
   1.352 +		   in it.  */
   1.353 +		(void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
   1.354 +	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
   1.355 +
   1.356 +	if (i == -1)
   1.357 +		{
   1.358 +		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
   1.359 +		OPENSSL_free(pointer);
   1.360 +		}
   1.361 +	else
   1.362 +		i += 1; /* to avoid 0 */
   1.363 +	return -i;
   1.364 +	}
   1.365 +
   1.366 +EXPORT_C void CRYPTO_destroy_dynlockid(int i)
   1.367 +	{
   1.368 +	CRYPTO_dynlock *pointer = NULL;
   1.369 +	if (i)
   1.370 +		i = -i-1;
   1.371 +	if (dynlock_destroy_callback == NULL)
   1.372 +		return;
   1.373 +
   1.374 +	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
   1.375 +
   1.376 +	if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
   1.377 +		{
   1.378 +		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
   1.379 +		return;
   1.380 +		}
   1.381 +	pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
   1.382 +	if (pointer != NULL)
   1.383 +		{
   1.384 +		--pointer->references;
   1.385 +#ifdef REF_CHECK
   1.386 +		if (pointer->references < 0)
   1.387 +			{
   1.388 +			fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
   1.389 +			abort();
   1.390 +			}
   1.391 +		else
   1.392 +#endif
   1.393 +			if (pointer->references <= 0)
   1.394 +				{
   1.395 +				(void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
   1.396 +				}
   1.397 +			else
   1.398 +				pointer = NULL;
   1.399 +		}
   1.400 +	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
   1.401 +
   1.402 +	if (pointer)
   1.403 +		{
   1.404 +		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
   1.405 +		OPENSSL_free(pointer);
   1.406 +		}
   1.407 +	}
   1.408 +
   1.409 +EXPORT_C struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
   1.410 +	{
   1.411 +	CRYPTO_dynlock *pointer = NULL;
   1.412 +	if (i)
   1.413 +		i = -i-1;
   1.414 +
   1.415 +	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
   1.416 +
   1.417 +	if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
   1.418 +		pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
   1.419 +	if (pointer)
   1.420 +		pointer->references++;
   1.421 +
   1.422 +	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
   1.423 +
   1.424 +	if (pointer)
   1.425 +		return pointer->data;
   1.426 +	return NULL;
   1.427 +	}
   1.428 +
   1.429 +EXPORT_C struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
   1.430 +	(const char *file,int line)
   1.431 +	{
   1.432 +	return(dynlock_create_callback);
   1.433 +	}
   1.434 +
   1.435 +EXPORT_C void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
   1.436 +	struct CRYPTO_dynlock_value *l, const char *file,int line)
   1.437 +	{
   1.438 +	return(dynlock_lock_callback);
   1.439 +	}
   1.440 +
   1.441 +EXPORT_C void (*CRYPTO_get_dynlock_destroy_callback(void))
   1.442 +	(struct CRYPTO_dynlock_value *l, const char *file,int line)
   1.443 +	{
   1.444 +	return(dynlock_destroy_callback);
   1.445 +	}
   1.446 +
   1.447 +EXPORT_C void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
   1.448 +	(const char *file, int line))
   1.449 +	{
   1.450 +	dynlock_create_callback=func;
   1.451 +	}
   1.452 +
   1.453 +EXPORT_C void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
   1.454 +	struct CRYPTO_dynlock_value *l, const char *file, int line))
   1.455 +	{
   1.456 +	dynlock_lock_callback=func;
   1.457 +	}
   1.458 +
   1.459 +EXPORT_C void CRYPTO_set_dynlock_destroy_callback(void (*func)
   1.460 +	(struct CRYPTO_dynlock_value *l, const char *file, int line))
   1.461 +	{
   1.462 +	dynlock_destroy_callback=func;
   1.463 +	}
   1.464 +
   1.465 +
   1.466 +EXPORT_C void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
   1.467 +		int line)
   1.468 +	{
   1.469 +	return(locking_callback);
   1.470 +	}
   1.471 +
   1.472 +EXPORT_C int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
   1.473 +					  const char *file,int line)
   1.474 +	{
   1.475 +	return(add_lock_callback);
   1.476 +	}
   1.477 +
   1.478 +EXPORT_C void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
   1.479 +					      const char *file,int line))
   1.480 +	{
   1.481 +	locking_callback=func;
   1.482 +	}
   1.483 +
   1.484 +EXPORT_C void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
   1.485 +					      const char *file,int line))
   1.486 +	{
   1.487 +	add_lock_callback=func;
   1.488 +	}
   1.489 +
   1.490 +EXPORT_C unsigned long (*CRYPTO_get_id_callback(void))(void)
   1.491 +	{
   1.492 +	return(id_callback);
   1.493 +	}
   1.494 +
   1.495 +EXPORT_C void CRYPTO_set_id_callback(unsigned long (*func)(void))
   1.496 +	{
   1.497 +	id_callback=func;
   1.498 +	}
   1.499 +
   1.500 +EXPORT_C unsigned long CRYPTO_thread_id(void)
   1.501 +	{
   1.502 +	unsigned long ret=0;
   1.503 +
   1.504 +	if (id_callback == NULL)
   1.505 +		{
   1.506 +#ifdef OPENSSL_SYS_WIN16
   1.507 +		ret=(unsigned long)GetCurrentTask();
   1.508 +#elif defined(OPENSSL_SYS_WIN32)
   1.509 +		ret=(unsigned long)GetCurrentThreadId();
   1.510 +#elif defined(GETPID_IS_MEANINGLESS)
   1.511 +		ret=1L;
   1.512 +#else
   1.513 +		//ret=(unsigned long)getpid();
   1.514 +		//ret=(unsigned long)getpid(;
   1.515 +#endif
   1.516 +		}
   1.517 +	else
   1.518 +		ret=id_callback();
   1.519 +	return(ret);
   1.520 +	}
   1.521 +
   1.522 +EXPORT_C void CRYPTO_lock(int mode, int type, const char *file, int line)
   1.523 +	{
   1.524 +#ifdef LOCK_DEBUG
   1.525 +		{
   1.526 +		char *rw_text,*operation_text;
   1.527 +
   1.528 +		if (mode & CRYPTO_LOCK)
   1.529 +			operation_text="lock  ";
   1.530 +		else if (mode & CRYPTO_UNLOCK)
   1.531 +			operation_text="unlock";
   1.532 +		else
   1.533 +			operation_text="ERROR ";
   1.534 +
   1.535 +		if (mode & CRYPTO_READ)
   1.536 +			rw_text="r";
   1.537 +		else if (mode & CRYPTO_WRITE)
   1.538 +			rw_text="w";
   1.539 +		else
   1.540 +			rw_text="ERROR";
   1.541 +
   1.542 +		fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
   1.543 +			CRYPTO_thread_id(), rw_text, operation_text,
   1.544 +			CRYPTO_get_lock_name(type), file, line);
   1.545 +		}
   1.546 +#endif
   1.547 +	if (type < 0)
   1.548 +		{
   1.549 +		if (dynlock_lock_callback != NULL)
   1.550 +			{
   1.551 +			struct CRYPTO_dynlock_value *pointer
   1.552 +				= CRYPTO_get_dynlock_value(type);
   1.553 +
   1.554 +			OPENSSL_assert(pointer != NULL);
   1.555 +
   1.556 +			dynlock_lock_callback(mode, pointer, file, line);
   1.557 +
   1.558 +			CRYPTO_destroy_dynlockid(type);
   1.559 +			}
   1.560 +		}
   1.561 +	else
   1.562 +		if (locking_callback != NULL)
   1.563 +			locking_callback(mode,type,file,line);
   1.564 +	}
   1.565 +
   1.566 +EXPORT_C int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
   1.567 +	     int line)
   1.568 +	{
   1.569 +	int ret = 0;
   1.570 +
   1.571 +	if (add_lock_callback != NULL)
   1.572 +		{
   1.573 +#ifdef LOCK_DEBUG
   1.574 +		int before= *pointer;
   1.575 +#endif
   1.576 +
   1.577 +		ret=add_lock_callback(pointer,amount,type,file,line);
   1.578 +#ifdef LOCK_DEBUG
   1.579 +		fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
   1.580 +			CRYPTO_thread_id(),
   1.581 +			before,amount,ret,
   1.582 +			CRYPTO_get_lock_name(type),
   1.583 +			file,line);
   1.584 +#endif
   1.585 +		}
   1.586 +	else
   1.587 +		{
   1.588 +		CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line);
   1.589 +
   1.590 +		ret= *pointer+amount;
   1.591 +#ifdef LOCK_DEBUG
   1.592 +		fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
   1.593 +			CRYPTO_thread_id(),
   1.594 +			*pointer,amount,ret,
   1.595 +			CRYPTO_get_lock_name(type),
   1.596 +			file,line);
   1.597 +#endif
   1.598 +		*pointer=ret;
   1.599 +		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
   1.600 +		}
   1.601 +	return(ret);
   1.602 +	}
   1.603 +
   1.604 +EXPORT_C const char *CRYPTO_get_lock_name(int type)
   1.605 +	{
   1.606 +	if (type < 0)
   1.607 +		return("dynamic");
   1.608 +	else if (type < CRYPTO_NUM_LOCKS)
   1.609 +		return(lock_names[type]);
   1.610 +	else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks))
   1.611 +		return("ERROR");
   1.612 +	else
   1.613 +		return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS));
   1.614 +	}
   1.615 +
   1.616 +#if	defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
   1.617 +	defined(__INTEL__) || \
   1.618 +	defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64)
   1.619 +
   1.620 +unsigned long  OPENSSL_ia32cap_P=0;
   1.621 +EXPORT_C unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; }
   1.622 +
   1.623 +#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
   1.624 +#define OPENSSL_CPUID_SETUP
   1.625 +EXPORT_C void OPENSSL_cpuid_setup(void)
   1.626 +{ static int trigger=0;
   1.627 +  unsigned long OPENSSL_ia32_cpuid(void);
   1.628 +  char *env;
   1.629 +
   1.630 +    if (trigger)	return;
   1.631 +
   1.632 +    trigger=1;
   1.633 +    if ((env=getenv("OPENSSL_ia32cap")))
   1.634 +	OPENSSL_ia32cap_P = strtoul(env,NULL,0)|(1<<10);
   1.635 +    else
   1.636 +	OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid()|(1<<10);
   1.637 +    /*
   1.638 +     * |(1<<10) sets a reserved bit to signal that variable
   1.639 +     * was initialized already... This is to avoid interference
   1.640 +     * with cpuid snippets in ELF .init segment.
   1.641 +     */
   1.642 +}
   1.643 +#endif
   1.644 +
   1.645 +#else
   1.646 +EXPORT_C unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; }
   1.647 +#endif
   1.648 +int OPENSSL_NONPIC_relocated = 0;
   1.649 +#if !defined(OPENSSL_CPUID_SETUP)
   1.650 +EXPORT_C void OPENSSL_cpuid_setup(void) {}
   1.651 +#endif
   1.652 +
   1.653 +#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
   1.654 +#ifdef __CYGWIN__
   1.655 +/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
   1.656 +#include <windows.h>
   1.657 +#endif
   1.658 +
   1.659 +/* All we really need to do is remove the 'error' state when a thread
   1.660 + * detaches */
   1.661 +
   1.662 +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
   1.663 +	     LPVOID lpvReserved)
   1.664 +	{
   1.665 +	switch(fdwReason)
   1.666 +		{
   1.667 +	case DLL_PROCESS_ATTACH:
   1.668 +		OPENSSL_cpuid_setup();
   1.669 +#if defined(_WIN32_WINNT)
   1.670 +		{
   1.671 +		IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *)hinstDLL;
   1.672 +		IMAGE_NT_HEADERS *nt_headers;
   1.673 +
   1.674 +		if (dos_header->e_magic==IMAGE_DOS_SIGNATURE)
   1.675 +			{
   1.676 +			nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header
   1.677 +						+ dos_header->e_lfanew);
   1.678 +			if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
   1.679 +			    hinstDLL!=(HINSTANCE)(nt_headers->OptionalHeader.ImageBase))
   1.680 +				OPENSSL_NONPIC_relocated=1;
   1.681 +			}
   1.682 +		}
   1.683 +#endif
   1.684 +		break;
   1.685 +	case DLL_THREAD_ATTACH:
   1.686 +		break;
   1.687 +	case DLL_THREAD_DETACH:
   1.688 +		ERR_remove_state(0);
   1.689 +		break;
   1.690 +	case DLL_PROCESS_DETACH:
   1.691 +		break;
   1.692 +		}
   1.693 +	return(TRUE);
   1.694 +	}
   1.695 +#endif
   1.696 +
   1.697 +#if defined(_WIN32) && !defined(__CYGWIN__)&& !defined(SYMBIAN)
   1.698 +#include <tchar.h>
   1.699 +
   1.700 +#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
   1.701 +EXPORT_C int OPENSSL_isservice(void)
   1.702 +{ HWINSTA h;
   1.703 +  DWORD len;
   1.704 +  WCHAR *name;
   1.705 +
   1.706 +    (void)GetDesktopWindow(); /* return value is ignored */
   1.707 +
   1.708 +    h = GetProcessWindowStation();
   1.709 +    if (h==NULL) return -1;
   1.710 +
   1.711 +    if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) ||
   1.712 +	GetLastError() != ERROR_INSUFFICIENT_BUFFER)
   1.713 +	return -1;
   1.714 +
   1.715 +    if (len>512) return -1;		/* paranoia */
   1.716 +    len++,len&=~1;			/* paranoia */
   1.717 +#ifdef _MSC_VER
   1.718 +    name=(WCHAR *)_alloca(len+sizeof(WCHAR));
   1.719 +#else
   1.720 +    name=(WCHAR *)alloca(len+sizeof(WCHAR));
   1.721 +#endif
   1.722 +    if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len))
   1.723 +	return -1;
   1.724 +
   1.725 +    len++,len&=~1;			/* paranoia */
   1.726 +    name[len/sizeof(WCHAR)]=L'\0';	/* paranoia */
   1.727 +#if 1
   1.728 +    /* This doesn't cover "interactive" services [working with real
   1.729 +     * WinSta0's] nor programs started non-interactively by Task
   1.730 +     * Scheduler [those are working with SAWinSta]. */
   1.731 +    if (wcsstr(name,L"Service-0x"))	return 1;
   1.732 +#else
   1.733 +    /* This covers all non-interactive programs such as services. */
   1.734 +    if (!wcsstr(name,L"WinSta0"))	return 1;
   1.735 +#endif
   1.736 +    else				return 0;
   1.737 +}
   1.738 +#else
   1.739 +EXPORT_C int OPENSSL_isservice(void) { return 0; }
   1.740 +#endif
   1.741 +
   1.742 +EXPORT_C void OPENSSL_showfatal (const char *fmta,...)
   1.743 +{ va_list ap;
   1.744 +#ifndef SYMBIAN	
   1.745 +  TCHAR buf[256];
   1.746 +#else
   1.747 +  TCHAR buf[100];
   1.748 +#endif  
   1.749 +  const TCHAR *fmt;
   1.750 +#ifdef STD_ERROR_HANDLE	/* what a dirty trick! */
   1.751 +  HANDLE h;
   1.752 +
   1.753 +    if ((h=GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
   1.754 +	GetFileType(h)!=FILE_TYPE_UNKNOWN)
   1.755 +    {	/* must be console application */
   1.756 +	va_start (ap,fmta);
   1.757 +	vfprintf (stderr,fmta,ap);
   1.758 +	va_end (ap);
   1.759 +	return;
   1.760 +    }
   1.761 +#endif
   1.762 +
   1.763 +    if (sizeof(TCHAR)==sizeof(char))
   1.764 +	fmt=(const TCHAR *)fmta;
   1.765 +    else do
   1.766 +    { int    keepgoing;
   1.767 +      size_t len_0=strlen(fmta)+1,i;
   1.768 +      WCHAR *fmtw;
   1.769 +
   1.770 +#ifdef _MSC_VER
   1.771 +	fmtw = (WCHAR *)_alloca (len_0*sizeof(WCHAR));
   1.772 +#else
   1.773 +	fmtw = (WCHAR *)alloca (len_0*sizeof(WCHAR));
   1.774 +#endif
   1.775 +	if (fmtw == NULL) { fmt=(const TCHAR *)L"no stack?"; break; }
   1.776 +
   1.777 +#ifndef OPENSSL_NO_MULTIBYTE
   1.778 +	if (!MultiByteToWideChar(CP_ACP,0,fmta,len_0,fmtw,len_0))
   1.779 +#endif
   1.780 +	    for (i=0;i<len_0;i++) fmtw[i]=(WCHAR)fmta[i];
   1.781 +
   1.782 +	for (i=0;i<len_0;i++)
   1.783 +	{   if (fmtw[i]==L'%') do
   1.784 +	    {	keepgoing=0;
   1.785 +		switch (fmtw[i+1])
   1.786 +		{   case L'0': case L'1': case L'2': case L'3': case L'4':
   1.787 +		    case L'5': case L'6': case L'7': case L'8': case L'9':
   1.788 +		    case L'.': case L'*':
   1.789 +		    case L'-':	i++; keepgoing=1; break;
   1.790 +		    case L's':	fmtw[i+1]=L'S';   break;
   1.791 +		    case L'S':	fmtw[i+1]=L's';   break;
   1.792 +		    case L'c':	fmtw[i+1]=L'C';   break;
   1.793 +		    case L'C':	fmtw[i+1]=L'c';   break;
   1.794 +		}
   1.795 +	    } while (keepgoing);
   1.796 +	}
   1.797 +	fmt = (const TCHAR *)fmtw;
   1.798 +    } while (0);
   1.799 +
   1.800 +    va_start (ap,fmta);
   1.801 +    _vsntprintf (buf,sizeof(buf)/sizeof(TCHAR)-1,fmt,ap);
   1.802 +    buf [sizeof(buf)/sizeof(TCHAR)-1] = _T('\0');
   1.803 +    va_end (ap);
   1.804 +
   1.805 +#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
   1.806 +    /* this -------------v--- guards NT-specific calls */
   1.807 +    if (GetVersion() < 0x80000000 && OPENSSL_isservice())
   1.808 +    {	HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
   1.809 +	const TCHAR *pmsg=buf;
   1.810 +	ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
   1.811 +	DeregisterEventSource(h);
   1.812 +    }
   1.813 +    else
   1.814 +#endif
   1.815 +	MessageBox (NULL,buf,_T("OpenSSL: FATAL"),MB_OK|MB_ICONSTOP);
   1.816 +}
   1.817 +#else
   1.818 +EXPORT_C void OPENSSL_showfatal (const char *fmta,...)
   1.819 +{ va_list ap;
   1.820 +
   1.821 +    va_start (ap,fmta);
   1.822 +    vfprintf (stderr,fmta,ap);
   1.823 +    va_end (ap);
   1.824 +}
   1.825 +EXPORT_C int OPENSSL_isservice (void) { return 0; }
   1.826 +#endif
   1.827 +
   1.828 +EXPORT_C void OpenSSLDie(const char *file,int line,const char *assertion)
   1.829 +	{
   1.830 +	OPENSSL_showfatal(
   1.831 +		"%s(%d): OpenSSL internal error, assertion failed: %s\n",
   1.832 +		file,line,assertion);
   1.833 +	abort();
   1.834 +	}
   1.835 +
   1.836 +EXPORT_C void *OPENSSL_stderr(void)	{ return stderr; }
   1.837 +