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