Added API unit test for certificate validation failure using corrupted signature in cert.

This commit is contained in:
David Garske
2017-04-04 11:15:32 -07:00
parent 26f3924c93
commit 2aa523e0ea
2 changed files with 162 additions and 15 deletions

View File

@ -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");
}

View File

@ -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