err.c revision 1.39
1/* $OpenBSD: err.c,v 1.39 2014/08/24 16:11:39 bcook Exp $ */
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 * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 *    notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 *    notice, this list of conditions and the following disclaimer in
70 *    the documentation and/or other materials provided with the
71 *    distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 *    software must display the following acknowledgment:
75 *    "This product includes software developed by the OpenSSL Project
76 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 *    endorse or promote products derived from this software without
80 *    prior written permission. For written permission, please contact
81 *    openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 *    nor may "OpenSSL" appear in their names without prior written
85 *    permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 *    acknowledgment:
89 *    "This product includes software developed by the OpenSSL Project
90 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com).  This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112#include <stdarg.h>
113#include <stdio.h>
114#include <string.h>
115
116#include <openssl/opensslconf.h>
117
118#include <openssl/bio.h>
119#include <openssl/buffer.h>
120#include <openssl/crypto.h>
121#include <openssl/err.h>
122#include <openssl/lhash.h>
123
124DECLARE_LHASH_OF(ERR_STRING_DATA);
125DECLARE_LHASH_OF(ERR_STATE);
126
127static void err_load_strings(int lib, ERR_STRING_DATA *str);
128
129static void ERR_STATE_free(ERR_STATE *s);
130#ifndef OPENSSL_NO_ERR
131static ERR_STRING_DATA ERR_str_libraries[] = {
132	{ERR_PACK(ERR_LIB_NONE,0,0),		"unknown library"},
133	{ERR_PACK(ERR_LIB_SYS,0,0),		"system library"},
134	{ERR_PACK(ERR_LIB_BN,0,0),		"bignum routines"},
135	{ERR_PACK(ERR_LIB_RSA,0,0),		"rsa routines"},
136	{ERR_PACK(ERR_LIB_DH,0,0),		"Diffie-Hellman routines"},
137	{ERR_PACK(ERR_LIB_EVP,0,0),		"digital envelope routines"},
138	{ERR_PACK(ERR_LIB_BUF,0,0),		"memory buffer routines"},
139	{ERR_PACK(ERR_LIB_OBJ,0,0),		"object identifier routines"},
140	{ERR_PACK(ERR_LIB_PEM,0,0),		"PEM routines"},
141	{ERR_PACK(ERR_LIB_DSA,0,0),		"dsa routines"},
142	{ERR_PACK(ERR_LIB_X509,0,0),		"x509 certificate routines"},
143	{ERR_PACK(ERR_LIB_ASN1,0,0),		"asn1 encoding routines"},
144	{ERR_PACK(ERR_LIB_CONF,0,0),		"configuration file routines"},
145	{ERR_PACK(ERR_LIB_CRYPTO,0,0),		"common libcrypto routines"},
146	{ERR_PACK(ERR_LIB_EC,0,0),		"elliptic curve routines"},
147	{ERR_PACK(ERR_LIB_SSL,0,0),		"SSL routines"},
148	{ERR_PACK(ERR_LIB_BIO,0,0),		"BIO routines"},
149	{ERR_PACK(ERR_LIB_PKCS7,0,0),		"PKCS7 routines"},
150	{ERR_PACK(ERR_LIB_X509V3,0,0),		"X509 V3 routines"},
151	{ERR_PACK(ERR_LIB_PKCS12,0,0),		"PKCS12 routines"},
152	{ERR_PACK(ERR_LIB_RAND,0,0),		"random number generator"},
153	{ERR_PACK(ERR_LIB_DSO,0,0),		"DSO support routines"},
154	{ERR_PACK(ERR_LIB_TS,0,0),		"time stamp routines"},
155	{ERR_PACK(ERR_LIB_ENGINE,0,0),		"engine routines"},
156	{ERR_PACK(ERR_LIB_OCSP,0,0),		"OCSP routines"},
157	{ERR_PACK(ERR_LIB_FIPS,0,0),		"FIPS routines"},
158	{ERR_PACK(ERR_LIB_CMS,0,0),		"CMS routines"},
159	{ERR_PACK(ERR_LIB_HMAC,0,0),		"HMAC routines"},
160	{0, NULL},
161};
162
163static ERR_STRING_DATA ERR_str_functs[] = {
164	{ERR_PACK(0,SYS_F_FOPEN, 0),     	"fopen"},
165	{ERR_PACK(0,SYS_F_CONNECT, 0),		"connect"},
166	{ERR_PACK(0,SYS_F_GETSERVBYNAME, 0),	"getservbyname"},
167	{ERR_PACK(0,SYS_F_SOCKET, 0),		"socket"},
168	{ERR_PACK(0,SYS_F_IOCTLSOCKET, 0),	"ioctl"},
169	{ERR_PACK(0,SYS_F_BIND, 0),		"bind"},
170	{ERR_PACK(0,SYS_F_LISTEN, 0),		"listen"},
171	{ERR_PACK(0,SYS_F_ACCEPT, 0),		"accept"},
172	{ERR_PACK(0,SYS_F_OPENDIR, 0),		"opendir"},
173	{ERR_PACK(0,SYS_F_FREAD, 0),		"fread"},
174	{0, NULL},
175};
176
177static ERR_STRING_DATA ERR_str_reasons[] = {
178	{ERR_R_SYS_LIB,				"system lib"},
179	{ERR_R_BN_LIB,				"BN lib"},
180	{ERR_R_RSA_LIB,				"RSA lib"},
181	{ERR_R_DH_LIB,				"DH lib"},
182	{ERR_R_EVP_LIB,				"EVP lib"},
183	{ERR_R_BUF_LIB,				"BUF lib"},
184	{ERR_R_OBJ_LIB,				"OBJ lib"},
185	{ERR_R_PEM_LIB,				"PEM lib"},
186	{ERR_R_DSA_LIB,				"DSA lib"},
187	{ERR_R_X509_LIB,			"X509 lib"},
188	{ERR_R_ASN1_LIB,			"ASN1 lib"},
189	{ERR_R_CONF_LIB,			"CONF lib"},
190	{ERR_R_CRYPTO_LIB,			"CRYPTO lib"},
191	{ERR_R_EC_LIB,				"EC lib"},
192	{ERR_R_SSL_LIB,				"SSL lib"},
193	{ERR_R_BIO_LIB,				"BIO lib"},
194	{ERR_R_PKCS7_LIB,			"PKCS7 lib"},
195	{ERR_R_X509V3_LIB,			"X509V3 lib"},
196	{ERR_R_PKCS12_LIB,			"PKCS12 lib"},
197	{ERR_R_RAND_LIB,			"RAND lib"},
198	{ERR_R_DSO_LIB,				"DSO lib"},
199	{ERR_R_ENGINE_LIB,			"ENGINE lib"},
200	{ERR_R_OCSP_LIB,			"OCSP lib"},
201	{ERR_R_TS_LIB,				"TS lib"},
202
203	{ERR_R_NESTED_ASN1_ERROR,		"nested asn1 error"},
204	{ERR_R_BAD_ASN1_OBJECT_HEADER,		"bad asn1 object header"},
205	{ERR_R_BAD_GET_ASN1_OBJECT_CALL,	"bad get asn1 object call"},
206	{ERR_R_EXPECTING_AN_ASN1_SEQUENCE,	"expecting an asn1 sequence"},
207	{ERR_R_ASN1_LENGTH_MISMATCH,		"asn1 length mismatch"},
208	{ERR_R_MISSING_ASN1_EOS,		"missing asn1 eos"},
209
210	{ERR_R_FATAL,				"fatal"},
211	{ERR_R_MALLOC_FAILURE,			"malloc failure"},
212	{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,	"called a function you should not call"},
213	{ERR_R_PASSED_NULL_PARAMETER,		"passed a null parameter"},
214	{ERR_R_INTERNAL_ERROR,			"internal error"},
215	{ERR_R_DISABLED	,			"called a function that was disabled at compile-time"},
216
217	{0, NULL},
218};
219#endif
220
221
222/* Define the predeclared (but externally opaque) "ERR_FNS" type */
223struct st_ERR_FNS {
224	/* Works on the "error_hash" string table */
225	LHASH_OF(ERR_STRING_DATA) *(*cb_err_get)(int create);
226	void (*cb_err_del)(void);
227	ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
228	ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
229	ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
230	/* Works on the "thread_hash" error-state table */
231	LHASH_OF(ERR_STATE) *(*cb_thread_get)(int create);
232	void (*cb_thread_release)(LHASH_OF(ERR_STATE) **hash);
233	ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
234	ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
235	void (*cb_thread_del_item)(const ERR_STATE *);
236	/* Returns the next available error "library" numbers */
237	int (*cb_get_next_lib)(void);
238};
239
240/* Predeclarations of the "err_defaults" functions */
241static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create);
242static void int_err_del(void);
243static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
244static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
245static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
246static LHASH_OF(ERR_STATE) *int_thread_get(int create);
247static void int_thread_release(LHASH_OF(ERR_STATE) **hash);
248static ERR_STATE *int_thread_get_item(const ERR_STATE *);
249static ERR_STATE *int_thread_set_item(ERR_STATE *);
250static void int_thread_del_item(const ERR_STATE *);
251static int int_err_get_next_lib(void);
252
253/* The static ERR_FNS table using these defaults functions */
254static const ERR_FNS err_defaults = {
255	int_err_get,
256	int_err_del,
257	int_err_get_item,
258	int_err_set_item,
259	int_err_del_item,
260	int_thread_get,
261	int_thread_release,
262	int_thread_get_item,
263	int_thread_set_item,
264	int_thread_del_item,
265	int_err_get_next_lib
266};
267
268/* The replacable table of ERR_FNS functions we use at run-time */
269static const ERR_FNS *err_fns = NULL;
270
271/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
272#define ERRFN(a) err_fns->cb_##a
273
274/* The internal state used by "err_defaults" - as such, the setting, reading,
275 * creating, and deleting of this data should only be permitted via the
276 * "err_defaults" functions. This way, a linked module can completely defer all
277 * ERR state operation (together with requisite locking) to the implementations
278 * and state in the loading application. */
279static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
280static LHASH_OF(ERR_STATE) *int_thread_hash = NULL;
281static int int_thread_hash_references = 0;
282static int int_err_library_number = ERR_LIB_USER;
283
284/* Internal function that checks whether "err_fns" is set and if not, sets it to
285 * the defaults. */
286static void
287err_fns_check(void)
288{
289	if (err_fns)
290		return;
291
292	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
293	if (!err_fns)
294		err_fns = &err_defaults;
295	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
296}
297
298/* API functions to get or set the underlying ERR functions. */
299
300const ERR_FNS *
301ERR_get_implementation(void)
302{
303	err_fns_check();
304	return err_fns;
305}
306
307int
308ERR_set_implementation(const ERR_FNS *fns)
309{
310	int ret = 0;
311
312	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
313	/* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
314	 * an error is there?! */
315	if (!err_fns) {
316		err_fns = fns;
317		ret = 1;
318	}
319	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
320	return ret;
321}
322
323/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
324 * internal to the "err_defaults" implementation. */
325
326static unsigned long get_error_values(int inc, int top, const char **file,
327    int *line, const char **data, int *flags);
328
329/* The internal functions used in the "err_defaults" implementation */
330
331static unsigned long
332err_string_data_hash(const ERR_STRING_DATA *a)
333{
334	unsigned long ret, l;
335
336	l = a->error;
337	ret = l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
338	return (ret^ret % 19*13);
339}
340static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA)
341
342static int
343err_string_data_cmp(const ERR_STRING_DATA *a, const ERR_STRING_DATA *b)
344{
345	return (int)(a->error - b->error);
346}
347static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA)
348
349static
350LHASH_OF(ERR_STRING_DATA) *int_err_get(int create)
351{
352	LHASH_OF(ERR_STRING_DATA) *ret = NULL;
353
354	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
355	if (!int_error_hash && create) {
356		CRYPTO_push_info("int_err_get (err.c)");
357		int_error_hash = lh_ERR_STRING_DATA_new();
358		CRYPTO_pop_info();
359	}
360	if (int_error_hash)
361		ret = int_error_hash;
362	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
363
364	return ret;
365}
366
367static void
368int_err_del(void)
369{
370	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
371	if (int_error_hash) {
372		lh_ERR_STRING_DATA_free(int_error_hash);
373		int_error_hash = NULL;
374	}
375	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
376}
377
378static ERR_STRING_DATA *
379int_err_get_item(const ERR_STRING_DATA *d)
380{
381	ERR_STRING_DATA *p;
382	LHASH_OF(ERR_STRING_DATA) *hash;
383
384	err_fns_check();
385	hash = ERRFN(err_get)(0);
386	if (!hash)
387		return NULL;
388
389	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
390	p = lh_ERR_STRING_DATA_retrieve(hash, d);
391	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
392
393	return p;
394}
395
396static ERR_STRING_DATA *
397int_err_set_item(ERR_STRING_DATA *d)
398{
399	ERR_STRING_DATA *p;
400	LHASH_OF(ERR_STRING_DATA) *hash;
401
402	err_fns_check();
403	hash = ERRFN(err_get)(1);
404	if (!hash)
405		return NULL;
406
407	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
408	p = lh_ERR_STRING_DATA_insert(hash, d);
409	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
410
411	return p;
412}
413
414static ERR_STRING_DATA *
415int_err_del_item(ERR_STRING_DATA *d)
416{
417	ERR_STRING_DATA *p;
418	LHASH_OF(ERR_STRING_DATA) *hash;
419
420	err_fns_check();
421	hash = ERRFN(err_get)(0);
422	if (!hash)
423		return NULL;
424
425	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
426	p = lh_ERR_STRING_DATA_delete(hash, d);
427	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
428
429	return p;
430}
431
432static unsigned long
433err_state_hash(const ERR_STATE *a)
434{
435	return CRYPTO_THREADID_hash(&a->tid) * 13;
436}
437static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
438
439static int
440err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
441{
442	return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
443}
444static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
445
446static
447LHASH_OF(ERR_STATE) *int_thread_get(int create)
448{
449	LHASH_OF(ERR_STATE) *ret = NULL;
450
451	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
452	if (!int_thread_hash && create) {
453		CRYPTO_push_info("int_thread_get (err.c)");
454		int_thread_hash = lh_ERR_STATE_new();
455		CRYPTO_pop_info();
456	}
457	if (int_thread_hash) {
458		int_thread_hash_references++;
459		ret = int_thread_hash;
460	}
461	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
462	return ret;
463}
464
465static void
466int_thread_release(LHASH_OF(ERR_STATE) **hash)
467{
468	int i;
469
470	if (hash == NULL || *hash == NULL)
471		return;
472
473	i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
474	if (i > 0)
475		return;
476
477	*hash = NULL;
478}
479
480static ERR_STATE *
481int_thread_get_item(const ERR_STATE *d)
482{
483	ERR_STATE *p;
484	LHASH_OF(ERR_STATE) *hash;
485
486	err_fns_check();
487	hash = ERRFN(thread_get)(0);
488	if (!hash)
489		return NULL;
490
491	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
492	p = lh_ERR_STATE_retrieve(hash, d);
493	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
494
495	ERRFN(thread_release)(&hash);
496	return p;
497}
498
499static ERR_STATE *
500int_thread_set_item(ERR_STATE *d)
501{
502	ERR_STATE *p;
503	LHASH_OF(ERR_STATE) *hash;
504
505	err_fns_check();
506	hash = ERRFN(thread_get)(1);
507	if (!hash)
508		return NULL;
509
510	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
511	p = lh_ERR_STATE_insert(hash, d);
512	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
513
514	ERRFN(thread_release)(&hash);
515	return p;
516}
517
518static void
519int_thread_del_item(const ERR_STATE *d)
520{
521	ERR_STATE *p;
522	LHASH_OF(ERR_STATE) *hash;
523
524	err_fns_check();
525	hash = ERRFN(thread_get)(0);
526	if (!hash)
527		return;
528
529	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
530	p = lh_ERR_STATE_delete(hash, d);
531	/* make sure we don't leak memory */
532	if (int_thread_hash_references == 1 &&
533	    int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0) {
534		lh_ERR_STATE_free(int_thread_hash);
535		int_thread_hash = NULL;
536	}
537	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
538
539	ERRFN(thread_release)(&hash);
540	if (p)
541		ERR_STATE_free(p);
542}
543
544static int
545int_err_get_next_lib(void)
546{
547	int ret;
548
549	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
550	ret = int_err_library_number++;
551	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
552
553	return ret;
554}
555
556
557#ifndef OPENSSL_NO_ERR
558#define NUM_SYS_STR_REASONS 127
559#define LEN_SYS_STR_REASON 32
560
561static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
562/* SYS_str_reasons is filled with copies of strerror() results at
563 * initialization.
564 * 'errno' values up to 127 should cover all usual errors,
565 * others will be displayed numerically by ERR_error_string.
566 * It is crucial that we have something for each reason code
567 * that occurs in ERR_str_reasons, or bogus reason strings
568 * will be returned for SYSerr(), which always gets an errno
569 * value and never one of those 'standard' reason codes. */
570
571static void
572build_SYS_str_reasons(void)
573{
574	/* malloc cannot be used here, use static storage instead */
575	static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
576	int i;
577	static int init = 1;
578
579	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
580	if (!init) {
581		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
582		return;
583	}
584
585	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
586	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
587	if (!init) {
588		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
589		return;
590	}
591
592	for (i = 1; i <= NUM_SYS_STR_REASONS; i++) {
593		ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
594
595		str->error = (unsigned long)i;
596		if (str->string == NULL) {
597			char (*dest)[LEN_SYS_STR_REASON] =
598			    &(strerror_tab[i - 1]);
599			const char *src = strerror(i);
600			if (src != NULL) {
601				strlcpy(*dest, src, sizeof *dest);
602				str->string = *dest;
603			}
604		}
605		if (str->string == NULL)
606			str->string = "unknown";
607	}
608
609	/* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
610	 * as required by ERR_load_strings. */
611
612	init = 0;
613
614	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
615}
616#endif
617
618#define err_clear_data(p,i) \
619	do { \
620		if (((p)->err_data[i] != NULL) && \
621		    (p)->err_data_flags[i] & ERR_TXT_MALLOCED) { \
622			free((p)->err_data[i]); \
623			(p)->err_data[i] = NULL; \
624		} \
625		(p)->err_data_flags[i] = 0; \
626	} while(0)
627
628#define err_clear(p,i) \
629	do { \
630		(p)->err_flags[i] = 0; \
631		(p)->err_buffer[i] = 0; \
632		err_clear_data(p, i); \
633		(p)->err_file[i] = NULL; \
634		(p)->err_line[i] = -1; \
635	} while(0)
636
637static void
638ERR_STATE_free(ERR_STATE *s)
639{
640	int i;
641
642	if (s == NULL)
643		return;
644
645	for (i = 0; i < ERR_NUM_ERRORS; i++) {
646		err_clear_data(s, i);
647	}
648	free(s);
649}
650
651void
652ERR_load_ERR_strings(void)
653{
654	err_fns_check();
655#ifndef OPENSSL_NO_ERR
656	err_load_strings(0, ERR_str_libraries);
657	err_load_strings(0, ERR_str_reasons);
658	err_load_strings(ERR_LIB_SYS, ERR_str_functs);
659	build_SYS_str_reasons();
660	err_load_strings(ERR_LIB_SYS, SYS_str_reasons);
661#endif
662}
663
664static void
665err_load_strings(int lib, ERR_STRING_DATA *str)
666{
667	while (str->error) {
668		if (lib)
669			str->error |= ERR_PACK(lib, 0, 0);
670		ERRFN(err_set_item)(str);
671		str++;
672	}
673}
674
675void
676ERR_load_strings(int lib, ERR_STRING_DATA *str)
677{
678	ERR_load_ERR_strings();
679	err_load_strings(lib, str);
680}
681
682void
683ERR_unload_strings(int lib, ERR_STRING_DATA *str)
684{
685	while (str->error) {
686		if (lib)
687			str->error |= ERR_PACK(lib, 0, 0);
688		ERRFN(err_del_item)(str);
689		str++;
690	}
691}
692
693void
694ERR_free_strings(void)
695{
696	err_fns_check();
697	ERRFN(err_del)();
698}
699
700/********************************************************/
701
702void
703ERR_put_error(int lib, int func, int reason, const char *file, int line)
704{
705	ERR_STATE *es;
706	int save_errno = errno;
707
708	es = ERR_get_state();
709
710	es->top = (es->top + 1) % ERR_NUM_ERRORS;
711	if (es->top == es->bottom)
712		es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS;
713	es->err_flags[es->top] = 0;
714	es->err_buffer[es->top] = ERR_PACK(lib, func, reason);
715	es->err_file[es->top] = file;
716	es->err_line[es->top] = line;
717	err_clear_data(es, es->top);
718	errno = save_errno;
719}
720
721void
722ERR_clear_error(void)
723{
724	int i;
725	ERR_STATE *es;
726
727	es = ERR_get_state();
728
729	for (i = 0; i < ERR_NUM_ERRORS; i++) {
730		err_clear(es, i);
731	}
732	es->top = es->bottom = 0;
733}
734
735
736unsigned long
737ERR_get_error(void)
738{
739	return (get_error_values(1, 0, NULL, NULL, NULL, NULL));
740}
741
742unsigned long
743ERR_get_error_line(const char **file, int *line)
744{
745	return (get_error_values(1, 0, file, line, NULL, NULL));
746}
747
748unsigned long
749ERR_get_error_line_data(const char **file, int *line,
750    const char **data, int *flags)
751{
752	return (get_error_values(1, 0, file, line, data, flags));
753}
754
755
756unsigned long
757ERR_peek_error(void)
758{
759	return (get_error_values(0, 0, NULL, NULL, NULL, NULL));
760}
761
762unsigned long
763ERR_peek_error_line(const char **file, int *line)
764{
765	return (get_error_values(0, 0, file, line, NULL, NULL));
766}
767
768unsigned long
769ERR_peek_error_line_data(const char **file, int *line,
770    const char **data, int *flags)
771{
772	return (get_error_values(0, 0, file, line, data, flags));
773}
774
775unsigned long
776ERR_peek_last_error(void)
777{
778	return (get_error_values(0, 1, NULL, NULL, NULL, NULL));
779}
780
781unsigned long
782ERR_peek_last_error_line(const char **file, int *line)
783{
784	return (get_error_values(0, 1, file, line, NULL, NULL));
785}
786
787unsigned long
788ERR_peek_last_error_line_data(const char **file, int *line,
789    const char **data, int *flags)
790{
791	return (get_error_values(0, 1, file, line, data, flags));
792}
793
794static unsigned long
795get_error_values(int inc, int top, const char **file, int *line,
796    const char **data, int *flags)
797{
798	int i = 0;
799	ERR_STATE *es;
800	unsigned long ret;
801
802	es = ERR_get_state();
803
804	if (inc && top) {
805		if (file)
806			*file = "";
807		if (line)
808			*line = 0;
809		if (data)
810			*data = "";
811		if (flags)
812			*flags = 0;
813
814		return ERR_R_INTERNAL_ERROR;
815	}
816
817	if (es->bottom == es->top)
818		return 0;
819	if (top)
820		i = es->top;			 /* last error */
821	else
822		i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */
823
824	ret = es->err_buffer[i];
825	if (inc) {
826		es->bottom = i;
827		es->err_buffer[i] = 0;
828	}
829
830	if ((file != NULL) && (line != NULL)) {
831		if (es->err_file[i] == NULL) {
832			*file = "NA";
833			if (line != NULL)
834				*line = 0;
835		} else {
836			*file = es->err_file[i];
837			if (line != NULL)
838				*line = es->err_line[i];
839		}
840	}
841
842	if (data == NULL) {
843		if (inc) {
844			err_clear_data(es, i);
845		}
846	} else {
847		if (es->err_data[i] == NULL) {
848			*data = "";
849			if (flags != NULL)
850				*flags = 0;
851		} else {
852			*data = es->err_data[i];
853			if (flags != NULL)
854				*flags = es->err_data_flags[i];
855		}
856	}
857	return ret;
858}
859
860void
861ERR_error_string_n(unsigned long e, char *buf, size_t len)
862{
863	char lsbuf[30], fsbuf[30], rsbuf[30];
864	const char *ls, *fs, *rs;
865	int l, f, r, ret;
866
867	l = ERR_GET_LIB(e);
868	f = ERR_GET_FUNC(e);
869	r = ERR_GET_REASON(e);
870
871	ls = ERR_lib_error_string(e);
872	fs = ERR_func_error_string(e);
873	rs = ERR_reason_error_string(e);
874
875	if (ls == NULL) {
876		(void) snprintf(lsbuf, sizeof(lsbuf), "lib(%d)", l);
877		ls = lsbuf;
878	}
879	if (fs == NULL) {
880		(void) snprintf(fsbuf, sizeof(fsbuf), "func(%d)", f);
881		fs = fsbuf;
882	}
883	if (rs == NULL) {
884		(void) snprintf(rsbuf, sizeof(rsbuf), "reason(%d)", r);
885		rs = rsbuf;
886	}
887
888	ret = snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, fs, rs);
889	if (ret == -1)
890		return;	/* can't happen, and can't do better if it does */
891	if (ret >= len) {
892		/* output may be truncated; make sure we always have 5
893		 * colon-separated fields, i.e. 4 colons ... */
894#define NUM_COLONS 4
895		if (len > NUM_COLONS) /* ... if possible */
896		{
897			int i;
898			char *s = buf;
899
900			for (i = 0; i < NUM_COLONS; i++) {
901				char *colon = strchr(s, ':');
902				if (colon == NULL ||
903				    colon > &buf[len - 1] - NUM_COLONS + i) {
904					/* set colon no. i at last possible position
905					 * (buf[len-1] is the terminating 0)*/
906					colon = &buf[len - 1] - NUM_COLONS + i;
907					*colon = ':';
908				}
909				s = colon + 1;
910			}
911		}
912	}
913}
914
915/* BAD for multi-threading: uses a local buffer if ret == NULL */
916/* ERR_error_string_n should be used instead for ret != NULL
917 * as ERR_error_string cannot know how large the buffer is */
918char *
919ERR_error_string(unsigned long e, char *ret)
920{
921	static char buf[256];
922
923	if (ret == NULL)
924		ret = buf;
925	ERR_error_string_n(e, ret, 256);
926
927	return ret;
928}
929
930LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void)
931{
932	err_fns_check();
933	return ERRFN(err_get)(0);
934}
935
936LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void)
937{
938	err_fns_check();
939	return ERRFN(thread_get)(0);
940}
941
942void
943ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash)
944{
945	err_fns_check();
946	ERRFN(thread_release)(hash);
947}
948
949const char *
950ERR_lib_error_string(unsigned long e)
951{
952	ERR_STRING_DATA d, *p;
953	unsigned long l;
954
955	err_fns_check();
956	l = ERR_GET_LIB(e);
957	d.error = ERR_PACK(l, 0, 0);
958	p = ERRFN(err_get_item)(&d);
959	return ((p == NULL) ? NULL : p->string);
960}
961
962const char *
963ERR_func_error_string(unsigned long e)
964{
965	ERR_STRING_DATA d, *p;
966	unsigned long l, f;
967
968	err_fns_check();
969	l = ERR_GET_LIB(e);
970	f = ERR_GET_FUNC(e);
971	d.error = ERR_PACK(l, f, 0);
972	p = ERRFN(err_get_item)(&d);
973	return ((p == NULL) ? NULL : p->string);
974}
975
976const char *
977ERR_reason_error_string(unsigned long e)
978{
979	ERR_STRING_DATA d, *p = NULL;
980	unsigned long l, r;
981
982	err_fns_check();
983	l = ERR_GET_LIB(e);
984	r = ERR_GET_REASON(e);
985	d.error = ERR_PACK(l, 0, r);
986	p = ERRFN(err_get_item)(&d);
987	if (!p) {
988		d.error = ERR_PACK(0, 0, r);
989		p = ERRFN(err_get_item)(&d);
990	}
991	return ((p == NULL) ? NULL : p->string);
992}
993
994void
995ERR_remove_thread_state(const CRYPTO_THREADID *id)
996{
997	ERR_STATE tmp;
998
999	if (id)
1000		CRYPTO_THREADID_cpy(&tmp.tid, id);
1001	else
1002		CRYPTO_THREADID_current(&tmp.tid);
1003	err_fns_check();
1004	/* thread_del_item automatically destroys the LHASH if the number of
1005	 * items reaches zero. */
1006	ERRFN(thread_del_item)(&tmp);
1007}
1008
1009#ifndef OPENSSL_NO_DEPRECATED
1010void
1011ERR_remove_state(unsigned long pid)
1012{
1013	ERR_remove_thread_state(NULL);
1014}
1015#endif
1016
1017ERR_STATE *
1018ERR_get_state(void)
1019{
1020	static ERR_STATE fallback;
1021	ERR_STATE *ret, tmp, *tmpp = NULL;
1022	int i;
1023	CRYPTO_THREADID tid;
1024
1025	err_fns_check();
1026	CRYPTO_THREADID_current(&tid);
1027	CRYPTO_THREADID_cpy(&tmp.tid, &tid);
1028	ret = ERRFN(thread_get_item)(&tmp);
1029
1030	/* ret == the error state, if NULL, make a new one */
1031	if (ret == NULL) {
1032		ret = malloc(sizeof(ERR_STATE));
1033		if (ret == NULL)
1034			return (&fallback);
1035		CRYPTO_THREADID_cpy(&ret->tid, &tid);
1036		ret->top = 0;
1037		ret->bottom = 0;
1038		for (i = 0; i < ERR_NUM_ERRORS; i++) {
1039			ret->err_data[i] = NULL;
1040			ret->err_data_flags[i] = 0;
1041		}
1042		tmpp = ERRFN(thread_set_item)(ret);
1043		/* To check if insertion failed, do a get. */
1044		if (ERRFN(thread_get_item)(ret) != ret) {
1045			ERR_STATE_free(ret); /* could not insert it */
1046			return (&fallback);
1047		}
1048		/* If a race occured in this function and we came second, tmpp
1049		 * is the first one that we just replaced. */
1050		if (tmpp)
1051			ERR_STATE_free(tmpp);
1052	}
1053	return ret;
1054}
1055
1056int
1057ERR_get_next_error_library(void)
1058{
1059	err_fns_check();
1060	return ERRFN(get_next_lib)();
1061}
1062
1063void
1064ERR_set_error_data(char *data, int flags)
1065{
1066	ERR_STATE *es;
1067	int i;
1068
1069	es = ERR_get_state();
1070
1071	i = es->top;
1072	if (i == 0)
1073		i = ERR_NUM_ERRORS - 1;
1074
1075	err_clear_data(es, i);
1076	es->err_data[i] = data;
1077	es->err_data_flags[i] = flags;
1078}
1079
1080void
1081ERR_asprintf_error_data(char * format, ...) {
1082	char *errbuf = NULL;
1083	va_list ap;
1084	int r;
1085
1086	va_start(ap, format);
1087	r = vasprintf(&errbuf, format, ap);
1088	va_end(ap);
1089	if (r == -1)
1090		ERR_set_error_data("malloc failed", ERR_TXT_STRING);
1091	else
1092		ERR_set_error_data(errbuf, ERR_TXT_MALLOCED|ERR_TXT_STRING);
1093}
1094void
1095ERR_add_error_data(int num, ...)
1096{
1097	va_list args;
1098	va_start(args, num);
1099	ERR_add_error_vdata(num, args);
1100	va_end(args);
1101}
1102
1103void
1104ERR_add_error_vdata(int num, va_list args)
1105{
1106	char format[129];
1107	char *errbuf;
1108	format[0] = '\0';
1109	int i;
1110	for (i = 0; i < num; i++) {
1111		if (strlcat(format, "%s", sizeof(format)) >= sizeof(format)) {
1112			ERR_set_error_data("too many errors", ERR_TXT_STRING);
1113			return;
1114		}
1115	}
1116	if (vasprintf(&errbuf, format, args) == -1)
1117		ERR_set_error_data("malloc failed", ERR_TXT_STRING);
1118	else
1119		ERR_set_error_data(errbuf, ERR_TXT_MALLOCED|ERR_TXT_STRING);
1120}
1121
1122int
1123ERR_set_mark(void)
1124{
1125	ERR_STATE *es;
1126
1127	es = ERR_get_state();
1128
1129	if (es->bottom == es->top)
1130		return 0;
1131	es->err_flags[es->top] |= ERR_FLAG_MARK;
1132	return 1;
1133}
1134
1135int
1136ERR_pop_to_mark(void)
1137{
1138	ERR_STATE *es;
1139
1140	es = ERR_get_state();
1141
1142	while (es->bottom != es->top &&
1143	    (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) {
1144		err_clear(es, es->top);
1145		es->top -= 1;
1146		if (es->top == -1)
1147			es->top = ERR_NUM_ERRORS - 1;
1148	}
1149
1150	if (es->bottom == es->top)
1151		return 0;
1152	es->err_flags[es->top]&=~ERR_FLAG_MARK;
1153	return 1;
1154}
1155