diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/err/err.c | 583 |
1 files changed, 286 insertions, 297 deletions
diff --git a/src/lib/libcrypto/err/err.c b/src/lib/libcrypto/err/err.c index 3babdb3211..f0001cd885 100644 --- a/src/lib/libcrypto/err/err.c +++ b/src/lib/libcrypto/err/err.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: err.c,v 1.64 2024/10/02 14:54:26 jsing Exp $ */ | 1 | /* $OpenBSD: err.c,v 1.65 2024/10/02 15:21:39 jsing Exp $ */ |
| 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 | * |
| @@ -140,11 +140,6 @@ typedef struct err_state_st { | |||
| 140 | int top, bottom; | 140 | int top, bottom; |
| 141 | } ERR_STATE; | 141 | } ERR_STATE; |
| 142 | 142 | ||
| 143 | static void err_load_strings(int lib, ERR_STRING_DATA *str); | ||
| 144 | |||
| 145 | static ERR_STATE *ERR_get_state(void); | ||
| 146 | static void ERR_STATE_free(ERR_STATE *s); | ||
| 147 | |||
| 148 | #ifndef OPENSSL_NO_ERR | 143 | #ifndef OPENSSL_NO_ERR |
| 149 | static ERR_STRING_DATA ERR_str_libraries[] = { | 144 | static ERR_STRING_DATA ERR_str_libraries[] = { |
| 150 | {ERR_PACK(ERR_LIB_NONE,0,0), "unknown library"}, | 145 | {ERR_PACK(ERR_LIB_NONE,0,0), "unknown library"}, |
| @@ -238,6 +233,8 @@ static ERR_STRING_DATA ERR_str_reasons[] = { | |||
| 238 | }; | 233 | }; |
| 239 | #endif | 234 | #endif |
| 240 | 235 | ||
| 236 | static void ERR_STATE_free(ERR_STATE *s); | ||
| 237 | |||
| 241 | /* | 238 | /* |
| 242 | * The internal state used by "err_defaults" - as such, the setting, reading, | 239 | * The internal state used by "err_defaults" - as such, the setting, reading, |
| 243 | * creating, and deleting of this data should only be permitted via the | 240 | * creating, and deleting of this data should only be permitted via the |
| @@ -257,9 +254,6 @@ static pthread_t err_init_thread; | |||
| 257 | * internal to the "err_defaults" implementation. | 254 | * internal to the "err_defaults" implementation. |
| 258 | */ | 255 | */ |
| 259 | 256 | ||
| 260 | static unsigned long get_error_values(int inc, int top, const char **file, | ||
| 261 | int *line, const char **data, int *flags); | ||
| 262 | |||
| 263 | /* The internal functions used in the "err_defaults" implementation */ | 257 | /* The internal functions used in the "err_defaults" implementation */ |
| 264 | 258 | ||
| 265 | static unsigned long | 259 | static unsigned long |
| @@ -574,6 +568,121 @@ ERR_STATE_free(ERR_STATE *s) | |||
| 574 | free(s); | 568 | free(s); |
| 575 | } | 569 | } |
| 576 | 570 | ||
| 571 | static ERR_STATE * | ||
| 572 | ERR_get_state(void) | ||
| 573 | { | ||
| 574 | static ERR_STATE fallback; | ||
| 575 | ERR_STATE *ret, tmp, *tmpp = NULL; | ||
| 576 | int i; | ||
| 577 | CRYPTO_THREADID tid; | ||
| 578 | |||
| 579 | CRYPTO_THREADID_current(&tid); | ||
| 580 | CRYPTO_THREADID_cpy(&tmp.tid, &tid); | ||
| 581 | ret = err_thread_get_item(&tmp); | ||
| 582 | |||
| 583 | /* ret == the error state, if NULL, make a new one */ | ||
| 584 | if (ret == NULL) { | ||
| 585 | ret = malloc(sizeof(ERR_STATE)); | ||
| 586 | if (ret == NULL) | ||
| 587 | return (&fallback); | ||
| 588 | CRYPTO_THREADID_cpy(&ret->tid, &tid); | ||
| 589 | ret->top = 0; | ||
| 590 | ret->bottom = 0; | ||
| 591 | for (i = 0; i < ERR_NUM_ERRORS; i++) { | ||
| 592 | ret->err_data[i] = NULL; | ||
| 593 | ret->err_data_flags[i] = 0; | ||
| 594 | } | ||
| 595 | tmpp = err_thread_set_item(ret); | ||
| 596 | /* To check if insertion failed, do a get. */ | ||
| 597 | if (err_thread_get_item(ret) != ret) { | ||
| 598 | ERR_STATE_free(ret); /* could not insert it */ | ||
| 599 | return (&fallback); | ||
| 600 | } | ||
| 601 | /* If a race occurred in this function and we came second, tmpp | ||
| 602 | * is the first one that we just replaced. */ | ||
| 603 | if (tmpp) | ||
| 604 | ERR_STATE_free(tmpp); | ||
| 605 | } | ||
| 606 | return ret; | ||
| 607 | } | ||
| 608 | |||
| 609 | static void | ||
| 610 | err_load_strings(int lib, ERR_STRING_DATA *str) | ||
| 611 | { | ||
| 612 | while (str->error) { | ||
| 613 | if (lib) | ||
| 614 | str->error |= ERR_PACK(lib, 0, 0); | ||
| 615 | err_set_item(str); | ||
| 616 | str++; | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 620 | static unsigned long | ||
| 621 | get_error_values(int inc, int top, const char **file, int *line, | ||
| 622 | const char **data, int *flags) | ||
| 623 | { | ||
| 624 | int i = 0; | ||
| 625 | ERR_STATE *es; | ||
| 626 | unsigned long ret; | ||
| 627 | |||
| 628 | es = ERR_get_state(); | ||
| 629 | |||
| 630 | if (inc && top) { | ||
| 631 | if (file) | ||
| 632 | *file = ""; | ||
| 633 | if (line) | ||
| 634 | *line = 0; | ||
| 635 | if (data) | ||
| 636 | *data = ""; | ||
| 637 | if (flags) | ||
| 638 | *flags = 0; | ||
| 639 | |||
| 640 | return ERR_R_INTERNAL_ERROR; | ||
| 641 | } | ||
| 642 | |||
| 643 | if (es->bottom == es->top) | ||
| 644 | return 0; | ||
| 645 | if (top) | ||
| 646 | i = es->top; /* last error */ | ||
| 647 | else | ||
| 648 | i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */ | ||
| 649 | |||
| 650 | ret = es->err_buffer[i]; | ||
| 651 | if (inc) { | ||
| 652 | es->bottom = i; | ||
| 653 | es->err_buffer[i] = 0; | ||
| 654 | } | ||
| 655 | |||
| 656 | if ((file != NULL) && (line != NULL)) { | ||
| 657 | if (es->err_file[i] == NULL) { | ||
| 658 | *file = "NA"; | ||
| 659 | if (line != NULL) | ||
| 660 | *line = 0; | ||
| 661 | } else { | ||
| 662 | *file = es->err_file[i]; | ||
| 663 | if (line != NULL) | ||
| 664 | *line = es->err_line[i]; | ||
| 665 | } | ||
| 666 | } | ||
| 667 | |||
| 668 | if (data == NULL) { | ||
| 669 | if (inc) { | ||
| 670 | err_clear_data(es, i); | ||
| 671 | } | ||
| 672 | } else { | ||
| 673 | if (es->err_data[i] == NULL) { | ||
| 674 | *data = ""; | ||
| 675 | if (flags != NULL) | ||
| 676 | *flags = 0; | ||
| 677 | } else { | ||
| 678 | *data = es->err_data[i]; | ||
| 679 | if (flags != NULL) | ||
| 680 | *flags = es->err_data_flags[i]; | ||
| 681 | } | ||
| 682 | } | ||
| 683 | return ret; | ||
| 684 | } | ||
| 685 | |||
| 577 | void | 686 | void |
| 578 | ERR_load_ERR_strings_internal(void) | 687 | ERR_load_ERR_strings_internal(void) |
| 579 | { | 688 | { |
| @@ -587,7 +696,6 @@ ERR_load_ERR_strings_internal(void) | |||
| 587 | #endif | 696 | #endif |
| 588 | } | 697 | } |
| 589 | 698 | ||
| 590 | |||
| 591 | void | 699 | void |
| 592 | ERR_load_ERR_strings(void) | 700 | ERR_load_ERR_strings(void) |
| 593 | { | 701 | { |
| @@ -603,17 +711,6 @@ ERR_load_ERR_strings(void) | |||
| 603 | } | 711 | } |
| 604 | LCRYPTO_ALIAS(ERR_load_ERR_strings); | 712 | LCRYPTO_ALIAS(ERR_load_ERR_strings); |
| 605 | 713 | ||
| 606 | static void | ||
| 607 | err_load_strings(int lib, ERR_STRING_DATA *str) | ||
| 608 | { | ||
| 609 | while (str->error) { | ||
| 610 | if (lib) | ||
| 611 | str->error |= ERR_PACK(lib, 0, 0); | ||
| 612 | err_set_item(str); | ||
| 613 | str++; | ||
| 614 | } | ||
| 615 | } | ||
| 616 | |||
| 617 | void | 714 | void |
| 618 | ERR_load_strings(int lib, ERR_STRING_DATA *str) | 715 | ERR_load_strings(int lib, ERR_STRING_DATA *str) |
| 619 | { | 716 | { |
| @@ -657,7 +754,106 @@ ERR_free_strings(void) | |||
| 657 | } | 754 | } |
| 658 | LCRYPTO_ALIAS(ERR_free_strings); | 755 | LCRYPTO_ALIAS(ERR_free_strings); |
| 659 | 756 | ||
| 660 | /********************************************************/ | 757 | int |
| 758 | ERR_get_next_error_library(void) | ||
| 759 | { | ||
| 760 | return err_get_next_lib(); | ||
| 761 | } | ||
| 762 | LCRYPTO_ALIAS(ERR_get_next_error_library); | ||
| 763 | |||
| 764 | void | ||
| 765 | ERR_remove_thread_state(const CRYPTO_THREADID *id) | ||
| 766 | { | ||
| 767 | ERR_STATE tmp; | ||
| 768 | |||
| 769 | if (id) | ||
| 770 | CRYPTO_THREADID_cpy(&tmp.tid, id); | ||
| 771 | else | ||
| 772 | CRYPTO_THREADID_current(&tmp.tid); | ||
| 773 | /* err_thread_del_item automatically destroys the LHASH if the number of | ||
| 774 | * items reaches zero. */ | ||
| 775 | err_thread_del_item(&tmp); | ||
| 776 | } | ||
| 777 | LCRYPTO_ALIAS(ERR_remove_thread_state); | ||
| 778 | |||
| 779 | void | ||
| 780 | ERR_remove_state(unsigned long pid) | ||
| 781 | { | ||
| 782 | ERR_remove_thread_state(NULL); | ||
| 783 | } | ||
| 784 | LCRYPTO_ALIAS(ERR_remove_state); | ||
| 785 | |||
| 786 | int | ||
| 787 | ERR_set_mark(void) | ||
| 788 | { | ||
| 789 | ERR_STATE *es; | ||
| 790 | |||
| 791 | es = ERR_get_state(); | ||
| 792 | |||
| 793 | if (es->bottom == es->top) | ||
| 794 | return 0; | ||
| 795 | es->err_flags[es->top] |= ERR_FLAG_MARK; | ||
| 796 | return 1; | ||
| 797 | } | ||
| 798 | LCRYPTO_ALIAS(ERR_set_mark); | ||
| 799 | |||
| 800 | int | ||
| 801 | ERR_pop_to_mark(void) | ||
| 802 | { | ||
| 803 | ERR_STATE *es; | ||
| 804 | |||
| 805 | es = ERR_get_state(); | ||
| 806 | |||
| 807 | while (es->bottom != es->top && | ||
| 808 | (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { | ||
| 809 | err_clear(es, es->top); | ||
| 810 | es->top -= 1; | ||
| 811 | if (es->top == -1) | ||
| 812 | es->top = ERR_NUM_ERRORS - 1; | ||
| 813 | } | ||
| 814 | |||
| 815 | if (es->bottom == es->top) | ||
| 816 | return 0; | ||
| 817 | es->err_flags[es->top]&=~ERR_FLAG_MARK; | ||
| 818 | return 1; | ||
| 819 | } | ||
| 820 | LCRYPTO_ALIAS(ERR_pop_to_mark); | ||
| 821 | |||
| 822 | void | ||
| 823 | ERR_clear_error(void) | ||
| 824 | { | ||
| 825 | int i; | ||
| 826 | ERR_STATE *es; | ||
| 827 | |||
| 828 | es = ERR_get_state(); | ||
| 829 | |||
| 830 | for (i = 0; i < ERR_NUM_ERRORS; i++) { | ||
| 831 | err_clear(es, i); | ||
| 832 | } | ||
| 833 | es->top = es->bottom = 0; | ||
| 834 | } | ||
| 835 | LCRYPTO_ALIAS(ERR_clear_error); | ||
| 836 | |||
| 837 | void | ||
| 838 | err_clear_last_constant_time(int clear) | ||
| 839 | { | ||
| 840 | ERR_STATE *es; | ||
| 841 | int top; | ||
| 842 | |||
| 843 | es = ERR_get_state(); | ||
| 844 | if (es == NULL) | ||
| 845 | return; | ||
| 846 | |||
| 847 | top = es->top; | ||
| 848 | |||
| 849 | es->err_flags[top] &= ~(0 - clear); | ||
| 850 | es->err_buffer[top] &= ~(0UL - clear); | ||
| 851 | es->err_file[top] = (const char *)((uintptr_t)es->err_file[top] & | ||
| 852 | ~((uintptr_t)0 - clear)); | ||
| 853 | es->err_line[top] |= 0 - clear; | ||
| 854 | |||
| 855 | es->top = (top + ERR_NUM_ERRORS - clear) % ERR_NUM_ERRORS; | ||
| 856 | } | ||
| 661 | 857 | ||
| 662 | void | 858 | void |
| 663 | ERR_put_error(int lib, int func, int reason, const char *file, int line) | 859 | ERR_put_error(int lib, int func, int reason, const char *file, int line) |
| @@ -680,20 +876,39 @@ ERR_put_error(int lib, int func, int reason, const char *file, int line) | |||
| 680 | LCRYPTO_ALIAS(ERR_put_error); | 876 | LCRYPTO_ALIAS(ERR_put_error); |
| 681 | 877 | ||
| 682 | void | 878 | void |
| 683 | ERR_clear_error(void) | 879 | ERR_asprintf_error_data(char * format, ...) |
| 880 | { | ||
| 881 | char *errbuf = NULL; | ||
| 882 | va_list ap; | ||
| 883 | int r; | ||
| 884 | |||
| 885 | va_start(ap, format); | ||
| 886 | r = vasprintf(&errbuf, format, ap); | ||
| 887 | va_end(ap); | ||
| 888 | if (r == -1) | ||
| 889 | ERR_set_error_data("malloc failed", ERR_TXT_STRING); | ||
| 890 | else | ||
| 891 | ERR_set_error_data(errbuf, ERR_TXT_MALLOCED|ERR_TXT_STRING); | ||
| 892 | } | ||
| 893 | LCRYPTO_ALIAS(ERR_asprintf_error_data); | ||
| 894 | |||
| 895 | void | ||
| 896 | ERR_set_error_data(char *data, int flags) | ||
| 684 | { | 897 | { |
| 685 | int i; | ||
| 686 | ERR_STATE *es; | 898 | ERR_STATE *es; |
| 899 | int i; | ||
| 687 | 900 | ||
| 688 | es = ERR_get_state(); | 901 | es = ERR_get_state(); |
| 689 | 902 | ||
| 690 | for (i = 0; i < ERR_NUM_ERRORS; i++) { | 903 | i = es->top; |
| 691 | err_clear(es, i); | 904 | if (i == 0) |
| 692 | } | 905 | i = ERR_NUM_ERRORS - 1; |
| 693 | es->top = es->bottom = 0; | ||
| 694 | } | ||
| 695 | LCRYPTO_ALIAS(ERR_clear_error); | ||
| 696 | 906 | ||
| 907 | err_clear_data(es, i); | ||
| 908 | es->err_data[i] = data; | ||
| 909 | es->err_data_flags[i] = flags; | ||
| 910 | } | ||
| 911 | LCRYPTO_ALIAS(ERR_set_error_data); | ||
| 697 | 912 | ||
| 698 | unsigned long | 913 | unsigned long |
| 699 | ERR_get_error(void) | 914 | ERR_get_error(void) |
| @@ -717,7 +932,6 @@ ERR_get_error_line_data(const char **file, int *line, | |||
| 717 | } | 932 | } |
| 718 | LCRYPTO_ALIAS(ERR_get_error_line_data); | 933 | LCRYPTO_ALIAS(ERR_get_error_line_data); |
| 719 | 934 | ||
| 720 | |||
| 721 | unsigned long | 935 | unsigned long |
| 722 | ERR_peek_error(void) | 936 | ERR_peek_error(void) |
| 723 | { | 937 | { |
| @@ -762,71 +976,56 @@ ERR_peek_last_error_line_data(const char **file, int *line, | |||
| 762 | } | 976 | } |
| 763 | LCRYPTO_ALIAS(ERR_peek_last_error_line_data); | 977 | LCRYPTO_ALIAS(ERR_peek_last_error_line_data); |
| 764 | 978 | ||
| 765 | static unsigned long | 979 | const char * |
| 766 | get_error_values(int inc, int top, const char **file, int *line, | 980 | ERR_lib_error_string(unsigned long e) |
| 767 | const char **data, int *flags) | ||
| 768 | { | 981 | { |
| 769 | int i = 0; | 982 | const ERR_STRING_DATA *p; |
| 770 | ERR_STATE *es; | 983 | ERR_STRING_DATA d; |
| 771 | unsigned long ret; | 984 | unsigned long l; |
| 772 | |||
| 773 | es = ERR_get_state(); | ||
| 774 | 985 | ||
| 775 | if (inc && top) { | 986 | if (!OPENSSL_init_crypto(0, NULL)) |
| 776 | if (file) | 987 | return NULL; |
| 777 | *file = ""; | ||
| 778 | if (line) | ||
| 779 | *line = 0; | ||
| 780 | if (data) | ||
| 781 | *data = ""; | ||
| 782 | if (flags) | ||
| 783 | *flags = 0; | ||
| 784 | 988 | ||
| 785 | return ERR_R_INTERNAL_ERROR; | 989 | l = ERR_GET_LIB(e); |
| 786 | } | 990 | d.error = ERR_PACK(l, 0, 0); |
| 991 | p = err_get_item(&d); | ||
| 992 | return ((p == NULL) ? NULL : p->string); | ||
| 993 | } | ||
| 994 | LCRYPTO_ALIAS(ERR_lib_error_string); | ||
| 787 | 995 | ||
| 788 | if (es->bottom == es->top) | 996 | const char * |
| 789 | return 0; | 997 | ERR_func_error_string(unsigned long e) |
| 790 | if (top) | 998 | { |
| 791 | i = es->top; /* last error */ | 999 | const ERR_STRING_DATA *p; |
| 792 | else | 1000 | ERR_STRING_DATA d; |
| 793 | i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */ | 1001 | unsigned long l, f; |
| 794 | 1002 | ||
| 795 | ret = es->err_buffer[i]; | 1003 | l = ERR_GET_LIB(e); |
| 796 | if (inc) { | 1004 | f = ERR_GET_FUNC(e); |
| 797 | es->bottom = i; | 1005 | d.error = ERR_PACK(l, f, 0); |
| 798 | es->err_buffer[i] = 0; | 1006 | p = err_get_item(&d); |
| 799 | } | 1007 | return ((p == NULL) ? NULL : p->string); |
| 1008 | } | ||
| 1009 | LCRYPTO_ALIAS(ERR_func_error_string); | ||
| 800 | 1010 | ||
| 801 | if ((file != NULL) && (line != NULL)) { | 1011 | const char * |
| 802 | if (es->err_file[i] == NULL) { | 1012 | ERR_reason_error_string(unsigned long e) |
| 803 | *file = "NA"; | 1013 | { |
| 804 | if (line != NULL) | 1014 | const ERR_STRING_DATA *p = NULL; |
| 805 | *line = 0; | 1015 | ERR_STRING_DATA d; |
| 806 | } else { | 1016 | unsigned long l, r; |
| 807 | *file = es->err_file[i]; | ||
| 808 | if (line != NULL) | ||
| 809 | *line = es->err_line[i]; | ||
| 810 | } | ||
| 811 | } | ||
| 812 | 1017 | ||
| 813 | if (data == NULL) { | 1018 | l = ERR_GET_LIB(e); |
| 814 | if (inc) { | 1019 | r = ERR_GET_REASON(e); |
| 815 | err_clear_data(es, i); | 1020 | d.error = ERR_PACK(l, 0, r); |
| 816 | } | 1021 | p = err_get_item(&d); |
| 817 | } else { | 1022 | if (!p) { |
| 818 | if (es->err_data[i] == NULL) { | 1023 | d.error = ERR_PACK(0, 0, r); |
| 819 | *data = ""; | 1024 | p = err_get_item(&d); |
| 820 | if (flags != NULL) | ||
| 821 | *flags = 0; | ||
| 822 | } else { | ||
| 823 | *data = es->err_data[i]; | ||
| 824 | if (flags != NULL) | ||
| 825 | *flags = es->err_data_flags[i]; | ||
| 826 | } | ||
| 827 | } | 1025 | } |
| 828 | return ret; | 1026 | return ((p == NULL) ? NULL : p->string); |
| 829 | } | 1027 | } |
| 1028 | LCRYPTO_ALIAS(ERR_reason_error_string); | ||
| 830 | 1029 | ||
| 831 | void | 1030 | void |
| 832 | ERR_error_string_n(unsigned long e, char *buf, size_t len) | 1031 | ERR_error_string_n(unsigned long e, char *buf, size_t len) |
| @@ -899,213 +1098,3 @@ ERR_error_string(unsigned long e, char *ret) | |||
| 899 | return ret; | 1098 | return ret; |
| 900 | } | 1099 | } |
| 901 | LCRYPTO_ALIAS(ERR_error_string); | 1100 | LCRYPTO_ALIAS(ERR_error_string); |
| 902 | |||
| 903 | const char * | ||
| 904 | ERR_lib_error_string(unsigned long e) | ||
| 905 | { | ||
| 906 | const ERR_STRING_DATA *p; | ||
| 907 | ERR_STRING_DATA d; | ||
| 908 | unsigned long l; | ||
| 909 | |||
| 910 | if (!OPENSSL_init_crypto(0, NULL)) | ||
| 911 | return NULL; | ||
| 912 | |||
| 913 | l = ERR_GET_LIB(e); | ||
| 914 | d.error = ERR_PACK(l, 0, 0); | ||
| 915 | p = err_get_item(&d); | ||
| 916 | return ((p == NULL) ? NULL : p->string); | ||
| 917 | } | ||
| 918 | LCRYPTO_ALIAS(ERR_lib_error_string); | ||
| 919 | |||
| 920 | const char * | ||
| 921 | ERR_func_error_string(unsigned long e) | ||
| 922 | { | ||
| 923 | const ERR_STRING_DATA *p; | ||
| 924 | ERR_STRING_DATA d; | ||
| 925 | unsigned long l, f; | ||
| 926 | |||
| 927 | l = ERR_GET_LIB(e); | ||
| 928 | f = ERR_GET_FUNC(e); | ||
| 929 | d.error = ERR_PACK(l, f, 0); | ||
| 930 | p = err_get_item(&d); | ||
| 931 | return ((p == NULL) ? NULL : p->string); | ||
| 932 | } | ||
| 933 | LCRYPTO_ALIAS(ERR_func_error_string); | ||
| 934 | |||
| 935 | const char * | ||
| 936 | ERR_reason_error_string(unsigned long e) | ||
| 937 | { | ||
| 938 | const ERR_STRING_DATA *p = NULL; | ||
| 939 | ERR_STRING_DATA d; | ||
| 940 | unsigned long l, r; | ||
| 941 | |||
| 942 | l = ERR_GET_LIB(e); | ||
| 943 | r = ERR_GET_REASON(e); | ||
| 944 | d.error = ERR_PACK(l, 0, r); | ||
| 945 | p = err_get_item(&d); | ||
| 946 | if (!p) { | ||
| 947 | d.error = ERR_PACK(0, 0, r); | ||
| 948 | p = err_get_item(&d); | ||
| 949 | } | ||
| 950 | return ((p == NULL) ? NULL : p->string); | ||
| 951 | } | ||
| 952 | LCRYPTO_ALIAS(ERR_reason_error_string); | ||
| 953 | |||
| 954 | void | ||
| 955 | ERR_remove_thread_state(const CRYPTO_THREADID *id) | ||
| 956 | { | ||
| 957 | ERR_STATE tmp; | ||
| 958 | |||
| 959 | if (id) | ||
| 960 | CRYPTO_THREADID_cpy(&tmp.tid, id); | ||
| 961 | else | ||
| 962 | CRYPTO_THREADID_current(&tmp.tid); | ||
| 963 | /* err_thread_del_item automatically destroys the LHASH if the number of | ||
| 964 | * items reaches zero. */ | ||
| 965 | err_thread_del_item(&tmp); | ||
| 966 | } | ||
| 967 | LCRYPTO_ALIAS(ERR_remove_thread_state); | ||
| 968 | |||
| 969 | void | ||
| 970 | ERR_remove_state(unsigned long pid) | ||
| 971 | { | ||
| 972 | ERR_remove_thread_state(NULL); | ||
| 973 | } | ||
| 974 | LCRYPTO_ALIAS(ERR_remove_state); | ||
| 975 | |||
| 976 | static ERR_STATE * | ||
| 977 | ERR_get_state(void) | ||
| 978 | { | ||
| 979 | static ERR_STATE fallback; | ||
| 980 | ERR_STATE *ret, tmp, *tmpp = NULL; | ||
| 981 | int i; | ||
| 982 | CRYPTO_THREADID tid; | ||
| 983 | |||
| 984 | CRYPTO_THREADID_current(&tid); | ||
| 985 | CRYPTO_THREADID_cpy(&tmp.tid, &tid); | ||
| 986 | ret = err_thread_get_item(&tmp); | ||
| 987 | |||
| 988 | /* ret == the error state, if NULL, make a new one */ | ||
| 989 | if (ret == NULL) { | ||
| 990 | ret = malloc(sizeof(ERR_STATE)); | ||
| 991 | if (ret == NULL) | ||
| 992 | return (&fallback); | ||
| 993 | CRYPTO_THREADID_cpy(&ret->tid, &tid); | ||
| 994 | ret->top = 0; | ||
| 995 | ret->bottom = 0; | ||
| 996 | for (i = 0; i < ERR_NUM_ERRORS; i++) { | ||
| 997 | ret->err_data[i] = NULL; | ||
| 998 | ret->err_data_flags[i] = 0; | ||
| 999 | } | ||
| 1000 | tmpp = err_thread_set_item(ret); | ||
| 1001 | /* To check if insertion failed, do a get. */ | ||
| 1002 | if (err_thread_get_item(ret) != ret) { | ||
| 1003 | ERR_STATE_free(ret); /* could not insert it */ | ||
| 1004 | return (&fallback); | ||
| 1005 | } | ||
| 1006 | /* If a race occurred in this function and we came second, tmpp | ||
| 1007 | * is the first one that we just replaced. */ | ||
| 1008 | if (tmpp) | ||
| 1009 | ERR_STATE_free(tmpp); | ||
| 1010 | } | ||
| 1011 | return ret; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | int | ||
| 1015 | ERR_get_next_error_library(void) | ||
| 1016 | { | ||
| 1017 | return err_get_next_lib(); | ||
| 1018 | } | ||
| 1019 | LCRYPTO_ALIAS(ERR_get_next_error_library); | ||
| 1020 | |||
| 1021 | void | ||
| 1022 | ERR_set_error_data(char *data, int flags) | ||
| 1023 | { | ||
| 1024 | ERR_STATE *es; | ||
| 1025 | int i; | ||
| 1026 | |||
| 1027 | es = ERR_get_state(); | ||
| 1028 | |||
| 1029 | i = es->top; | ||
| 1030 | if (i == 0) | ||
| 1031 | i = ERR_NUM_ERRORS - 1; | ||
| 1032 | |||
| 1033 | err_clear_data(es, i); | ||
| 1034 | es->err_data[i] = data; | ||
| 1035 | es->err_data_flags[i] = flags; | ||
| 1036 | } | ||
| 1037 | LCRYPTO_ALIAS(ERR_set_error_data); | ||
| 1038 | |||
| 1039 | void | ||
| 1040 | ERR_asprintf_error_data(char * format, ...) | ||
| 1041 | { | ||
| 1042 | char *errbuf = NULL; | ||
| 1043 | va_list ap; | ||
| 1044 | int r; | ||
| 1045 | |||
| 1046 | va_start(ap, format); | ||
| 1047 | r = vasprintf(&errbuf, format, ap); | ||
| 1048 | va_end(ap); | ||
| 1049 | if (r == -1) | ||
| 1050 | ERR_set_error_data("malloc failed", ERR_TXT_STRING); | ||
| 1051 | else | ||
| 1052 | ERR_set_error_data(errbuf, ERR_TXT_MALLOCED|ERR_TXT_STRING); | ||
| 1053 | } | ||
| 1054 | LCRYPTO_ALIAS(ERR_asprintf_error_data); | ||
| 1055 | |||
| 1056 | int | ||
| 1057 | ERR_set_mark(void) | ||
| 1058 | { | ||
| 1059 | ERR_STATE *es; | ||
| 1060 | |||
| 1061 | es = ERR_get_state(); | ||
| 1062 | |||
| 1063 | if (es->bottom == es->top) | ||
| 1064 | return 0; | ||
| 1065 | es->err_flags[es->top] |= ERR_FLAG_MARK; | ||
| 1066 | return 1; | ||
| 1067 | } | ||
| 1068 | LCRYPTO_ALIAS(ERR_set_mark); | ||
| 1069 | |||
| 1070 | int | ||
| 1071 | ERR_pop_to_mark(void) | ||
| 1072 | { | ||
| 1073 | ERR_STATE *es; | ||
| 1074 | |||
| 1075 | es = ERR_get_state(); | ||
| 1076 | |||
| 1077 | while (es->bottom != es->top && | ||
| 1078 | (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { | ||
| 1079 | err_clear(es, es->top); | ||
| 1080 | es->top -= 1; | ||
| 1081 | if (es->top == -1) | ||
| 1082 | es->top = ERR_NUM_ERRORS - 1; | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | if (es->bottom == es->top) | ||
| 1086 | return 0; | ||
| 1087 | es->err_flags[es->top]&=~ERR_FLAG_MARK; | ||
| 1088 | return 1; | ||
| 1089 | } | ||
| 1090 | LCRYPTO_ALIAS(ERR_pop_to_mark); | ||
| 1091 | |||
| 1092 | void | ||
| 1093 | err_clear_last_constant_time(int clear) | ||
| 1094 | { | ||
| 1095 | ERR_STATE *es; | ||
| 1096 | int top; | ||
| 1097 | |||
| 1098 | es = ERR_get_state(); | ||
| 1099 | if (es == NULL) | ||
| 1100 | return; | ||
| 1101 | |||
| 1102 | top = es->top; | ||
| 1103 | |||
| 1104 | es->err_flags[top] &= ~(0 - clear); | ||
| 1105 | es->err_buffer[top] &= ~(0UL - clear); | ||
| 1106 | es->err_file[top] = (const char *)((uintptr_t)es->err_file[top] & | ||
| 1107 | ~((uintptr_t)0 - clear)); | ||
| 1108 | es->err_line[top] |= 0 - clear; | ||
| 1109 | |||
| 1110 | es->top = (top + ERR_NUM_ERRORS - clear) % ERR_NUM_ERRORS; | ||
| 1111 | } | ||
