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