summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/err/err.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/err/err.c')
-rw-r--r--src/lib/libcrypto/err/err.c154
1 files changed, 101 insertions, 53 deletions
diff --git a/src/lib/libcrypto/err/err.c b/src/lib/libcrypto/err/err.c
index eb8c76aa0b..99272e437c 100644
--- a/src/lib/libcrypto/err/err.c
+++ b/src/lib/libcrypto/err/err.c
@@ -116,8 +116,8 @@
116#include <openssl/crypto.h> 116#include <openssl/crypto.h>
117#include "cryptlib.h" 117#include "cryptlib.h"
118#include <openssl/buffer.h> 118#include <openssl/buffer.h>
119#include <openssl/bio.h>
119#include <openssl/err.h> 120#include <openssl/err.h>
120#include <openssl/crypto.h>
121 121
122 122
123static LHASH *error_hash=NULL; 123static LHASH *error_hash=NULL;
@@ -137,6 +137,7 @@ static ERR_STRING_DATA ERR_str_libraries[]=
137{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"}, 137{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"},
138{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"}, 138{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"},
139{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"}, 139{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"},
140{ERR_PACK(ERR_LIB_DSA,0,0) ,"dsa routines"},
140{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"}, 141{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"},
141{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"}, 142{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"},
142{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"}, 143{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"},
@@ -155,6 +156,8 @@ static ERR_STRING_DATA ERR_str_libraries[]=
155{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"}, 156{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"},
156{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"}, 157{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"},
157{ERR_PACK(ERR_LIB_RAND,0,0) ,"random number generator"}, 158{ERR_PACK(ERR_LIB_RAND,0,0) ,"random number generator"},
159{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"},
160{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"},
158{0,NULL}, 161{0,NULL},
159 }; 162 };
160 163
@@ -205,6 +208,8 @@ static ERR_STRING_DATA ERR_str_reasons[]=
205{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"}, 208{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"},
206{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"}, 209{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"},
207{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"}, 210{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"},
211{ERR_R_DSO_LIB ,"DSO lib"},
212{ERR_R_ENGINE_LIB ,"ENGINE lib"},
208 213
209{0,NULL}, 214{0,NULL},
210 }; 215 };
@@ -225,7 +230,7 @@ static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
225 230
226static void build_SYS_str_reasons() 231static void build_SYS_str_reasons()
227 { 232 {
228 /* Malloc cannot be used here, use static storage instead */ 233 /* OPENSSL_malloc cannot be used here, use static storage instead */
229 static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON]; 234 static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
230 int i; 235 int i;
231 236
@@ -262,7 +267,7 @@ static void build_SYS_str_reasons()
262 if (((p)->err_data[i] != NULL) && \ 267 if (((p)->err_data[i] != NULL) && \
263 (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \ 268 (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
264 { \ 269 { \
265 Free((p)->err_data[i]); \ 270 OPENSSL_free((p)->err_data[i]); \
266 (p)->err_data[i]=NULL; \ 271 (p)->err_data[i]=NULL; \
267 } \ 272 } \
268 (p)->err_data_flags[i]=0; 273 (p)->err_data_flags[i]=0;
@@ -278,7 +283,7 @@ static void ERR_STATE_free(ERR_STATE *s)
278 { 283 {
279 err_clear_data(s,i); 284 err_clear_data(s,i);
280 } 285 }
281 Free(s); 286 OPENSSL_free(s);
282 } 287 }
283 288
284void ERR_load_ERR_strings(void) 289void ERR_load_ERR_strings(void)
@@ -475,13 +480,11 @@ static unsigned long get_error_values(int inc, const char **file, int *line,
475 return(ret); 480 return(ret);
476 } 481 }
477 482
478/* BAD for multi-threaded, uses a local buffer if ret == NULL */ 483void ERR_error_string_n(unsigned long e, char *buf, size_t len)
479char *ERR_error_string(unsigned long e, char *ret)
480 { 484 {
481 static char buf[256]; 485 char lsbuf[64], fsbuf[64], rsbuf[64];
482 const char *ls,*fs,*rs; 486 const char *ls,*fs,*rs;
483 unsigned long l,f,r; 487 unsigned long l,f,r;
484 int i;
485 488
486 l=ERR_GET_LIB(e); 489 l=ERR_GET_LIB(e);
487 f=ERR_GET_FUNC(e); 490 f=ERR_GET_FUNC(e);
@@ -491,21 +494,50 @@ char *ERR_error_string(unsigned long e, char *ret)
491 fs=ERR_func_error_string(e); 494 fs=ERR_func_error_string(e);
492 rs=ERR_reason_error_string(e); 495 rs=ERR_reason_error_string(e);
493 496
494 if (ret == NULL) ret=buf; 497 if (ls == NULL)
495 498 BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
496 sprintf(&(ret[0]),"error:%08lX:",e);
497 i=strlen(ret);
498 if (ls == NULL)
499 sprintf(&(ret[i]),":lib(%lu) ",l);
500 else sprintf(&(ret[i]),"%s",ls);
501 i=strlen(ret);
502 if (fs == NULL) 499 if (fs == NULL)
503 sprintf(&(ret[i]),":func(%lu) ",f); 500 BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
504 else sprintf(&(ret[i]),":%s",fs);
505 i=strlen(ret);
506 if (rs == NULL) 501 if (rs == NULL)
507 sprintf(&(ret[i]),":reason(%lu)",r); 502 BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
508 else sprintf(&(ret[i]),":%s",rs); 503
504 BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf,
505 fs?fs:fsbuf, rs?rs:rsbuf);
506 if (strlen(buf) == len-1)
507 {
508 /* output may be truncated; make sure we always have 5
509 * colon-separated fields, i.e. 4 colons ... */
510#define NUM_COLONS 4
511 if (len > NUM_COLONS) /* ... if possible */
512 {
513 int i;
514 char *s = buf;
515
516 for (i = 0; i < NUM_COLONS; i++)
517 {
518 char *colon = strchr(s, ':');
519 if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
520 {
521 /* set colon no. i at last possible position
522 * (buf[len-1] is the terminating 0)*/
523 colon = &buf[len-1] - NUM_COLONS + i;
524 *colon = ':';
525 }
526 s = colon + 1;
527 }
528 }
529 }
530 }
531
532/* BAD for multi-threading: uses a local buffer if ret == NULL */
533/* ERR_error_string_n should be used instead for ret != NULL
534 * as ERR_error_string cannot know how large the buffer is */
535char *ERR_error_string(unsigned long e, char *ret)
536 {
537 static char buf[256];
538
539 if (ret == NULL) ret=buf;
540 ERR_error_string_n(e, ret, 256);
509 541
510 return(ret); 542 return(ret);
511 } 543 }
@@ -515,6 +547,7 @@ LHASH *ERR_get_string_table(void)
515 return(error_hash); 547 return(error_hash);
516 } 548 }
517 549
550/* not thread-safe */
518LHASH *ERR_get_err_state_table(void) 551LHASH *ERR_get_err_state_table(void)
519 { 552 {
520 return(thread_hash); 553 return(thread_hash);
@@ -527,7 +560,7 @@ const char *ERR_lib_error_string(unsigned long e)
527 560
528 l=ERR_GET_LIB(e); 561 l=ERR_GET_LIB(e);
529 562
530 CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH); 563 CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH);
531 564
532 if (error_hash != NULL) 565 if (error_hash != NULL)
533 { 566 {
@@ -535,7 +568,7 @@ const char *ERR_lib_error_string(unsigned long e)
535 p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d); 568 p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d);
536 } 569 }
537 570
538 CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH); 571 CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
539 572
540 return((p == NULL)?NULL:p->string); 573 return((p == NULL)?NULL:p->string);
541 } 574 }
@@ -548,7 +581,7 @@ const char *ERR_func_error_string(unsigned long e)
548 l=ERR_GET_LIB(e); 581 l=ERR_GET_LIB(e);
549 f=ERR_GET_FUNC(e); 582 f=ERR_GET_FUNC(e);
550 583
551 CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH); 584 CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH);
552 585
553 if (error_hash != NULL) 586 if (error_hash != NULL)
554 { 587 {
@@ -556,7 +589,7 @@ const char *ERR_func_error_string(unsigned long e)
556 p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d); 589 p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d);
557 } 590 }
558 591
559 CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH); 592 CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
560 593
561 return((p == NULL)?NULL:p->string); 594 return((p == NULL)?NULL:p->string);
562 } 595 }
@@ -569,7 +602,7 @@ const char *ERR_reason_error_string(unsigned long e)
569 l=ERR_GET_LIB(e); 602 l=ERR_GET_LIB(e);
570 r=ERR_GET_REASON(e); 603 r=ERR_GET_REASON(e);
571 604
572 CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH); 605 CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH);
573 606
574 if (error_hash != NULL) 607 if (error_hash != NULL)
575 { 608 {
@@ -582,7 +615,7 @@ const char *ERR_reason_error_string(unsigned long e)
582 } 615 }
583 } 616 }
584 617
585 CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH); 618 CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
586 619
587 return((p == NULL)?NULL:p->string); 620 return((p == NULL)?NULL:p->string);
588 } 621 }
@@ -613,7 +646,7 @@ static int pid_cmp(ERR_STATE *a, ERR_STATE *b)
613 646
614void ERR_remove_state(unsigned long pid) 647void ERR_remove_state(unsigned long pid)
615 { 648 {
616 ERR_STATE *p,tmp; 649 ERR_STATE *p = NULL,tmp;
617 650
618 if (thread_hash == NULL) 651 if (thread_hash == NULL)
619 return; 652 return;
@@ -621,7 +654,16 @@ void ERR_remove_state(unsigned long pid)
621 pid=(unsigned long)CRYPTO_thread_id(); 654 pid=(unsigned long)CRYPTO_thread_id();
622 tmp.pid=pid; 655 tmp.pid=pid;
623 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 656 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
624 p=(ERR_STATE *)lh_delete(thread_hash,&tmp); 657 if (thread_hash)
658 {
659 p=(ERR_STATE *)lh_delete(thread_hash,&tmp);
660 if (lh_num_items(thread_hash) == 0)
661 {
662 /* make sure we don't leak memory */
663 lh_free(thread_hash);
664 thread_hash = NULL;
665 }
666 }
625 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 667 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
626 668
627 if (p != NULL) ERR_STATE_free(p); 669 if (p != NULL) ERR_STATE_free(p);
@@ -630,39 +672,25 @@ void ERR_remove_state(unsigned long pid)
630ERR_STATE *ERR_get_state(void) 672ERR_STATE *ERR_get_state(void)
631 { 673 {
632 static ERR_STATE fallback; 674 static ERR_STATE fallback;
633 ERR_STATE *ret=NULL,tmp,*tmpp; 675 ERR_STATE *ret=NULL,tmp,*tmpp=NULL;
676 int thread_state_exists;
634 int i; 677 int i;
635 unsigned long pid; 678 unsigned long pid;
636 679
637 pid=(unsigned long)CRYPTO_thread_id(); 680 pid=(unsigned long)CRYPTO_thread_id();
638 681
639 CRYPTO_r_lock(CRYPTO_LOCK_ERR); 682 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
640 if (thread_hash == NULL) 683 if (thread_hash != NULL)
641 {
642 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
643 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
644 if (thread_hash == NULL)
645 {
646 MemCheck_off();
647 thread_hash=lh_new(pid_hash,pid_cmp);
648 MemCheck_on();
649 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
650 if (thread_hash == NULL) return(&fallback);
651 }
652 else
653 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
654 }
655 else
656 { 684 {
657 tmp.pid=pid; 685 tmp.pid=pid;
658 ret=(ERR_STATE *)lh_retrieve(thread_hash,&tmp); 686 ret=(ERR_STATE *)lh_retrieve(thread_hash,&tmp);
659 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
660 } 687 }
688 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
661 689
662 /* ret == the error state, if NULL, make a new one */ 690 /* ret == the error state, if NULL, make a new one */
663 if (ret == NULL) 691 if (ret == NULL)
664 { 692 {
665 ret=(ERR_STATE *)Malloc(sizeof(ERR_STATE)); 693 ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
666 if (ret == NULL) return(&fallback); 694 if (ret == NULL) return(&fallback);
667 ret->pid=pid; 695 ret->pid=pid;
668 ret->top=0; 696 ret->top=0;
@@ -672,9 +700,29 @@ ERR_STATE *ERR_get_state(void)
672 ret->err_data[i]=NULL; 700 ret->err_data[i]=NULL;
673 ret->err_data_flags[i]=0; 701 ret->err_data_flags[i]=0;
674 } 702 }
703
675 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 704 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
676 tmpp=(ERR_STATE *)lh_insert(thread_hash,ret); 705
706 /* no entry yet in thread_hash for current thread -
707 * thus, it may have changed since we last looked at it */
708 if (thread_hash == NULL)
709 thread_hash = lh_new(pid_hash, pid_cmp);
710 if (thread_hash == NULL)
711 thread_state_exists = 0; /* allocation error */
712 else
713 {
714 tmpp=(ERR_STATE *)lh_insert(thread_hash,ret);
715 thread_state_exists = 1;
716 }
717
677 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 718 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
719
720 if (!thread_state_exists)
721 {
722 ERR_STATE_free(ret); /* could not insert it */
723 return(&fallback);
724 }
725
678 if (tmpp != NULL) /* old entry - should not happen */ 726 if (tmpp != NULL) /* old entry - should not happen */
679 { 727 {
680 ERR_STATE_free(tmpp); 728 ERR_STATE_free(tmpp);
@@ -712,7 +760,7 @@ void ERR_add_error_data(int num, ...)
712 char *str,*p,*a; 760 char *str,*p,*a;
713 761
714 s=64; 762 s=64;
715 str=Malloc(s+1); 763 str=OPENSSL_malloc(s+1);
716 if (str == NULL) return; 764 if (str == NULL) return;
717 str[0]='\0'; 765 str[0]='\0';
718 766
@@ -728,10 +776,10 @@ void ERR_add_error_data(int num, ...)
728 if (n > s) 776 if (n > s)
729 { 777 {
730 s=n+20; 778 s=n+20;
731 p=Realloc(str,s+1); 779 p=OPENSSL_realloc(str,s+1);
732 if (p == NULL) 780 if (p == NULL)
733 { 781 {
734 Free(str); 782 OPENSSL_free(str);
735 return; 783 return;
736 } 784 }
737 else 785 else