Skip to content

Commit e78418d

Browse files
authored
Merge pull request #10306 from sebastian-carpenter/tls-ech-client-oe
Add OuterExtensions encoding for TLS ECH client
2 parents 8ac2a1a + 15b8c88 commit e78418d

5 files changed

Lines changed: 386 additions & 79 deletions

File tree

.github/scripts/openssl-ech.sh

Lines changed: 106 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,17 @@ cleanup() {
1111
trap cleanup EXIT
1212

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

18+
# --------------------------------------------------------------------------
19+
# Argument parsing
20+
# --------------------------------------------------------------------------
1821
MODE=""
1922
SUITE=""
23+
PQC=""
24+
FORCE_HRR=0
2025

2126
WORKSPACE=${GITHUB_WORKSPACE:-"."}
2227

@@ -36,9 +41,15 @@ while [ $# -gt 0 ]; do
3641
[ -z "$2" ] && { echo "ERROR: --suite requires a value"; exit 1; }
3742
SUITE="$2"
3843
shift 2
39-
echo ""
40-
echo "Using suite: $SUITE"
41-
echo ""
44+
;;
45+
--pqc)
46+
[ -z "$2" ] && { echo "ERROR: --pqc requires a value"; exit 1; }
47+
PQC="$2"
48+
shift 2
49+
;;
50+
--hrr)
51+
FORCE_HRR=1
52+
shift
4253
;;
4354
--workspace)
4455
[ -z "$2" ] && { echo "ERROR: --workspace requires a value"; exit 1; }
@@ -49,6 +60,25 @@ while [ $# -gt 0 ]; do
4960
esac
5061
done
5162

63+
if [ "$FORCE_HRR" -ne 0 ] && [ -n "$PQC" ]; then
64+
echo "ERROR: --hrr and --pqc are mutually exclusive"
65+
exit 1
66+
fi
67+
68+
# Pick exactly one test variant. The variant decides which -groups go to
69+
# each side and any extra flags needed to drive the desired handshake.
70+
# default - both sides use secp256r1 (no HRR)
71+
# pqc - both sides use the chosen PQC group
72+
# hrr - pin one side to a group the other doesn't keyshare by
73+
# default, forcing the server to send HelloRetryRequest
74+
if [ -n "$PQC" ]; then
75+
VARIANT="pqc"
76+
elif [ "$FORCE_HRR" -ne 0 ]; then
77+
VARIANT="hrr"
78+
else
79+
VARIANT="default"
80+
fi
81+
5282
OPENSSL=${OPENSSL:-"openssl"}
5383
WOLFSSL_CLIENT=${WOLFSSL_CLIENT:-"$WORKSPACE/examples/client/client"}
5484
WOLFSSL_SERVER=${WOLFSSL_SERVER:-"$WORKSPACE/examples/server/server"}
@@ -59,21 +89,49 @@ PRIV_NAME="ech-private-name.com"
5989
PUB_NAME="ech-public-name.com"
6090
MAX_WAIT=50
6191

92+
# --------------------------------------------------------------------------
93+
# server mode -- OpenSSL is the server, wolfSSL is the client
94+
# --------------------------------------------------------------------------
6295
openssl_server(){
6396
local ech_file="$WORKSPACE/ech_config.pem"
6497
local ech_config=""
6598
local port=""
6699

100+
# Per-variant args.
101+
# openssl_groups : -groups passed to OpenSSL s_server
102+
# openssl_suite : -suite passed to `openssl ech` for key generation
103+
# wolfssl_extra : extra flags for the wolfSSL client
104+
local openssl_groups=""
105+
local openssl_suite=""
106+
local wolfssl_extra=""
107+
108+
case "$VARIANT" in
109+
default)
110+
openssl_groups="-groups secp256r1"
111+
;;
112+
pqc)
113+
openssl_groups="-groups $PQC"
114+
wolfssl_extra="--pqc $PQC"
115+
;;
116+
hrr)
117+
# wolfSSL client keyshares X25519 by default; pin OpenSSL
118+
# server to secp384r1 so it must send HelloRetryRequest.
119+
openssl_groups="-groups secp384r1"
120+
;;
121+
esac
122+
[ -n "$SUITE" ] && openssl_suite="-suite $SUITE"
123+
67124
rm -f "$ech_file"
68125

69-
$OPENSSL ech -public_name "$PUB_NAME" -out "$ech_file" $SUITE &>> "$TMP_LOG"
126+
$OPENSSL ech -public_name "$PUB_NAME" -out "$ech_file" $openssl_suite \
127+
&>> "$TMP_LOG"
70128

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

75-
# start OpenSSL ECH server with ephemeral port and make sure it is
76-
# line-buffered
133+
# start OpenSSL ECH server with ephemeral port; line-buffer so the
134+
# log can be grepped
77135
stdbuf -oL $OPENSSL s_server \
78136
-tls1_3 \
79137
-cert "$CERT_DIR/server-cert.pem" \
@@ -82,6 +140,7 @@ openssl_server(){
82140
-key2 "$CERT_DIR/server-key.pem" \
83141
-ech_key "$ech_file" \
84142
-servername "$PRIV_NAME" \
143+
$openssl_groups \
85144
-accept 0 \
86145
-naccept 1 \
87146
&>> "$TMP_LOG" <<< "wolfssl!" &
@@ -104,29 +163,61 @@ openssl_server(){
104163
-p "$port" \
105164
-S "$PRIV_NAME" \
106165
--ech "$ech_config" \
166+
$wolfssl_extra \
107167
&>> "$TMP_LOG"
108168

109169
rm -f "$ech_file"
110170

111171
grep -q "ech_success=1" "$TMP_LOG"
112172
}
113173

174+
# --------------------------------------------------------------------------
175+
# client mode -- wolfSSL is the server, OpenSSL is the client
176+
# --------------------------------------------------------------------------
114177
openssl_client(){
115178
local ready_file="$WORKSPACE/wolfssl_tls13_ready$$"
116179
local ech_config=""
117180
local port=0
118181

182+
# Per-variant args.
183+
# openssl_groups : -groups passed to OpenSSL s_client
184+
# wolfssl_suite : --ech-suite passed to wolfSSL server for key gen
185+
# wolfssl_extra : extra flags for the wolfSSL server
186+
local openssl_groups=""
187+
local wolfssl_suite=""
188+
local wolfssl_extra=""
189+
190+
case "$VARIANT" in
191+
default)
192+
openssl_groups="-groups secp256r1"
193+
;;
194+
pqc)
195+
openssl_groups="-groups $PQC"
196+
wolfssl_extra="--pqc $PQC"
197+
;;
198+
hrr)
199+
# Pin wolfSSL server to SECP384R1 only. Have OpenSSL offer
200+
# X25519 as keyshare with P-384 in supported_groups: the
201+
# mismatched keyshare forces HelloRetryRequest, and P-384 in
202+
# supported_groups lets the client answer it.
203+
openssl_groups="-groups X25519:P-384"
204+
wolfssl_extra="--force-curve SECP384R1"
205+
;;
206+
esac
207+
[ -n "$SUITE" ] && wolfssl_suite="--ech-suite $SUITE"
208+
119209
rm -f "$ready_file"
120210

121-
# start server with ephemeral port + ready file
122-
# also set server to be line buffered so the log can be grepped
211+
# start server with ephemeral port + ready file; line-buffer so the
212+
# log can be grepped
123213
stdbuf -oL $WOLFSSL_SERVER \
124214
-v 4 \
125215
-R "$ready_file" \
126216
-p "$port" \
127217
-S "$PRIV_NAME" \
128218
--ech "$PUB_NAME" \
129-
$SUITE \
219+
$wolfssl_suite \
220+
$wolfssl_extra \
130221
&>> "$TMP_LOG" &
131222

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

160-
# Test with OpenSSL s_client using ECH
251+
# test with OpenSSL s_client using ECH
161252
echo "wolfssl" | $OPENSSL s_client \
162253
-tls1_3 \
163254
-connect "localhost:$port" \
@@ -166,6 +257,7 @@ openssl_client(){
166257
-CAfile "$CERT_DIR/ca-cert.pem" \
167258
-servername "$PRIV_NAME" \
168259
-ech_config_list "$ech_config" \
260+
$openssl_groups \
169261
&>> "$TMP_LOG"
170262

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

176268
case "$MODE" in
177-
server)
178-
if [ -n "$SUITE" ]; then
179-
SUITE="-suite $SUITE"
180-
fi
181-
openssl_server
182-
;;
183-
client)
184-
if [ -n "$SUITE" ]; then
185-
SUITE="--ech-suite $SUITE"
186-
fi
187-
openssl_client
188-
;;
189-
*)
190-
exit 1
191-
;;
269+
server) openssl_server ;;
270+
client) openssl_client ;;
271+
*) exit 1 ;;
192272
esac

.github/workflows/openssl-ech.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
with:
2525
path: wolfssl
2626
configure: >-
27-
--enable-ech --enable-sha512 --enable-aes
27+
--enable-ech --enable-sha512 --enable-aes --enable-mlkem
2828
CFLAGS='-DUSE_FLAT_TEST_H -DWOLFSSL_TEST_ECH'
2929
check: true
3030
install: true
@@ -147,6 +147,18 @@ jobs:
147147
echo -e "\nTesting default suite with OpenSSL client and wolfSSL server\n" &>> "$LOG_FILE"
148148
bash ./openssl-ech.sh client &>> "$LOG_FILE"
149149
150+
echo -e "\nTesting default suite with OpenSSL server and wolfSSL client (PQC)\n" &>> "$LOG_FILE"
151+
bash ./openssl-ech.sh server --pqc SecP384r1MLKEM1024 &>> "$LOG_FILE"
152+
153+
echo -e "\nTesting default suite with OpenSSL client and wolfSSL server (PQC)\n" &>> "$LOG_FILE"
154+
bash ./openssl-ech.sh client --pqc SecP384r1MLKEM1024 &>> "$LOG_FILE"
155+
156+
echo -e "\nTesting default suite with OpenSSL server and wolfSSL client (HRR)\n" &>> "$LOG_FILE"
157+
bash ./openssl-ech.sh server --hrr &>> "$LOG_FILE"
158+
159+
echo -e "\nTesting default suite with OpenSSL client and wolfSSL server (HRR)\n" &>> "$LOG_FILE"
160+
bash ./openssl-ech.sh client --hrr &>> "$LOG_FILE"
161+
150162
# weird suite (DHKEM_P521_HKDF_SHA512, HKDF_SHA256, HPKE_AES_256_GCM)
151163
echo -e "\nTesting weird suite with OpenSSL server and wolfSSL client\n" &>> "$LOG_FILE"
152164
bash ./openssl-ech.sh server --suite "18,1,2" &>> "$LOG_FILE"

0 commit comments

Comments
 (0)