diff --git a/tests/api.c b/tests/api.c index 78a3a4d68..d6d623406 100644 --- a/tests/api.c +++ b/tests/api.c @@ -77,7 +77,7 @@ static const char* passed = "passed"; static const char* failed = "failed"; #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) - static const char* bogusFile = + static const char* bogusFile = #ifdef _WIN32 "NUL" #else @@ -86,6 +86,12 @@ static const char* failed = "failed"; ; #endif +enum { + TESTING_RSA = 1, + TESTING_ECC = 2 +}; + + /*----------------------------------------------------------------------------* | Setup *----------------------------------------------------------------------------*/ @@ -541,7 +547,7 @@ static void test_wolfSSL_SetTmpDH_buffer(void) /* Test function for wolfSSL_SetMinVersion. Sets the minimum downgrade version - * allowed. + * allowed. * POST: return 1 on success. */ static int test_wolfSSL_SetMinVersion(void) @@ -3128,6 +3134,111 @@ static void test_wc_ecc_get_curve_id_from_name(void) } +/*----------------------------------------------------------------------------* + | Certficate Failure Checks + *----------------------------------------------------------------------------*/ +#ifndef NO_CERTS + /* Use the Cert Manager(CM) API to generate the error ASN_SIG_CONFIRM_E */ + static int verify_sig_cm(const char* ca, byte* cert_buf, size_t cert_sz, + int type) + { + int ret; + WOLFSSL_CERT_MANAGER* cm = NULL; + + switch (type) { + case TESTING_RSA: + #ifdef NO_RSA + printf("RSA disabled, skipping test\n"); + return ASN_SIG_CONFIRM_E; + #else + break; + #endif + case TESTING_ECC: + #ifndef HAVE_ECC + printf("ECC disabled, skipping test\n"); + return ASN_SIG_CONFIRM_E; + #else + break; + #endif + default: + printf("Bad function argument\n"); + return BAD_FUNC_ARG; + } + cm = wolfSSL_CertManagerNew(); + if (cm == NULL) { + printf("wolfSSL_CertManagerNew failed\n"); + return -1; + } + + ret = wolfSSL_CertManagerLoadCA(cm, ca, 0); + if (ret != SSL_SUCCESS) { + printf("wolfSSL_CertManagerLoadCA failed\n"); + wolfSSL_CertManagerFree(cm); + return ret; + } + + ret = wolfSSL_CertManagerVerifyBuffer(cm, cert_buf, cert_sz, SSL_FILETYPE_ASN1); + /* Let AssertIntEQ handle return code */ + + wolfSSL_CertManagerFree(cm); + + return ret; + } + + static int test_RsaConfirmSig_cm(void) + { + int ret = 0; + const char* ca_cert = "./certs/ca-cert.pem"; + const char* server_cert = "./certs/server-cert.der"; + byte* cert_buf = NULL; + size_t cert_sz = 0; + + ret = load_file(server_cert, &cert_buf, &cert_sz); + if (ret == 0) { + /* corrupt DER - invert last byte, which is signature */ + cert_buf[cert_sz-1] = ~cert_buf[cert_sz-1]; + + /* test bad cert */ + ret = verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_RSA); + } + + printf("Verify signature exception test: RSA: Ret %d\n", ret); + + if (cert_buf) + free(cert_buf); + + return ret; + } + + static int test_EccConfirmSig_cm(void) + { + int ret = 0; + /* self-signed ECC cert, so use server cert as CA */ + const char* ca_cert = "./certs/server-ecc.pem"; + const char* server_cert = "./certs/server-ecc.der"; + byte* cert_buf = NULL; + size_t cert_sz = 0; + + ret = load_file(server_cert, &cert_buf, &cert_sz); + if (ret == 0) { + /* corrupt DER - invert last byte, which is signature */ + cert_buf[cert_sz-1] = ~cert_buf[cert_sz-1]; + + /* test bad cert */ + ret = verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_ECC); + } + + printf("Verify signature exception test: ECC: Ret %d\n", ret); + + if (cert_buf) + free(cert_buf); + + return ret; + } + +#endif /* NO_CERTS */ + + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -3196,6 +3307,12 @@ void ApiTest(void) test_wc_ecc_get_curve_size_from_name(); test_wc_ecc_get_curve_id_from_name(); +#ifndef NO_CERTS + /* Bad certificate tests */ + AssertIntEQ(test_EccConfirmSig_cm(), ASN_SIG_CONFIRM_E); + AssertIntEQ(test_RsaConfirmSig_cm(), ASN_SIG_CONFIRM_E); +#endif /* NO_CERTS */ + printf(" End API Tests\n"); } diff --git a/wolfssl/test.h b/wolfssl/test.h index db73f406c..4e5e7446a 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1099,8 +1099,41 @@ static INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity, #endif /* USE_WINDOWS_API */ -#if defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(FORCE_BUFFER_TEST) +#if !defined(NO_CERTS) + /* reads file size, allocates buffer, reads into buffer, returns buffer */ + static INLINE int load_file(const char* fname, byte** buf, size_t* bufLen) + { + int ret = 0; + FILE* file = fopen(fname, "rb"); + + if (!file) { + printf("Error loading %s\n", fname); + return -1; + } + + fseek(file, 0, SEEK_END); + *bufLen = ftell(file); + rewind(file); + if (*bufLen > 0) { + *buf = (byte*)malloc(*bufLen); + if (*buf == NULL) { + ret = MEMORY_E; + printf("Error allocating %lu bytes\n", *bufLen); + } + else { + size_t readLen = fread(*buf, *bufLen, 1, file); + + /* check response code */ + ret = (readLen > 0) ? 0 : -1; + } + } + fclose(file); + + return ret; + } + + #if defined(NO_FILESYSTEM) && defined(FORCE_BUFFER_TEST) enum { WOLFSSL_CA = 1, WOLFSSL_CERT = 2, @@ -1111,19 +1144,14 @@ static INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity, static INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type) { int format = SSL_FILETYPE_PEM; + byte* buff = NULL; + size_t sz = 0; - /* test buffer load */ - long sz = 0; - byte buff[10000]; - FILE* file = fopen(fname, "rb"); - - if (!file) + ret = load_file(fname, &buff, &sz); + if (ret != 0) { err_sys("can't open file for buffer load " "Please run from wolfSSL home directory if not"); - fseek(file, 0, SEEK_END); - sz = ftell(file); - rewind(file); - fread(buff, sizeof(buff), 1, file); + } /* determine format */ if (strstr(fname, ".der")) @@ -1150,10 +1178,12 @@ static INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity, err_sys("can't load cert chain buffer"); } - fclose(file); + if (buff) + free(buff); } + #endif /* NO_FILESYSTEM && FORCE_BUFFER_TEST */ -#endif /* NO_FILESYSTEM */ +#endif /* !NO_CERTS */ #ifdef VERIFY_CALLBACK