diff options
author | jsing <> | 2024-10-02 15:21:39 +0000 |
---|---|---|
committer | jsing <> | 2024-10-02 15:21:39 +0000 |
commit | f093080572cd64366654263857e458e2b5987c8a (patch) | |
tree | 1705bafea01dc0f2bd6966282a82fd2af17cdcda /src | |
parent | d496a691ad7804a7d3cace89ff92a9b88b8bb653 (diff) | |
download | openbsd-f093080572cd64366654263857e458e2b5987c8a.tar.gz openbsd-f093080572cd64366654263857e458e2b5987c8a.tar.bz2 openbsd-f093080572cd64366654263857e458e2b5987c8a.zip |
Reorder functions.
Reorder functions so that things are somewhat more logical, moving internal
functions towards the top (and removing now unnecessary prototypes).
Diffstat (limited to 'src')
-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 | } | ||