@@ -11,12 +11,17 @@ cleanup() {
1111trap cleanup EXIT
1212
1313usage () {
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+ # --------------------------------------------------------------------------
1821MODE=" "
1922SUITE=" "
23+ PQC=" "
24+ FORCE_HRR=0
2025
2126WORKSPACE=${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
5061done
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+
5282OPENSSL=${OPENSSL:- " openssl" }
5383WOLFSSL_CLIENT=${WOLFSSL_CLIENT:- " $WORKSPACE /examples/client/client" }
5484WOLFSSL_SERVER=${WOLFSSL_SERVER:- " $WORKSPACE /examples/server/server" }
@@ -59,21 +89,49 @@ PRIV_NAME="ech-private-name.com"
5989PUB_NAME=" ech-public-name.com"
6090MAX_WAIT=50
6191
92+ # --------------------------------------------------------------------------
93+ # server mode -- OpenSSL is the server, wolfSSL is the client
94+ # --------------------------------------------------------------------------
6295openssl_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+ # --------------------------------------------------------------------------
114177openssl_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(){
174266rm -f " $TMP_LOG "
175267
176268case " $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 ;;
192272esac
0 commit comments