-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathechsvr.sh
More file actions
executable file
·324 lines (283 loc) · 7.96 KB
/
echsvr.sh
File metadata and controls
executable file
·324 lines (283 loc) · 7.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
#!/bin/bash
# set -x
# to pick up correct .so's - maybe note
: ${CODETOP:=$HOME/code/defo-project-org/openssl}
export LD_LIBRARY_PATH=$CODETOP
# to pick up the relevant configuration
: ${CFGTOP:=`/bin/pwd`}
: ${ECHKEYFILE:="$CFGTOP/echconfig.pem"}
# Path to openssl binary
if [[ "$PACKAGING" == "" ]]
then
CMDPATH=$CODETOP/apps/openssl
else
CMDPATH=`which openssl`
set -e
fi
HIDDEN="foo.example.com"
HIDDEN2="bar.example.com"
CLEAR_SNI="example.com"
ECHDIR="$CFGTOP/echkeydir"
SSLCFG="/etc/ssl/openssl.cnf"
# variables/settings
VG="no"
NOECH="no"
DEBUG="no"
KEYGEN="no"
PORT="8443"
TRIALDECRYPT="no"
SUPPLIEDPORT=""
WEBSERVER=""
FORCEHRR="no"
SUPPLIEDKEYFILE=""
SUPPLIEDHIDDEN=""
SUPPLIEDCLEAR_SNI=""
SUPPLIEDDIR=""
CAPATH="$CFGTOP/cadir/"
EARLY_DATA="no"
NREQS=""
# whether we feed a bad key pair to server for testing
BADKEY="no"
# whethe or not to do ECH-specific paddng
ECHPAD="no"
function whenisitagain()
{
/bin/date -u +%Y%m%d-%H%M%S
}
NOW=$(whenisitagain)
echo "Running $0 at $NOW"
function usage()
{
echo "$0 [-cHpDsdNnlvhKw] [-- [literal s_server opts]] - try out encrypted SNI via openssl s_server"
echo " -B to input a bad key pair to server setup, for testing"
echo " -c [name] specifices a name that I'll accept as a cleartext SNI (NONE is special)"
echo " -D means find ech config files in that directory"
echo " -d means run s_server in verbose mode"
echo " -e means allow default amount of early data"
echo " -F says to hard fail if ECH attempted but fails"
echo " -g says to GREASE retry_configs"
echo " -H means serve that hidden server"
echo " -h means print this"
echo " -K to generate server keys "
echo " -k provide ECH Key pair PEM file"
echo " -N [number] means to exit after number requests"
echo " -n means don't trigger ech at all"
echo " -p [port] specifices a port (default: 8443)"
echo " -P turn on ECH specific padding"
echo " -R trigger HRR by limiting server to P-384"
echo " -v means run with valgrind"
echo " -T says to attempt trial decryption if necessary"
echo " -w means to run as a pretty dumb web server"
echo " -- anything after -- is passed directly to s_server"
echo ""
echo "The following should work:"
echo " $0 -c example.com -H foo.example.com"
echo "To generate keys, set -H/-c as required:"
echo " $0 -K"
exit 99
}
# options may be followed by one colon to indicate they have a required argument
if ! options=$(/usr/bin/getopt -s bash -o k:BTc:D:eH:p:PRKdlvN:nhwg -l keyfile,badkey,trialdecrypt,dir:,early,clear_sni:,hidden:,port:,pad,hrr,keygen,debug,stale,valgrind,nreq,noech,help,web,grease -- "$@")
then
# something went wrong, getopt will put out an error message for us
exit 1
fi
#echo "|$options|"
eval set -- "$options"
while [ $# -gt 0 ]
do
case "$1" in
-B|--badkey) BADKEY="yes";;
-c|--clear_sni) SUPPLIEDCLEAR_SNI=$2; shift;;
-D|--dir) SUPPLIEDDIR=$2; shift;;
-d|--debug) DEBUG="yes" ;;
-e|--early) EARLY_DATA="yes";;
-g|--grease) GREASE="yes";;
-h|--help) usage;;
-H|--hidden) SUPPLIEDHIDDEN=$2; shift;;
-k|--keyfile) SUPPLIEDKEYFILE=$2; shift;;
-K|--keygen) KEYGEN="yes" ;;
-N|--nreq) NREQS=$2; shift;;
-n|--noech) NOECH="yes" ;;
-p|--port) SUPPLIEDPORT=$2; shift;;
-P|--pad) ECHPAD="yes";;
-R|--hrr) FORCEHRR="yes";;
-T|--trialdecrypt) TRIALDECRYPT="yes";;
-v|--valgrind) VG="yes";;
-w|--web) WEBSERVER=" -WWW ";;
(--) shift; break;;
(-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
(*) break;;
esac
shift
done
hidden=$HIDDEN
if [[ "$SUPPLIEDHIDDEN" != "" ]]
then
hidden=$SUPPLIEDHIDDEN
fi
# Set SNI
clear_sni=$CLEAR_SNI
snicmd="-servername $clear_sni"
if [[ "$SUPPLIEDCLEAR_SNI" != "" ]]
then
if [[ "$SUPPLIEDCLEAR_SNI" == "NONE" ]]
then
snicmd="-noservername "
else
clear_sni=$SUPPLIEDCLEAR_SNI
snicmd=" -servername $clear_sni "
fi
fi
# Set preferred ALPN - can parameterise later if/as needed
alpn_cmd=" -alpn http/1.1,h2 "
# Set padding if needed
echpad_cmd=""
if [[ "$ECHPAD" == "yes" ]]
then
echpad_cmd=" -ech_specificpad "
fi
hrr_cmd=""
if [[ "$FORCEHRR" == "yes" ]]
then
echo "Forcing HRR"
hrr_cmd=" -groups P-384"
else
echo "Not forcing HRR"
fi
nreq_cmd=""
if [[ "$NREQS" != "" ]]
then
echo "Exiting after $NREQS requests"
nreq_cmd=" -naccept $NREQS "
fi
KEYFILE1=$CFGTOP/cadir/$clear_sni.priv
CERTFILE1=$CFGTOP/cadir/$clear_sni.crt
KEYFILE2=$CFGTOP/cadir/$hidden.priv
CERTFILE2=$CFGTOP/cadir/$hidden.crt
KEYFILE3=$CFGTOP/cadir/$HIDDEN2.priv
CERTFILE3=$CFGTOP/cadir/$HIDDEN2.crt
if [[ "$KEYGEN" == "yes" ]]
then
echo "Generating kays and exiting..."
./make-example-ca.sh
exit 0
fi
keyfile1="-key $KEYFILE1 -cert $CERTFILE1"
keyfile2="-key2 $KEYFILE2 -cert2 $CERTFILE2"
#keyfile3="-key2 $KEYFILE3 -cert2 $CERTFILE3"
# figure out if we have tracing enabled within OpenSSL
# there's probably an easier way but s_server -help
# ought work
TRACING=""
tmpf=`mktemp`
$CMDPATH s_server -help >$tmpf 2>&1
tcount=`grep -c 'trace protocol messages' $tmpf` || true
if [[ "$tcount" == "1" ]]
then
TRACING="-trace "
fi
rm -f $tmpf
#dbgstr=" -verify_quiet"
dbgstr=" -quiet"
if [[ "$DEBUG" == "yes" ]]
then
dbgstr="-msg $TRACING -tlsextdebug -ign_eof"
#dbgstr="-msg $TRACING -tlsextdebug -ign_eof -keylogfile keys.srv"
#dbgstr="-msg $TRACING -debug -security_debug_verbose -state -tlsextdebug -keylogfile srv.keys"
fi
vgcmd=""
if [[ "$VG" == "yes" ]]
then
vgcmd="valgrind --track-origins=yes --leak-check=full "
fi
if [[ "$SUPPLIEDPORT" != "" ]]
then
PORT=$SUPPLIEDPORT
fi
portstr=" -port $PORT "
echdir=$ECHDIR
if [[ "$SUPPLIEDDIR" != "" ]]
then
echdir=$SUPPLIEDDIR
fi
if [[ "$BADKEY" == "yes" ]]
then
if [[ "$echdir" == "" ]]
then
echo "Can't feed bad key pair without setting echkeydir"
exit 88
else
echo "Feeding bogus key pair to server for test"
echo "boguscfg" >$echdir/badconfig.pem
fi
fi
echstr=""
if [[ "$SUPPLIEDKEYFILE" != "" ]]
then
ECHKEYFILE="$SUPPLIEDKEYFILE"
fi
if [ -f $ECHKEYFILE ]
then
echo "Using key pair from $ECHKEYFILE"
echstr="$echstr -ech_key $ECHKEYFILE "
fi
if [ -d $echdir ]
then
echo "Using all key pairs found in $echdir "
echstr="$echstr -ech_dir $echdir"
fi
if [[ "$NOECH" == "yes" ]]
then
echo "Not trying ECH"
echstr=""
fi
trialdecrypt=""
if [[ "$TRIALDECRYPT" == "yes" ]]
then
trialdecrypt=" -ech_trialdecrypt"
fi
# tell it where CA stuff is...
certsdb=" -CApath $CAPATH"
# handle early data
earlystr=""
if [[ "$EARLY_DATA" == "yes" ]]
then
# if we're debugging and want to use a single session a few
# times then we need -no_anti_replay
earlystr=" -early_data -no_anti_replay "
# if not, then use this...
# earlystr=" -early_data "
fi
# GREASEy retry_configs
greasestr=""
if [[ "$GREASE" == "yes" ]]
then
echo "GREASEing retry_configs"
greasestr=" -ech_greaseretries "
fi
# force tls13
#force13="-no_ssl3 -no_tls1 -no_tls1_1 -no_tls1_2"
#force13="-cipher TLS13-AES-128-GCM-SHA256 -no_ssl3 -no_tls1 -no_tls1_1 -no_tls1_2"
#force13="-tls1_3 -cipher TLS13-AES-128-GCM-SHA256 "
force13="-tls1_3 "
# catch the ctrl-C used to stop the server and do any clean up needed
cleanup() {
echo "Cleaning up after ctrl-c"
if [[ "$BADKEY" == "yes" ]]
then
rm -f $echdir/badkey.pub $echdir/badkey.priv
fi
}
trap cleanup SIGINT
sudocmd=""
if (( PORT < 1000 ))
then
sudocmd="sudo LD_LIBRARY_PATH=$LD_LIBRARY_PATH "
fi
if [[ "$DEBUG" == "yes" ]]
then
echo "Running: $sudocmd $vgcmd $CMDPATH s_server $dbgstr $keyfile1 $keyfile2 $certsdb $portstr $force13 $echstr $snicmd $trialdecrypt $alpn_cmd $echpad_cmd $hrr_cmd $nreq_cmd $WEBSERVER $earlystr $greasestr $@"
fi
$sudocmd $vgcmd $CMDPATH s_server $dbgstr $keyfile1 $keyfile2 $certsdb $portstr $force13 $echstr $snicmd $trialdecrypt $alpn_cmd $echpad_cmd $hrr_cmd $nreq_cmd $WEBSERVER $earlystr $greasestr $@
exit 0