Merge pull request #9443 from holtrop/report-rsa_pss_pss-sig-algo

TLSv1.3 certificate verify: report rsa_pss_pss_* signature algorithm when supported
This commit is contained in:
Sean Parkinson
2025-11-27 09:12:58 +10:00
committed by GitHub
6 changed files with 129 additions and 4 deletions

View File

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

92
scripts/rsapss.test Executable file
View File

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

View File

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

View File

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

View File

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

View File

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