From d43aa370415cf48cbb49c3494a0ed63e79845cef Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 3 May 2018 09:33:05 -0700 Subject: [PATCH 1/4] Fix for handling match on domain name that may have a null terminator inside. The check should match on len from ASN.1 reguardless of a null character. --- src/internal.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index c3dfc3495..f912c8c30 100644 --- a/src/internal.c +++ b/src/internal.c @@ -7525,9 +7525,6 @@ int MatchDomainName(const char* pattern, int len, const char* str) return 0; } - if (*str != '\0') - str++; - if (len > 0) len--; } From 89a4c9867033e6770cb0fdae7280c6ed51f5e95f Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 3 May 2018 09:40:51 -0700 Subject: [PATCH 2/4] * Added support for expected fail test cases with example client/server and suites unit test. * Added test for certificate with bad alt name containing a null character mid byte stream. * Fix for issue with suites unit test where last arg in file doesn't conain data for a param, causing it to skip test. * Fix for last test in tests/test.conf not being run for `TLSv1.2 RSA 3072-bit DH 3072-bit`. * Moved the `tls-cert-fail.test` tests into the new expected failure suite test (`./tests/test-fails.conf`). Now it explicilty checks RSA and ECC for the no signer and no sig tests. --- certs/test/gen-badaltnamenull.sh | 20 +++ certs/test/include.am | 9 ++ certs/test/server-badaltnamenull.conf | 17 +++ certs/test/server-badaltnamenull.csr | 17 +++ certs/test/server-badaltnamenull.der | Bin 0 -> 855 bytes certs/test/server-badaltnamenull.key | 27 ++++ certs/test/server-badaltnamenull.pem | 72 +++++++++++ examples/client/client.c | 29 ++--- examples/server/server.c | 32 ++--- scripts/include.am | 5 - scripts/tls-cert-fail.test | 173 -------------------------- tests/include.am | 3 +- tests/suites.c | 81 +++++++++--- tests/test-dtls.conf | 1 - tests/test-ed25519.conf | 1 - tests/test-fails.conf | 50 ++++++++ tests/test-psk-no-id.conf | 1 - tests/test-qsh.conf | 1 - tests/test-sctp.conf | 1 - tests/test-sig.conf | 1 - tests/test-tls13-ecc.conf | 1 - tests/test-tls13.conf | 1 - tests/test.conf | 2 +- wolfssl/test.h | 8 +- 24 files changed, 311 insertions(+), 242 deletions(-) create mode 100755 certs/test/gen-badaltnamenull.sh create mode 100644 certs/test/server-badaltnamenull.conf create mode 100644 certs/test/server-badaltnamenull.csr create mode 100644 certs/test/server-badaltnamenull.der create mode 100644 certs/test/server-badaltnamenull.key create mode 100644 certs/test/server-badaltnamenull.pem delete mode 100755 scripts/tls-cert-fail.test create mode 100644 tests/test-fails.conf diff --git a/certs/test/gen-badaltnamenull.sh b/certs/test/gen-badaltnamenull.sh new file mode 100755 index 000000000..8ca9d8c7a --- /dev/null +++ b/certs/test/gen-badaltnamenull.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +echo "step 1 create key" +openssl genrsa -out server-badaltnamenull.key 2048 + +echo "step 2 create csr" +echo "US\nMontana\nBozeman\nEngineering\nlocalhost\n.\n" | openssl req -new -sha256 -out server-badaltnamenull.csr -key server-badaltnamenull.key -config server-badaltnamenull.conf + +echo "step 3 check csr" +openssl req -text -noout -in server-badaltnamenull.csr + +echo "step 4 create cert" +openssl x509 -req -days 1000 -in server-badaltnamenull.csr -signkey server-badaltnamenull.key \ + -out server-badaltnamenull.pem -extensions req_ext -extfile server-badaltnamenull.conf + +echo "step 5 make human reviewable" +openssl x509 -inform pem -in server-badaltnamenull.pem -text > tmp.pem +mv tmp.pem server-badaltnamenull.pem + +openssl x509 -inform pem -in server-badaltnamenull.pem -outform der -out server-badaltnamenull.der diff --git a/certs/test/include.am b/certs/test/include.am index 1bc9e8e78..6b9d07d72 100644 --- a/certs/test/include.am +++ b/certs/test/include.am @@ -17,3 +17,12 @@ EXTRA_DIST += \ certs/test/server-cert-rsa-badsig.pem \ certs/test/server-cert-ecc-badsig.der \ certs/test/server-cert-ecc-badsig.pem + + +EXTRA_DIST += \ + certs/test/gen-badaltnamenull.sh \ + certs/test/server-badaltnamenull.conf \ + certs/test/server-badaltnamenull.csr \ + certs/test/server-badaltnamenull.key \ + certs/test/server-badaltnamenull.pem \ + certs/test/server-badaltnamenull.der diff --git a/certs/test/server-badaltnamenull.conf b/certs/test/server-badaltnamenull.conf new file mode 100644 index 000000000..cfca7b7e1 --- /dev/null +++ b/certs/test/server-badaltnamenull.conf @@ -0,0 +1,17 @@ +[ req ] +default_bits = 2048 +distinguished_name = req_distinguished_name +req_extensions = req_ext + +[ req_distinguished_name ] +countryName = US +stateOrProvinceName = Montana +localityName = Bozeman +organizationName = Engineering +commonName = www.wolfssl.com +commonName_max = 64 +commonName_default = localhost + +[ req_ext ] +#subjectAltName = localhost\0h +subjectAltName = DER:30:0d:82:0b:6c:6f:63:61:6c:68:6f:73:74:00:68 diff --git a/certs/test/server-badaltnamenull.csr b/certs/test/server-badaltnamenull.csr new file mode 100644 index 000000000..7ee5658d6 --- /dev/null +++ b/certs/test/server-badaltnamenull.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICyTCCAbECAQAwWzELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB01vbnRhbmExEDAO +BgNVBAcMB0JvemVtYW4xFDASBgNVBAoMC0VuZ2luZWVyaW5nMRIwEAYDVQQDDAls +b2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBWOI9sH7D +UouzlAgOLJgVQEyrHw9nwxeIEqmxfU2kZZcD95DWBzExpT0mbluER8yoj6E3//LY +58aDdASC+x/gxTLWuCNIgF9GWIOfP2TaWj9AHT6mIeklP2z9qJm3Md7UT52xOLkz +0wblZzSjcqEY61c1MGH6xAtfYfWZgmkxej4aAKd7jR1LAXCSIx+EO2WvvA8c5fiS +ozQgftXSM/5437VVSwu4dH4ptRNou/6nXi74cYzO4+/Unh7j/4ggwuvegNdEqeRg +CtASpQalRN+xrqghQaj786t/kBkqH6L0KKzzcsfLi4oE6dJXn4e7SFWgzbRayp5y +a7jal5x/6U+5AgMBAAGgKTAnBgkqhkiG9w0BCQ4xGjAYMBYGA1UdEQQPMA2CC2xv +Y2FsaG9zdABoMA0GCSqGSIb3DQEBCwUAA4IBAQCHfMbbmvXJGKjO6Z6UOkF3f7sa +cB8gEyjm9+Aa8gMQnaWOH8Sw6nGhGNSOVTQUIqt8EohqNCd/jrjZF34mecaJ3ycw +ryt7AGQzQX5uutBLVr55jszVVC8EDKuPzO3jXH6h6ptvSebG/0KL0P+JHL5JvzZ1 +wAsTBtnnnrnxCQO3a2SFC4zVyH+LCP+EWehH7Sjt9FtrCIoP+xoM6AJ2tCxb4CHH +A8WGuw36lG78DH6rs4kbh0iCP/pKYrYeG9EBOj6+Bw7WF4ee6QhL0VzHXUcIFjkp +YlVLGBTL6KVjPW4uim1az5F1+HxZTvbAbnPU7f81M2ePmqbFfODYO1KPXycg +-----END CERTIFICATE REQUEST----- diff --git a/certs/test/server-badaltnamenull.der b/certs/test/server-badaltnamenull.der new file mode 100644 index 0000000000000000000000000000000000000000..b844057227287489832d48d5d20ed74a6770d022 GIT binary patch literal 855 zcmXqLVh%QFVzOSq%*4pV#K~~eFjda=$HLhLylk9WZ60mkc^Mg5Ss4tX4Y>_C*_cCF z*o2uvgAD}?_&^*E9(LdSypqJcM3@LW54%%-RcdZxo}q|=5J(Ld54USxdS+f~YEfoh zx}lJP07#UXhchQXIWZ?AzqrIePMp`!!obwP*wDV-Ql3_%~Lq|bY_S;_^g)aPd_Z)A+&O1t?!c5 z>CE3JTw^yhTxzS97v181W<~!(^Z%c2JU`Z4!qW6x{=reBYde%Z8sgm|n&;c6+={Yy zkhNQ;_)^tA=kJP{+YRqs@t?cVVyE$Cwx{VPi;EUYybd=tNc?q#J3jI2%%)7kDmy8L z<<-5i-i!s4l;vBjQ`hg|mwEbQ(qa>Zx~rFr|5e=I8tToxqohuAt8m8df6L?aeiZhc zd;I>&Jh{jJI}{GRzSnTwW#y9ut_wm-*_OK8-?(mtqT`C+pI6sUkkpc2^hIOM=c41M zySrFkUJ9SzzS|>o!PzZQr{)!9@3=L6PW?;&olMM(42+AV3?vN1fDtDv$ii>H+r$lz zJcbP9&;uqFVCXS2tSfsJXRLEx?8KWz>ROUJm3C)tnP&Q3RpxH@?;|UW#5;=@>``9q zdF8Lv^*{UDW1WP&6%uRQV9{jkt$tr?-3oG|Qrd!MIoXSav_}47+=k4)5)9!Ct zZ}?TiRrl(FD5t51Q;xdDob9_-{ddmSQkOH=>TXO6jbWHCzvd$syC%=B)wS|#dL2UB zo|wuCb_#SKO8-C8DD88s*J1NGb0ddp%>dP>2XEZ3PO Whitewood config file, default %s\n", wnrConfig); #endif - printf("-H Internal tests [defCipherList, badCert]\n"); + printf("-H Internal tests [defCipherList, skipExit]\n"); #ifdef WOLFSSL_TLS13 printf("-J Use HelloRetryRequest to choose group for KE\n"); printf("-K Key Exchange for PSK not using (EC)DHE\n"); @@ -887,7 +887,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) unsigned char alpn_opt = 0; char* cipherList = NULL; int useDefCipherList = 0; - int useBadCert = 0; const char* verifyCert = caCertFile; const char* ourCert = cliCertFile; const char* ourKey = cliKeyFile; @@ -937,6 +936,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) char* ocspUrl = NULL; #endif int useX25519 = 0; + int skipExit = 0; #ifdef HAVE_WNR const char* wnrConfigFile = wnrConfig; @@ -988,7 +988,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void)useX25519; (void)helloRetry; (void)onlyKeyShare; - (void)useBadCert; StackTrap(); @@ -1113,9 +1112,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) printf("Using default cipher list for testing\n"); useDefCipherList = 1; } - else if (XSTRNCMP(myoptarg, "badCert", 7) == 0) { - printf("Using bad certificate for testing\n"); - useBadCert = 1; + else if (XSTRNCMP(myoptarg, "skipExit", 7) == 0) { + printf("Skip exit() for testing\n"); + skipExit = 1; } else { Usage(); @@ -1712,15 +1711,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif } - /* for testing only - use client cert as CA to force no signer error */ - if (useBadCert) { - #if !defined(NO_RSA) - verifyCert = "./certs/client-cert.pem"; - #elif defined(HAVE_ECC) - verifyCert = "./certs/client-ecc-cert.pem"; - #endif - } - if (!usePsk && !useAnon && !useVerifyCb) { #if !defined(NO_FILESYSTEM) if (wolfSSL_CTX_load_verify_locations(ctx, verifyCert,0) @@ -2114,9 +2104,16 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_ERR_error_string(err, buffer)); wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); - err_sys("wolfSSL_connect failed"); + CloseSocket(sockfd); + + if (!skipExit) + err_sys("wolfSSL_connect failed"); /* see note at top of README */ /* if you're getting an error here */ + + err = wolfSSL_get_error(ssl, 0); + ((func_args*)args)->return_code = err; + return 0; } showPeer(ssl); diff --git a/examples/server/server.c b/examples/server/server.c index 3d42a04e0..14b864603 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -413,7 +413,7 @@ static void Usage(void) #endif printf("-g Return basic HTML web page\n"); printf("-C The number of connections to accept, default: 1\n"); - printf("-H Internal tests [defCipherList, badCert]\n"); + printf("-H Internal tests [defCipherList, skipExit]\n"); #ifdef WOLFSSL_TLS13 printf("-U Update keys and IVs before sending\n"); printf("-K Key Exchange for PSK not using (EC)DHE\n"); @@ -500,7 +500,6 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) unsigned char alpn_opt = 0; char* cipherList = NULL; int useDefCipherList = 0; - int useBadCert = 0; const char* verifyCert = cliCertFile; const char* ourCert = svrCertFile; const char* ourKey = svrKeyFile; @@ -564,6 +563,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) int noTicket = 0; #endif int useX25519 = 0; + int skipExit = 0; ((func_args*)args)->return_code = -1; /* error state */ @@ -589,7 +589,6 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) (void)readySignal; (void)updateKeysIVs; (void)mcastID; - (void)useBadCert; (void)useX25519; #ifdef CYASSL_TIRTOS @@ -694,9 +693,9 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) printf("Using default cipher list for testing\n"); useDefCipherList = 1; } - else if (XSTRNCMP(myoptarg, "badCert", 7) == 0) { - printf("Using bad certificate for testing\n"); - useBadCert = 1; + else if (XSTRNCMP(myoptarg, "skipExit", 7) == 0) { + printf("Skip exit() for testing\n"); + skipExit = 1; } else { Usage(); @@ -1051,15 +1050,6 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif #if !defined(NO_CERTS) - /* for testing only - use bad cert as server cert for sig confirm err */ - if (useBadCert) { - #if !defined(NO_RSA) - ourCert = "./certs/test/server-cert-rsa-badsig.pem"; - #elif defined(HAVE_ECC) - ourCert = "./certs/test/server-cert-ecc-badsig.pem"; - #endif - } - if ((!usePsk || usePskPlus) && !useAnon) { #if !defined(NO_FILESYSTEM) if (SSL_CTX_use_certificate_chain_file(ctx, ourCert) @@ -1490,7 +1480,17 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) err = SSL_get_error(ssl, 0); printf("SSL_accept error %d, %s\n", err, ERR_error_string(err, buffer)); - err_sys_ex(runWithErrors, "SSL_accept failed"); + + if (!skipExit) + err_sys_ex(runWithErrors, "SSL_accept failed"); + + /* cleanup and return */ + SSL_free(ssl); + SSL_CTX_free(ctx); + CloseSocket(clientfd); + CloseSocket(sockfd); + ((func_args*)args)->return_code = err; + return 0; } showPeer(ssl); diff --git a/scripts/include.am b/scripts/include.am index 1a6c3ec23..57c8012db 100644 --- a/scripts/include.am +++ b/scripts/include.am @@ -12,11 +12,6 @@ if BUILD_EXAMPLE_SERVERS dist_noinst_SCRIPTS+= scripts/resume.test -# only run this test if we have the ability to support cert validation -if BUILD_PKI -dist_noinst_SCRIPTS+= scripts/tls-cert-fail.test -endif - EXTRA_DIST+= scripts/benchmark.test if BUILD_CRL diff --git a/scripts/tls-cert-fail.test b/scripts/tls-cert-fail.test deleted file mode 100755 index ea7d49177..000000000 --- a/scripts/tls-cert-fail.test +++ /dev/null @@ -1,173 +0,0 @@ -#!/bin/sh - -#tls-cert-fail.test - -asn_no_signer_e="-188" -asn_sig_confirm_e="-155" -exit_code=1 -counter=0 - -# need a unique resume port since may run the same time as testsuite -# use server port zero hack to get one -tls_port=0 - -#no_pid tells us process was never started if -1 -no_pid=-1 - -#server_pid captured on startup, stores the id of the server process -server_pid=$no_pid - -# let's use absolute path to a local dir (make distcheck may be in sub dir) -# also let's add some randomness by adding pid in case multiple 'make check's -# per source tree -ready_file=`pwd`/wolfssl_tls_ready$$ - -remove_ready_file() { - if test -e $ready_file; then - echo -e "removing existing ready file" - rm $ready_file - fi -} - -# trap this function so if user aborts with ^C or other kill signal we still -# get an exit that will in turn clean up the file system -abort_trap() { - echo "script aborted" - - if [ $server_pid != $no_pid ] - then - echo "killing server" - kill -9 $server_pid - fi - - exit_code=2 #different exit code in case of user interrupt - - echo "got abort signal, exiting with $exit_code" - exit $exit_code -} -trap abort_trap INT TERM - - -# trap this function so that if we exit on an error the file system will still -# be restored and the other tests may still pass. Never call this function -# instead use "exit " and this function will run automatically -restore_file_system() { - remove_ready_file -} -trap restore_file_system EXIT - -run_tls_no_signer_test() { - echo -e "\nStarting example server for tls no signer fail test...\n" - - remove_ready_file - - # starts the server on tls_port, -R generates ready file to be used as a - # mutex lock. We capture the processid into the variable server_pid - ./examples/server/server -R $ready_file -p $tls_port & - server_pid=$! - - while [ ! -s $ready_file -a "$counter" -lt 20 ]; do - echo -e "waiting for ready file..." - sleep 0.1 - counter=$((counter+ 1)) - done - - if test -e $ready_file; then - echo -e "found ready file, starting client..." - else - echo -e "NO ready file ending test..." - exit 1 - fi - - # get created port 0 ephemeral port - tls_port=`cat $ready_file` - - # starts client on tls_port and captures the output from client - capture_out=$(./examples/client/client -p $tls_port -H badCert 2>&1) - client_result=$? - - wait $server_pid - server_result=$? - - case "$capture_out" in - *$asn_no_signer_e*) - # only exit with zero on detection of the expected error code - echo "" - echo "$capture_out" - echo "" - echo "No signer error as expected! Test pass" - echo "" - exit_code=0 - ;; - *) - echo "" - echo "Client did not return asn_no_signer_e as expected: $capture_out" - echo "" - exit_code=1 - esac -} - -run_tls_sig_confirm_test() { - echo -e "\nStarting example server for tls sig confirm fail test...\n" - - remove_ready_file - - # starts the server on tls_port, -R generates ready file to be used as a - # mutex lock. We capture the processid into the variable server_pid - ./examples/server/server -R $ready_file -p $tls_port -H badCert & - server_pid=$! - - while [ ! -s $ready_file -a "$counter" -lt 20 ]; do - echo -e "waiting for ready file..." - sleep 0.1 - counter=$((counter+ 1)) - done - - if test -e $ready_file; then - echo -e "found ready file, starting client..." - else - echo -e "NO ready file ending test..." - exit 1 - fi - - # get created port 0 ephemeral port - tls_port=`cat $ready_file` - - # starts client on tls_port and captures the output from client - capture_out=$(./examples/client/client -p $tls_port 2>&1) - client_result=$? - - wait $server_pid - server_result=$? - - case "$capture_out" in - *$asn_sig_confirm_e*) - # only exit with zero on detection of the expected error code - echo "" - echo "$capture_out" - echo "" - echo "Sig confirm error as expected! Test pass" - echo "" - exit_code=0 - ;; - *) - echo "" - echo "Client did not return asn_sig_confirm_e as expected: $capture_out" - echo "" - exit_code=1 - esac -} - - -######### begin program ######### - -# run the test -run_tls_no_signer_test - -tls_port=0 -run_tls_sig_confirm_test - -echo "exiting with $exit_code" -exit $exit_code -########## end program ########## - diff --git a/tests/include.am b/tests/include.am index 7453a1793..91100e49a 100644 --- a/tests/include.am +++ b/tests/include.am @@ -28,5 +28,6 @@ EXTRA_DIST += tests/test.conf \ tests/test-sctp.conf \ tests/test-sig.conf \ tests/test-ed25519.conf \ - tests/test-enckeys.conf + tests/test-enckeys.conf \ + tests/test-fails.conf DISTCLEANFILES+= tests/.libs/unit.test diff --git a/tests/suites.c b/tests/suites.c index f5dda4da1..86b6bf83c 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -56,6 +56,7 @@ static char flagSep[] = " "; static char svrPort[] = "0"; #endif static char forceDefCipherListFlag[] = "-HdefCipherList"; +static char skipExitFlag[] = "-HskipExit"; #ifdef WOLFSSL_ASYNC_CRYPT static int devId = INVALID_DEVID; @@ -161,7 +162,7 @@ static int execute_test_case(int svr_argc, char** svr_argv, int cli_argc, char** cli_argv, int addNoVerify, int addNonBlocking, int addDisableEMS, int forceSrvDefCipherList, - int forceCliDefCipherList) + int forceCliDefCipherList, int testShouldFail) { #ifdef WOLFSSL_TIRTOS func_args cliArgs = {0}; @@ -264,6 +265,9 @@ static int execute_test_case(int svr_argc, char** svr_argv, #ifdef TEST_PK_PRIVKEY svr_argv[svrArgs.argc++] = (char*)"-P"; #endif + if (testShouldFail) { + svr_argv[svrArgs.argc++] = skipExitFlag; + } /* update server flags list */ commandLine[0] = '\0'; @@ -327,6 +331,9 @@ static int execute_test_case(int svr_argc, char** svr_argv, #ifdef TEST_PK_PRIVKEY cli_argv[cliArgs.argc++] = (char*)"-P"; #endif + if (testShouldFail) { + cli_argv[cliArgs.argc++] = skipExitFlag; + } commandLine[0] = '\0'; added = 0; @@ -345,13 +352,15 @@ static int execute_test_case(int svr_argc, char** svr_argv, client_test(&cliArgs); /* verify results */ - if (cliArgs.return_code != 0) { + if ((cliArgs.return_code != 0 && testShouldFail == 0) || + (cliArgs.return_code == 0 && testShouldFail != 0)) { printf("client_test failed\n"); exit(EXIT_FAILURE); } join_thread(serverThread); - if (svrArgs.return_code != 0) { + if ((svrArgs.return_code != 0 && testShouldFail == 0) || + (svrArgs.return_code == 0 && testShouldFail != 0)) { printf("server_test failed\n"); exit(EXIT_FAILURE); } @@ -361,6 +370,11 @@ static int execute_test_case(int svr_argc, char** svr_argv, #endif FreeTcpReady(&ready); + /* only run the first test for failure cases */ + if (testShouldFail) { + return NOT_BUILT_IN; + } + return 0; } @@ -379,18 +393,23 @@ static void test_harness(void* vargs) char* cursor; char* comment; const char* fname = "tests/test.conf"; + int testShouldFail = 0; if (args->argc == 1) { printf("notice: using default file %s\n", fname); } - else if(args->argc != 2) { - printf("usage: harness [FILE]\n"); + else if(args->argc > 3) { + printf("usage: harness [FILE] [ARG]\n"); args->return_code = 1; return; } - else { + + if (args->argc >= 2) { fname = args->argv[1]; } + if (args->argc == 3) { + testShouldFail = 1; + } file = fopen(fname, "rb"); if (file == NULL) { @@ -463,6 +482,8 @@ static void test_harness(void* vargs) cliArgs[cliArgsSz++] = XSTRSEP(&cursor, " \n"); else svrArgs[svrArgsSz++] = XSTRSEP(&cursor, " \n"); + if (*cursor == 0) /* eof */ + do_it = 1; break; default: /* Anything from cursor until end of line that isn't the above @@ -474,6 +495,7 @@ static void test_harness(void* vargs) svrArgs[svrArgsSz++] = XSTRSEP(&cursor, "\n"); if (*cursor == 0) /* eof */ do_it = 1; + break; } if (svrArgsSz == MAX_ARGS || cliArgsSz == MAX_ARGS) { @@ -483,31 +505,41 @@ static void test_harness(void* vargs) if (do_it) { ret = execute_test_case(svrArgsSz, svrArgs, - cliArgsSz, cliArgs, 0, 0, 0, 0, 0); + cliArgsSz, cliArgs, 0, 0, 0, 0, 0, + testShouldFail); /* don't repeat if not supported in build */ if (ret == 0) { /* test with default cipher list on server side */ execute_test_case(svrArgsSz, svrArgs, - cliArgsSz, cliArgs, 0, 0, 0, 1, 0); + cliArgsSz, cliArgs, 0, 0, 0, 1, 0, + testShouldFail); /* test with default cipher list on client side */ execute_test_case(svrArgsSz, svrArgs, - cliArgsSz, cliArgs, 0, 0, 0, 0, 1); + cliArgsSz, cliArgs, 0, 0, 0, 0, 1, + testShouldFail); execute_test_case(svrArgsSz, svrArgs, - cliArgsSz, cliArgs, 0, 1, 0, 0, 0); + cliArgsSz, cliArgs, 0, 1, 0, 0, 0, + testShouldFail); execute_test_case(svrArgsSz, svrArgs, - cliArgsSz, cliArgs, 1, 0, 0, 0, 0); + cliArgsSz, cliArgs, 1, 0, 0, 0, 0, + testShouldFail); execute_test_case(svrArgsSz, svrArgs, - cliArgsSz, cliArgs, 1, 1, 0, 0, 0); + cliArgsSz, cliArgs, 1, 1, 0, 0, 0, + testShouldFail); #ifdef HAVE_EXTENDED_MASTER execute_test_case(svrArgsSz, svrArgs, - cliArgsSz, cliArgs, 0, 0, 1, 0, 0); + cliArgsSz, cliArgs, 0, 0, 1, 0, 0, + testShouldFail); execute_test_case(svrArgsSz, svrArgs, - cliArgsSz, cliArgs, 0, 1, 1, 0, 0); + cliArgsSz, cliArgs, 0, 1, 1, 0, 0, + testShouldFail); execute_test_case(svrArgsSz, svrArgs, - cliArgsSz, cliArgs, 1, 0, 1, 0, 0); + cliArgsSz, cliArgs, 1, 0, 1, 0, 0, + testShouldFail); execute_test_case(svrArgsSz, svrArgs, - cliArgsSz, cliArgs, 1, 1, 1, 0, 0); + cliArgsSz, cliArgs, 1, 1, 1, 0, 0, + testShouldFail); #endif } svrArgsSz = 1; @@ -526,14 +558,15 @@ int SuiteTest(void) { #if !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) func_args args; - char argv0[2][80]; - char* myArgv[2]; + char argv0[3][80]; + char* myArgv[3]; printf(" Begin Cipher Suite Tests\n"); /* setup */ myArgv[0] = argv0[0]; myArgv[1] = argv0[1]; + myArgv[2] = argv0[2]; args.argv = myArgv; strcpy(argv0[0], "SuiteTest"); @@ -681,6 +714,18 @@ int SuiteTest(void) } #endif + /* failure tests */ + args.argc = 3; + strcpy(argv0[1], "tests/test-fails.conf"); + strcpy(argv0[2], "-f"); + printf("starting tests that expect failure\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + args.return_code = EXIT_FAILURE; + goto exit; + } + exit: printf(" End Cipher Suite Tests\n"); diff --git a/tests/test-dtls.conf b/tests/test-dtls.conf index 7a124f2a2..1ace19d5f 100644 --- a/tests/test-dtls.conf +++ b/tests/test-dtls.conf @@ -959,4 +959,3 @@ -a -v 2 -l ADH-AES128-SHA - diff --git a/tests/test-ed25519.conf b/tests/test-ed25519.conf index cdd3ade35..cc68ba2d7 100644 --- a/tests/test-ed25519.conf +++ b/tests/test-ed25519.conf @@ -53,4 +53,3 @@ #-k ./certs/ed25519/client-ed25519-key.pem #-A ./certs/ed25519/root-ed25519.pem #-C - diff --git a/tests/test-fails.conf b/tests/test-fails.conf new file mode 100644 index 000000000..3c78cc038 --- /dev/null +++ b/tests/test-fails.conf @@ -0,0 +1,50 @@ +# server bad certificate alt name +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-k ./certs/test/server-badaltnamenull.key +-c ./certs/test/server-badaltnamenull.pem +-d + +# client bad certificate alt name +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-h localhost +-A ./certs/test/server-badaltnamenull.pem +-m +-x + +# server RSA no signer error +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 + +# client RSA no signer error +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-A ./certs/client-cert.pem + +# server ECC no signer error +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 + +# client ECC no signer error +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-A ./certs/client-ecc-cert.pem + +# server RSA bad sig error +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 +-c ./certs/test/server-cert-rsa-badsig.pem + +# client RSA bad sig error +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 + +# server ECC bad sig error +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/test/server-cert-ecc-badsig.pem + +# client ECC bad sig error +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 diff --git a/tests/test-psk-no-id.conf b/tests/test-psk-no-id.conf index c5c0a190e..d6247b1e4 100644 --- a/tests/test-psk-no-id.conf +++ b/tests/test-psk-no-id.conf @@ -300,4 +300,3 @@ -l TLS13-AES128-GCM-SHA256 -r -s - diff --git a/tests/test-qsh.conf b/tests/test-qsh.conf index d7ed05867..357467465 100644 --- a/tests/test-qsh.conf +++ b/tests/test-qsh.conf @@ -2152,4 +2152,3 @@ # client TLSv1.2 NTRU_AES128 -v 3 -l QSH:NTRU-AES128-SHA - diff --git a/tests/test-sctp.conf b/tests/test-sctp.conf index 8dcd6e800..1f6a303fc 100644 --- a/tests/test-sctp.conf +++ b/tests/test-sctp.conf @@ -1108,4 +1108,3 @@ -a -v 2 -l ADH-AES128-SHA - diff --git a/tests/test-sig.conf b/tests/test-sig.conf index adf0ce952..680eb3506 100644 --- a/tests/test-sig.conf +++ b/tests/test-sig.conf @@ -217,4 +217,3 @@ -v 3 -l ECDHE-ECDSA-AES128-CCM-8 -A ./certs/ca-cert.pem - diff --git a/tests/test-tls13-ecc.conf b/tests/test-tls13-ecc.conf index 04f5022ee..3496eab8c 100644 --- a/tests/test-tls13-ecc.conf +++ b/tests/test-tls13-ecc.conf @@ -78,4 +78,3 @@ -l TLS13-AES128-GCM-SHA256 -A ./certs/ca-ecc-cert.pem -y - diff --git a/tests/test-tls13.conf b/tests/test-tls13.conf index 532934b89..8233626d9 100644 --- a/tests/test-tls13.conf +++ b/tests/test-tls13.conf @@ -71,4 +71,3 @@ -v 4 -l TLS13-AES128-GCM-SHA256 -r - diff --git a/tests/test.conf b/tests/test.conf index ebd0664cc..18cb942e5 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -2240,9 +2240,9 @@ -v 3 -D certs/dh3072.pem -A certs/client-cert-3072.pem + # client TLSv1.2 RSA 3072-bit DH 3072-bit -v 3 -D certs/dh3072.pem -c certs/client-cert-3072.pem -k certs/client-key-3072.pem - diff --git a/wolfssl/test.h b/wolfssl/test.h index 6aea1f491..9fcf06c70 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1478,7 +1478,7 @@ static INLINE void CRL_CallBack(const char* url) static INLINE void SetDH(WOLFSSL* ssl) { /* dh1024 p */ - static unsigned char p[] = + static const unsigned char p[] = { 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, @@ -1494,7 +1494,7 @@ static INLINE void SetDH(WOLFSSL* ssl) }; /* dh1024 g */ - static unsigned char g[] = + static const unsigned char g[] = { 0x02, }; @@ -1505,7 +1505,7 @@ static INLINE void SetDH(WOLFSSL* ssl) static INLINE void SetDHCtx(WOLFSSL_CTX* ctx) { /* dh1024 p */ - static unsigned char p[] = + static const unsigned char p[] = { 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, @@ -1521,7 +1521,7 @@ static INLINE void SetDHCtx(WOLFSSL_CTX* ctx) }; /* dh1024 g */ - static unsigned char g[] = + static const unsigned char g[] = { 0x02, }; From 325402cf5af614e75a5a61fbcaf21b913e112828 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 3 May 2018 10:02:59 -0700 Subject: [PATCH 3/4] Minor fix for the expected failure case use of `ssl` after free. Renamed `skipExit` to `exitWithRet`. --- examples/client/client.c | 14 ++++++++------ examples/server/server.c | 18 +++++++++--------- tests/suites.c | 6 +++--- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 6f7581c6d..0c951d65f 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -796,7 +796,7 @@ static void Usage(void) #ifdef HAVE_WNR printf("-q Whitewood config file, default %s\n", wnrConfig); #endif - printf("-H Internal tests [defCipherList, skipExit]\n"); + printf("-H Internal tests [defCipherList, exitWithRet]\n"); #ifdef WOLFSSL_TLS13 printf("-J Use HelloRetryRequest to choose group for KE\n"); printf("-K Key Exchange for PSK not using (EC)DHE\n"); @@ -936,7 +936,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) char* ocspUrl = NULL; #endif int useX25519 = 0; - int skipExit = 0; + int exitWithRet = 0; #ifdef HAVE_WNR const char* wnrConfigFile = wnrConfig; @@ -1112,9 +1112,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) printf("Using default cipher list for testing\n"); useDefCipherList = 1; } - else if (XSTRNCMP(myoptarg, "skipExit", 7) == 0) { + else if (XSTRNCMP(myoptarg, "exitWithRet", 7) == 0) { printf("Skip exit() for testing\n"); - skipExit = 1; + exitWithRet = 1; } else { Usage(); @@ -2100,18 +2100,20 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) ret = NonBlockingSSL_Connect(ssl); /* will keep retrying on timeout */ #endif if (ret != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); printf("wolfSSL_connect error %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer)); + + /* cleanup */ wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); CloseSocket(sockfd); - if (!skipExit) + if (!exitWithRet) err_sys("wolfSSL_connect failed"); /* see note at top of README */ /* if you're getting an error here */ - err = wolfSSL_get_error(ssl, 0); ((func_args*)args)->return_code = err; return 0; } diff --git a/examples/server/server.c b/examples/server/server.c index 14b864603..d9083a3f3 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -413,7 +413,7 @@ static void Usage(void) #endif printf("-g Return basic HTML web page\n"); printf("-C The number of connections to accept, default: 1\n"); - printf("-H Internal tests [defCipherList, skipExit]\n"); + printf("-H Internal tests [defCipherList, exitWithRet]\n"); #ifdef WOLFSSL_TLS13 printf("-U Update keys and IVs before sending\n"); printf("-K Key Exchange for PSK not using (EC)DHE\n"); @@ -563,7 +563,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) int noTicket = 0; #endif int useX25519 = 0; - int skipExit = 0; + int exitWithRet = 0; ((func_args*)args)->return_code = -1; /* error state */ @@ -693,9 +693,9 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) printf("Using default cipher list for testing\n"); useDefCipherList = 1; } - else if (XSTRNCMP(myoptarg, "skipExit", 7) == 0) { + else if (XSTRNCMP(myoptarg, "exitWithRet", 7) == 0) { printf("Skip exit() for testing\n"); - skipExit = 1; + exitWithRet = 1; } else { Usage(); @@ -1480,15 +1480,15 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) err = SSL_get_error(ssl, 0); printf("SSL_accept error %d, %s\n", err, ERR_error_string(err, buffer)); - - if (!skipExit) - err_sys_ex(runWithErrors, "SSL_accept failed"); - - /* cleanup and return */ + /* cleanup */ SSL_free(ssl); SSL_CTX_free(ctx); CloseSocket(clientfd); CloseSocket(sockfd); + + if (!exitWithRet) + err_sys_ex(runWithErrors, "SSL_accept failed"); + ((func_args*)args)->return_code = err; return 0; } diff --git a/tests/suites.c b/tests/suites.c index 86b6bf83c..f6ef5b06b 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -56,7 +56,7 @@ static char flagSep[] = " "; static char svrPort[] = "0"; #endif static char forceDefCipherListFlag[] = "-HdefCipherList"; -static char skipExitFlag[] = "-HskipExit"; +static char exitWithRetFlag[] = "-HexitWithRet"; #ifdef WOLFSSL_ASYNC_CRYPT static int devId = INVALID_DEVID; @@ -266,7 +266,7 @@ static int execute_test_case(int svr_argc, char** svr_argv, svr_argv[svrArgs.argc++] = (char*)"-P"; #endif if (testShouldFail) { - svr_argv[svrArgs.argc++] = skipExitFlag; + svr_argv[svrArgs.argc++] = exitWithRetFlag; } /* update server flags list */ @@ -332,7 +332,7 @@ static int execute_test_case(int svr_argc, char** svr_argv, cli_argv[cliArgs.argc++] = (char*)"-P"; #endif if (testShouldFail) { - cli_argv[cliArgs.argc++] = skipExitFlag; + cli_argv[cliArgs.argc++] = exitWithRetFlag; } commandLine[0] = '\0'; From 3fd47bdff30c2067ba8292d9189ec342c77f5825 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 3 May 2018 13:39:37 -0700 Subject: [PATCH 4/4] Fix for example client/server with `-H exitWithRet` option to make sure all cleanup is performed. Resolves valgrind report due to `TicketCleanup()` not being called. --- examples/client/client.c | 4 +++- examples/server/server.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 0c951d65f..61efdd19d 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -2115,7 +2115,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) /* if you're getting an error here */ ((func_args*)args)->return_code = err; - return 0; + goto exit; } showPeer(ssl); @@ -2577,6 +2577,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) ((func_args*)args)->return_code = 0; +exit: + #ifdef WOLFSSL_ASYNC_CRYPT wolfAsync_DevClose(&devId); #endif diff --git a/examples/server/server.c b/examples/server/server.c index d9083a3f3..0a44095ed 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -1490,7 +1490,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) err_sys_ex(runWithErrors, "SSL_accept failed"); ((func_args*)args)->return_code = err; - return 0; + goto exit; } showPeer(ssl); @@ -1677,6 +1677,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) ((func_args*)args)->return_code = 0; +exit: #if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \ && defined(HAVE_THREAD_LS)