From dcb9ef6651071a860412d843bc57cdb9020f36a6 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 6 Jan 2017 14:29:16 -0700 Subject: [PATCH 1/6] better compatibility with printing errors to a file --- src/ssl.c | 10 ++ tests/api.c | 6 + wolfcrypt/benchmark/benchmark.c | 4 + wolfcrypt/src/logging.c | 201 ++++++++++++++++++++++++++++++-- wolfcrypt/src/wc_port.c | 23 ++++ wolfcrypt/test/test.c | 8 ++ wolfssl/openssl/ssl.h | 3 +- wolfssl/ssl.h | 3 + wolfssl/wolfcrypt/logging.h | 25 +++- wolfssl/wolfcrypt/types.h | 3 +- wolfssl/wolfcrypt/wc_port.h | 1 + 11 files changed, 267 insertions(+), 20 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index fde1fac45..3f6f3a6eb 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2721,6 +2721,12 @@ void wolfSSL_ERR_print_errors_fp(FILE* fp, int err) fprintf(fp, "%s", data); } +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) +void wolfSSL_ERR_dump_errors_fp(FILE* fp) +{ + wc_ERR_print_errors_fp(fp); +} +#endif #endif @@ -8288,6 +8294,10 @@ int wolfSSL_Cleanup(void) wc_ecc_fp_free(); #endif + if (wolfCrypt_Cleanup() != 0) { + WOLFSSL_MSG("Error with wolfCrypt_Cleanup call"); + } + return ret; } diff --git a/tests/api.c b/tests/api.c index ad204ad11..0d5b1c205 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2698,6 +2698,12 @@ static void test_wolfSSL_ERR_peek_last_error_line(void) #endif printf(resultFmt, passed); + + printf("\nTesting error print out\n"); + ERR_print_errors_fp(stdout); + printf("Done testing print out\n\n"); + fflush(stdout); + wolfSSL_Cleanup(); #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ !defined(NO_FILESYSTEM) && !defined(DEBUG_WOLFSSL) */ } diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 0b5ad6ad7..3881a45f3 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -489,6 +489,10 @@ int benchmark_test(void *args) } #endif + if (wolfCrypt_Cleanup() != 0) { + printf("error with wolfCrypt_Cleanup\n"); + } + #if defined(USE_WOLFSSL_MEMORY) && defined(WOLFSSL_TRACK_MEMORY) ShowMemoryTracker(); #endif diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 9307413b5..d0b66ef98 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -41,13 +41,31 @@ } #endif +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) +static wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */ + +/* accessing any of these global variables should be wrapped in a lock of + * debug_mutex */ +volatile char wc_last_error_file[WOLFSSL_MAX_ERROR_SZ]; +volatile unsigned long wc_last_error_line; +volatile unsigned long wc_last_error; +volatile void* wc_error_heap; + +struct wc_error_queue { + void* heap; /* the heap hint used with nodes creation */ + struct wc_error_queue* next; + char error[WOLFSSL_MAX_ERROR_SZ]; + char file[WOLFSSL_MAX_ERROR_SZ]; + int value; + int line; +}; +volatile struct wc_error_queue* wc_errors; +static struct wc_error_queue* wc_last_node; +/* pointer to last node in queue to make insertion O(1) */ +#endif + #ifdef DEBUG_WOLFSSL - #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) - volatile char wc_last_error_file[80]; - volatile unsigned long wc_last_error_line; - volatile unsigned long wc_last_error; - #endif /* Set these to default values initially. */ static wolfSSL_Logging_cb log_function = 0; @@ -220,15 +238,27 @@ void WOLFSSL_ERROR(int error) #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) (void)usrCtx; /* a user ctx for future flexibility */ (void)func; - if (error < 0) error = error - (2*error); /* get absolute value */ - wc_last_error = (unsigned long)error; - wc_last_error_line = (unsigned long)line; - XMEMSET((char*)wc_last_error_file, 0, sizeof(file)); - if (XSTRLEN(file) < sizeof(file)) { - XSTRNCPY((char*)wc_last_error_file, file, XSTRLEN(file)); + + if (wc_LockMutex(&debug_mutex) != 0) { + WOLFSSL_MSG("Lock debug mutex failed"); + sprintf(buffer, "wolfSSL error occurred, error = %d", error); } - sprintf(buffer, "wolfSSL error occurred, error = %d line:%d file:%s", + else { + if (error < 0) error = error - (2*error); /*get absolute value*/ + wc_last_error = (unsigned long)error; + wc_last_error_line = (unsigned long)line; + XMEMSET((char*)wc_last_error_file, 0, sizeof(file)); + if (XSTRLEN(file) < sizeof(file)) { + XSTRNCPY((char*)wc_last_error_file, file, XSTRLEN(file)); + } + sprintf(buffer, "wolfSSL error occurred, error = %d line:%d file:%s", error, line, file); + if (wc_AddErrorNode(error, line, buffer, (char*)file) != 0) { + WOLFSSL_MSG("Error creating logging node"); + } + + wc_UnLockMutex(&debug_mutex); + } #else sprintf(buffer, "wolfSSL error occurred, error = %d", error); #endif @@ -237,3 +267,150 @@ void WOLFSSL_ERROR(int error) } #endif /* DEBUG_WOLFSSL */ + +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) +/* Internal function that is called by wolfCrypt_Init() */ +int wc_LoggingInit(void) +{ + if (wc_InitMutex(&debug_mutex) != 0) { + WOLFSSL_MSG("Bad Init Mutex frnih"); + return BAD_MUTEX_E; + } + XMEMSET((char*)wc_last_error_file, 0, sizeof(wc_last_error_file)); + wc_last_error_line = 0; + wc_last_error = 0; + wc_errors = NULL; + wc_error_heap = NULL; + wc_last_node = NULL; + + return 0; +} + + +/* internal function that is called by wolfCrypt_Cleanup */ +int wc_LoggingCleanup(void) +{ + if (wc_LockMutex(&debug_mutex) != 0) { + WOLFSSL_MSG("Lock debug mutex failed"); + return BAD_MUTEX_E; + } + + /* free all nodes from error queue */ + { + struct wc_error_queue* current; + struct wc_error_queue* next; + + current = (struct wc_error_queue*)wc_errors; + while (current != NULL) { + next = current->next; + XFREE(current, current->heap, DYNAMIC_TYPE_LOG); + current = next; + } + } + + wc_UnLockMutex(&debug_mutex); + if (wc_FreeMutex(&debug_mutex) != 0) { + WOLFSSL_MSG("Bad Init Mutex frnih"); + return BAD_MUTEX_E; + } + return 0; +} + + +#ifdef DEBUG_WOLFSSL +/* create new error node and add it to the queue + * buffers are assumed to be of size WOLFSSL_MAX_ERROR_SZ for this internal + * function */ +int wc_AddErrorNode(int error, int line, char* buf, char* file) +{ + + struct wc_error_queue* err; + + err = (struct wc_error_queue*)XMALLOC( + sizeof(struct wc_error_queue), wc_error_heap, DYNAMIC_TYPE_LOG); + if (err == NULL) { + WOLFSSL_MSG("Unable to create error node for log"); + return MEMORY_E; + } + else { + XMEMSET(err, 0, sizeof(struct wc_error_queue)); + err->heap = (void*)wc_error_heap; + XMEMCPY(err->error, buf, WOLFSSL_MAX_ERROR_SZ - 1); + XMEMCPY(err->file, file, WOLFSSL_MAX_ERROR_SZ - 1); + err->value = error; + err->line = line; + + /* make sure is terminated */ + err->error[WOLFSSL_MAX_ERROR_SZ - 1] = '\0'; + err->file[WOLFSSL_MAX_ERROR_SZ - 1] = '\0'; + + + /* since is queue place new node at last of the list */ + if (wc_last_node == NULL) { + /* case of first node added to queue */ + if (wc_errors != NULL) { + /* check for unexpected case before over writing wc_errors */ + WOLFSSL_MSG("ERROR in adding new node to logging queue!!\n"); + } + else { + wc_errors = err; + wc_last_node = err; + } + } + else { + wc_last_node->next = err; + wc_last_node = err; + } + } + + return 0; +} +#endif /* DEBUG_WOLFSSL */ + + +int wc_SetLoggingHeap(void* h) +{ + if (wc_LockMutex(&debug_mutex) != 0) { + WOLFSSL_MSG("Lock debug mutex failed"); + return BAD_MUTEX_E; + } + wc_error_heap = h; + wc_UnLockMutex(&debug_mutex); + return 0; +} + +#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) +/* empties out the error queue into the file */ +void wc_ERR_print_errors_fp(FILE* fp) +{ + WOLFSSL_ENTER("wc_ERR_print_errors_fp"); + + if (wc_LockMutex(&debug_mutex) != 0) { + WOLFSSL_MSG("Lock debug mutex failed"); + } + else { + /* free all nodes from error queue and print them to file */ + { + struct wc_error_queue* current; + struct wc_error_queue* next; + + current = (struct wc_error_queue*)wc_errors; + while (current != NULL) { + next = current->next; + fprintf(fp, "%s\n", current->error); + XFREE(current, current->heap, DYNAMIC_TYPE_LOG); + current = next; + } + + /* set global pointers to match having been freed */ + wc_errors = NULL; + wc_last_node = NULL; + } + + wc_UnLockMutex(&debug_mutex); + } +} +#endif /* !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) */ + +#endif /* defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) */ + diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 434248fd7..1048dc987 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -97,12 +97,35 @@ int wolfCrypt_Init(void) wolfSSL_EVP_init(); #endif + #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) + if ((ret = wc_LoggingInit()) != 0) { + WOLFSSL_MSG("Error creating logging mutex"); + return ret; + } + #endif + initRefCount = 1; } return ret; } + +/* return success value is the same as wolfCrypt_Init */ +int wolfCrypt_Cleanup(void) +{ + int ret = 0; + + WOLFSSL_ENTER("wolfCrypt_Cleanup"); + + #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) + ret = wc_LoggingCleanup(); + #endif + + return ret; +} + + wolfSSL_Mutex* wc_InitAndAllocMutex() { wolfSSL_Mutex* m = (wolfSSL_Mutex*) XMALLOC(sizeof(wolfSSL_Mutex), NULL, diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index d7c6fb4ce..5a629980a 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -326,6 +326,10 @@ int wolfcrypt_test(void* args) wolfCrypt_Init(); +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) + wc_SetLoggingHeap(HEAP_HINT); +#endif + #ifdef HAVE_FIPS wolfCrypt_SetCb_fips(myFipsCb); #endif @@ -717,6 +721,10 @@ int wolfcrypt_test(void* args) printf( "PKCS7encrypted test passed!\n"); #endif + if ((ret = wolfCrypt_Cleanup())!= 0) { + return err_sys("Error with wolfCrypt_Cleanup!\n", ret); + } + #if defined(USE_WOLFSSL_MEMORY) && defined(WOLFSSL_TRACK_MEMORY) ShowMemoryTracker(); #endif diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index f89c3608c..6e63fed55 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -106,8 +106,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define SSL_get_shared_ciphers(ctx,buf,len) \ strncpy(buf, "Not Implemented, SSLv2 only", len) -/* @TODO */ -#define ERR_print_errors_fp(file) wolfSSL_ERR_print_errors_fp((file)) +#define ERR_print_errors_fp(file) wolfSSL_ERR_dump_errors_fp((file)) /* at the moment only returns ok */ #define SSL_get_verify_result wolfSSL_get_verify_result diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index dc74b6b19..6fc8a6e87 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -891,6 +891,9 @@ enum { since not using thread storage error queue */ #include WOLFSSL_API void wolfSSL_ERR_print_errors_fp(FILE*, int err); +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) +WOLFSSL_API void wolfSSL_ERR_dump_errors_fp(FILE* fp); +#endif #endif enum { /* ssl Constants */ diff --git a/wolfssl/wolfcrypt/logging.h b/wolfssl/wolfcrypt/logging.h index a69bde5c7..1807e41df 100644 --- a/wolfssl/wolfcrypt/logging.h +++ b/wolfssl/wolfcrypt/logging.h @@ -46,6 +46,26 @@ typedef void (*wolfSSL_Logging_cb)(const int logLevel, WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function); +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) + typedef struct wc_error_queue wc_error_queue; + + /* make these variables global and declare them in logging.c */ + extern volatile char wc_last_error_file[80]; + extern volatile unsigned long wc_last_error_line; + extern volatile unsigned long wc_last_error; + extern volatile void* wc_error_heap; + extern volatile wc_error_queue* wc_errors; + + WOLFSSL_LOCAL int wc_LoggingInit(void); + WOLFSSL_LOCAL int wc_LoggingCleanup(void); + WOLFSSL_LOCAL int wc_AddErrorNode(int error, int line, char* buf, + char* file); + WOLFSSL_API int wc_SetLoggingHeap(void* h); + #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) + WOLFSSL_API void wc_ERR_print_errors_fp(FILE* fp); + #endif +#endif /* defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) */ + #ifdef DEBUG_WOLFSSL /* a is prepended to m and b is appended, creating a log msg a + m + b */ #define WOLFSSL_LOG_CAT(a, m, b) #a " " m " " #b @@ -56,11 +76,6 @@ WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function); WOLFSSL_MSG(WOLFSSL_LOG_CAT(wolfSSL Stub, m, not implemented)) #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) - /* make these variables global and declare them in logging.c */ - extern volatile char wc_last_error_file[80]; - extern volatile unsigned long wc_last_error_line; - extern volatile unsigned long wc_last_error; - void WOLFSSL_ERROR_LINE(int err, const char* func, unsigned int line, const char* file, void* ctx); #define WOLFSSL_ERROR(x) WOLFSSL_ERROR_LINE((x), __func__, __LINE__, __FILE__,NULL) diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index d40916548..00b184668 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -340,7 +340,8 @@ DYNAMIC_TYPE_PKCS = 58, DYNAMIC_TYPE_MUTEX = 59, DYNAMIC_TYPE_PKCS7 = 60, - DYNAMIC_TYPE_ASN1 = 61 + DYNAMIC_TYPE_ASN1 = 61, + DYNAMIC_TYPE_LOG = 62 }; /* max error buffer string size */ diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index db8d1ee43..3643c2627 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -186,6 +186,7 @@ WOLFSSL_API int wc_UnLockMutex(wolfSSL_Mutex*); /* main crypto initialization function */ WOLFSSL_API int wolfCrypt_Init(void); +WOLFSSL_API int wolfCrypt_Cleanup(void); /* filesystem abstraction layer, used by ssl.c */ #ifndef NO_FILESYSTEM From 4be5f624e89a37da4a96b3b12d8c8cb00e6020f9 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 6 Jan 2017 16:40:19 -0700 Subject: [PATCH 2/6] include logging.h in test.c --- wolfcrypt/test/test.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 5a629980a..e98d87a94 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -101,6 +101,9 @@ #ifdef WOLFSSL_ASYNC_CRYPT #include #endif +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) + #include +#endif #ifdef _MSC_VER /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ From 0b8730f0b68eb4e4424db81e9b43fef2c6d94a84 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 27 Jan 2017 15:14:25 -0700 Subject: [PATCH 3/6] check bounds of buffer and get file buffer size --- wolfcrypt/src/logging.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index d0b66ef98..56ce90fc1 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -247,8 +247,8 @@ void WOLFSSL_ERROR(int error) if (error < 0) error = error - (2*error); /*get absolute value*/ wc_last_error = (unsigned long)error; wc_last_error_line = (unsigned long)line; - XMEMSET((char*)wc_last_error_file, 0, sizeof(file)); - if (XSTRLEN(file) < sizeof(file)) { + XMEMSET((char*)wc_last_error_file, 0, sizeof(wc_last_error_file)); + if (XSTRLEN(file) < sizeof(wc_last_error_file)) { XSTRNCPY((char*)wc_last_error_file, file, XSTRLEN(file)); } sprintf(buffer, "wolfSSL error occurred, error = %d line:%d file:%s", @@ -333,10 +333,26 @@ int wc_AddErrorNode(int error, int line, char* buf, char* file) return MEMORY_E; } else { + int sz; + XMEMSET(err, 0, sizeof(struct wc_error_queue)); err->heap = (void*)wc_error_heap; - XMEMCPY(err->error, buf, WOLFSSL_MAX_ERROR_SZ - 1); - XMEMCPY(err->file, file, WOLFSSL_MAX_ERROR_SZ - 1); + sz = (int)XSTRLEN(buf); + if (sz > WOLFSSL_MAX_ERROR_SZ - 1) { + sz = WOLFSSL_MAX_ERROR_SZ - 1; + } + if (sz > 0) { + XMEMCPY(err->error, buf, sz); + } + + sz = (int)XSTRLEN(file); + if (sz > WOLFSSL_MAX_ERROR_SZ - 1) { + sz = WOLFSSL_MAX_ERROR_SZ - 1; + } + if (sz > 0) { + XMEMCPY(err->file, file, sz); + } + err->value = error; err->line = line; From 0f91542cf4e0c94e796ee04c3ec4aef971daee62 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 3 Feb 2017 11:52:36 -0700 Subject: [PATCH 4/6] add peek error node function to make use of debug mutex --- src/ssl.c | 14 ++++---- tests/api.c | 1 - wolfcrypt/src/logging.c | 65 +++++++++++++++++++++++++++++++++++-- wolfssl/wolfcrypt/logging.h | 2 ++ 4 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 3f6f3a6eb..e98ae1cb6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -20469,13 +20469,15 @@ unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line) (void)line; (void)file; #if defined(DEBUG_WOLFSSL) - if (line != NULL) { - *line = (int)wc_last_error_line; + { + int ret; + + if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) { + WOLFSSL_MSG("Issue peeking at error node in queue"); + return 0; + } + return (unsigned long)ret; } - if (file != NULL) { - *file = (char*)wc_last_error_file; - } - return wc_last_error; #else return (unsigned long)(0 - NOT_COMPILED_IN); #endif diff --git a/tests/api.c b/tests/api.c index 0d5b1c205..d0d1a00d7 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2703,7 +2703,6 @@ static void test_wolfSSL_ERR_peek_last_error_line(void) ERR_print_errors_fp(stdout); printf("Done testing print out\n\n"); fflush(stdout); - wolfSSL_Cleanup(); #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ !defined(NO_FILESYSTEM) && !defined(DEBUG_WOLFSSL) */ } diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 56ce90fc1..1ecef97c0 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -273,7 +273,7 @@ void WOLFSSL_ERROR(int error) int wc_LoggingInit(void) { if (wc_InitMutex(&debug_mutex) != 0) { - WOLFSSL_MSG("Bad Init Mutex frnih"); + WOLFSSL_MSG("Bad Init Mutex"); return BAD_MUTEX_E; } XMEMSET((char*)wc_last_error_file, 0, sizeof(wc_last_error_file)); @@ -310,7 +310,7 @@ int wc_LoggingCleanup(void) wc_UnLockMutex(&debug_mutex); if (wc_FreeMutex(&debug_mutex) != 0) { - WOLFSSL_MSG("Bad Init Mutex frnih"); + WOLFSSL_MSG("Bad Mutex free"); return BAD_MUTEX_E; } return 0; @@ -318,6 +318,67 @@ int wc_LoggingCleanup(void) #ifdef DEBUG_WOLFSSL +/* peek at an error node + * + * index : if -1 then the most recent node is looked at, otherwise search + * through queue for node at the given index + * file : pointer to internal file string + * reason : pointer to internal error reason + * line : line number that error happened at + * + * Returns a negative value in error case, on success returns the nodes error + * value which is positve (absolute value) + */ +int wc_PeekErrorNode(int index, const char **file, const char **reason, + int *line) +{ + struct wc_error_queue* err; + + if (wc_LockMutex(&debug_mutex) != 0) { + WOLFSSL_MSG("Lock debug mutex failed"); + return BAD_MUTEX_E; + } + + if (index < 0) { + err = wc_last_node; + if (err == NULL) { + WOLFSSL_MSG("No Errors in queue"); + wc_UnLockMutex(&debug_mutex); + return BAD_STATE_E; + } + } + else { + int i; + + err = (struct wc_error_queue*)wc_errors; + for (i = 0; i < index; i++) { + if (err == NULL) { + WOLFSSL_MSG("Error node not found. Bad index?"); + wc_UnLockMutex(&debug_mutex); + return BAD_FUNC_ARG; + } + err = err->next; + } + } + + if (file != NULL) { + *file = err->file; + } + + if (reason != NULL) { + *reason = err->error; + } + + if (line != NULL) { + *line = err->line; + } + + wc_UnLockMutex(&debug_mutex); + + return err->value; +} + + /* create new error node and add it to the queue * buffers are assumed to be of size WOLFSSL_MAX_ERROR_SZ for this internal * function */ diff --git a/wolfssl/wolfcrypt/logging.h b/wolfssl/wolfcrypt/logging.h index 1807e41df..e95e65835 100644 --- a/wolfssl/wolfcrypt/logging.h +++ b/wolfssl/wolfcrypt/logging.h @@ -60,6 +60,8 @@ WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function); WOLFSSL_LOCAL int wc_LoggingCleanup(void); WOLFSSL_LOCAL int wc_AddErrorNode(int error, int line, char* buf, char* file); + WOLFSSL_LOCAL int wc_PeekErrorNode(int index, const char **file, + const char **reason, int *line); WOLFSSL_API int wc_SetLoggingHeap(void* h); #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) WOLFSSL_API void wc_ERR_print_errors_fp(FILE* fp); From 53bebb4785d7215649f3a3b75a8f0bed89d608c2 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Mon, 6 Feb 2017 14:51:55 -0700 Subject: [PATCH 5/6] add error code for wolfCrypt_Cleanup --- src/ssl.c | 1 + wolfcrypt/src/error.c | 3 +++ wolfssl/wolfcrypt/error-crypt.h | 1 + 3 files changed, 5 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index e98ae1cb6..85468627f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8296,6 +8296,7 @@ int wolfSSL_Cleanup(void) if (wolfCrypt_Cleanup() != 0) { WOLFSSL_MSG("Error with wolfCrypt_Cleanup call"); + ret = WC_CLEANUP_E; } return ret; diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index 2de4e7c0a..2981bfdc0 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -407,6 +407,9 @@ const char* wc_GetErrorString(int error) case BAD_KEYWRAP_IV_E: return "Decrypted AES key wrap IV does not match expected"; + case WC_CLEANUP_E: + return "wolfcrypt cleanup failed"; + default: return "unknown error number"; diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index 9ebdc5d21..bd8b83636 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -180,6 +180,7 @@ enum { BAD_KEYWRAP_ALG_E = -239, BAD_KEYWRAP_IV_E = -240, /* Decrypted AES key wrap IV incorrect */ + WC_CLEANUP_E = -241, /* wolfcrypt cleanup failed */ MIN_CODE_E = -300 /* errors -101 - -299 */ From 993a6041248166b02d3adebacd94136665bd650b Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Tue, 7 Feb 2017 17:16:22 -0700 Subject: [PATCH 6/6] remove extern variables and use error queue instead --- wolfcrypt/src/logging.c | 24 ++++++------------------ wolfssl/wolfcrypt/logging.h | 9 --------- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 1ecef97c0..43c5a1aad 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -44,13 +44,9 @@ #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) static wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */ -/* accessing any of these global variables should be wrapped in a lock of +/* accessing any node from the queue should be wrapped in a lock of * debug_mutex */ -volatile char wc_last_error_file[WOLFSSL_MAX_ERROR_SZ]; -volatile unsigned long wc_last_error_line; -volatile unsigned long wc_last_error; -volatile void* wc_error_heap; - +static void* wc_error_heap; struct wc_error_queue { void* heap; /* the heap hint used with nodes creation */ struct wc_error_queue* next; @@ -245,16 +241,12 @@ void WOLFSSL_ERROR(int error) } else { if (error < 0) error = error - (2*error); /*get absolute value*/ - wc_last_error = (unsigned long)error; - wc_last_error_line = (unsigned long)line; - XMEMSET((char*)wc_last_error_file, 0, sizeof(wc_last_error_file)); - if (XSTRLEN(file) < sizeof(wc_last_error_file)) { - XSTRNCPY((char*)wc_last_error_file, file, XSTRLEN(file)); - } sprintf(buffer, "wolfSSL error occurred, error = %d line:%d file:%s", error, line, file); if (wc_AddErrorNode(error, line, buffer, (char*)file) != 0) { WOLFSSL_MSG("Error creating logging node"); + /* with void function there is no return here, continue on + * to unlock mutex and log what buffer was created. */ } wc_UnLockMutex(&debug_mutex); @@ -276,11 +268,7 @@ int wc_LoggingInit(void) WOLFSSL_MSG("Bad Init Mutex"); return BAD_MUTEX_E; } - XMEMSET((char*)wc_last_error_file, 0, sizeof(wc_last_error_file)); - wc_last_error_line = 0; - wc_last_error = 0; wc_errors = NULL; - wc_error_heap = NULL; wc_last_node = NULL; return 0; @@ -381,7 +369,7 @@ int wc_PeekErrorNode(int index, const char **file, const char **reason, /* create new error node and add it to the queue * buffers are assumed to be of size WOLFSSL_MAX_ERROR_SZ for this internal - * function */ + * function. debug_mutex should be locked before a call to this function. */ int wc_AddErrorNode(int error, int line, char* buf, char* file) { @@ -397,7 +385,7 @@ int wc_AddErrorNode(int error, int line, char* buf, char* file) int sz; XMEMSET(err, 0, sizeof(struct wc_error_queue)); - err->heap = (void*)wc_error_heap; + err->heap = wc_error_heap; sz = (int)XSTRLEN(buf); if (sz > WOLFSSL_MAX_ERROR_SZ - 1) { sz = WOLFSSL_MAX_ERROR_SZ - 1; diff --git a/wolfssl/wolfcrypt/logging.h b/wolfssl/wolfcrypt/logging.h index e95e65835..c8f9a657a 100644 --- a/wolfssl/wolfcrypt/logging.h +++ b/wolfssl/wolfcrypt/logging.h @@ -47,15 +47,6 @@ typedef void (*wolfSSL_Logging_cb)(const int logLevel, WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function); #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) - typedef struct wc_error_queue wc_error_queue; - - /* make these variables global and declare them in logging.c */ - extern volatile char wc_last_error_file[80]; - extern volatile unsigned long wc_last_error_line; - extern volatile unsigned long wc_last_error; - extern volatile void* wc_error_heap; - extern volatile wc_error_queue* wc_errors; - WOLFSSL_LOCAL int wc_LoggingInit(void); WOLFSSL_LOCAL int wc_LoggingCleanup(void); WOLFSSL_LOCAL int wc_AddErrorNode(int error, int line, char* buf,