diff --git a/scripts/include.am b/scripts/include.am index 95e95e8ad..7325d3b66 100644 --- a/scripts/include.am +++ b/scripts/include.am @@ -116,6 +116,7 @@ EXTRA_DIST += scripts/sniffer-static-rsa.pcap \ # leave openssl.test as extra until non bash works EXTRA_DIST += scripts/openssl.test +EXTRA_DIST += scripts/rsapss.test EXTRA_DIST += scripts/dertoc.pl diff --git a/scripts/rsapss.test b/scripts/rsapss.test new file mode 100755 index 000000000..8a6b857a0 --- /dev/null +++ b/scripts/rsapss.test @@ -0,0 +1,92 @@ +#!/usr/bin/env bash + +# rsapss.test + +if ! ./examples/client/client -V | grep -q 4; then + echo "skipping because TLS 1.3 not enabled in this build" + exit 0 +fi +if ! grep -q -- -DWC_RSA_PSS config.log 2>/dev/null; then + echo "skipping because WC_RSA_PSS not enabled in this build" + exit 0 +fi +if ! grep -q -- '-DHAVE_ECC\>' config.log 2>/dev/null; then + echo "skipping because HAVE_ECC not enabled in this build" + exit 0 +fi +if grep -q -- '-DNO_CODING' config.log 2>/dev/null; then + echo "skipping because NO_CODING is defined in this build" + exit 0 +fi + +CERT_DIR="$PWD/$(dirname "$0")/../certs" +if [ "$OPENSSL" = "" ]; then + OPENSSL=openssl +fi + +# if we can, isolate the network namespace to eliminate port collisions. +if [[ -n "$NETWORK_UNSHARE_HELPER" ]]; then + if [[ -z "$NETWORK_UNSHARE_HELPER_CALLED" ]]; then + export NETWORK_UNSHARE_HELPER_CALLED=yes + exec "$NETWORK_UNSHARE_HELPER" "$0" "$@" || exit $? + fi +elif [ "${AM_BWRAPPED-}" != "yes" ]; then + bwrap_path="$(command -v bwrap)" + if [ -n "$bwrap_path" ]; then + export AM_BWRAPPED=yes + exec "$bwrap_path" --unshare-net --dev-bind / / "$0" "$@" + fi + unset AM_BWRAPPED +fi + +# need a unique port since may run the same time as testsuite +generate_port() { + #-------------------------------------------------------------------------# + # Generate a random port number + #-------------------------------------------------------------------------# + + if [[ "$OSTYPE" == "linux"* ]]; then + port=$(($(od -An -N2 /dev/urandom) % (65535-49512) + 49512)) + elif [[ "$OSTYPE" == "darwin"* ]]; then + port=$(($(od -An -N2 /dev/random) % (65535-49512) + 49512)) + else + echo "skipping due to unsupported OS" + exit 0 + fi +} + +WOLFSSL_SERVER=./examples/server/server + +start_wolfssl_server() { + generate_port + server_port=$port + $WOLFSSL_SERVER -p $server_port -v 4 -c $CERT_DIR/rsapss/server-rsapss.pem -k $CERT_DIR/rsapss/server-rsapss-priv.pem -A $CERT_DIR/rsapss/root-rsapss.pem -d & +} + +# +# Run OpenSSL client against wolfSSL server +# +do_openssl_client() { + echo "test connection" | $OPENSSL s_client -connect 127.0.0.1:$server_port -cert $CERT_DIR/rsapss/client-rsapss.pem -key $CERT_DIR/rsapss/client-rsapss-priv.pem -CAfile $CERT_DIR/rsapss/root-rsapss.pem > rsapss.test.log + result=$? + cat rsapss.test.log + if [ $result != 0 ] + then + echo "$OPENSSL s_client command failed" + exit 1 + fi + grep -q "Peer signature type:.*rsa_pss_rsae_sha256" rsapss.test.log + result=$? + rm -f rsapss.test.log + if [ $result == 0 ] + then + echo "Test failed: Peer signature type identified as rsa_pss_rsae_sha256" + exit 1 + fi +} + +start_wolfssl_server +sleep 1 +do_openssl_client +echo -e "\nSuccess!\n\n" +exit 0 diff --git a/src/internal.c b/src/internal.c index 2fa53d67a..33797db61 100644 --- a/src/internal.c +++ b/src/internal.c @@ -7005,6 +7005,9 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #endif #ifndef NO_RSA ssl->options.minRsaKeySz = ctx->minRsaKeySz; + #ifdef WC_RSA_PSS + ssl->useRsaPss = ctx->useRsaPss; + #endif #endif #ifdef HAVE_ECC ssl->options.minEccKeySz = ctx->minEccKeySz; diff --git a/src/ssl_load.c b/src/ssl_load.c index bb14cbef3..dc652748c 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -1624,6 +1624,14 @@ static int ProcessBufferCertPublicKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl, ret = CHECK_KEY_SZ(ssl ? ssl->options.minRsaKeySz : ctx->minRsaKeySz, RSA_MAX_SIZE / 8, keySz, RSA_KEY_SIZE_E); } + #ifdef WC_RSA_PSS + if (ssl) { + ssl->useRsaPss = cert->keyOID == RSAPSSk; + } + if (ctx) { + ctx->useRsaPss = cert->keyOID == RSAPSSk; + } + #endif break; #endif /* !NO_RSA */ #ifdef HAVE_ECC diff --git a/src/tls13.c b/src/tls13.c index 918f96407..2c91f81b4 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -7867,8 +7867,9 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, * hsType The signature type. * output The buffer to encode into. */ -static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) +static WC_INLINE void EncodeSigAlg(const WOLFSSL * ssl, byte hashAlgo, byte hsType, byte* output) { + (void)ssl; switch (hsType) { #ifdef HAVE_ECC case ecc_dsa_sa_algo: @@ -7899,10 +7900,24 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) break; #endif #ifndef NO_RSA - /* PSS signatures: 0x080[4-6] */ + /* PSS signatures: 0x080[4-6] or 0x080[9-B] */ case rsa_pss_sa_algo: output[0] = rsa_pss_sa_algo; - output[1] = hashAlgo; +#ifdef WC_RSA_PSS + /* If the private key uses the RSA-PSS OID, and the peer supports + * the rsa_pss_pss_* signature algorithm in use, then report + * rsa_pss_pss_* rather than rsa_pss_rsae_*. */ + if (ssl->useRsaPss && + ((ssl->pssAlgo & (1U << hashAlgo)) != 0U) && + (sha256_mac <= hashAlgo) && (hashAlgo <= sha512_mac)) + { + output[1] = PSS_RSAE_TO_PSS_PSS(hashAlgo); + } + else +#endif + { + output[1] = hashAlgo; + } break; #endif #ifdef HAVE_FALCON @@ -9361,7 +9376,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) } else #endif /* WOLFSSL_DUAL_ALG_CERTS */ - EncodeSigAlg(ssl->options.hashAlgo, args->sigAlgo, + EncodeSigAlg(ssl, ssl->options.hashAlgo, args->sigAlgo, args->verify); if (args->sigData == NULL) { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 32c7ac25b..9dc54ab8e 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3914,6 +3914,9 @@ struct WOLFSSL_CTX { #endif #ifndef NO_RSA short minRsaKeySz; /* minimum RSA key size */ +#ifdef WC_RSA_PSS + word8 useRsaPss; /* cert supports RSA-PSS */ +#endif #endif #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) short minEccKeySz; /* minimum ECC key size */ @@ -5944,6 +5947,9 @@ struct WOLFSSL { byte* peerSceTsipEncRsaKeyIndex; #endif byte peerRsaKeyPresent; +#ifdef WC_RSA_PSS + word8 useRsaPss; /* cert supports RSA-PSS */ +#endif #endif #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) word16 namedGroup;