diff --git a/cmd/strsclnt/strsclnt.c b/cmd/strsclnt/strsclnt.c index bba53efac6..099b7bf5ea 100644 --- a/cmd/strsclnt/strsclnt.c +++ b/cmd/strsclnt/strsclnt.c @@ -121,6 +121,9 @@ static PRBool enableCertStatus = PR_FALSE; PRIntervalTime maxInterval = PR_INTERVAL_NO_TIMEOUT; +static const SSLSignatureScheme *enabledSigSchemes = NULL; +static unsigned int enabledSigSchemeCount = 0; + char *progName; secuPWData pwdata = { PW_NONE, 0 }; @@ -143,7 +146,8 @@ Usage(void) "Usage: %s [-n nickname] [-p port] [-d dbdir] [-c connections]\n" " [-BDNovqs] [-f filename] [-N | -P percentage]\n" " [-w dbpasswd] [-C cipher(s)] [-t threads] [-W pwfile]\n" - " [-V [min-version]:[max-version]] [-a sniHostName] hostname\n" + " [-V [min-version]:[max-version]] [-a sniHostName]\n" + " [-J signatureschemes] hostname\n" " where -v means verbose\n" " -o flag is interpreted as follows:\n" " 1 -o means override the result of server certificate validation.\n" @@ -161,7 +165,17 @@ Usage(void) " -T enable the cert_status extension (OCSP stapling)\n" " -u enable TLS Session Ticket extension\n" " -z enable compression\n" - " -g enable false start\n", + " -g enable false start\n" + " -J enable signature schemes\n" + " This takes a comma separated list of signature schemes in preference\n" + " order.\n" + " Possible values are:\n" + " rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n" + " ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n" + " ecdsa_secp521r1_sha512,\n" + " rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n" + " rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n" + " dsa_sha1, dsa_sha256, dsa_sha384, dsa_sha512\n", progName); exit(1); } @@ -1158,6 +1172,14 @@ client_main( errExit("error setting SSL/TLS version range "); } + if (enabledSigSchemes) { + rv = SSL_SignatureSchemePrefSet(model_sock, enabledSigSchemes, + enabledSigSchemeCount); + if (rv < 0) { + errExit("SSL_SignatureSchemePrefSet"); + } + } + if (bigBuf.data) { /* doing FDX */ rv = SSL_OptionSet(model_sock, SSL_ENABLE_FDX, 1); if (rv < 0) { @@ -1316,7 +1338,7 @@ main(int argc, char **argv) /* XXX: 'B' was used in the past but removed in 3.28, * please leave some time before resuing it. */ optstate = PL_CreateOptState(argc, argv, - "C:DNP:TUV:W:a:c:d:f:gin:op:qst:uvw:z"); + "C:DJ:NP:TUV:W:a:c:d:f:gin:op:qst:uvw:z"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case 'C': @@ -1330,6 +1352,15 @@ main(int argc, char **argv) case 'I': /* reserved for OCSP multi-stapling */ break; + case 'J': + rv = parseSigSchemeList(optstate->value, &enabledSigSchemes, &enabledSigSchemeCount); + if (rv != SECSuccess) { + PL_DestroyOptState(optstate); + fprintf(stderr, "Bad signature scheme specified.\n"); + Usage(); + } + break; + case 'N': NoReuse = 1; break; @@ -1516,6 +1547,8 @@ main(int argc, char **argv) PL_strfree(hostName); + PORT_Free((SSLSignatureScheme *)enabledSigSchemes); + /* some final stats. */ printf( "strsclnt: %ld cache hits; %ld cache misses, %ld cache not reusable\n" diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh index c1730d8d76..525855e100 100755 --- a/tests/ssl/ssl.sh +++ b/tests/ssl/ssl.sh @@ -1225,6 +1225,51 @@ ssl_scheme() html "
" } +############################ ssl_scheme_stress ########################## +# local shell function to test strsclnt and selfserv handling of signature schemes +######################################################################### +ssl_scheme_stress() +{ + if [ "$SERVER_MODE" = "fips" -o "$CLIENT_MODE" = "fips" ] ; then + echo "$SCRIPTNAME: skipping $testname (non-FIPS only)" + return 0 + fi + + html_head "SSL SCHEME $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" + + NO_ECC_CERTS=1 + schemes=("rsa_pkcs1_sha256" "rsa_pss_rsae_sha256" "rsa_pkcs1_sha256,rsa_pss_rsae_sha256") + for sscheme in "${schemes[@]}"; do + for cscheme in "${schemes[@]}"; do + testname="ssl_scheme server='$sscheme' client='$cscheme'" + echo "${testname}" + + start_selfserv -V tls1.2:tls1.2 -J "$sscheme" + + echo "strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" + echo " -V tls1.2:tls1.2 -J "$cscheme" ${HOSTADDR} < ${REQUEST_FILE}" + ${PROFTOOL} ${BINDIR}/strsclnt -q -p ${PORT} ${CLIENT_OPTIONS} \ + -d ${P_R_CLIENTDIR} $verbose -V tls1.2:tls1.2 -J "$cscheme" ${HOSTADDR} < ${REQUEST_FILE} 2>&1 + ret=$? + # If both schemes include just one option and those options don't + # match, then the test should fail; otherwise, assume that it works. + if [ "${cscheme#*,}" = "$cscheme" -a \ + "${sscheme#*,}" = "$sscheme" -a \ + "$cscheme" != "$sscheme" ]; then + expected=1 + else + expected=0 + fi + html_msg $ret $expected "${testname}" \ + "produced a returncode of $ret, expected is $expected" + kill_selfserv + done + done + NO_ECC_CERTS=0 + + html "
" +} + ############################## ssl_cleanup ############################# # local shell function to finish this script (no exit since it might be # sourced) @@ -1267,6 +1312,7 @@ ssl_run() ;; "scheme") ssl_scheme + ssl_scheme_stress ;; esac done