From e741a240893d0017fbb1f96dd1aea9619210fa38 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 30 Nov 2016 13:26:24 -0700 Subject: [PATCH] add get last error and line function, fix ASN1 object redeclaration --- src/ssl.c | 55 +++++++++++++++++++++ tests/api.c | 87 ++++++++++++++++++++++++++++++++-- wolfcrypt/src/asn.c | 32 ------------- wolfcrypt/src/logging.c | 27 +++++++++++ wolfssl/ssl.h | 5 +- wolfssl/wolfcrypt/asn_public.h | 9 ---- wolfssl/wolfcrypt/logging.h | 11 +++++ 7 files changed, 178 insertions(+), 48 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 46fdfca67..139b4cb54 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -12824,6 +12824,38 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJCET_pop( } +WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void) +{ + WOLFSSL_ASN1_OBJECT* obj; + + obj = (WOLFSSL_ASN1_OBJECT*)XMALLOC(sizeof(WOLFSSL_ASN1_OBJECT), NULL, + DYNAMIC_TYPE_ASN1); + if (obj == NULL) { + return NULL; + } + + XMEMSET(obj, 0, sizeof(WOLFSSL_ASN1_OBJECT)); + return obj; +} + + +void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj) +{ + if (obj == NULL) { + return; + } + + if (obj->dynamic == 1) { + if (obj->obj != NULL) { + WOLFSSL_MSG("Freeing ASN1 OBJECT data"); + XFREE(obj->obj, obj->heap, DYNAMIC_TYPE_ASN1); + } + } + + XFREE(obj, NULL, DYNAMIC_TYPE_ASN1); +} + + /* free structure for x509 stack */ void wolfSSL_sk_ASN1_OBJECT_free(STACK_OF(WOLFSSL_ASN1_OBJECT)* sk) { @@ -19924,6 +19956,29 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) #ifdef OPENSSL_EXTRA +/* wolfSSL uses negative values for error states. This function returns an + * unsigned type so the value returned is the absolute value of the error. + */ +unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line) +{ + WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error"); + + (void)line; + (void)file; +#if defined(DEBUG_WOLFSSL) + if (line != NULL) { + *line = (int)wc_last_error_line; + } + if (file != NULL) { + *file = (char*)wc_last_error_file; + } + return wc_last_error; +#else + return NOT_COMPILED_IN; +#endif +} + + int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) { WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey"); diff --git a/tests/api.c b/tests/api.c index f8ffe1dba..bfa9c9f41 100644 --- a/tests/api.c +++ b/tests/api.c @@ -636,7 +636,13 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) #endif ((func_args*)args)->return_code = TEST_FAIL; - method = wolfSSLv23_server_method(); + if (((func_args*)args)->callbacks != NULL && + ((func_args*)args)->callbacks->method != NULL) { + method = ((func_args*)args)->callbacks->method(); + } + else { + method = wolfSSLv23_server_method(); + } ctx = wolfSSL_CTX_new(method); #if defined(USE_WINDOWS_API) @@ -779,7 +785,13 @@ static void test_client_nofail(void* args) #endif ((func_args*)args)->return_code = TEST_FAIL; - method = wolfSSLv23_client_method(); + if (((func_args*)args)->callbacks != NULL && + ((func_args*)args)->callbacks->method != NULL) { + method = ((func_args*)args)->callbacks->method(); + } + else { + method = wolfSSLv23_client_method(); + } ctx = wolfSSL_CTX_new(method); #ifdef OPENSSL_EXTRA @@ -1145,6 +1157,8 @@ static void test_wolfSSL_read_write(void) func_args server_args; THREAD_TYPE serverThread; + XMEMSET(&client_args, 0, sizeof(func_args)); + XMEMSET(&server_args, 0, sizeof(func_args)); #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); #endif @@ -1190,6 +1204,8 @@ static void test_wolfSSL_dtls_export(void) InitTcpReady(&ready); /* set using dtls */ + XMEMSET(&client_args, 0, sizeof(func_args)); + XMEMSET(&server_args, 0, sizeof(func_args)); XMEMSET(&server_cbf, 0, sizeof(callback_functions)); XMEMSET(&client_cbf, 0, sizeof(callback_functions)); server_cbf.method = wolfDTLSv1_2_server_method; @@ -1233,6 +1249,9 @@ static void test_wolfSSL_client_server(callback_functions* client_callbacks, func_args server_args; THREAD_TYPE serverThread; + XMEMSET(&client_args, 0, sizeof(func_args)); + XMEMSET(&server_args, 0, sizeof(func_args)); + StartTCP(); client_args.callbacks = client_callbacks; @@ -2572,11 +2591,11 @@ static void test_wolfSSL_ctrl(void) static void test_wolfSSL_CTX_add_extra_chain_cert(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ - !defined(NO_FILESYSTEM) + !defined(NO_FILESYSTEM) && !defined(NO_RSA) char caFile[] = "./certs/client-ca.pem"; char clientFile[] = "./certs/client-cert.pem"; SSL_CTX* ctx; - X509* x509; + X509* x509 = NULL; printf(testingFmt, "wolfSSL_CTX_add_extra_chain_cert()"); @@ -2593,7 +2612,64 @@ static void test_wolfSSL_CTX_add_extra_chain_cert(void) SSL_CTX_free(ctx); printf(resultFmt, passed); #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ - !defined(NO_FILESYSTEM) */ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) */ +} + + +static void test_wolfSSL_ERR_peek_last_error_line(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && defined(DEBUG_WOLFSSL) + tcp_ready ready; + func_args client_args; + func_args server_args; + THREAD_TYPE serverThread; + callback_functions client_cb; + callback_functions server_cb; + int line = 0; + const char* file = NULL; + + printf(testingFmt, "wolfSSL_ERR_peek_last_error_line()"); + + /* create a failed connection and inspect the error */ +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + XMEMSET(&client_args, 0, sizeof(func_args)); + XMEMSET(&server_args, 0, sizeof(func_args)); + + StartTCP(); + InitTcpReady(&ready); + + client_cb.method = wolfTLSv1_1_client_method; + server_cb.method = wolfTLSv1_2_server_method; + + server_args.signal = &ready; + server_args.callbacks = &server_cb; + client_args.signal = &ready; + client_args.callbacks = &client_cb; + + start_thread(test_server_nofail, &server_args, &serverThread); + wait_tcp_ready(&server_args); + test_client_nofail(&client_args); + join_thread(serverThread); + + FreeTcpReady(&ready); + + /* check that error code was stored */ + AssertIntNE(wolfSSL_ERR_peek_last_error_line(NULL, NULL), 0); + wolfSSL_ERR_peek_last_error_line(NULL, &line); + AssertIntNE(line, 0); + wolfSSL_ERR_peek_last_error_line(&file, NULL); + AssertNotNull(file); + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) */ } /*----------------------------------------------------------------------------* @@ -2648,6 +2724,7 @@ void ApiTest(void) test_wolfSSL_tmp_dh(); test_wolfSSL_ctrl(); test_wolfSSL_CTX_add_extra_chain_cert(); + test_wolfSSL_ERR_peek_last_error_line(); AssertIntEQ(test_wolfSSL_Cleanup(), SSL_SUCCESS); printf(" End API Tests\n"); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 765f42c73..41fd3b57a 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -1398,38 +1398,6 @@ int GetObjectId(const byte* input, word32* inOutIdx, word32* oid, } -WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void) -{ - WOLFSSL_ASN1_OBJECT* obj; - - obj = (WOLFSSL_ASN1_OBJECT*)XMALLOC(sizeof(WOLFSSL_ASN1_OBJECT), NULL, - DYNAMIC_TYPE_ASN1); - if (obj == NULL) { - return NULL; - } - - XMEMSET(obj, 0, sizeof(WOLFSSL_ASN1_OBJECT)); - return obj; -} - - -void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj) -{ - if (obj == NULL) { - return; - } - - if (obj->dynamic == 1) { - if (obj->obj != NULL) { - WOLFSSL_MSG("Freeing ASN1 OBJECT data"); - XFREE(obj->obj, obj->heap, DYNAMIC_TYPE_ASN1); - } - } - - XFREE(obj, NULL, DYNAMIC_TYPE_ASN1); -} - - #ifndef NO_RSA #ifndef HAVE_USER_RSA #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA) diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 9a4fac5f4..2c7e5be04 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -43,6 +43,11 @@ #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; @@ -198,11 +203,33 @@ void WOLFSSL_LEAVE(const char* msg, int ret) } +/* + * When using OPENSSL_EXTRA or DEBUG_WOLFSSL_VERBOSE macro then WOLFSSL_ERROR is + * mapped to new funtion WOLFSSL_ERROR_LINE which gets the line # and function + * name where WOLFSSL_ERROR is called at. + */ +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) +void WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line, + const char* file, void* usrCtx) +#else void WOLFSSL_ERROR(int error) +#endif { if (loggingEnabled) { char buffer[80]; sprintf(buffer, "wolfSSL error occurred, error = %d", 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)); + } + sprintf(buffer, "%s line:%d file:%s", buffer, line, file); + #endif wolfssl_log(ERROR_LOG , buffer); } } diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index ecfda40b3..f81a3a004 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -443,7 +443,8 @@ WOLFSSL_API int wolfSSL_sk_X509_push(STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509); WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_pop(STACK_OF(WOLFSSL_X509_NAME)* sk); WOLFSSL_API void wolfSSL_sk_X509_free(STACK_OF(WOLFSSL_X509_NAME)* sk); - +WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void); +WOLFSSL_API void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj); WOLFSSL_API int wolfSSL_sk_ASN1_OBJECT_push(STACK_OF(WOLFSSL_ASN1_OBJEXT)* sk, WOLFSSL_ASN1_OBJECT* obj); WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJCET_pop( @@ -1895,6 +1896,7 @@ WOLFSSL_API char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time, #endif /* WOLFSSL_MYSQL_COMPATIBLE */ #ifdef OPENSSL_EXTRA +WOLFSSL_API unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line); WOLFSSL_API long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt); WOLFSSL_API long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt,void* pt); @@ -2071,7 +2073,6 @@ WOLFSSL_API void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX *, WOLFSSL_API void wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX *, void*); WOLFSSL_API void WOLFSSL_ERR_remove_thread_state(void*); -WOLFSSL_API unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line); #ifndef NO_FILESYSTEM WOLFSSL_API void wolfSSL_print_all_errors_fp(XFILE *fp); diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 7bd3265f0..576d2d28f 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -158,12 +158,6 @@ typedef struct Cert { #endif void* heap; /* heap hint */ } Cert; -#endif /* WOLFSSL_CERT_GEN */ - -typedef struct WOLFSSL_ASN1_OBJECT WOLFSSL_ASN1_OBJECT; - -#ifdef WOLFSSL_CERT_GEN - /* Initialize and Set Certificate defaults: @@ -282,9 +276,6 @@ WOLFSSL_API int wc_GetCTC_HashOID(int type); */ WOLFSSL_API int wc_GetTime(void* timePtr, word32 timeSize); -WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void); -WOLFSSL_API void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj); - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/logging.h b/wolfssl/wolfcrypt/logging.h index 29bf0abea..a69bde5c7 100644 --- a/wolfssl/wolfcrypt/logging.h +++ b/wolfssl/wolfcrypt/logging.h @@ -55,7 +55,18 @@ WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function); #define WOLFSSL_STUB(m) \ 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) +#else void WOLFSSL_ERROR(int); +#endif void WOLFSSL_MSG(const char* msg); void WOLFSSL_BUFFER(byte* buffer, word32 length);