From a13b09ecb4a1d10328b8e9f35dc7272353e6cbe3 Mon Sep 17 00:00:00 2001 From: Sebastian Carpenter Date: Mon, 23 Jun 2025 14:56:39 -0600 Subject: [PATCH 1/5] Made x11vnc tests and fixed rsa certificate display Made a testsuit for x11vnc in lieu of a make check Private and public key display was not handled. Paul gave me some code that addressed the bug then I reworked it to match the output from OSSL and look pretty. --- .github/workflows/x11vnc.yml | 428 +++++++++++++++++++++++++++++++ include/wolfprovider/alg_funcs.h | 1 + include/wolfprovider/internal.h | 4 + scripts/env-setup | 10 +- src/wp_rsa_kmgmt.c | 315 +++++++++++++++++++++++ src/wp_wolfprov.c | 4 + 6 files changed, 761 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/x11vnc.yml diff --git a/.github/workflows/x11vnc.yml b/.github/workflows/x11vnc.yml new file mode 100644 index 00000000..0f8c7174 --- /dev/null +++ b/.github/workflows/x11vnc.yml @@ -0,0 +1,428 @@ +name: x11vnc Tests + +# START OF COMMON SECTION +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +# END OF COMMON SECTION + +jobs: + build_wolfprovider: + uses: ./.github/workflows/build-wolfprovider.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + strategy: + matrix: + wolfssl_ref: [ 'master', 'v5.8.0-stable' ] + openssl_ref: [ 'openssl-3.5.0' ] + + test_x11vnc: + runs-on: ubuntu-22.04 + needs: build_wolfprovider + timeout-minutes: 10 + strategy: + matrix: + x11vnc_ref: [ 'master', '0.9.17' ] + wolfssl_ref: [ 'master', 'v5.8.0-stable' ] + openssl_ref: [ 'openssl-3.5.0' ] + force_fail: [ 'WOLFPROV_FORCE_FAIL=1', '' ] + + steps: + - name: Checkout wolfProvider + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Retrieving wolfSSL/wolfProvider from cache + uses: actions/cache/restore@v4 + id: wolfprov-cache + with: + path: | + wolfssl-install + wolfprov-install + openssl-install/lib64 + openssl-install/include + openssl-install/bin + + key: wolfprov-${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ github.sha }} + fail-on-cache-miss: true + + - name: Install x11vnc dependencies + run: | + sudo apt-get update + + sudo apt-get install -y build-essential autoconf automake libtool pkg-config gcc make ca-certificates + sudo apt-get install -y libc6-dev libjpeg-dev x11proto-core-dev libxss-dev zlib1g-dev libavahi-client-dev libssl-dev libvncserver-dev libx11-dev libxdamage-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxrandr-dev libxtst-dev + sudo apt-get install -y xvfb tigervnc-viewer psmisc expect curl + + - name: Download x11vnc + uses: actions/checkout@v4 + with: + repository: LibVNC/x11vnc + ref: ${{ matrix.x11vnc_ref }} + path: x11vnc + + - name: Build x11vnc + working-directory: x11vnc + run: | + # force x11vnc to use the openssl binary in wolfProvider + sudo ln -sf $GITHUB_WORKSPACE/openssl-install/bin/openssl /usr/bin/openssl + + # change certs from being hashed with MD5 to SHA256 + perl -pi -e 's/default_md\s*=\s*md5/default_md = SHA256/' src/ssltools.h + + # change encryption for cert keys from des3 to aes256 + perl -pi -e 's/-des3/-aes256/' src/ssltools.h + + autoreconf -vfi + ./configure --with-ssl="$GITHUB_WORKSPACE/openssl-install/lib64" + make -j $(nproc) + sudo make install + + - name: Create x11vnc main test + run: | + cat > test_x11vnc.sh << 'TEST_X11VNC_EOF' + #!/bin/bash + + SCRIPTS_LOC="./" + + killall x11vnc > /dev/null 2> /dev/null + killall Xvfb > /dev/null 2> /dev/null + + X11VNC_TEST_FAIL=0 + + + # CA / cert generation + + + echo -e "\n\nTesting -sslGenCA\n" > x11vnc_test.log + + $SCRIPTS_LOC/x11vnc_sslgenca.exp >> x11vnc_test.log 2>> x11vnc_test.log + + if [ $? -eq 0 ] && [ -f "ca-dir/CA/cacert.pem" ] && [ -f "ca-dir/CA/private/cakey.pem" ] + then + echo "[ PASSED ] -sslGenCA" + else + echo "[ FAILED ] -sslGenCA" + X11VNC_TEST_FAIL=1 + fi + + + echo -e "\n\nTesting -sslGenCert client\n" >> x11vnc_test.log + + $SCRIPTS_LOC/x11vnc_sslgencert_client.exp >> x11vnc_test.log 2>> x11vnc_test.log + + if [ $? -eq 0 ] && [ -f "ca-dir/clients/wolf.pem" ] && [ -f "ca-dir/clients/wolf.crt" ] + then + echo "[ PASSED ] -sslGenCert client" + else + echo "[ FAILED ] -sslGenCert client" + X11VNC_TEST_FAIL=1 + fi + + + echo -e "\n\nTesting -sslGenCert server\n" >> x11vnc_test.log + + $SCRIPTS_LOC/x11vnc_sslgencert_server.exp >> x11vnc_test.log 2>> x11vnc_test.log + + if [ $? -eq 0 ] && [ -f "ca-dir/server-wolf.pem" ] && [ -f "ca-dir/server-wolf.crt" ] + then + echo "[ PASSED ] -sslGenCert server" + else + echo "[ FAILED ] -sslGenCert server" + X11VNC_TEST_FAIL=1 + fi + + + echo -e "\n\nTesting -sslCertInfo\n" >> x11vnc_test.log + + OPENSSL_CONF='' OPENSSL_MODULES='' timeout 1 x11vnc -sslCertInfo ca-dir/server-wolf.pem > cert_info_ossl.txt + timeout 1 x11vnc -sslCertInfo ca-dir/server-wolf.pem > cert_info.txt + + if [ $? -eq 0 ] && diff -y cert_info.txt cert_info_ossl.txt >> x11vnc_test.log 2>> x11vnc_test.log \ + && cat cert_info.txt >> x11vnc_test.log + then + echo "[ PASSED ] -sslCertInfo" + else + echo "[ FAILED ] -sslCertInfo" + X11VNC_TEST_FAIL=1 + fi + + + echo -e "\n\nTesting -sslEncKey\n" >> x11vnc_test.log + + $SCRIPTS_LOC/x11vnc_sslenckey.exp >> x11vnc_test.log 2>> x11vnc_test.log + + if [ $? -eq 0 ] && grep -q "BEGIN ENCRYPTED PRIVATE KEY" ca-dir/server-wolf.pem + then + echo "[ PASSED ] -sslEncKey" + else + echo "[ FAILED ] -sslEncKey" + X11VNC_TEST_FAIL=1 + fi + + + # SSL + + + # Setup Xvfb, which is a purely virtual display, i.e., humans cannot see it + # but it works the same as any other X server + Xvfb :0 -screen 0 100x100x8 2>> x11vnc_test.log & + sleep 2 + + + # Testing with SSL will use the TLSNone security type + echo -e "\n\nTesting -ssl handshake, authentication, initialization...\n" >> x11vnc_test.log + + PORT=`x11vnc -ssl TMP -display :0 -localhost -bg -o server.log` + PORT=`echo "$PORT" | grep -m 1 "PORT=" | sed -e 's/PORT=//'` + + timeout 10 vncviewer -GnuTLSPriority=LEGACY -DesktopSize=0 -display :0 -log *:stderr:100 localhost::$PORT 2> client.log + + if grep -Eq "SSL: handshake with helper process[[0-9]+] succeeded" server.log \ + && grep -q "CConnection: Authentication success" client.log \ + && grep -q "CConnection: initialisation done" client.log + then + echo "[ PASSED ] -ssl handshake, authentication, initialization" + else + echo "[ FAILED ] -ssl handshake, authentication, initialization" + X11VNC_TEST_FAIL=1 + fi + killall x11vnc > /dev/null 2> /dev/null + cat server.log client.log >> x11vnc_test.log + + + # Testing with a password changes the security type from TLSNone to TLSVnc + echo -e "\n\nTesting -ssl with a password...\n" >> x11vnc_test.log + + x11vnc -storepasswd wolfprov passwd 2>> x11vnc_test.log + + PORT=`x11vnc -ssl TMP -display :0 -localhost -bg -o server.log -rfbauth passwd` + PORT=`echo "$PORT" | grep -m 1 "PORT=" | sed -e 's/PORT=//'` + + timeout 10 vncviewer -GnuTLSPriority=LEGACY -DesktopSize=0 -display :0 -passwd passwd -log *:stderr:100 localhost::$PORT 2> client.log + + if grep -Eq "SSL: handshake with helper process[[0-9]+] succeeded" server.log \ + && grep -q "CConnection: Authentication success" client.log \ + && grep -q "CConnection: initialisation done" client.log + then + echo "[ PASSED ] -ssl with a password" + else + echo "[ FAILED ] -ssl with a password" + X11VNC_TEST_FAIL=1 + fi + killall x11vnc > /dev/null 2> /dev/null + cat server.log client.log >> x11vnc_test.log + + + # HTTP HTTPS + + + echo "Use WolfSSL!" > index.html + + + PORT=`x11vnc -ssl TMP -display :0 -localhost -httpdir . -https 5678 -bg -o server.log` + PORT=`echo "$PORT" | grep -m 1 -Eo "http://localhost:[0-9]+" server.log | sed -e 's/http:\/\/localhost://'` + + echo -e "\n\nTesting -https with http...\n" >> x11vnc_test.log + + if OPENSSL_CONF='' OPENSSL_MODULES='' curl -ks "http://localhost:$PORT/index.html" >> x11vnc_test.log + then + echo "[ PASSED ] -https with an http request" + else + echo "[ FAILED ] -https with an http request" + X11VNC_TEST_FAIL=1 + fi + + + echo -e "\n\nTesting -https with https...\n" >> x11vnc_test.log + + if OPENSSL_CONF='' OPENSSL_MODULES='' curl -ks "https://localhost:5678/index.html" >> x11vnc_test.log + then + echo "[ PASSED ] -https with an https request" + else + echo "[ FAILED ] -https with an https request" + X11VNC_TEST_FAIL=1 + fi + + killall x11vnc > /dev/null 2> /dev/null + killall Xvfb > /dev/null 2> /dev/null + cat server.log >> x11vnc_test.log + + if [[ $WOLFPROV_FORCE_FAIL -eq 1 ]]; then + ((X11VNC_TEST_FAIL ^= 1)) + fi + + if [[ $X11VNC_TEST_FAIL -eq 1 ]]; then cat x11vnc_test.log; fi + + exit $X11VNC_TEST_FAIL + TEST_X11VNC_EOF + + chmod +x test_x11vnc.sh + + - name: Create x11vnc expect tests + run: | + # generating CA test + cat > x11vnc_sslgenca.exp << 'X11VNC_SSLGENCA_END' + #!/bin/expect + + set timeout 1 + + spawn x11vnc -sslGenCA ca-dir + + sleep 1 + + # provide password and verify + expect { + "PEM" { send "wolfprov\r" } + eof { exit 1 } + } + expect "PEM" { send "wolfprov\r" } + + # provide CA information + expect "Country Name" { send "US\r" } + expect "State" { send "montana\r" } + expect "Locality" { send "bozeman\r" } + expect "Organization" { send "wolfssl\r" } + expect "Organizational" { send "wolfssl\r" } + expect "Common" { send "wolfserver\r" } + expect "Email" { send "wolf@server.com\r" } + + # if CA creation has succeeded then the enter key will be expected + expect { + "Enter" { send "\r" } + eof { exit 1 } + } + + expect eof + exit 0 + X11VNC_SSLGENCA_END + + # generating client cert test + cat > x11vnc_sslgencert_client.exp << 'X11VNC_SSLGENCERT_CLIENT_END' + #!/bin/expect + + set timeout 1 + + # generate a cert for the client + spawn x11vnc -ssldir ca-dir -sslGenCert client wolf + + sleep 1 + + # provide CA information + expect { + "Country Name" { send "US\r" } + eof { exit 1 } + } + expect "State" { send "montana\r" } + expect "Locality" { send "bozeman\r" } + expect "Organization" { send "wolfssl\r" } + expect "Organizational" { send "wolfssl\r" } + expect "Common" { send "wolfclient\r" } + expect "Email" { send "wolf@client.com\r" } + + # challenge password and company name + expect "challenge" { send "wolfprov\r" } + expect "company" { send "wolfssl\r" } + + # create the cert + expect "passphrase" { send "n\r" } + expect "pass phrase" { send "wolfprov\r" } + expect "Sign" { send "y\r" } + expect "commit" { send "y\r" } + + # if cert creation has succeeded then the enter key will be expected + expect { + "Enter" { send "\r" } + eof { exit 1 } + } + + expect eof + exit 0 + X11VNC_SSLGENCERT_CLIENT_END + + # generating server cert test + cat > x11vnc_sslgencert_server.exp << 'X11VNC_SSLGENCERT_SERVER_END' + #!/bin/expect + + set timeout 1 + + # generate a cert for the server + spawn x11vnc -ssldir ca-dir -sslGenCert server wolf + + sleep 1 + + # provide CA information + expect { + "Country Name" { send "US\r" } + eof { exit 1 } + } + expect "State" { send "montana\r" } + expect "Locality" { send "bozeman\r" } + expect "Organization" { send "wolfssl\r" } + expect "Organizational" { send "wolfssl\r" } + expect "Common" { send "wolfserver\r" } + expect "Email" { send "wolf@server.com\r" } + + # challenge password and company name + expect "challenge" { send "wolfprov\r" } + expect "company" { send "wolfssl\r" } + + # create the cert + expect "passphrase" { send "n\r" } + expect "pass phrase" { send "wolfprov\r" } + expect "Sign" { send "y\r" } + expect "commit" { send "y\r" } + + # if cert creation has succeeded then the enter key will be expected + expect { + "Enter" { send "\r" } + eof { exit 1 } + } + + expect eof + exit 0 + X11VNC_SSLGENCERT_SERVER_END + + # generating enckey test + cat > x11vnc_sslenckey.exp << 'X11VNC_SSLENCKEY_END' + #!/bin/expect + + set timeout 1 + + spawn x11vnc -sslEncKey ca-dir/server-wolf.pem + + sleep 1 + + # verify encryption is desired + expect { + "Protect key with a passphrase?" { send "y\r" } + eof { exit 1 } + } + + # supply password + expect { + "Enter pass phrase:" { send "wolfprov\r" } + eof { exit 1 } + } + expect "Verifying" { send "wolfprov\r" } + + expect eof + exit 0 + X11VNC_SSLENCKEY_END + + chmod +x x11vnc_sslgenca.exp x11vnc_sslgencert_client.exp x11vnc_sslgencert_server.exp x11vnc_sslenckey.exp + + - name: Run x11vnc tests + run: | + source $GITHUB_WORKSPACE/scripts/env-setup + export ${{ matrix.force_fail }} + + ./test_x11vnc.sh diff --git a/include/wolfprovider/alg_funcs.h b/include/wolfprovider/alg_funcs.h index d1ca52f6..2cc077af 100644 --- a/include/wolfprovider/alg_funcs.h +++ b/include/wolfprovider/alg_funcs.h @@ -366,6 +366,7 @@ extern const OSSL_DISPATCH wp_rsa_epki_der_encoder_functions[]; extern const OSSL_DISPATCH wp_rsa_epki_pem_encoder_functions[]; extern const OSSL_DISPATCH wp_rsa_kp_der_encoder_functions[]; extern const OSSL_DISPATCH wp_rsa_kp_pem_encoder_functions[]; +extern const OSSL_DISPATCH wp_rsa_text_encoder_functions[]; extern const OSSL_DISPATCH wp_rsapss_spki_der_encoder_functions[]; extern const OSSL_DISPATCH wp_rsapss_spki_pem_encoder_functions[]; extern const OSSL_DISPATCH wp_rsapss_pki_der_encoder_functions[]; diff --git a/include/wolfprovider/internal.h b/include/wolfprovider/internal.h index 9465cd5d..bfc1f905 100644 --- a/include/wolfprovider/internal.h +++ b/include/wolfprovider/internal.h @@ -76,12 +76,16 @@ #define WP_ENC_FORMAT_TYPE_SPECIFIC 4 /** X9_62 encoding format. */ #define WP_ENC_FORMAT_X9_62 5 +/** Text encoding format. */ +#define WP_ENC_FORMAT_TEXT 6 /* Data format. */ /** DER - Binary encoding. */ #define WP_FORMAT_DER 0 /** PEM - Text encoding. */ #define WP_FORMAT_PEM 1 +/** Human readable text encoding. */ +#define WP_FORMAT_TEXT 2 /* MAC key types. */ /** HMAC key type. */ diff --git a/scripts/env-setup b/scripts/env-setup index 2a6ed900..bef01e9c 100755 --- a/scripts/env-setup +++ b/scripts/env-setup @@ -13,7 +13,15 @@ if [ $is_sourced -eq 0 ]; then exit 1 fi -SCRIPT_DIR="$(cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)" +if [ -n "$BASH_SOURCE" ]; then + SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}") +elif [ -n "$ZSH_VERSION" ]; then + SCRIPT_DIR=$(dirname "${(%):-%x}") +else + echo "Unsupported shell" + exit 1 +fi + pushd $SCRIPT_DIR REPO_ROOT="${GITHUB_WORKSPACE:-$(git rev-parse --show-toplevel)}" popd diff --git a/src/wp_rsa_kmgmt.c b/src/wp_rsa_kmgmt.c index 6e7080d5..f62f53cd 100644 --- a/src/wp_rsa_kmgmt.c +++ b/src/wp_rsa_kmgmt.c @@ -3840,5 +3840,320 @@ const OSSL_DISPATCH wp_rsapss_pki_pem_encoder_functions[] = { { 0, NULL } }; + +/** + * Create a new RSA text encoder context. + * + * @param [in] provCtx Provider context. + * @return New RSA encoder/decoder context object on success. + * @return NULL on failure. + */ +static wp_RsaEncDecCtx* wp_rsa_text_enc_new(WOLFPROV_CTX* provCtx) +{ + return wp_rsa_enc_dec_new(provCtx, RSA_FLAG_TYPE_RSA, WP_ENC_FORMAT_TEXT, + WP_FORMAT_TEXT); +} + +/** + * Dispose of RSA text encoder context object. + * + * @param [in, out] ctx RSA encoder/decoder context object. + */ +static void wp_rsa_text_enc_free(wp_RsaEncDecCtx* ctx) +{ + wp_rsa_enc_dec_free(ctx); +} + +/** + * Return whether the RSA text encoder handles this part of the key. + * + * @param [in] provCtx Provider context. Unused. + * @param [in] selection Parts of key to handle. + * @return 1 when supported. + * @return 0 when not supported. + */ +static int wp_rsa_text_enc_does_selection(WOLFPROV_CTX* provCtx, int selection) +{ + int ok; + + (void)provCtx; + + /* Text encoder supports both public and private key parts */ + if (selection == 0) { + ok = 1; + } + else { + ok = ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) || + ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0); + } + + WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); + return ok; +} + +/** + * Encode a portion of the RSA key as hexadecimal. + * + * @param [in] num An mp_int to convert to hexadecimal. + * @param [out] textData Buffer to store hex in. + * @param [in] textLen Size of buffer. + * @param [in, out] pos Current position in buffer. + * @param [in] label String describing section being encoded. + * @return 1 on success. + * @return 0 on failure. + */ +static int wp_rsa_encode_text_format_hex(const mp_int* num, char* textData, + size_t textLen, size_t* pos, const char* label) +{ + unsigned char* binData = NULL; + size_t binLen = 0; + size_t printAmt; + size_t dPos = *pos; + int bytes = 0; + int i; + + int ok = 1; + + if ((binLen = mp_unsigned_bin_size(num)) <= 0 + || (binData = OPENSSL_malloc(binLen)) == NULL) { + ok = 0; + } + else if (mp_to_unsigned_bin(num, binData) != MP_OKAY) { + ok = 0; + OPENSSL_free(binData); + binData = NULL; + } + else { + if ((printAmt = XSNPRINTF(textData + dPos, textLen - dPos, + "%s:\n ", label)) <= 0){ + ok = 0; + } + dPos += printAmt; + + /* OSSL adds a leading 00 if MSB is set */ + if (ok && *binData > 127){ + if ((printAmt = XSNPRINTF(textData + dPos, textLen - dPos, + "00:")) <= 0){ + ok = 0; + } + dPos += printAmt; + bytes++; + } + + /* OSSL does a newline + indent every 15 bytes */ + if (ok) { + for (i = 0; i < (int)binLen - 1; i++) { + if (bytes >= 14){ + if ((printAmt = XSNPRINTF(textData + dPos, + textLen - dPos, "%02x:\n ", binData[i])) <= 0){ + ok = 0; + break; + } + bytes = 0; + } + else{ + if ((printAmt = XSNPRINTF(textData + dPos, + textLen - dPos, "%02x:", binData[i])) <= 0){ + ok = 0; + break; + } + bytes++; + } + dPos += printAmt; + } + if (ok && (printAmt = XSNPRINTF(textData + dPos, + textLen - dPos, "%02x\n", binData[i])) <= 0){ + ok = 0; + } + dPos += printAmt; + } + + OPENSSL_free(binData); + binData = NULL; + } + + *pos = dPos; + return ok; +} + +/** + * Encode the RSA key in text format. + * + * @param [in] ctx RSA encoder/decoder context object. + * @param [in, out] cBio Core BIO to write data to. + * @param [in] key RSA key object. + * @param [in] params Key parameters. Unused. + * @param [in] selection Parts of key to encode. + * @param [in] pwCb Password callback. Unused. + * @param [in] pwCbArg Argument to pass to password callback. Unused. + * @return 1 on success. + * @return 0 on failure. + */ +static int wp_rsa_encode_text(wp_RsaEncDecCtx* ctx, OSSL_CORE_BIO* cBio, + const wp_Rsa* key, const OSSL_PARAM* params, int selection, + OSSL_PASSPHRASE_CALLBACK* pwCb, void* pwCbArg) +{ + int ok = 1; + BIO *out = wp_corebio_get_bio(ctx->provCtx, cBio); + int hasPriv = (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0; + int hasPub = (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0; + char* textData = NULL; + size_t textLen = 0; + size_t pos = 0; + size_t printAmt; + char* expStr; + int expLen; + + (void)params; + (void)pwCb; + (void)pwCbArg; + + if (out == NULL) { + ok = 0; + } + + /* Calculate total size needed for text output */ + if (ok) { + textLen = 128; + if (hasPriv) { + textLen += key->bits << 1; + } + else if (hasPub) { + textLen += key->bits >> 1; + } + + if ((textData = OPENSSL_malloc(textLen)) == NULL) { + ok = 0; + } + } + + if (ok) { + /* OSSL uses nested macros to determine the number of primes, not sure + * when there wouldn't be two primes */ + if (hasPriv && (printAmt = XSNPRINTF(textData + pos, textLen - pos, + "Private-Key: (%d bit, 2 primes)\n", key->bits)) <= 0){ + ok = 0; + } else if (hasPub && (printAmt = XSNPRINTF(textData + pos, + textLen - pos, "Public-Key: (%d bit)\n", key->bits)) <= 0){ + ok = 0; + } + pos += printAmt; + } + + /* OSSL uses 'modulus' and 'Modulus' */ + if (hasPriv){ + ok = wp_rsa_encode_text_format_hex(&key->key.n, textData, textLen, &pos, + "modulus"); + } + else if (hasPub){ + ok = wp_rsa_encode_text_format_hex(&key->key.n, textData, textLen, &pos, + "Modulus"); + } + + /* OSSL uses 'publicExponent' and 'Exponent' */ + if (ok){ + if (mp_radix_size(&key->key.e, MP_RADIX_DEC, &expLen) != MP_OKAY + || ((expStr = OPENSSL_malloc(expLen)) == NULL)) { + ok = 0; + } + else if (mp_todecimal(&key->key.e, expStr) != MP_OKAY) { + ok = 0; + OPENSSL_free(expStr); + expStr = NULL; + } + else { + if (hasPriv && (printAmt = XSNPRINTF(textData + pos, + textLen - pos, "publicExponent: %s ", expStr)) <= 0) { + ok = 0; + } + else if (hasPub && (printAmt = XSNPRINTF(textData + pos, + textLen - pos, "Exponent: %s ", expStr)) <= 0) { + ok = 0; + } + pos += printAmt; + + OPENSSL_free(expStr); + expStr = NULL; + } + } + + if (ok){ + if (mp_radix_size(&key->key.e, MP_RADIX_HEX, &expLen) != MP_OKAY + || ((expStr = OPENSSL_malloc(expLen)) == NULL)) { + ok = 0; + } + else if (mp_tohex(&key->key.e, expStr) != MP_OKAY) { + ok = 0; + OPENSSL_free(expStr); + expStr = NULL; + } + else{ + /* OSSL does not print a leading zero for the hex part */ + if ((printAmt = XSNPRINTF(textData + pos, + textLen - pos, "(0x%s)\n", + (*expStr == '0') ? (expStr + 1) : (expStr))) <= 0) { + ok = 0; + } + pos += printAmt; + + OPENSSL_free(expStr); + expStr = NULL; + } + } + + /* Write private key components */ + if (ok && hasPriv) { + if (ok) { + ok = wp_rsa_encode_text_format_hex(&key->key.d, textData, textLen, + &pos, "privateExponent"); + } + + if (ok) { + ok = wp_rsa_encode_text_format_hex(&key->key.p, textData, textLen, + &pos, "prime1"); + } + + if (ok) { + ok = wp_rsa_encode_text_format_hex(&key->key.q, textData, textLen, + &pos, "prime2"); + } + + if (ok) { + ok = wp_rsa_encode_text_format_hex(&key->key.dP, textData, textLen, + &pos, "exponent1"); + } + + if (ok) { + ok = wp_rsa_encode_text_format_hex(&key->key.dQ, textData, textLen, + &pos, "exponent2"); + } + + if (ok) { + ok = wp_rsa_encode_text_format_hex(&key->key.u, textData, textLen, + &pos, "coefficient"); + } + } + + /* TODO: display RSAPSS info */ + + if (ok && (BIO_write(out, textData, (int)pos) <= 0)) { + ok = 0; + } + + OPENSSL_free(textData); + BIO_free(out); + + WOLFPROV_LEAVE(WP_LOG_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); + return ok; +} + +const OSSL_DISPATCH wp_rsa_text_encoder_functions[] = { + { OSSL_FUNC_ENCODER_NEWCTX, (DFUNC)wp_rsa_text_enc_new }, + { OSSL_FUNC_ENCODER_FREECTX, (DFUNC)wp_rsa_text_enc_free }, + { OSSL_FUNC_ENCODER_DOES_SELECTION, (DFUNC)wp_rsa_text_enc_does_selection }, + { OSSL_FUNC_ENCODER_ENCODE, (DFUNC)wp_rsa_encode_text }, + { 0, NULL } +}; + #endif /* WP_HAVE_RSA */ diff --git a/src/wp_wolfprov.c b/src/wp_wolfprov.c index 55b47b5d..93cf86bb 100644 --- a/src/wp_wolfprov.c +++ b/src/wp_wolfprov.c @@ -735,6 +735,10 @@ static const OSSL_ALGORITHM wolfprov_encoder[] = { { WP_NAMES_RSA_PSS, WP_ENCODER_PROPERTIES(PrivateKeyInfo, pem), wp_rsapss_pki_pem_encoder_functions, "" }, + /*{ WP_NAMES_RSA, WOLFPROV_PROPERTIES ",output=text", \*/ + { WP_NAMES_RSA, WP_ENCODER_PROPERTIES(type-specific, text), \ + wp_rsa_text_encoder_functions, + "" }, #endif #endif /* WP_HAVE_RSA */ From a489e54f70a5a2cd32dbe5acf9f345242c5d911b Mon Sep 17 00:00:00 2001 From: Sebastian Carpenter Date: Thu, 3 Jul 2025 11:32:58 -0600 Subject: [PATCH 2/5] cleaned up x11vnc tests and new code x11vnc tests needed some scripts broken out into separate files and use of a shared script. The new code for displaying rsa certificates needed some fixes and extra comments --- .github/scripts/x11vnc/test_x11vnc.sh | 173 +++++++++ .github/scripts/x11vnc/x11vnc_sslenckey.exp | 23 ++ .github/scripts/x11vnc/x11vnc_sslgenca.exp | 32 ++ .../x11vnc/x11vnc_sslgencert_client.exp | 39 ++ .../x11vnc/x11vnc_sslgencert_server.exp | 39 ++ .github/workflows/x11vnc.yml | 338 +----------------- scripts/env-setup | 4 +- src/wp_rsa_kmgmt.c | 47 ++- 8 files changed, 341 insertions(+), 354 deletions(-) create mode 100755 .github/scripts/x11vnc/test_x11vnc.sh create mode 100644 .github/scripts/x11vnc/x11vnc_sslenckey.exp create mode 100644 .github/scripts/x11vnc/x11vnc_sslgenca.exp create mode 100644 .github/scripts/x11vnc/x11vnc_sslgencert_client.exp create mode 100644 .github/scripts/x11vnc/x11vnc_sslgencert_server.exp diff --git a/.github/scripts/x11vnc/test_x11vnc.sh b/.github/scripts/x11vnc/test_x11vnc.sh new file mode 100755 index 00000000..1ca24e30 --- /dev/null +++ b/.github/scripts/x11vnc/test_x11vnc.sh @@ -0,0 +1,173 @@ +#!/bin/bash + +SCRIPTS_DIR="$GITHUB_WORKSPACE/.github/scripts/x11vnc" + +killall x11vnc > /dev/null 2> /dev/null +killall Xvfb > /dev/null 2> /dev/null + +X11VNC_TEST_FAIL=0 + + +# CA / cert generation + + +echo -e "\n\nTesting -sslGenCA\n" > x11vnc_test.log + +$SCRIPTS_DIR/x11vnc_sslgenca.exp >> x11vnc_test.log 2>> x11vnc_test.log + +if [ $? -eq 0 ] && [ -f "ca-dir/CA/cacert.pem" ] && [ -f "ca-dir/CA/private/cakey.pem" ] +then + echo "[ PASSED ] -sslGenCA" +else + echo "[ FAILED ] -sslGenCA" + X11VNC_TEST_FAIL=1 +fi + + +echo -e "\n\nTesting -sslGenCert client\n" >> x11vnc_test.log + +$SCRIPTS_DIR/x11vnc_sslgencert_client.exp >> x11vnc_test.log 2>> x11vnc_test.log + +if [ $? -eq 0 ] && [ -f "ca-dir/clients/wolf.pem" ] && [ -f "ca-dir/clients/wolf.crt" ] +then + echo "[ PASSED ] -sslGenCert client" +else + echo "[ FAILED ] -sslGenCert client" + X11VNC_TEST_FAIL=1 +fi + + +echo -e "\n\nTesting -sslGenCert server\n" >> x11vnc_test.log + +$SCRIPTS_DIR/x11vnc_sslgencert_server.exp >> x11vnc_test.log 2>> x11vnc_test.log + +if [ $? -eq 0 ] && [ -f "ca-dir/server-wolf.pem" ] && [ -f "ca-dir/server-wolf.crt" ] +then + echo "[ PASSED ] -sslGenCert server" +else + echo "[ FAILED ] -sslGenCert server" + X11VNC_TEST_FAIL=1 +fi + + +echo -e "\n\nTesting -sslCertInfo\n" >> x11vnc_test.log + +OPENSSL_CONF='' OPENSSL_MODULES='' timeout 1 x11vnc -sslCertInfo ca-dir/server-wolf.pem > cert_info_ossl.txt +timeout 1 x11vnc -sslCertInfo ca-dir/server-wolf.pem > cert_info.txt + +if [ $? -eq 0 ] && diff -y cert_info.txt cert_info_ossl.txt >> x11vnc_test.log 2>> x11vnc_test.log \ + && cat cert_info.txt >> x11vnc_test.log +then + echo "[ PASSED ] -sslCertInfo" +else + echo "[ FAILED ] -sslCertInfo" + X11VNC_TEST_FAIL=1 +fi + + +echo -e "\n\nTesting -sslEncKey\n" >> x11vnc_test.log + +$SCRIPTS_DIR/x11vnc_sslenckey.exp >> x11vnc_test.log 2>> x11vnc_test.log + +if [ $? -eq 0 ] && grep -q "BEGIN ENCRYPTED PRIVATE KEY" ca-dir/server-wolf.pem +then + echo "[ PASSED ] -sslEncKey" +else + echo "[ FAILED ] -sslEncKey" + X11VNC_TEST_FAIL=1 +fi + + +# SSL + + +# Setup Xvfb, which is a purely virtual display, i.e., humans cannot see it +# but it works the same as any other X server +Xvfb :0 -screen 0 100x100x8 2>> x11vnc_test.log & +sleep 2 + + +# Testing with SSL will use the TLSNone security type +echo -e "\n\nTesting -ssl handshake, authentication, initialization...\n" >> x11vnc_test.log + +PORT=`x11vnc -ssl TMP -display :0 -localhost -bg -o server.log` +PORT=`echo "$PORT" | grep -m 1 "PORT=" | sed -e 's/PORT=//'` + +timeout 10 vncviewer -GnuTLSPriority=LEGACY -DesktopSize=0 -display :0 -log *:stderr:100 localhost::$PORT 2> client.log + +if grep -Eq "SSL: handshake with helper process[[0-9]+] succeeded" server.log \ + && grep -q "CConnection: Authentication success" client.log \ + && grep -q "CConnection: initialisation done" client.log +then + echo "[ PASSED ] -ssl handshake, authentication, initialization" +else + echo "[ FAILED ] -ssl handshake, authentication, initialization" + X11VNC_TEST_FAIL=1 +fi +killall x11vnc > /dev/null 2> /dev/null +cat server.log client.log >> x11vnc_test.log + + +# Testing with a password changes the security type from TLSNone to TLSVnc +echo -e "\n\nTesting -ssl with a password...\n" >> x11vnc_test.log + +x11vnc -storepasswd wolfprov passwd 2>> x11vnc_test.log + +PORT=`x11vnc -ssl TMP -display :0 -localhost -bg -o server.log -rfbauth passwd` +PORT=`echo "$PORT" | grep -m 1 "PORT=" | sed -e 's/PORT=//'` + +timeout 10 vncviewer -GnuTLSPriority=LEGACY -DesktopSize=0 -display :0 -passwd passwd -log *:stderr:100 localhost::$PORT 2> client.log + +if grep -Eq "SSL: handshake with helper process[[0-9]+] succeeded" server.log \ + && grep -q "CConnection: Authentication success" client.log \ + && grep -q "CConnection: initialisation done" client.log +then + echo "[ PASSED ] -ssl with a password" +else + echo "[ FAILED ] -ssl with a password" + X11VNC_TEST_FAIL=1 +fi +killall x11vnc > /dev/null 2> /dev/null +cat server.log client.log >> x11vnc_test.log + + +# HTTP HTTPS + + +echo "Use WolfSSL!" > index.html + + +PORT=`x11vnc -ssl TMP -display :0 -localhost -httpdir . -https 5678 -bg -o server.log` +PORT=`echo "$PORT" | grep -m 1 -Eo "http://localhost:[0-9]+" server.log | sed -e 's/http:\/\/localhost://'` + +echo -e "\n\nTesting -https with http...\n" >> x11vnc_test.log + +if OPENSSL_CONF='' OPENSSL_MODULES='' curl -ks "http://localhost:$PORT/index.html" >> x11vnc_test.log +then + echo "[ PASSED ] -https with an http request" +else + echo "[ FAILED ] -https with an http request" + X11VNC_TEST_FAIL=1 +fi + + +echo -e "\n\nTesting -https with https...\n" >> x11vnc_test.log + +if OPENSSL_CONF='' OPENSSL_MODULES='' curl -ks "https://localhost:5678/index.html" >> x11vnc_test.log +then + echo "[ PASSED ] -https with an https request" +else + echo "[ FAILED ] -https with an https request" + X11VNC_TEST_FAIL=1 +fi + +killall x11vnc > /dev/null 2> /dev/null +killall Xvfb > /dev/null 2> /dev/null +cat server.log >> x11vnc_test.log + +$GITHUB_WORKSPACE/.github/scripts/check-workflow-result.sh $X11VNC_TEST_FAIL "$WOLFPROV_FORCE_FAIL_STR" x11vnc +X11VNC_TEST_FAIL=$? + +if [[ $X11VNC_TEST_FAIL -eq 1 ]]; then cat x11vnc_test.log; fi + +exit $X11VNC_TEST_FAIL diff --git a/.github/scripts/x11vnc/x11vnc_sslenckey.exp b/.github/scripts/x11vnc/x11vnc_sslenckey.exp new file mode 100644 index 00000000..52d7418f --- /dev/null +++ b/.github/scripts/x11vnc/x11vnc_sslenckey.exp @@ -0,0 +1,23 @@ +#!/bin/expect + +set timeout 1 + +spawn x11vnc -sslEncKey ca-dir/server-wolf.pem + +sleep 1 + +# verify encryption is desired +expect { + "Protect key with a passphrase?" { send "y\r" } + eof { exit 1 } +} + +# supply password +expect { + "Enter pass phrase:" { send "wolfprov\r" } + eof { exit 1 } +} +expect "Verifying" { send "wolfprov\r" } + +expect eof +exit 0 diff --git a/.github/scripts/x11vnc/x11vnc_sslgenca.exp b/.github/scripts/x11vnc/x11vnc_sslgenca.exp new file mode 100644 index 00000000..6641954d --- /dev/null +++ b/.github/scripts/x11vnc/x11vnc_sslgenca.exp @@ -0,0 +1,32 @@ +#!/bin/expect + +set timeout 1 + +spawn x11vnc -sslGenCA ca-dir + +sleep 1 + +# provide password and verify +expect { + "PEM" { send "wolfprov\r" } + eof { exit 1 } +} +expect "PEM" { send "wolfprov\r" } + +# provide CA information +expect "Country Name" { send "US\r" } +expect "State" { send "montana\r" } +expect "Locality" { send "bozeman\r" } +expect "Organization" { send "wolfssl\r" } +expect "Organizational" { send "wolfssl\r" } +expect "Common" { send "wolfserver\r" } +expect "Email" { send "wolf@server.com\r" } + +# if CA creation has succeeded then the enter key will be expected +expect { + "Enter" { send "\r" } + eof { exit 1 } +} + +expect eof +exit 0 diff --git a/.github/scripts/x11vnc/x11vnc_sslgencert_client.exp b/.github/scripts/x11vnc/x11vnc_sslgencert_client.exp new file mode 100644 index 00000000..900b123a --- /dev/null +++ b/.github/scripts/x11vnc/x11vnc_sslgencert_client.exp @@ -0,0 +1,39 @@ +#!/bin/expect + +set timeout 1 + +# generate a cert for the client +spawn x11vnc -ssldir ca-dir -sslGenCert client wolf + +sleep 1 + +# provide CA information +expect { + "Country Name" { send "US\r" } + eof { exit 1 } +} +expect "State" { send "montana\r" } +expect "Locality" { send "bozeman\r" } +expect "Organization" { send "wolfssl\r" } +expect "Organizational" { send "wolfssl\r" } +expect "Common" { send "wolfclient\r" } +expect "Email" { send "wolf@client.com\r" } + +# challenge password and company name +expect "challenge" { send "wolfprov\r" } +expect "company" { send "wolfssl\r" } + +# create the cert +expect "passphrase" { send "n\r" } +expect "pass phrase" { send "wolfprov\r" } +expect "Sign" { send "y\r" } +expect "commit" { send "y\r" } + +# if cert creation has succeeded then the enter key will be expected +expect { + "Enter" { send "\r" } + eof { exit 1 } +} + +expect eof +exit 0 diff --git a/.github/scripts/x11vnc/x11vnc_sslgencert_server.exp b/.github/scripts/x11vnc/x11vnc_sslgencert_server.exp new file mode 100644 index 00000000..439cf9a7 --- /dev/null +++ b/.github/scripts/x11vnc/x11vnc_sslgencert_server.exp @@ -0,0 +1,39 @@ +#!/bin/expect + +set timeout 1 + +# generate a cert for the server +spawn x11vnc -ssldir ca-dir -sslGenCert server wolf + +sleep 1 + +# provide CA information +expect { + "Country Name" { send "US\r" } + eof { exit 1 } +} +expect "State" { send "montana\r" } +expect "Locality" { send "bozeman\r" } +expect "Organization" { send "wolfssl\r" } +expect "Organizational" { send "wolfssl\r" } +expect "Common" { send "wolfserver\r" } +expect "Email" { send "wolf@server.com\r" } + +# challenge password and company name +expect "challenge" { send "wolfprov\r" } +expect "company" { send "wolfssl\r" } + +# create the cert +expect "passphrase" { send "n\r" } +expect "pass phrase" { send "wolfprov\r" } +expect "Sign" { send "y\r" } +expect "commit" { send "y\r" } + +# if cert creation has succeeded then the enter key will be expected +expect { + "Enter" { send "\r" } + eof { exit 1 } +} + +expect eof +exit 0 diff --git a/.github/workflows/x11vnc.yml b/.github/workflows/x11vnc.yml index 0f8c7174..f8fc6a5c 100644 --- a/.github/workflows/x11vnc.yml +++ b/.github/workflows/x11vnc.yml @@ -86,343 +86,9 @@ jobs: make -j $(nproc) sudo make install - - name: Create x11vnc main test - run: | - cat > test_x11vnc.sh << 'TEST_X11VNC_EOF' - #!/bin/bash - - SCRIPTS_LOC="./" - - killall x11vnc > /dev/null 2> /dev/null - killall Xvfb > /dev/null 2> /dev/null - - X11VNC_TEST_FAIL=0 - - - # CA / cert generation - - - echo -e "\n\nTesting -sslGenCA\n" > x11vnc_test.log - - $SCRIPTS_LOC/x11vnc_sslgenca.exp >> x11vnc_test.log 2>> x11vnc_test.log - - if [ $? -eq 0 ] && [ -f "ca-dir/CA/cacert.pem" ] && [ -f "ca-dir/CA/private/cakey.pem" ] - then - echo "[ PASSED ] -sslGenCA" - else - echo "[ FAILED ] -sslGenCA" - X11VNC_TEST_FAIL=1 - fi - - - echo -e "\n\nTesting -sslGenCert client\n" >> x11vnc_test.log - - $SCRIPTS_LOC/x11vnc_sslgencert_client.exp >> x11vnc_test.log 2>> x11vnc_test.log - - if [ $? -eq 0 ] && [ -f "ca-dir/clients/wolf.pem" ] && [ -f "ca-dir/clients/wolf.crt" ] - then - echo "[ PASSED ] -sslGenCert client" - else - echo "[ FAILED ] -sslGenCert client" - X11VNC_TEST_FAIL=1 - fi - - - echo -e "\n\nTesting -sslGenCert server\n" >> x11vnc_test.log - - $SCRIPTS_LOC/x11vnc_sslgencert_server.exp >> x11vnc_test.log 2>> x11vnc_test.log - - if [ $? -eq 0 ] && [ -f "ca-dir/server-wolf.pem" ] && [ -f "ca-dir/server-wolf.crt" ] - then - echo "[ PASSED ] -sslGenCert server" - else - echo "[ FAILED ] -sslGenCert server" - X11VNC_TEST_FAIL=1 - fi - - - echo -e "\n\nTesting -sslCertInfo\n" >> x11vnc_test.log - - OPENSSL_CONF='' OPENSSL_MODULES='' timeout 1 x11vnc -sslCertInfo ca-dir/server-wolf.pem > cert_info_ossl.txt - timeout 1 x11vnc -sslCertInfo ca-dir/server-wolf.pem > cert_info.txt - - if [ $? -eq 0 ] && diff -y cert_info.txt cert_info_ossl.txt >> x11vnc_test.log 2>> x11vnc_test.log \ - && cat cert_info.txt >> x11vnc_test.log - then - echo "[ PASSED ] -sslCertInfo" - else - echo "[ FAILED ] -sslCertInfo" - X11VNC_TEST_FAIL=1 - fi - - - echo -e "\n\nTesting -sslEncKey\n" >> x11vnc_test.log - - $SCRIPTS_LOC/x11vnc_sslenckey.exp >> x11vnc_test.log 2>> x11vnc_test.log - - if [ $? -eq 0 ] && grep -q "BEGIN ENCRYPTED PRIVATE KEY" ca-dir/server-wolf.pem - then - echo "[ PASSED ] -sslEncKey" - else - echo "[ FAILED ] -sslEncKey" - X11VNC_TEST_FAIL=1 - fi - - - # SSL - - - # Setup Xvfb, which is a purely virtual display, i.e., humans cannot see it - # but it works the same as any other X server - Xvfb :0 -screen 0 100x100x8 2>> x11vnc_test.log & - sleep 2 - - - # Testing with SSL will use the TLSNone security type - echo -e "\n\nTesting -ssl handshake, authentication, initialization...\n" >> x11vnc_test.log - - PORT=`x11vnc -ssl TMP -display :0 -localhost -bg -o server.log` - PORT=`echo "$PORT" | grep -m 1 "PORT=" | sed -e 's/PORT=//'` - - timeout 10 vncviewer -GnuTLSPriority=LEGACY -DesktopSize=0 -display :0 -log *:stderr:100 localhost::$PORT 2> client.log - - if grep -Eq "SSL: handshake with helper process[[0-9]+] succeeded" server.log \ - && grep -q "CConnection: Authentication success" client.log \ - && grep -q "CConnection: initialisation done" client.log - then - echo "[ PASSED ] -ssl handshake, authentication, initialization" - else - echo "[ FAILED ] -ssl handshake, authentication, initialization" - X11VNC_TEST_FAIL=1 - fi - killall x11vnc > /dev/null 2> /dev/null - cat server.log client.log >> x11vnc_test.log - - - # Testing with a password changes the security type from TLSNone to TLSVnc - echo -e "\n\nTesting -ssl with a password...\n" >> x11vnc_test.log - - x11vnc -storepasswd wolfprov passwd 2>> x11vnc_test.log - - PORT=`x11vnc -ssl TMP -display :0 -localhost -bg -o server.log -rfbauth passwd` - PORT=`echo "$PORT" | grep -m 1 "PORT=" | sed -e 's/PORT=//'` - - timeout 10 vncviewer -GnuTLSPriority=LEGACY -DesktopSize=0 -display :0 -passwd passwd -log *:stderr:100 localhost::$PORT 2> client.log - - if grep -Eq "SSL: handshake with helper process[[0-9]+] succeeded" server.log \ - && grep -q "CConnection: Authentication success" client.log \ - && grep -q "CConnection: initialisation done" client.log - then - echo "[ PASSED ] -ssl with a password" - else - echo "[ FAILED ] -ssl with a password" - X11VNC_TEST_FAIL=1 - fi - killall x11vnc > /dev/null 2> /dev/null - cat server.log client.log >> x11vnc_test.log - - - # HTTP HTTPS - - - echo "Use WolfSSL!" > index.html - - - PORT=`x11vnc -ssl TMP -display :0 -localhost -httpdir . -https 5678 -bg -o server.log` - PORT=`echo "$PORT" | grep -m 1 -Eo "http://localhost:[0-9]+" server.log | sed -e 's/http:\/\/localhost://'` - - echo -e "\n\nTesting -https with http...\n" >> x11vnc_test.log - - if OPENSSL_CONF='' OPENSSL_MODULES='' curl -ks "http://localhost:$PORT/index.html" >> x11vnc_test.log - then - echo "[ PASSED ] -https with an http request" - else - echo "[ FAILED ] -https with an http request" - X11VNC_TEST_FAIL=1 - fi - - - echo -e "\n\nTesting -https with https...\n" >> x11vnc_test.log - - if OPENSSL_CONF='' OPENSSL_MODULES='' curl -ks "https://localhost:5678/index.html" >> x11vnc_test.log - then - echo "[ PASSED ] -https with an https request" - else - echo "[ FAILED ] -https with an https request" - X11VNC_TEST_FAIL=1 - fi - - killall x11vnc > /dev/null 2> /dev/null - killall Xvfb > /dev/null 2> /dev/null - cat server.log >> x11vnc_test.log - - if [[ $WOLFPROV_FORCE_FAIL -eq 1 ]]; then - ((X11VNC_TEST_FAIL ^= 1)) - fi - - if [[ $X11VNC_TEST_FAIL -eq 1 ]]; then cat x11vnc_test.log; fi - - exit $X11VNC_TEST_FAIL - TEST_X11VNC_EOF - - chmod +x test_x11vnc.sh - - - name: Create x11vnc expect tests - run: | - # generating CA test - cat > x11vnc_sslgenca.exp << 'X11VNC_SSLGENCA_END' - #!/bin/expect - - set timeout 1 - - spawn x11vnc -sslGenCA ca-dir - - sleep 1 - - # provide password and verify - expect { - "PEM" { send "wolfprov\r" } - eof { exit 1 } - } - expect "PEM" { send "wolfprov\r" } - - # provide CA information - expect "Country Name" { send "US\r" } - expect "State" { send "montana\r" } - expect "Locality" { send "bozeman\r" } - expect "Organization" { send "wolfssl\r" } - expect "Organizational" { send "wolfssl\r" } - expect "Common" { send "wolfserver\r" } - expect "Email" { send "wolf@server.com\r" } - - # if CA creation has succeeded then the enter key will be expected - expect { - "Enter" { send "\r" } - eof { exit 1 } - } - - expect eof - exit 0 - X11VNC_SSLGENCA_END - - # generating client cert test - cat > x11vnc_sslgencert_client.exp << 'X11VNC_SSLGENCERT_CLIENT_END' - #!/bin/expect - - set timeout 1 - - # generate a cert for the client - spawn x11vnc -ssldir ca-dir -sslGenCert client wolf - - sleep 1 - - # provide CA information - expect { - "Country Name" { send "US\r" } - eof { exit 1 } - } - expect "State" { send "montana\r" } - expect "Locality" { send "bozeman\r" } - expect "Organization" { send "wolfssl\r" } - expect "Organizational" { send "wolfssl\r" } - expect "Common" { send "wolfclient\r" } - expect "Email" { send "wolf@client.com\r" } - - # challenge password and company name - expect "challenge" { send "wolfprov\r" } - expect "company" { send "wolfssl\r" } - - # create the cert - expect "passphrase" { send "n\r" } - expect "pass phrase" { send "wolfprov\r" } - expect "Sign" { send "y\r" } - expect "commit" { send "y\r" } - - # if cert creation has succeeded then the enter key will be expected - expect { - "Enter" { send "\r" } - eof { exit 1 } - } - - expect eof - exit 0 - X11VNC_SSLGENCERT_CLIENT_END - - # generating server cert test - cat > x11vnc_sslgencert_server.exp << 'X11VNC_SSLGENCERT_SERVER_END' - #!/bin/expect - - set timeout 1 - - # generate a cert for the server - spawn x11vnc -ssldir ca-dir -sslGenCert server wolf - - sleep 1 - - # provide CA information - expect { - "Country Name" { send "US\r" } - eof { exit 1 } - } - expect "State" { send "montana\r" } - expect "Locality" { send "bozeman\r" } - expect "Organization" { send "wolfssl\r" } - expect "Organizational" { send "wolfssl\r" } - expect "Common" { send "wolfserver\r" } - expect "Email" { send "wolf@server.com\r" } - - # challenge password and company name - expect "challenge" { send "wolfprov\r" } - expect "company" { send "wolfssl\r" } - - # create the cert - expect "passphrase" { send "n\r" } - expect "pass phrase" { send "wolfprov\r" } - expect "Sign" { send "y\r" } - expect "commit" { send "y\r" } - - # if cert creation has succeeded then the enter key will be expected - expect { - "Enter" { send "\r" } - eof { exit 1 } - } - - expect eof - exit 0 - X11VNC_SSLGENCERT_SERVER_END - - # generating enckey test - cat > x11vnc_sslenckey.exp << 'X11VNC_SSLENCKEY_END' - #!/bin/expect - - set timeout 1 - - spawn x11vnc -sslEncKey ca-dir/server-wolf.pem - - sleep 1 - - # verify encryption is desired - expect { - "Protect key with a passphrase?" { send "y\r" } - eof { exit 1 } - } - - # supply password - expect { - "Enter pass phrase:" { send "wolfprov\r" } - eof { exit 1 } - } - expect "Verifying" { send "wolfprov\r" } - - expect eof - exit 0 - X11VNC_SSLENCKEY_END - - chmod +x x11vnc_sslgenca.exp x11vnc_sslgencert_client.exp x11vnc_sslgencert_server.exp x11vnc_sslenckey.exp - - name: Run x11vnc tests run: | source $GITHUB_WORKSPACE/scripts/env-setup - export ${{ matrix.force_fail }} + export WOLFPROV_FORCE_FAIL_STR="${{ matrix.force_fail }}" - ./test_x11vnc.sh + $GITHUB_WORKSPACE/.github/scripts/test_x11vnc.sh diff --git a/scripts/env-setup b/scripts/env-setup index bef01e9c..58e69250 100755 --- a/scripts/env-setup +++ b/scripts/env-setup @@ -13,6 +13,7 @@ if [ $is_sourced -eq 0 ]; then exit 1 fi + if [ -n "$BASH_SOURCE" ]; then SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}") elif [ -n "$ZSH_VERSION" ]; then @@ -22,6 +23,7 @@ else exit 1 fi +SCRIPT_DIR="$(cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)" pushd $SCRIPT_DIR REPO_ROOT="${GITHUB_WORKSPACE:-$(git rev-parse --show-toplevel)}" popd @@ -64,4 +66,4 @@ else return 1 fi -echo "Done!\n" +echo "Done!" diff --git a/src/wp_rsa_kmgmt.c b/src/wp_rsa_kmgmt.c index f62f53cd..abb2b638 100644 --- a/src/wp_rsa_kmgmt.c +++ b/src/wp_rsa_kmgmt.c @@ -3925,15 +3925,15 @@ static int wp_rsa_encode_text_format_hex(const mp_int* num, char* textData, } else { if ((printAmt = XSNPRINTF(textData + dPos, textLen - dPos, - "%s:\n ", label)) <= 0){ + "%s:\n ", label)) <= 0) { ok = 0; } dPos += printAmt; /* OSSL adds a leading 00 if MSB is set */ - if (ok && *binData > 127){ + if (ok && *binData > 127) { if ((printAmt = XSNPRINTF(textData + dPos, textLen - dPos, - "00:")) <= 0){ + "00:")) <= 0) { ok = 0; } dPos += printAmt; @@ -3943,17 +3943,17 @@ static int wp_rsa_encode_text_format_hex(const mp_int* num, char* textData, /* OSSL does a newline + indent every 15 bytes */ if (ok) { for (i = 0; i < (int)binLen - 1; i++) { - if (bytes >= 14){ + if (bytes >= 14) { if ((printAmt = XSNPRINTF(textData + dPos, - textLen - dPos, "%02x:\n ", binData[i])) <= 0){ + textLen - dPos, "%02x:\n ", binData[i])) <= 0) { ok = 0; break; } bytes = 0; } - else{ + else { if ((printAmt = XSNPRINTF(textData + dPos, - textLen - dPos, "%02x:", binData[i])) <= 0){ + textLen - dPos, "%02x:", binData[i])) <= 0) { ok = 0; break; } @@ -3962,7 +3962,7 @@ static int wp_rsa_encode_text_format_hex(const mp_int* num, char* textData, dPos += printAmt; } if (ok && (printAmt = XSNPRINTF(textData + dPos, - textLen - dPos, "%02x\n", binData[i])) <= 0){ + textLen - dPos, "%02x\n", binData[i])) <= 0) { ok = 0; } dPos += printAmt; @@ -3972,7 +3972,10 @@ static int wp_rsa_encode_text_format_hex(const mp_int* num, char* textData, binData = NULL; } - *pos = dPos; + if (ok) { + *pos = dPos; + } + return ok; } @@ -4014,11 +4017,20 @@ static int wp_rsa_encode_text(wp_RsaEncDecCtx* ctx, OSSL_CORE_BIO* cBio, /* Calculate total size needed for text output */ if (ok) { + /* 128 bytes provides space for labels: 'modulus:', 'prime1:', etc. */ textLen = 128; if (hasPriv) { + /* displaying modulus and private exponent requires roughly 3 bytes + * per byte in key. + * prime1, prime2, exponent1, exponent2, and coefficient requires + * roughly 1.5 bytes per byte inkey. + * This is then 13.5 bytes per bytes in key + indents, which should + * be less than bits * 2.*/ textLen += key->bits << 1; } else if (hasPub) { + /* displaying modulus requires roughly 3 bytes per byte in key + a + * small amount for indents. This should be less than bits / 2 */ textLen += key->bits >> 1; } @@ -4031,27 +4043,28 @@ static int wp_rsa_encode_text(wp_RsaEncDecCtx* ctx, OSSL_CORE_BIO* cBio, /* OSSL uses nested macros to determine the number of primes, not sure * when there wouldn't be two primes */ if (hasPriv && (printAmt = XSNPRINTF(textData + pos, textLen - pos, - "Private-Key: (%d bit, 2 primes)\n", key->bits)) <= 0){ + "Private-Key: (%d bit, 2 primes)\n", key->bits)) <= 0) { ok = 0; - } else if (hasPub && (printAmt = XSNPRINTF(textData + pos, - textLen - pos, "Public-Key: (%d bit)\n", key->bits)) <= 0){ + } + else if (hasPub && (printAmt = XSNPRINTF(textData + pos, + textLen - pos, "Public-Key: (%d bit)\n", key->bits)) <= 0) { ok = 0; } pos += printAmt; } /* OSSL uses 'modulus' and 'Modulus' */ - if (hasPriv){ + if (hasPriv) { ok = wp_rsa_encode_text_format_hex(&key->key.n, textData, textLen, &pos, "modulus"); } - else if (hasPub){ + else if (hasPub) { ok = wp_rsa_encode_text_format_hex(&key->key.n, textData, textLen, &pos, "Modulus"); } /* OSSL uses 'publicExponent' and 'Exponent' */ - if (ok){ + if (ok) { if (mp_radix_size(&key->key.e, MP_RADIX_DEC, &expLen) != MP_OKAY || ((expStr = OPENSSL_malloc(expLen)) == NULL)) { ok = 0; @@ -4077,7 +4090,7 @@ static int wp_rsa_encode_text(wp_RsaEncDecCtx* ctx, OSSL_CORE_BIO* cBio, } } - if (ok){ + if (ok) { if (mp_radix_size(&key->key.e, MP_RADIX_HEX, &expLen) != MP_OKAY || ((expStr = OPENSSL_malloc(expLen)) == NULL)) { ok = 0; @@ -4087,7 +4100,7 @@ static int wp_rsa_encode_text(wp_RsaEncDecCtx* ctx, OSSL_CORE_BIO* cBio, OPENSSL_free(expStr); expStr = NULL; } - else{ + else { /* OSSL does not print a leading zero for the hex part */ if ((printAmt = XSNPRINTF(textData + pos, textLen - pos, "(0x%s)\n", From 395dfc72d36cd0f350dc26de507e03238cad6271 Mon Sep 17 00:00:00 2001 From: Sebastian Carpenter Date: Thu, 3 Jul 2025 12:04:15 -0600 Subject: [PATCH 3/5] updated location for test_x11vnc.sh --- .github/workflows/x11vnc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/x11vnc.yml b/.github/workflows/x11vnc.yml index f8fc6a5c..f75d1020 100644 --- a/.github/workflows/x11vnc.yml +++ b/.github/workflows/x11vnc.yml @@ -91,4 +91,4 @@ jobs: source $GITHUB_WORKSPACE/scripts/env-setup export WOLFPROV_FORCE_FAIL_STR="${{ matrix.force_fail }}" - $GITHUB_WORKSPACE/.github/scripts/test_x11vnc.sh + $GITHUB_WORKSPACE/.github/scripts/x11vnc/test_x11vnc.sh From b3d3ec9bb29b95da8f59cea1493457a2f6435086 Mon Sep 17 00:00:00 2001 From: Sebastian Carpenter Date: Thu, 3 Jul 2025 12:51:14 -0600 Subject: [PATCH 4/5] x11vnc expects tests not executable updated the tests to have execution privileges --- .github/scripts/x11vnc/x11vnc_sslenckey.exp | 0 .github/scripts/x11vnc/x11vnc_sslgenca.exp | 0 .github/scripts/x11vnc/x11vnc_sslgencert_client.exp | 0 .github/scripts/x11vnc/x11vnc_sslgencert_server.exp | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .github/scripts/x11vnc/x11vnc_sslenckey.exp mode change 100644 => 100755 .github/scripts/x11vnc/x11vnc_sslgenca.exp mode change 100644 => 100755 .github/scripts/x11vnc/x11vnc_sslgencert_client.exp mode change 100644 => 100755 .github/scripts/x11vnc/x11vnc_sslgencert_server.exp diff --git a/.github/scripts/x11vnc/x11vnc_sslenckey.exp b/.github/scripts/x11vnc/x11vnc_sslenckey.exp old mode 100644 new mode 100755 diff --git a/.github/scripts/x11vnc/x11vnc_sslgenca.exp b/.github/scripts/x11vnc/x11vnc_sslgenca.exp old mode 100644 new mode 100755 diff --git a/.github/scripts/x11vnc/x11vnc_sslgencert_client.exp b/.github/scripts/x11vnc/x11vnc_sslgencert_client.exp old mode 100644 new mode 100755 diff --git a/.github/scripts/x11vnc/x11vnc_sslgencert_server.exp b/.github/scripts/x11vnc/x11vnc_sslgencert_server.exp old mode 100644 new mode 100755 From 0758ca63735418efe1940dad4b59f45be48514e2 Mon Sep 17 00:00:00 2001 From: Sebastian Carpenter Date: Thu, 3 Jul 2025 13:19:24 -0600 Subject: [PATCH 5/5] accidentally removed FORCE_FAIL export --- .github/workflows/x11vnc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/x11vnc.yml b/.github/workflows/x11vnc.yml index f75d1020..099bd6de 100644 --- a/.github/workflows/x11vnc.yml +++ b/.github/workflows/x11vnc.yml @@ -89,6 +89,7 @@ jobs: - name: Run x11vnc tests run: | source $GITHUB_WORKSPACE/scripts/env-setup + export ${{ matrix.force_fail }} export WOLFPROV_FORCE_FAIL_STR="${{ matrix.force_fail }}" $GITHUB_WORKSPACE/.github/scripts/x11vnc/test_x11vnc.sh