err.c revision ac6c5371f5e5beafc345f312a097c3ebd4766afa
1/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay@cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay@cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] 56 */ 57/* ==================================================================== 58 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. 59 * 60 * Redistribution and use in source and binary forms, with or without 61 * modification, are permitted provided that the following conditions 62 * are met: 63 * 64 * 1. Redistributions of source code must retain the above copyright 65 * notice, this list of conditions and the following disclaimer. 66 * 67 * 2. Redistributions in binary form must reproduce the above copyright 68 * notice, this list of conditions and the following disclaimer in 69 * the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3. All advertising materials mentioning features or use of this 73 * software must display the following acknowledgment: 74 * "This product includes software developed by the OpenSSL Project 75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 76 * 77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 78 * endorse or promote products derived from this software without 79 * prior written permission. For written permission, please contact 80 * openssl-core@openssl.org. 81 * 82 * 5. Products derived from this software may not be called "OpenSSL" 83 * nor may "OpenSSL" appear in their names without prior written 84 * permission of the OpenSSL Project. 85 * 86 * 6. Redistributions of any form whatsoever must retain the following 87 * acknowledgment: 88 * "This product includes software developed by the OpenSSL Project 89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 90 * 91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 102 * OF THE POSSIBILITY OF SUCH DAMAGE. 103 * ==================================================================== 104 * 105 * This product includes cryptographic software written by Eric Young 106 * (eay@cryptsoft.com). This product includes software written by Tim 107 * Hudson (tjh@cryptsoft.com). */ 108 109#include <openssl/err.h> 110 111#include <assert.h> 112#include <errno.h> 113#include <inttypes.h> 114#include <stdarg.h> 115#include <stdio.h> 116#include <string.h> 117 118#if defined(OPENSSL_WINDOWS) 119#pragma warning(push, 3) 120#include <windows.h> 121#pragma warning(pop) 122#endif 123 124#include <openssl/lhash.h> 125#include <openssl/mem.h> 126#include <openssl/thread.h> 127 128 129/* err_fns contains a pointer to the current error implementation. */ 130static const struct ERR_FNS_st *err_fns = NULL; 131extern const struct ERR_FNS_st openssl_err_default_impl; 132 133#define ERRFN(a) err_fns->a 134 135/* err_fns_check is an internal function that checks whether "err_fns" is set 136 * and if not, sets it to the default. */ 137static void err_fns_check(void) { 138 /* In practice, this is not a race problem because loading the error strings 139 * at init time will cause this pointer to be set before the process goes 140 * multithreaded. */ 141 if (err_fns) { 142 return; 143 } 144 145 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 146 if (!err_fns) { 147 err_fns = &openssl_err_default_impl; 148 } 149 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 150} 151 152/* err_clear_data frees the optional |data| member of the given error. */ 153static void err_clear_data(struct err_error_st *error) { 154 if (error->data != NULL && (error->flags & ERR_FLAG_MALLOCED) != 0) { 155 OPENSSL_free(error->data); 156 } 157 error->data = NULL; 158 error->flags &= ~ERR_FLAG_MALLOCED; 159} 160 161/* err_clear clears the given queued error. */ 162static void err_clear(struct err_error_st *error) { 163 err_clear_data(error); 164 memset(error, 0, sizeof(struct err_error_st)); 165} 166 167/* err_get_state gets the ERR_STATE object for the current thread. */ 168static ERR_STATE *err_get_state(void) { 169 err_fns_check(); 170 return ERRFN(get_state)(); 171} 172 173static uint32_t get_error_values(int inc, int top, const char **file, int *line, 174 const char **data, int *flags) { 175 unsigned i = 0; 176 ERR_STATE *state; 177 struct err_error_st *error; 178 uint32_t ret; 179 180 state = err_get_state(); 181 if (state == NULL || state->bottom == state->top) { 182 return 0; 183 } 184 185 if (top) { 186 assert(!inc); 187 /* last error */ 188 i = state->top; 189 } else { 190 i = (state->bottom + 1) % ERR_NUM_ERRORS; 191 } 192 193 error = &state->errors[i]; 194 ret = error->packed; 195 196 if (file != NULL && line != NULL) { 197 if (error->file == NULL) { 198 *file = "NA"; 199 *line = 0; 200 } else { 201 *file = error->file; 202 *line = error->line; 203 } 204 } 205 206 if (data != NULL) { 207 if (error->data == NULL) { 208 *data = ""; 209 if (flags != NULL) { 210 *flags = 0; 211 } 212 } else { 213 *data = error->data; 214 if (flags != NULL) { 215 *flags = error->flags & ERR_FLAG_PUBLIC_MASK; 216 } 217 /* If this error is being removed, take ownership of data from 218 * the error. The semantics are such that the caller doesn't 219 * take ownership either. Instead the error system takes 220 * ownership and retains it until the next call that affects the 221 * error queue. */ 222 if (inc) { 223 if (error->flags & ERR_FLAG_MALLOCED) { 224 if (state->to_free) { 225 OPENSSL_free(state->to_free); 226 } 227 state->to_free = error->data; 228 } 229 error->data = NULL; 230 error->flags = 0; 231 } 232 } 233 } 234 235 if (inc) { 236 assert(!top); 237 err_clear(error); 238 state->bottom = i; 239 } 240 241 return ret; 242} 243 244uint32_t ERR_get_error(void) { 245 return get_error_values(1, 0, NULL, NULL, NULL, NULL); 246} 247 248uint32_t ERR_get_error_line(const char **file, int *line) { 249 return get_error_values(1, 0, file, line, NULL, NULL); 250} 251 252uint32_t ERR_get_error_line_data(const char **file, int *line, 253 const char **data, int *flags) { 254 return get_error_values(1, 0, file, line, data, flags); 255} 256 257uint32_t ERR_peek_error(void) { 258 return get_error_values(0, 0, NULL, NULL, NULL, NULL); 259} 260 261uint32_t ERR_peek_error_line(const char **file, int *line) { 262 return get_error_values(0, 0, file, line, NULL, NULL); 263} 264 265uint32_t ERR_peek_error_line_data(const char **file, int *line, 266 const char **data, int *flags) { 267 return get_error_values(0, 0, file, line, data, flags); 268} 269 270uint32_t ERR_peek_last_error(void) { 271 return get_error_values(0, 1, NULL, NULL, NULL, NULL); 272} 273 274uint32_t ERR_peek_last_error_line(const char **file, int *line) { 275 return get_error_values(0, 1, file, line, NULL, NULL); 276} 277 278uint32_t ERR_peek_last_error_line_data(const char **file, int *line, 279 const char **data, int *flags) { 280 return get_error_values(0, 1, file, line, data, flags); 281} 282 283void ERR_clear_error(void) { 284 ERR_STATE *const state = err_get_state(); 285 unsigned i; 286 287 if (state == NULL) { 288 return; 289 } 290 291 for (i = 0; i < ERR_NUM_ERRORS; i++) { 292 err_clear(&state->errors[i]); 293 } 294 if (state->to_free) { 295 OPENSSL_free(state->to_free); 296 state->to_free = NULL; 297 } 298 299 state->top = state->bottom = 0; 300} 301 302static void err_state_free(ERR_STATE *state) { 303 unsigned i; 304 305 for (i = 0; i < ERR_NUM_ERRORS; i++) { 306 err_clear(&state->errors[i]); 307 } 308 if (state->to_free) { 309 OPENSSL_free(state->to_free); 310 } 311 OPENSSL_free(state); 312} 313 314void ERR_remove_thread_state(const CRYPTO_THREADID *tid) { 315 CRYPTO_THREADID current; 316 ERR_STATE *state; 317 318 if (tid == NULL) { 319 CRYPTO_THREADID_current(¤t); 320 tid = ¤t; 321 } 322 323 err_fns_check(); 324 state = ERRFN(release_state)(tid); 325 if (state == NULL) { 326 return; 327 } 328 329 err_state_free(state); 330} 331 332int ERR_get_next_error_library(void) { 333 err_fns_check(); 334 return ERRFN(get_next_library)(); 335} 336 337void ERR_clear_system_error(void) { 338 errno = 0; 339} 340 341char *ERR_error_string(uint32_t packed_error, char *ret) { 342 static char buf[ERR_ERROR_STRING_BUF_LEN]; 343 344 if (ret == NULL) { 345 /* TODO(fork): remove this. */ 346 ret = buf; 347 } 348 349#if !defined(NDEBUG) 350 /* This is aimed to help catch callers who don't provide 351 * |ERR_ERROR_STRING_BUF_LEN| bytes of space. */ 352 memset(ret, 0, ERR_ERROR_STRING_BUF_LEN); 353#endif 354 355 ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN); 356 357 return ret; 358} 359 360void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) { 361 char lib_buf[64], func_buf[64], reason_buf[64]; 362 const char *lib_str, *func_str, *reason_str; 363 unsigned lib, func, reason; 364 365 if (len == 0) { 366 return; 367 } 368 369 lib = ERR_GET_LIB(packed_error); 370 func = ERR_GET_FUNC(packed_error); 371 reason = ERR_GET_REASON(packed_error); 372 373 lib_str = ERR_lib_error_string(packed_error); 374 func_str = ERR_func_error_string(packed_error); 375 reason_str = ERR_reason_error_string(packed_error); 376 377 if (lib_str == NULL) { 378 BIO_snprintf(lib_buf, sizeof(lib_buf), "lib(%u)", lib); 379 lib_str = lib_buf; 380 } 381 382 if (func_str == NULL) { 383 BIO_snprintf(func_buf, sizeof(func_buf), "func(%u)", func); 384 func_str = func_buf; 385 } 386 387 if (reason_str == NULL) { 388 BIO_snprintf(reason_buf, sizeof(reason_buf), "reason(%u)", reason); 389 reason_str = reason_buf; 390 } 391 392 BIO_snprintf(buf, len, "error:%08" PRIx32 ":%s:%s:%s", 393 packed_error, lib_str, func_str, reason_str); 394 395 if (strlen(buf) == len - 1) { 396 /* output may be truncated; make sure we always have 5 colon-separated 397 * fields, i.e. 4 colons. */ 398 static const unsigned num_colons = 4; 399 unsigned i; 400 char *s = buf; 401 402 if (len <= num_colons) { 403 /* In this situation it's not possible to ensure that the correct number 404 * of colons are included in the output. */ 405 return; 406 } 407 408 for (i = 0; i < num_colons; i++) { 409 char *colon = strchr(s, ':'); 410 char *last_pos = &buf[len - 1] - num_colons + i; 411 412 if (colon == NULL || colon > last_pos) { 413 /* set colon |i| at last possible position (buf[len-1] is the 414 * terminating 0). If we're setting this colon, then all whole of the 415 * rest of the string must be colons in order to have the correct 416 * number. */ 417 memset(last_pos, ':', num_colons - i); 418 break; 419 } 420 421 s = colon + 1; 422 } 423 } 424} 425 426/* err_component_error_string returns the error string associated with 427 * |packed_error|, which must be of a special form matching the keys inserted 428 * into the error hash table. */ 429static const char *err_component_error_string(uint32_t packed_error) { 430 ERR_STRING_DATA *p; 431 432 err_fns_check(); 433 p = ERRFN(get_item)(packed_error); 434 435 if (p == NULL) { 436 return NULL; 437 } 438 return p->string; 439} 440 441const char *ERR_lib_error_string(uint32_t packed_error) { 442 return err_component_error_string(ERR_PACK(ERR_GET_LIB(packed_error), 0, 0)); 443} 444 445const char *ERR_func_error_string(uint32_t packed_error) { 446 return err_component_error_string( 447 ERR_PACK(ERR_GET_LIB(packed_error), ERR_GET_FUNC(packed_error), 0)); 448} 449 450const char *ERR_reason_error_string(uint32_t packed_error) { 451 const char *reason_str = err_component_error_string( 452 ERR_PACK(ERR_GET_LIB(packed_error), 0, ERR_GET_REASON(packed_error))); 453 454 if (reason_str != NULL) { 455 return reason_str; 456 } 457 458 return err_component_error_string( 459 ERR_PACK(0, 0, ERR_GET_REASON(packed_error))); 460} 461 462void ERR_print_errors_cb(ERR_print_errors_callback_t callback, void *ctx) { 463 CRYPTO_THREADID current_thread; 464 char buf[ERR_ERROR_STRING_BUF_LEN]; 465 char buf2[1024]; 466 unsigned long thread_hash; 467 const char *file, *data; 468 int line, flags; 469 uint32_t packed_error; 470 471 CRYPTO_THREADID_current(¤t_thread); 472 thread_hash = CRYPTO_THREADID_hash(¤t_thread); 473 474 for (;;) { 475 packed_error = ERR_get_error_line_data(&file, &line, &data, &flags); 476 if (packed_error == 0) { 477 break; 478 } 479 480 ERR_error_string_n(packed_error, buf, sizeof(buf)); 481 BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", thread_hash, buf, 482 file, line, (flags & ERR_FLAG_STRING) ? data : ""); 483 if (callback(buf2, strlen(buf2), ctx) <= 0) { 484 break; 485 } 486 } 487} 488 489/* err_set_error_data sets the data on the most recent error. The |flags| 490 * argument is a combination of the |ERR_FLAG_*| values. */ 491static void err_set_error_data(char *data, int flags) { 492 ERR_STATE *const state = err_get_state(); 493 struct err_error_st *error; 494 495 if (state == NULL || state->top == state->bottom) { 496 if (flags & ERR_FLAG_MALLOCED) { 497 OPENSSL_free(data); 498 } 499 return; 500 } 501 502 error = &state->errors[state->top]; 503 504 err_clear_data(error); 505 error->data = data; 506 error->flags = flags; 507} 508 509void ERR_put_error(int library, int func, int reason, const char *file, 510 unsigned line) { 511 ERR_STATE *const state = err_get_state(); 512 struct err_error_st *error; 513 514 if (state == NULL) { 515 return; 516 } 517 518 if (library == ERR_LIB_SYS && reason == 0) { 519#if defined(WIN32) 520 reason = GetLastError(); 521#else 522 reason = errno; 523#endif 524 } 525 526 state->top = (state->top + 1) % ERR_NUM_ERRORS; 527 if (state->top == state->bottom) { 528 state->bottom = (state->bottom + 1) % ERR_NUM_ERRORS; 529 } 530 531 error = &state->errors[state->top]; 532 err_clear(error); 533 error->file = file; 534 error->line = line; 535 error->packed = ERR_PACK(library, func, reason); 536} 537 538/* ERR_add_error_data_vdata takes a variable number of const char* pointers, 539 * concatenates them and sets the result as the data on the most recent 540 * error. */ 541static void err_add_error_vdata(unsigned num, va_list args) { 542 size_t alloced, new_len, len = 0, substr_len; 543 char *buf; 544 const char *substr; 545 unsigned i; 546 547 alloced = 80; 548 buf = OPENSSL_malloc(alloced + 1); 549 if (buf == NULL) { 550 return; 551 } 552 553 for (i = 0; i < num; i++) { 554 substr = va_arg(args, const char *); 555 if (substr == NULL) { 556 continue; 557 } 558 559 substr_len = strlen(substr); 560 new_len = len + substr_len; 561 if (new_len > alloced) { 562 char *new_buf; 563 564 if (alloced + 20 + 1 < alloced) { 565 /* overflow. */ 566 OPENSSL_free(buf); 567 return; 568 } 569 570 alloced = new_len + 20; 571 new_buf = OPENSSL_realloc(buf, alloced + 1); 572 if (new_buf == NULL) { 573 OPENSSL_free(buf); 574 return; 575 } 576 buf = new_buf; 577 } 578 579 memcpy(buf + len, substr, substr_len); 580 len = new_len; 581 } 582 583 buf[len] = 0; 584 err_set_error_data(buf, ERR_FLAG_MALLOCED | ERR_FLAG_STRING); 585} 586 587void ERR_add_error_data(unsigned count, ...) { 588 va_list args; 589 va_start(args, count); 590 err_add_error_vdata(count, args); 591 va_end(args); 592} 593 594void ERR_add_error_dataf(const char *format, ...) { 595 va_list ap; 596 char *buf; 597 static const unsigned buf_len = 256; 598 599 /* A fixed-size buffer is used because va_copy (which would be needed in 600 * order to call vsnprintf twice and measure the buffer) wasn't defined until 601 * C99. */ 602 buf = OPENSSL_malloc(buf_len + 1); 603 if (buf == NULL) { 604 return; 605 } 606 607 va_start(ap, format); 608 BIO_vsnprintf(buf, buf_len, format, ap); 609 buf[buf_len] = 0; 610 va_end(ap); 611 612 err_set_error_data(buf, ERR_FLAG_MALLOCED | ERR_FLAG_STRING); 613} 614 615int ERR_set_mark(void) { 616 ERR_STATE *const state = err_get_state(); 617 618 if (state == NULL || state->bottom == state->top) { 619 return 0; 620 } 621 state->errors[state->top].flags |= ERR_FLAG_MARK; 622 return 1; 623} 624 625int ERR_pop_to_mark(void) { 626 ERR_STATE *const state = err_get_state(); 627 628 if (state == NULL) { 629 return 0; 630 } 631 632 while (state->bottom != state->top) { 633 struct err_error_st *error = &state->errors[state->top]; 634 635 if ((error->flags & ERR_FLAG_MARK) != 0) { 636 error->flags &= ~ERR_FLAG_MARK; 637 return 1; 638 } 639 640 err_clear(error); 641 if (state->top == 0) { 642 state->top = ERR_NUM_ERRORS - 1; 643 } else { 644 state->top--; 645 } 646 } 647 648 return 0; 649} 650 651static const char *const kLibraryNames[ERR_NUM_LIBS] = { 652 "invalid library (0)", 653 "unknown library", /* ERR_LIB_NONE */ 654 "system library", /* ERR_LIB_SYS */ 655 "bignum routines", /* ERR_LIB_BN */ 656 "RSA routines", /* ERR_LIB_RSA */ 657 "Diffie-Hellman routines", /* ERR_LIB_DH */ 658 "public key routines", /* ERR_LIB_EVP */ 659 "memory buffer routines", /* ERR_LIB_BUF */ 660 "object identifier routines", /* ERR_LIB_OBJ */ 661 "PEM routines", /* ERR_LIB_PEM */ 662 "DSA routines", /* ERR_LIB_DSA */ 663 "X.509 certificate routines", /* ERR_LIB_X509 */ 664 "ASN.1 encoding routines", /* ERR_LIB_ASN1 */ 665 "configuration file routines", /* ERR_LIB_CONF */ 666 "common libcrypto routines", /* ERR_LIB_CRYPTO */ 667 "elliptic curve routines", /* ERR_LIB_EC */ 668 "SSL routines", /* ERR_LIB_SSL */ 669 "BIO routines", /* ERR_LIB_BIO */ 670 "PKCS7 routines", /* ERR_LIB_PKCS7 */ 671 "PKCS8 routines", /* ERR_LIB_PKCS8 */ 672 "X509 V3 routines", /* ERR_LIB_X509V3 */ 673 "random number generator", /* ERR_LIB_RAND */ 674 "ENGINE routines", /* ERR_LIB_ENGINE */ 675 "OCSP routines", /* ERR_LIB_OCSP */ 676 "UI routines", /* ERR_LIB_UI */ 677 "COMP routines", /* ERR_LIB_COMP */ 678 "ECDSA routines", /* ERR_LIB_ECDSA */ 679 "ECDH routines", /* ERR_LIB_ECDH */ 680 "HMAC routines", /* ERR_LIB_HMAC */ 681 "Digest functions", /* ERR_LIB_DIGEST */ 682 "Cipher functions", /* ERR_LIB_CIPHER */ 683 "User defined functions", /* ERR_LIB_USER */ 684 "HKDF functions", /* ERR_LIB_HKDF */ 685}; 686 687#define NUM_SYS_ERRNOS 127 688 689/* kStaticErrors provides storage for ERR_STRING_DATA values that are created 690 * at init time because we assume that ERR_STRING_DATA structures aren't 691 * allocated on the heap. */ 692static ERR_STRING_DATA kStaticErrors[ERR_NUM_LIBS * 2 + NUM_SYS_ERRNOS]; 693 694static const ERR_STRING_DATA kGlobalErrors[] = { 695 {ERR_R_MALLOC_FAILURE, "malloc failure"}, 696 {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, "function should not be called"}, 697 {ERR_R_PASSED_NULL_PARAMETER, "passed a null parameter"}, 698 {ERR_R_INTERNAL_ERROR, "internal error"}, 699 {ERR_R_OVERFLOW, "overflow"}, 700 701 {ERR_PACK(ERR_LIB_SYS, SYS_F_fopen, 0), "fopen"}, 702 {ERR_PACK(ERR_LIB_SYS, SYS_F_fclose, 0), "fclose"}, 703 {ERR_PACK(ERR_LIB_SYS, SYS_F_fread, 0), "fread"}, 704 {ERR_PACK(ERR_LIB_SYS, SYS_F_fwrite, 0), "fwrite"}, 705 {ERR_PACK(ERR_LIB_SYS, SYS_F_socket, 0), "socket"}, 706 {ERR_PACK(ERR_LIB_SYS, SYS_F_setsockopt, 0), "setsockopt"}, 707 {ERR_PACK(ERR_LIB_SYS, SYS_F_connect, 0), "connect"}, 708 {ERR_PACK(ERR_LIB_SYS, SYS_F_getaddrinfo, 0), "getaddrinfo"}, 709 710 {0, NULL}, 711}; 712 713 714extern const ERR_STRING_DATA ASN1_error_string_data[]; 715extern const ERR_STRING_DATA BIO_error_string_data[]; 716extern const ERR_STRING_DATA BN_error_string_data[]; 717extern const ERR_STRING_DATA BUF_error_string_data[]; 718extern const ERR_STRING_DATA CIPHER_error_string_data[]; 719extern const ERR_STRING_DATA CONF_error_string_data[]; 720extern const ERR_STRING_DATA CRYPTO_error_string_data[]; 721extern const ERR_STRING_DATA DH_error_string_data[]; 722extern const ERR_STRING_DATA DIGEST_error_string_data[]; 723extern const ERR_STRING_DATA DSA_error_string_data[]; 724extern const ERR_STRING_DATA ECDH_error_string_data[]; 725extern const ERR_STRING_DATA ECDSA_error_string_data[]; 726extern const ERR_STRING_DATA EC_error_string_data[]; 727extern const ERR_STRING_DATA ENGINE_error_string_data[]; 728extern const ERR_STRING_DATA EVP_error_string_data[]; 729extern const ERR_STRING_DATA HKDF_error_string_data[]; 730extern const ERR_STRING_DATA OBJ_error_string_data[]; 731extern const ERR_STRING_DATA PEM_error_string_data[]; 732extern const ERR_STRING_DATA PKCS8_error_string_data[]; 733extern const ERR_STRING_DATA RSA_error_string_data[]; 734extern const ERR_STRING_DATA X509V3_error_string_data[]; 735extern const ERR_STRING_DATA X509_error_string_data[]; 736 737static void err_load_strings(void) { 738 unsigned i, j = 0; 739 740 err_fns_check(); 741 742 /* This loop loads strings for the libraries for the ERR_R_*_LIB 743 * reasons. */ 744 for (i = ERR_LIB_NONE; i < ERR_NUM_LIBS; i++) { 745 ERR_STRING_DATA *data = &kStaticErrors[j++]; 746 data->string = kLibraryNames[i]; 747 data->error = ERR_PACK(i, 0, 0); 748 ERRFN(set_item)(data); 749 750 data = &kStaticErrors[j++]; 751 data->string = kLibraryNames[i]; 752 data->error = ERR_PACK(0, 0, i); 753 ERRFN(set_item)(data); 754 } 755 756 for (i = 1; i < 1 + NUM_SYS_ERRNOS; i++) { 757 /* The "SYS" library sets errno values as the reason for its errors. 758 * Thus we load the first |NUM_SYS_ERRNOS| errno strings as the 759 * reason strings for that library. */ 760 761 ERR_STRING_DATA *data = &kStaticErrors[j++]; 762 data->string = strerror(i); 763 data->error = ERR_PACK(ERR_LIB_SYS, 0, i); 764 ERRFN(set_item)(data); 765 } 766 767 ERR_load_strings(kGlobalErrors); 768 769 ERR_load_strings(ASN1_error_string_data); 770 ERR_load_strings(BIO_error_string_data); 771 ERR_load_strings(BN_error_string_data); 772 ERR_load_strings(BUF_error_string_data); 773 ERR_load_strings(CIPHER_error_string_data); 774 ERR_load_strings(CONF_error_string_data); 775 ERR_load_strings(CRYPTO_error_string_data); 776 ERR_load_strings(DH_error_string_data); 777 ERR_load_strings(DIGEST_error_string_data); 778 ERR_load_strings(DSA_error_string_data); 779 ERR_load_strings(ECDH_error_string_data); 780 ERR_load_strings(ECDSA_error_string_data); 781 ERR_load_strings(EC_error_string_data); 782 ERR_load_strings(ENGINE_error_string_data); 783 ERR_load_strings(EVP_error_string_data); 784 ERR_load_strings(HKDF_error_string_data); 785 ERR_load_strings(OBJ_error_string_data); 786 ERR_load_strings(PEM_error_string_data); 787 ERR_load_strings(PKCS8_error_string_data); 788 ERR_load_strings(RSA_error_string_data); 789 ERR_load_strings(X509V3_error_string_data); 790 ERR_load_strings(X509_error_string_data); 791} 792 793void ERR_load_strings(const ERR_STRING_DATA *str) { 794 err_fns_check(); 795 796 while (str->error) { 797 ERRFN(set_item)(str); 798 str++; 799 } 800} 801 802void ERR_load_crypto_strings(void) { err_load_strings(); } 803 804void ERR_free_strings(void) { 805 err_fns_check(); 806 ERRFN(shutdown)(err_state_free); 807} 808 809void ERR_load_BIO_strings(void) {} 810