Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 106 additions & 26 deletions .github/scripts/openssl-ech.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ cleanup() {
trap cleanup EXIT

usage() {
echo "Usage: $0 <client|server> [--suite <KEM,KDF,AEAD>] [--workspace <path>]"
echo "Usage: $0 <client|server> [--suite <KEM,KDF,AEAD>] [--pqc <group>] [--hrr] [--workspace <path>]"
exit 1
}

# --------------------------------------------------------------------------
# Argument parsing
# --------------------------------------------------------------------------
MODE=""
SUITE=""
PQC=""
FORCE_HRR=0

WORKSPACE=${GITHUB_WORKSPACE:-"."}

Expand All @@ -36,9 +41,15 @@ while [ $# -gt 0 ]; do
[ -z "$2" ] && { echo "ERROR: --suite requires a value"; exit 1; }
SUITE="$2"
shift 2
echo ""
echo "Using suite: $SUITE"
echo ""
;;
--pqc)
[ -z "$2" ] && { echo "ERROR: --pqc requires a value"; exit 1; }
PQC="$2"
shift 2
;;
--hrr)
FORCE_HRR=1
shift
;;
--workspace)
[ -z "$2" ] && { echo "ERROR: --workspace requires a value"; exit 1; }
Expand All @@ -49,6 +60,25 @@ while [ $# -gt 0 ]; do
esac
done

if [ "$FORCE_HRR" -ne 0 ] && [ -n "$PQC" ]; then
echo "ERROR: --hrr and --pqc are mutually exclusive"
exit 1
fi

# Pick exactly one test variant. The variant decides which -groups go to
# each side and any extra flags needed to drive the desired handshake.
# default - both sides use secp256r1 (no HRR)
# pqc - both sides use the chosen PQC group
# hrr - pin one side to a group the other doesn't keyshare by
# default, forcing the server to send HelloRetryRequest
if [ -n "$PQC" ]; then
VARIANT="pqc"
elif [ "$FORCE_HRR" -ne 0 ]; then
VARIANT="hrr"
else
VARIANT="default"
fi

OPENSSL=${OPENSSL:-"openssl"}
WOLFSSL_CLIENT=${WOLFSSL_CLIENT:-"$WORKSPACE/examples/client/client"}
WOLFSSL_SERVER=${WOLFSSL_SERVER:-"$WORKSPACE/examples/server/server"}
Expand All @@ -59,21 +89,49 @@ PRIV_NAME="ech-private-name.com"
PUB_NAME="ech-public-name.com"
MAX_WAIT=50

# --------------------------------------------------------------------------
# server mode -- OpenSSL is the server, wolfSSL is the client
# --------------------------------------------------------------------------
openssl_server(){
local ech_file="$WORKSPACE/ech_config.pem"
local ech_config=""
local port=""

# Per-variant args.
# openssl_groups : -groups passed to OpenSSL s_server
# openssl_suite : -suite passed to `openssl ech` for key generation
# wolfssl_extra : extra flags for the wolfSSL client
local openssl_groups=""
local openssl_suite=""
local wolfssl_extra=""

case "$VARIANT" in
default)
openssl_groups="-groups secp256r1"
;;
pqc)
openssl_groups="-groups $PQC"
wolfssl_extra="--pqc $PQC"
;;
hrr)
# wolfSSL client keyshares X25519 by default; pin OpenSSL
# server to secp384r1 so it must send HelloRetryRequest.
openssl_groups="-groups secp384r1"
;;
esac
[ -n "$SUITE" ] && openssl_suite="-suite $SUITE"

rm -f "$ech_file"

$OPENSSL ech -public_name "$PUB_NAME" -out "$ech_file" $SUITE &>> "$TMP_LOG"
$OPENSSL ech -public_name "$PUB_NAME" -out "$ech_file" $openssl_suite \
&>> "$TMP_LOG"

# parse ECH config from file
ech_config=$(sed -n '/BEGIN ECHCONFIG/,/END ECHCONFIG/{/BEGIN ECHCONFIG\|END ECHCONFIG/d;p}' "$ech_file" | tr -d '\n')
echo "parsed ech config: $ech_config" &>> "$TMP_LOG"

# start OpenSSL ECH server with ephemeral port and make sure it is
# line-buffered
# start OpenSSL ECH server with ephemeral port; line-buffer so the
# log can be grepped
stdbuf -oL $OPENSSL s_server \
-tls1_3 \
-cert "$CERT_DIR/server-cert.pem" \
Expand All @@ -82,6 +140,7 @@ openssl_server(){
-key2 "$CERT_DIR/server-key.pem" \
-ech_key "$ech_file" \
-servername "$PRIV_NAME" \
$openssl_groups \
-accept 0 \
-naccept 1 \
&>> "$TMP_LOG" <<< "wolfssl!" &
Expand All @@ -104,29 +163,61 @@ openssl_server(){
-p "$port" \
-S "$PRIV_NAME" \
--ech "$ech_config" \
$wolfssl_extra \
&>> "$TMP_LOG"

rm -f "$ech_file"

grep -q "ech_success=1" "$TMP_LOG"
}

# --------------------------------------------------------------------------
# client mode -- wolfSSL is the server, OpenSSL is the client
# --------------------------------------------------------------------------
openssl_client(){
local ready_file="$WORKSPACE/wolfssl_tls13_ready$$"
local ech_config=""
local port=0

# Per-variant args.
# openssl_groups : -groups passed to OpenSSL s_client
# wolfssl_suite : --ech-suite passed to wolfSSL server for key gen
# wolfssl_extra : extra flags for the wolfSSL server
local openssl_groups=""
local wolfssl_suite=""
local wolfssl_extra=""

case "$VARIANT" in
default)
openssl_groups="-groups secp256r1"
;;
pqc)
openssl_groups="-groups $PQC"
wolfssl_extra="--pqc $PQC"
;;
hrr)
# Pin wolfSSL server to SECP384R1 only. Have OpenSSL offer
# X25519 as keyshare with P-384 in supported_groups: the
# mismatched keyshare forces HelloRetryRequest, and P-384 in
# supported_groups lets the client answer it.
openssl_groups="-groups X25519:P-384"
wolfssl_extra="--force-curve SECP384R1"
;;
esac
[ -n "$SUITE" ] && wolfssl_suite="--ech-suite $SUITE"

rm -f "$ready_file"

# start server with ephemeral port + ready file
# also set server to be line buffered so the log can be grepped
# start server with ephemeral port + ready file; line-buffer so the
# log can be grepped
stdbuf -oL $WOLFSSL_SERVER \
-v 4 \
-R "$ready_file" \
-p "$port" \
-S "$PRIV_NAME" \
--ech "$PUB_NAME" \
$SUITE \
$wolfssl_suite \
$wolfssl_extra \
&>> "$TMP_LOG" &

# wait for server to be ready, then get port
Expand Down Expand Up @@ -157,7 +248,7 @@ openssl_client(){
done
echo "parsed ech config: $ech_config" &>> "$TMP_LOG"

# Test with OpenSSL s_client using ECH
# test with OpenSSL s_client using ECH
echo "wolfssl" | $OPENSSL s_client \
-tls1_3 \
-connect "localhost:$port" \
Expand All @@ -166,6 +257,7 @@ openssl_client(){
-CAfile "$CERT_DIR/ca-cert.pem" \
-servername "$PRIV_NAME" \
-ech_config_list "$ech_config" \
$openssl_groups \
&>> "$TMP_LOG"

grep -q "ECH: success: 1" "$TMP_LOG"
Expand All @@ -174,19 +266,7 @@ openssl_client(){
rm -f "$TMP_LOG"

case "$MODE" in
server)
if [ -n "$SUITE" ]; then
SUITE="-suite $SUITE"
fi
openssl_server
;;
client)
if [ -n "$SUITE" ]; then
SUITE="--ech-suite $SUITE"
fi
openssl_client
;;
*)
exit 1
;;
server) openssl_server ;;
client) openssl_client ;;
*) exit 1 ;;
esac
14 changes: 13 additions & 1 deletion .github/workflows/openssl-ech.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
with:
path: wolfssl
configure: >-
--enable-ech --enable-sha512 --enable-aes
--enable-ech --enable-sha512 --enable-aes --enable-mlkem
CFLAGS='-DUSE_FLAT_TEST_H -DWOLFSSL_TEST_ECH'
check: true
install: true
Expand Down Expand Up @@ -147,6 +147,18 @@ jobs:
echo -e "\nTesting default suite with OpenSSL client and wolfSSL server\n" &>> "$LOG_FILE"
bash ./openssl-ech.sh client &>> "$LOG_FILE"

echo -e "\nTesting default suite with OpenSSL server and wolfSSL client (PQC)\n" &>> "$LOG_FILE"
bash ./openssl-ech.sh server --pqc SecP384r1MLKEM1024 &>> "$LOG_FILE"

echo -e "\nTesting default suite with OpenSSL client and wolfSSL server (PQC)\n" &>> "$LOG_FILE"
bash ./openssl-ech.sh client --pqc SecP384r1MLKEM1024 &>> "$LOG_FILE"

echo -e "\nTesting default suite with OpenSSL server and wolfSSL client (HRR)\n" &>> "$LOG_FILE"
bash ./openssl-ech.sh server --hrr &>> "$LOG_FILE"

echo -e "\nTesting default suite with OpenSSL client and wolfSSL server (HRR)\n" &>> "$LOG_FILE"
bash ./openssl-ech.sh client --hrr &>> "$LOG_FILE"

# weird suite (DHKEM_P521_HKDF_SHA512, HKDF_SHA256, HPKE_AES_256_GCM)
echo -e "\nTesting weird suite with OpenSSL server and wolfSSL client\n" &>> "$LOG_FILE"
bash ./openssl-ech.sh server --suite "18,1,2" &>> "$LOG_FILE"
Expand Down
Loading
Loading