summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/err/err.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/err/err.c (renamed from src/lib/libcrypto/err/err_def.c)700
1 files changed, 585 insertions, 115 deletions
diff --git a/src/lib/libcrypto/err/err_def.c b/src/lib/libcrypto/err/err.c
index 7ed3d84955..69713a6e2f 100644
--- a/src/lib/libcrypto/err/err_def.c
+++ b/src/lib/libcrypto/err/err.c
@@ -1,4 +1,4 @@
1/* crypto/err/err_def.c */ 1/* crypto/err/err.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -56,7 +56,7 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ==================================================================== 58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 * 60 *
61 * Redistribution and use in source and binary forms, with or without 61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions 62 * modification, are permitted provided that the following conditions
@@ -119,42 +119,122 @@
119#include <openssl/bio.h> 119#include <openssl/bio.h>
120#include <openssl/err.h> 120#include <openssl/err.h>
121 121
122#define err_clear_data(p,i) \ 122DECLARE_LHASH_OF(ERR_STRING_DATA);
123 do { \ 123DECLARE_LHASH_OF(ERR_STATE);
124 if (((p)->err_data[i] != NULL) && \
125 (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
126 { \
127 OPENSSL_free((p)->err_data[i]); \
128 (p)->err_data[i]=NULL; \
129 } \
130 (p)->err_data_flags[i]=0; \
131 } while(0)
132
133#define err_clear(p,i) \
134 do { \
135 (p)->err_flags[i]=0; \
136 (p)->err_buffer[i]=0; \
137 err_clear_data(p,i); \
138 (p)->err_file[i]=NULL; \
139 (p)->err_line[i]= -1; \
140 } while(0)
141 124
142static void err_load_strings(int lib, ERR_STRING_DATA *str); 125static void err_load_strings(int lib, ERR_STRING_DATA *str);
143 126
144static void ERR_STATE_free(ERR_STATE *s); 127static void ERR_STATE_free(ERR_STATE *s);
128#ifndef OPENSSL_NO_ERR
129static ERR_STRING_DATA ERR_str_libraries[]=
130 {
131{ERR_PACK(ERR_LIB_NONE,0,0) ,"unknown library"},
132{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"},
133{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"},
134{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"},
135{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"},
136{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"},
137{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"},
138{ERR_PACK(ERR_LIB_OBJ,0,0) ,"object identifier routines"},
139{ERR_PACK(ERR_LIB_PEM,0,0) ,"PEM routines"},
140{ERR_PACK(ERR_LIB_DSA,0,0) ,"dsa routines"},
141{ERR_PACK(ERR_LIB_X509,0,0) ,"x509 certificate routines"},
142{ERR_PACK(ERR_LIB_ASN1,0,0) ,"asn1 encoding routines"},
143{ERR_PACK(ERR_LIB_CONF,0,0) ,"configuration file routines"},
144{ERR_PACK(ERR_LIB_CRYPTO,0,0) ,"common libcrypto routines"},
145{ERR_PACK(ERR_LIB_EC,0,0) ,"elliptic curve routines"},
146{ERR_PACK(ERR_LIB_SSL,0,0) ,"SSL routines"},
147{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"},
148{ERR_PACK(ERR_LIB_PKCS7,0,0) ,"PKCS7 routines"},
149{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"},
150{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"},
151{ERR_PACK(ERR_LIB_RAND,0,0) ,"random number generator"},
152{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"},
153{ERR_PACK(ERR_LIB_TS,0,0) ,"time stamp routines"},
154{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"},
155{ERR_PACK(ERR_LIB_OCSP,0,0) ,"OCSP routines"},
156{ERR_PACK(ERR_LIB_FIPS,0,0) ,"FIPS routines"},
157{ERR_PACK(ERR_LIB_CMS,0,0) ,"CMS routines"},
158{ERR_PACK(ERR_LIB_HMAC,0,0) ,"HMAC routines"},
159{0,NULL},
160 };
161
162static ERR_STRING_DATA ERR_str_functs[]=
163 {
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), "ioctlsocket"},
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#ifdef OPENSSL_SYS_WINDOWS
173 {ERR_PACK(0,SYS_F_WSASTARTUP,0), "WSAstartup"},
174#endif
175 {ERR_PACK(0,SYS_F_OPENDIR,0), "opendir"},
176 {ERR_PACK(0,SYS_F_FREAD,0), "fread"},
177 {0,NULL},
178 };
179
180static ERR_STRING_DATA ERR_str_reasons[]=
181 {
182{ERR_R_SYS_LIB ,"system lib"},
183{ERR_R_BN_LIB ,"BN lib"},
184{ERR_R_RSA_LIB ,"RSA lib"},
185{ERR_R_DH_LIB ,"DH lib"},
186{ERR_R_EVP_LIB ,"EVP lib"},
187{ERR_R_BUF_LIB ,"BUF lib"},
188{ERR_R_OBJ_LIB ,"OBJ lib"},
189{ERR_R_PEM_LIB ,"PEM lib"},
190{ERR_R_DSA_LIB ,"DSA lib"},
191{ERR_R_X509_LIB ,"X509 lib"},
192{ERR_R_ASN1_LIB ,"ASN1 lib"},
193{ERR_R_CONF_LIB ,"CONF lib"},
194{ERR_R_CRYPTO_LIB ,"CRYPTO lib"},
195{ERR_R_EC_LIB ,"EC lib"},
196{ERR_R_SSL_LIB ,"SSL lib"},
197{ERR_R_BIO_LIB ,"BIO lib"},
198{ERR_R_PKCS7_LIB ,"PKCS7 lib"},
199{ERR_R_X509V3_LIB ,"X509V3 lib"},
200{ERR_R_PKCS12_LIB ,"PKCS12 lib"},
201{ERR_R_RAND_LIB ,"RAND lib"},
202{ERR_R_DSO_LIB ,"DSO lib"},
203{ERR_R_ENGINE_LIB ,"ENGINE lib"},
204{ERR_R_OCSP_LIB ,"OCSP lib"},
205{ERR_R_TS_LIB ,"TS lib"},
206
207{ERR_R_NESTED_ASN1_ERROR ,"nested asn1 error"},
208{ERR_R_BAD_ASN1_OBJECT_HEADER ,"bad asn1 object header"},
209{ERR_R_BAD_GET_ASN1_OBJECT_CALL ,"bad get asn1 object call"},
210{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"},
211{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"},
212{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"},
213
214{ERR_R_FATAL ,"fatal"},
215{ERR_R_MALLOC_FAILURE ,"malloc failure"},
216{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED ,"called a function you should not call"},
217{ERR_R_PASSED_NULL_PARAMETER ,"passed a null parameter"},
218{ERR_R_INTERNAL_ERROR ,"internal error"},
219{ERR_R_DISABLED ,"called a function that was disabled at compile-time"},
220
221{0,NULL},
222 };
223#endif
224
145 225
146/* Define the predeclared (but externally opaque) "ERR_FNS" type */ 226/* Define the predeclared (but externally opaque) "ERR_FNS" type */
147struct st_ERR_FNS 227struct st_ERR_FNS
148 { 228 {
149 /* Works on the "error_hash" string table */ 229 /* Works on the "error_hash" string table */
150 LHASH *(*cb_err_get)(int create); 230 LHASH_OF(ERR_STRING_DATA) *(*cb_err_get)(int create);
151 void (*cb_err_del)(void); 231 void (*cb_err_del)(void);
152 ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *); 232 ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
153 ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *); 233 ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
154 ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *); 234 ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
155 /* Works on the "thread_hash" error-state table */ 235 /* Works on the "thread_hash" error-state table */
156 LHASH *(*cb_thread_get)(int create); 236 LHASH_OF(ERR_STATE) *(*cb_thread_get)(int create);
157 void (*cb_thread_release)(LHASH **hash); 237 void (*cb_thread_release)(LHASH_OF(ERR_STATE) **hash);
158 ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *); 238 ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
159 ERR_STATE *(*cb_thread_set_item)(ERR_STATE *); 239 ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
160 void (*cb_thread_del_item)(const ERR_STATE *); 240 void (*cb_thread_del_item)(const ERR_STATE *);
@@ -163,13 +243,13 @@ struct st_ERR_FNS
163 }; 243 };
164 244
165/* Predeclarations of the "err_defaults" functions */ 245/* Predeclarations of the "err_defaults" functions */
166static LHASH *int_err_get(int create); 246static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create);
167static void int_err_del(void); 247static void int_err_del(void);
168static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); 248static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
169static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *); 249static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
170static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *); 250static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
171static LHASH *int_thread_get(int create); 251static LHASH_OF(ERR_STATE) *int_thread_get(int create);
172static void int_thread_release(LHASH **hash); 252static void int_thread_release(LHASH_OF(ERR_STATE) **hash);
173static ERR_STATE *int_thread_get_item(const ERR_STATE *); 253static ERR_STATE *int_thread_get_item(const ERR_STATE *);
174static ERR_STATE *int_thread_set_item(ERR_STATE *); 254static ERR_STATE *int_thread_set_item(ERR_STATE *);
175static void int_thread_del_item(const ERR_STATE *); 255static void int_thread_del_item(const ERR_STATE *);
@@ -201,8 +281,8 @@ static const ERR_FNS *err_fns = NULL;
201 * "err_defaults" functions. This way, a linked module can completely defer all 281 * "err_defaults" functions. This way, a linked module can completely defer all
202 * ERR state operation (together with requisite locking) to the implementations 282 * ERR state operation (together with requisite locking) to the implementations
203 * and state in the loading application. */ 283 * and state in the loading application. */
204static LHASH *int_error_hash = NULL; 284static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
205static LHASH *int_thread_hash = NULL; 285static LHASH_OF(ERR_STATE) *int_thread_hash = NULL;
206static int int_thread_hash_references = 0; 286static int int_thread_hash_references = 0;
207static int int_err_library_number= ERR_LIB_USER; 287static int int_err_library_number= ERR_LIB_USER;
208 288
@@ -245,26 +325,37 @@ int ERR_set_implementation(const ERR_FNS *fns)
245/* These are the callbacks provided to "lh_new()" when creating the LHASH tables 325/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
246 * internal to the "err_defaults" implementation. */ 326 * internal to the "err_defaults" implementation. */
247 327
248/* static unsigned long err_hash(ERR_STRING_DATA *a); */ 328static unsigned long get_error_values(int inc,int top,const char **file,int *line,
249static unsigned long err_hash(const void *a_void); 329 const char **data,int *flags);
250/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b); */
251static int err_cmp(const void *a_void, const void *b_void);
252/* static unsigned long pid_hash(ERR_STATE *pid); */
253static unsigned long pid_hash(const void *pid_void);
254/* static int pid_cmp(ERR_STATE *a,ERR_STATE *pid); */
255static int pid_cmp(const void *a_void,const void *pid_void);
256 330
257/* The internal functions used in the "err_defaults" implementation */ 331/* The internal functions used in the "err_defaults" implementation */
258 332
259static LHASH *int_err_get(int create) 333static unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
260 { 334 {
261 LHASH *ret = NULL; 335 unsigned long ret,l;
336
337 l=a->error;
338 ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
339 return(ret^ret%19*13);
340 }
341static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA)
342
343static int err_string_data_cmp(const ERR_STRING_DATA *a,
344 const ERR_STRING_DATA *b)
345 {
346 return (int)(a->error - b->error);
347 }
348static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA)
349
350static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create)
351 {
352 LHASH_OF(ERR_STRING_DATA) *ret = NULL;
262 353
263 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 354 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
264 if (!int_error_hash && create) 355 if (!int_error_hash && create)
265 { 356 {
266 CRYPTO_push_info("int_err_get (err.c)"); 357 CRYPTO_push_info("int_err_get (err.c)");
267 int_error_hash = lh_new(err_hash, err_cmp); 358 int_error_hash = lh_ERR_STRING_DATA_new();
268 CRYPTO_pop_info(); 359 CRYPTO_pop_info();
269 } 360 }
270 if (int_error_hash) 361 if (int_error_hash)
@@ -279,7 +370,7 @@ static void int_err_del(void)
279 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 370 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
280 if (int_error_hash) 371 if (int_error_hash)
281 { 372 {
282 lh_free(int_error_hash); 373 lh_ERR_STRING_DATA_free(int_error_hash);
283 int_error_hash = NULL; 374 int_error_hash = NULL;
284 } 375 }
285 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 376 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
@@ -288,7 +379,7 @@ static void int_err_del(void)
288static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) 379static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
289 { 380 {
290 ERR_STRING_DATA *p; 381 ERR_STRING_DATA *p;
291 LHASH *hash; 382 LHASH_OF(ERR_STRING_DATA) *hash;
292 383
293 err_fns_check(); 384 err_fns_check();
294 hash = ERRFN(err_get)(0); 385 hash = ERRFN(err_get)(0);
@@ -296,7 +387,7 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
296 return NULL; 387 return NULL;
297 388
298 CRYPTO_r_lock(CRYPTO_LOCK_ERR); 389 CRYPTO_r_lock(CRYPTO_LOCK_ERR);
299 p = (ERR_STRING_DATA *)lh_retrieve(hash, d); 390 p = lh_ERR_STRING_DATA_retrieve(hash, d);
300 CRYPTO_r_unlock(CRYPTO_LOCK_ERR); 391 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
301 392
302 return p; 393 return p;
@@ -305,7 +396,7 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
305static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d) 396static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
306 { 397 {
307 ERR_STRING_DATA *p; 398 ERR_STRING_DATA *p;
308 LHASH *hash; 399 LHASH_OF(ERR_STRING_DATA) *hash;
309 400
310 err_fns_check(); 401 err_fns_check();
311 hash = ERRFN(err_get)(1); 402 hash = ERRFN(err_get)(1);
@@ -313,7 +404,7 @@ static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
313 return NULL; 404 return NULL;
314 405
315 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 406 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
316 p = (ERR_STRING_DATA *)lh_insert(hash, d); 407 p = lh_ERR_STRING_DATA_insert(hash, d);
317 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 408 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
318 409
319 return p; 410 return p;
@@ -322,7 +413,7 @@ static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
322static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d) 413static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
323 { 414 {
324 ERR_STRING_DATA *p; 415 ERR_STRING_DATA *p;
325 LHASH *hash; 416 LHASH_OF(ERR_STRING_DATA) *hash;
326 417
327 err_fns_check(); 418 err_fns_check();
328 hash = ERRFN(err_get)(0); 419 hash = ERRFN(err_get)(0);
@@ -330,21 +421,33 @@ static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
330 return NULL; 421 return NULL;
331 422
332 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 423 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
333 p = (ERR_STRING_DATA *)lh_delete(hash, d); 424 p = lh_ERR_STRING_DATA_delete(hash, d);
334 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 425 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
335 426
336 return p; 427 return p;
337 } 428 }
338 429
339static LHASH *int_thread_get(int create) 430static unsigned long err_state_hash(const ERR_STATE *a)
340 { 431 {
341 LHASH *ret = NULL; 432 return CRYPTO_THREADID_hash(&a->tid) * 13;
433 }
434static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
435
436static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
437 {
438 return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
439 }
440static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
441
442static LHASH_OF(ERR_STATE) *int_thread_get(int create)
443 {
444 LHASH_OF(ERR_STATE) *ret = NULL;
342 445
343 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 446 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
344 if (!int_thread_hash && create) 447 if (!int_thread_hash && create)
345 { 448 {
346 CRYPTO_push_info("int_thread_get (err.c)"); 449 CRYPTO_push_info("int_thread_get (err.c)");
347 int_thread_hash = lh_new(pid_hash, pid_cmp); 450 int_thread_hash = lh_ERR_STATE_new();
348 CRYPTO_pop_info(); 451 CRYPTO_pop_info();
349 } 452 }
350 if (int_thread_hash) 453 if (int_thread_hash)
@@ -356,7 +459,7 @@ static LHASH *int_thread_get(int create)
356 return ret; 459 return ret;
357 } 460 }
358 461
359static void int_thread_release(LHASH **hash) 462static void int_thread_release(LHASH_OF(ERR_STATE) **hash)
360 { 463 {
361 int i; 464 int i;
362 465
@@ -382,7 +485,7 @@ static void int_thread_release(LHASH **hash)
382static ERR_STATE *int_thread_get_item(const ERR_STATE *d) 485static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
383 { 486 {
384 ERR_STATE *p; 487 ERR_STATE *p;
385 LHASH *hash; 488 LHASH_OF(ERR_STATE) *hash;
386 489
387 err_fns_check(); 490 err_fns_check();
388 hash = ERRFN(thread_get)(0); 491 hash = ERRFN(thread_get)(0);
@@ -390,7 +493,7 @@ static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
390 return NULL; 493 return NULL;
391 494
392 CRYPTO_r_lock(CRYPTO_LOCK_ERR); 495 CRYPTO_r_lock(CRYPTO_LOCK_ERR);
393 p = (ERR_STATE *)lh_retrieve(hash, d); 496 p = lh_ERR_STATE_retrieve(hash, d);
394 CRYPTO_r_unlock(CRYPTO_LOCK_ERR); 497 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
395 498
396 ERRFN(thread_release)(&hash); 499 ERRFN(thread_release)(&hash);
@@ -400,7 +503,7 @@ static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
400static ERR_STATE *int_thread_set_item(ERR_STATE *d) 503static ERR_STATE *int_thread_set_item(ERR_STATE *d)
401 { 504 {
402 ERR_STATE *p; 505 ERR_STATE *p;
403 LHASH *hash; 506 LHASH_OF(ERR_STATE) *hash;
404 507
405 err_fns_check(); 508 err_fns_check();
406 hash = ERRFN(thread_get)(1); 509 hash = ERRFN(thread_get)(1);
@@ -408,7 +511,7 @@ static ERR_STATE *int_thread_set_item(ERR_STATE *d)
408 return NULL; 511 return NULL;
409 512
410 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 513 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
411 p = (ERR_STATE *)lh_insert(hash, d); 514 p = lh_ERR_STATE_insert(hash, d);
412 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 515 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
413 516
414 ERRFN(thread_release)(&hash); 517 ERRFN(thread_release)(&hash);
@@ -418,7 +521,7 @@ static ERR_STATE *int_thread_set_item(ERR_STATE *d)
418static void int_thread_del_item(const ERR_STATE *d) 521static void int_thread_del_item(const ERR_STATE *d)
419 { 522 {
420 ERR_STATE *p; 523 ERR_STATE *p;
421 LHASH *hash; 524 LHASH_OF(ERR_STATE) *hash;
422 525
423 err_fns_check(); 526 err_fns_check();
424 hash = ERRFN(thread_get)(0); 527 hash = ERRFN(thread_get)(0);
@@ -426,12 +529,12 @@ static void int_thread_del_item(const ERR_STATE *d)
426 return; 529 return;
427 530
428 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 531 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
429 p = (ERR_STATE *)lh_delete(hash, d); 532 p = lh_ERR_STATE_delete(hash, d);
430 /* make sure we don't leak memory */ 533 /* make sure we don't leak memory */
431 if (int_thread_hash_references == 1 534 if (int_thread_hash_references == 1
432 && int_thread_hash && (lh_num_items(int_thread_hash) == 0)) 535 && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0)
433 { 536 {
434 lh_free(int_thread_hash); 537 lh_ERR_STATE_free(int_thread_hash);
435 int_thread_hash = NULL; 538 int_thread_hash = NULL;
436 } 539 }
437 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 540 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
@@ -452,6 +555,92 @@ static int int_err_get_next_lib(void)
452 return ret; 555 return ret;
453 } 556 }
454 557
558
559#ifndef OPENSSL_NO_ERR
560#define NUM_SYS_STR_REASONS 127
561#define LEN_SYS_STR_REASON 32
562
563static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
564/* SYS_str_reasons is filled with copies of strerror() results at
565 * initialization.
566 * 'errno' values up to 127 should cover all usual errors,
567 * others will be displayed numerically by ERR_error_string.
568 * It is crucial that we have something for each reason code
569 * that occurs in ERR_str_reasons, or bogus reason strings
570 * will be returned for SYSerr(), which always gets an errno
571 * value and never one of those 'standard' reason codes. */
572
573static void build_SYS_str_reasons(void)
574 {
575 /* OPENSSL_malloc cannot be used here, use static storage instead */
576 static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
577 int i;
578 static int init = 1;
579
580 CRYPTO_r_lock(CRYPTO_LOCK_ERR);
581 if (!init)
582 {
583 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
584 return;
585 }
586
587 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
588 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
589 if (!init)
590 {
591 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
592 return;
593 }
594
595 for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
596 {
597 ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
598
599 str->error = (unsigned long)i;
600 if (str->string == NULL)
601 {
602 char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
603 char *src = strerror(i);
604 if (src != NULL)
605 {
606 strncpy(*dest, src, sizeof *dest);
607 (*dest)[sizeof *dest - 1] = '\0';
608 str->string = *dest;
609 }
610 }
611 if (str->string == NULL)
612 str->string = "unknown";
613 }
614
615 /* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
616 * as required by ERR_load_strings. */
617
618 init = 0;
619
620 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
621 }
622#endif
623
624#define err_clear_data(p,i) \
625 do { \
626 if (((p)->err_data[i] != NULL) && \
627 (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
628 { \
629 OPENSSL_free((p)->err_data[i]); \
630 (p)->err_data[i]=NULL; \
631 } \
632 (p)->err_data_flags[i]=0; \
633 } while(0)
634
635#define err_clear(p,i) \
636 do { \
637 (p)->err_flags[i]=0; \
638 (p)->err_buffer[i]=0; \
639 err_clear_data(p,i); \
640 (p)->err_file[i]=NULL; \
641 (p)->err_line[i]= -1; \
642 } while(0)
643
455static void ERR_STATE_free(ERR_STATE *s) 644static void ERR_STATE_free(ERR_STATE *s)
456 { 645 {
457 int i; 646 int i;
@@ -466,6 +655,18 @@ static void ERR_STATE_free(ERR_STATE *s)
466 OPENSSL_free(s); 655 OPENSSL_free(s);
467 } 656 }
468 657
658void ERR_load_ERR_strings(void)
659 {
660 err_fns_check();
661#ifndef OPENSSL_NO_ERR
662 err_load_strings(0,ERR_str_libraries);
663 err_load_strings(0,ERR_str_reasons);
664 err_load_strings(ERR_LIB_SYS,ERR_str_functs);
665 build_SYS_str_reasons();
666 err_load_strings(ERR_LIB_SYS,SYS_str_reasons);
667#endif
668 }
669
469static void err_load_strings(int lib, ERR_STRING_DATA *str) 670static void err_load_strings(int lib, ERR_STRING_DATA *str)
470 { 671 {
471 while (str->error) 672 while (str->error)
@@ -479,7 +680,7 @@ static void err_load_strings(int lib, ERR_STRING_DATA *str)
479 680
480void ERR_load_strings(int lib, ERR_STRING_DATA *str) 681void ERR_load_strings(int lib, ERR_STRING_DATA *str)
481 { 682 {
482 err_fns_check(); 683 ERR_load_ERR_strings();
483 err_load_strings(lib, str); 684 err_load_strings(lib, str);
484 } 685 }
485 686
@@ -500,19 +701,237 @@ void ERR_free_strings(void)
500 ERRFN(err_del)(); 701 ERRFN(err_del)();
501 } 702 }
502 703
503LHASH *ERR_get_string_table(void) 704/********************************************************/
705
706void ERR_put_error(int lib, int func, int reason, const char *file,
707 int line)
708 {
709 ERR_STATE *es;
710
711#ifdef _OSD_POSIX
712 /* In the BS2000-OSD POSIX subsystem, the compiler generates
713 * path names in the form "*POSIX(/etc/passwd)".
714 * This dirty hack strips them to something sensible.
715 * @@@ We shouldn't modify a const string, though.
716 */
717 if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {
718 char *end;
719
720 /* Skip the "*POSIX(" prefix */
721 file += sizeof("*POSIX(")-1;
722 end = &file[strlen(file)-1];
723 if (*end == ')')
724 *end = '\0';
725 /* Optional: use the basename of the path only. */
726 if ((end = strrchr(file, '/')) != NULL)
727 file = &end[1];
728 }
729#endif
730 es=ERR_get_state();
731
732 es->top=(es->top+1)%ERR_NUM_ERRORS;
733 if (es->top == es->bottom)
734 es->bottom=(es->bottom+1)%ERR_NUM_ERRORS;
735 es->err_flags[es->top]=0;
736 es->err_buffer[es->top]=ERR_PACK(lib,func,reason);
737 es->err_file[es->top]=file;
738 es->err_line[es->top]=line;
739 err_clear_data(es,es->top);
740 }
741
742void ERR_clear_error(void)
743 {
744 int i;
745 ERR_STATE *es;
746
747 es=ERR_get_state();
748
749 for (i=0; i<ERR_NUM_ERRORS; i++)
750 {
751 err_clear(es,i);
752 }
753 es->top=es->bottom=0;
754 }
755
756
757unsigned long ERR_get_error(void)
758 { return(get_error_values(1,0,NULL,NULL,NULL,NULL)); }
759
760unsigned long ERR_get_error_line(const char **file,
761 int *line)
762 { return(get_error_values(1,0,file,line,NULL,NULL)); }
763
764unsigned long ERR_get_error_line_data(const char **file, int *line,
765 const char **data, int *flags)
766 { return(get_error_values(1,0,file,line,data,flags)); }
767
768
769unsigned long ERR_peek_error(void)
770 { return(get_error_values(0,0,NULL,NULL,NULL,NULL)); }
771
772unsigned long ERR_peek_error_line(const char **file, int *line)
773 { return(get_error_values(0,0,file,line,NULL,NULL)); }
774
775unsigned long ERR_peek_error_line_data(const char **file, int *line,
776 const char **data, int *flags)
777 { return(get_error_values(0,0,file,line,data,flags)); }
778
779
780unsigned long ERR_peek_last_error(void)
781 { return(get_error_values(0,1,NULL,NULL,NULL,NULL)); }
782
783unsigned long ERR_peek_last_error_line(const char **file, int *line)
784 { return(get_error_values(0,1,file,line,NULL,NULL)); }
785
786unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
787 const char **data, int *flags)
788 { return(get_error_values(0,1,file,line,data,flags)); }
789
790
791static unsigned long get_error_values(int inc, int top, const char **file, int *line,
792 const char **data, int *flags)
793 {
794 int i=0;
795 ERR_STATE *es;
796 unsigned long ret;
797
798 es=ERR_get_state();
799
800 if (inc && top)
801 {
802 if (file) *file = "";
803 if (line) *line = 0;
804 if (data) *data = "";
805 if (flags) *flags = 0;
806
807 return ERR_R_INTERNAL_ERROR;
808 }
809
810 if (es->bottom == es->top) return 0;
811 if (top)
812 i=es->top; /* last error */
813 else
814 i=(es->bottom+1)%ERR_NUM_ERRORS; /* first error */
815
816 ret=es->err_buffer[i];
817 if (inc)
818 {
819 es->bottom=i;
820 es->err_buffer[i]=0;
821 }
822
823 if ((file != NULL) && (line != NULL))
824 {
825 if (es->err_file[i] == NULL)
826 {
827 *file="NA";
828 if (line != NULL) *line=0;
829 }
830 else
831 {
832 *file=es->err_file[i];
833 if (line != NULL) *line=es->err_line[i];
834 }
835 }
836
837 if (data == NULL)
838 {
839 if (inc)
840 {
841 err_clear_data(es, i);
842 }
843 }
844 else
845 {
846 if (es->err_data[i] == NULL)
847 {
848 *data="";
849 if (flags != NULL) *flags=0;
850 }
851 else
852 {
853 *data=es->err_data[i];
854 if (flags != NULL) *flags=es->err_data_flags[i];
855 }
856 }
857 return ret;
858 }
859
860void ERR_error_string_n(unsigned long e, char *buf, size_t len)
861 {
862 char lsbuf[64], fsbuf[64], rsbuf[64];
863 const char *ls,*fs,*rs;
864 unsigned long l,f,r;
865
866 l=ERR_GET_LIB(e);
867 f=ERR_GET_FUNC(e);
868 r=ERR_GET_REASON(e);
869
870 ls=ERR_lib_error_string(e);
871 fs=ERR_func_error_string(e);
872 rs=ERR_reason_error_string(e);
873
874 if (ls == NULL)
875 BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
876 if (fs == NULL)
877 BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
878 if (rs == NULL)
879 BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
880
881 BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf,
882 fs?fs:fsbuf, rs?rs:rsbuf);
883 if (strlen(buf) == len-1)
884 {
885 /* output may be truncated; make sure we always have 5
886 * colon-separated fields, i.e. 4 colons ... */
887#define NUM_COLONS 4
888 if (len > NUM_COLONS) /* ... if possible */
889 {
890 int i;
891 char *s = buf;
892
893 for (i = 0; i < NUM_COLONS; i++)
894 {
895 char *colon = strchr(s, ':');
896 if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
897 {
898 /* set colon no. i at last possible position
899 * (buf[len-1] is the terminating 0)*/
900 colon = &buf[len-1] - NUM_COLONS + i;
901 *colon = ':';
902 }
903 s = colon + 1;
904 }
905 }
906 }
907 }
908
909/* BAD for multi-threading: uses a local buffer if ret == NULL */
910/* ERR_error_string_n should be used instead for ret != NULL
911 * as ERR_error_string cannot know how large the buffer is */
912char *ERR_error_string(unsigned long e, char *ret)
913 {
914 static char buf[256];
915
916 if (ret == NULL) ret=buf;
917 ERR_error_string_n(e, ret, 256);
918
919 return ret;
920 }
921
922LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void)
504 { 923 {
505 err_fns_check(); 924 err_fns_check();
506 return ERRFN(err_get)(0); 925 return ERRFN(err_get)(0);
507 } 926 }
508 927
509LHASH *ERR_get_err_state_table(void) 928LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void)
510 { 929 {
511 err_fns_check(); 930 err_fns_check();
512 return ERRFN(thread_get)(0); 931 return ERRFN(thread_get)(0);
513 } 932 }
514 933
515void ERR_release_err_state_table(LHASH **hash) 934void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash)
516 { 935 {
517 err_fns_check(); 936 err_fns_check();
518 ERRFN(thread_release)(hash); 937 ERRFN(thread_release)(hash);
@@ -561,66 +980,37 @@ const char *ERR_reason_error_string(unsigned long e)
561 return((p == NULL)?NULL:p->string); 980 return((p == NULL)?NULL:p->string);
562 } 981 }
563 982
564/* static unsigned long err_hash(ERR_STRING_DATA *a) */ 983void ERR_remove_thread_state(const CRYPTO_THREADID *id)
565static unsigned long err_hash(const void *a_void)
566 {
567 unsigned long ret,l;
568
569 l=((const ERR_STRING_DATA *)a_void)->error;
570 ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
571 return(ret^ret%19*13);
572 }
573
574/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) */
575static int err_cmp(const void *a_void, const void *b_void)
576 {
577 return((int)(((const ERR_STRING_DATA *)a_void)->error -
578 ((const ERR_STRING_DATA *)b_void)->error));
579 }
580
581/* static unsigned long pid_hash(ERR_STATE *a) */
582static unsigned long pid_hash(const void *a_void)
583 {
584 return(((const ERR_STATE *)a_void)->pid*13);
585 }
586
587/* static int pid_cmp(ERR_STATE *a, ERR_STATE *b) */
588static int pid_cmp(const void *a_void, const void *b_void)
589 {
590 return((int)((long)((const ERR_STATE *)a_void)->pid -
591 (long)((const ERR_STATE *)b_void)->pid));
592 }
593#ifdef OPENSSL_FIPS
594static void int_err_remove_state(unsigned long pid)
595#else
596void ERR_remove_state(unsigned long pid)
597#endif
598 { 984 {
599 ERR_STATE tmp; 985 ERR_STATE tmp;
600 986
987 if (id)
988 CRYPTO_THREADID_cpy(&tmp.tid, id);
989 else
990 CRYPTO_THREADID_current(&tmp.tid);
601 err_fns_check(); 991 err_fns_check();
602 if (pid == 0)
603 pid=(unsigned long)CRYPTO_thread_id();
604 tmp.pid=pid;
605 /* thread_del_item automatically destroys the LHASH if the number of 992 /* thread_del_item automatically destroys the LHASH if the number of
606 * items reaches zero. */ 993 * items reaches zero. */
607 ERRFN(thread_del_item)(&tmp); 994 ERRFN(thread_del_item)(&tmp);
608 } 995 }
609 996
610#ifdef OPENSSL_FIPS 997#ifndef OPENSSL_NO_DEPRECATED
611 static ERR_STATE *int_err_get_state(void) 998void ERR_remove_state(unsigned long pid)
612#else 999 {
613ERR_STATE *ERR_get_state(void) 1000 ERR_remove_thread_state(NULL);
1001 }
614#endif 1002#endif
1003
1004ERR_STATE *ERR_get_state(void)
615 { 1005 {
616 static ERR_STATE fallback; 1006 static ERR_STATE fallback;
617 ERR_STATE *ret,tmp,*tmpp=NULL; 1007 ERR_STATE *ret,tmp,*tmpp=NULL;
618 int i; 1008 int i;
619 unsigned long pid; 1009 CRYPTO_THREADID tid;
620 1010
621 err_fns_check(); 1011 err_fns_check();
622 pid=(unsigned long)CRYPTO_thread_id(); 1012 CRYPTO_THREADID_current(&tid);
623 tmp.pid=pid; 1013 CRYPTO_THREADID_cpy(&tmp.tid, &tid);
624 ret=ERRFN(thread_get_item)(&tmp); 1014 ret=ERRFN(thread_get_item)(&tmp);
625 1015
626 /* ret == the error state, if NULL, make a new one */ 1016 /* ret == the error state, if NULL, make a new one */
@@ -628,7 +1018,7 @@ ERR_STATE *ERR_get_state(void)
628 { 1018 {
629 ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); 1019 ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
630 if (ret == NULL) return(&fallback); 1020 if (ret == NULL) return(&fallback);
631 ret->pid=pid; 1021 CRYPTO_THREADID_cpy(&ret->tid, &tid);
632 ret->top=0; 1022 ret->top=0;
633 ret->bottom=0; 1023 ret->bottom=0;
634 for (i=0; i<ERR_NUM_ERRORS; i++) 1024 for (i=0; i<ERR_NUM_ERRORS; i++)
@@ -651,15 +1041,95 @@ ERR_STATE *ERR_get_state(void)
651 return ret; 1041 return ret;
652 } 1042 }
653 1043
654#ifdef OPENSSL_FIPS
655void int_ERR_lib_init(void)
656 {
657 int_ERR_set_state_func(int_err_get_state, int_err_remove_state);
658 }
659#endif
660
661int ERR_get_next_error_library(void) 1044int ERR_get_next_error_library(void)
662 { 1045 {
663 err_fns_check(); 1046 err_fns_check();
664 return ERRFN(get_next_lib)(); 1047 return ERRFN(get_next_lib)();
665 } 1048 }
1049
1050void ERR_set_error_data(char *data, int flags)
1051 {
1052 ERR_STATE *es;
1053 int i;
1054
1055 es=ERR_get_state();
1056
1057 i=es->top;
1058 if (i == 0)
1059 i=ERR_NUM_ERRORS-1;
1060
1061 err_clear_data(es,i);
1062 es->err_data[i]=data;
1063 es->err_data_flags[i]=flags;
1064 }
1065
1066void ERR_add_error_data(int num, ...)
1067 {
1068 va_list args;
1069 int i,n,s;
1070 char *str,*p,*a;
1071
1072 s=80;
1073 str=OPENSSL_malloc(s+1);
1074 if (str == NULL) return;
1075 str[0]='\0';
1076
1077 va_start(args, num);
1078 n=0;
1079 for (i=0; i<num; i++)
1080 {
1081 a=va_arg(args, char*);
1082 /* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
1083 if (a != NULL)
1084 {
1085 n+=strlen(a);
1086 if (n > s)
1087 {
1088 s=n+20;
1089 p=OPENSSL_realloc(str,s+1);
1090 if (p == NULL)
1091 {
1092 OPENSSL_free(str);
1093 goto err;
1094 }
1095 else
1096 str=p;
1097 }
1098 BUF_strlcat(str,a,(size_t)s+1);
1099 }
1100 }
1101 ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
1102
1103err:
1104 va_end(args);
1105 }
1106
1107int ERR_set_mark(void)
1108 {
1109 ERR_STATE *es;
1110
1111 es=ERR_get_state();
1112
1113 if (es->bottom == es->top) return 0;
1114 es->err_flags[es->top]|=ERR_FLAG_MARK;
1115 return 1;
1116 }
1117
1118int ERR_pop_to_mark(void)
1119 {
1120 ERR_STATE *es;
1121
1122 es=ERR_get_state();
1123
1124 while(es->bottom != es->top
1125 && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0)
1126 {
1127 err_clear(es,es->top);
1128 es->top-=1;
1129 if (es->top == -1) es->top=ERR_NUM_ERRORS-1;
1130 }
1131
1132 if (es->bottom == es->top) return 0;
1133 es->err_flags[es->top]&=~ERR_FLAG_MARK;
1134 return 1;
1135 }