This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,6 @@
-----BEGIN DH PARAMETERS-----
MIGHAoGBAPmqFdDJzIT7OkV3ilTUbNK/vi8uosLWRg6BPoS3JdyUYchJgrXTX1wn
YDOMD64s+5mONvFY4qOMBvdHgWYsppunnZT4UN18QkZeLuWslu12RiDUbI7HY5vY
0NX2NvKfBXVp0lChvM1v9s7N14ID3t7cXlfwu3IaAcs3jgc2ZR9TAgEC
-----END DH PARAMETERS-----

View file

@ -0,0 +1,24 @@
(library
(name testlib)
(modules testlib)
(libraries tls ounit2 mirage-crypto-rng.unix)
(optional))
(test
(name unittestrunner)
(package tls)
(modules readertests readerwritertests writertests unittests unittestrunner)
(libraries tls ounit2 testlib))
(test
(name key_derivation)
(package tls)
(modules key_derivation)
(libraries tls mirage-crypto-rng.unix alcotest logs.fmt))
(test
(name feedback)
(package tls)
(modules feedback)
(deps server.key server.pem)
(libraries tls x509 testlib cmdliner fmt.cli logs.fmt fmt.tty logs.cli))

View file

@ -0,0 +1,134 @@
module Flow = struct
let rewrap_st = function (`S _, st) -> `S st | (`C _, st) -> `C st
let unwrap_st = function `S st -> st | `C st -> st
let can_handle_appdata st =
not (Tls.Engine.handshake_in_progress (unwrap_st st))
let send_application_data state data =
match Tls.Engine.send_application_data (unwrap_st state) data with
| None -> None
| Some (st', cs) -> Some (rewrap_st (state, st'), cs)
let handle_tls ~tag state msg =
let (st, descr) = match state with
| `S st -> (st, "server")
| `C st -> (st, "client")
in
match msg with
| None -> state, None, None
| Some msg ->
match Tls.Engine.handle_tls st msg with
| Ok (_, Some `Eof, _, _) ->
failwith "received eof"
| Ok (st', _eof, `Response (Some ans), `Data appdata) ->
(rewrap_st (state, st'), Some ans, appdata)
| Ok (st', _eof, `Response None, `Data appdata) ->
(rewrap_st (state, st'), None, appdata)
| Error (a, _) ->
failwith @@ Printf.sprintf "[%s] %s error: %s"
tag descr (Tls.Engine.string_of_failure a)
end
let get_ok = function
| Ok cfg -> cfg
| Error `Msg msg -> invalid_arg msg
let loop_chatter ~certificate ~loops ~size =
Printf.eprintf "Looping %d times, %d bytes.\n%!" loops size;
let message = Mirage_crypto_rng.generate size
and server = Tls.(Engine.server (get_ok (Config.server ~certificates:(`Single certificate) ())))
and (client, init) =
let authenticator ?ip:_ ~host:_ _ = Ok None in
Tls.(Engine.client @@ get_ok (Config.client ~authenticator ()))
in
Testlib.time @@ fun () ->
let rec handshake srv cli cli_msg =
let tag = "handshake" in
let (srv, ans, _) = Flow.handle_tls ~tag srv cli_msg in
let (cli, ans, _) = Flow.handle_tls ~tag cli ans in
if Flow.can_handle_appdata cli && Flow.can_handle_appdata srv then (srv, cli) else
handshake srv cli ans
and chat srv cli data = function
| 0 -> data
| n ->
let tag = "chat" in
let simplex sender recv data =
match Flow.send_application_data sender [data] with
| None -> failwith @@ "can't send"
| Some (sender', msg) ->
match Flow.handle_tls ~tag recv (Some msg) with
| (recv', _, Some data') -> (sender', recv', data')
| (_, _, None) -> failwith "expected data"
in
let (cli, srv, data1) = simplex cli srv data in
let (srv, cli, data2) = simplex srv cli data1 in
chat srv cli data2 (pred n)
in
let (srv, cli) = handshake (`S server) (`C client) (Some init) in
let message' = chat srv cli message loops in
if String.equal message message' then Ok ()
else Error "the message got corrupted :("
let string_of_file file =
try
let fh = open_in file in
let content = really_input_string fh (in_channel_length fh) in
close_in_noerr fh;
content
with _ -> invalid_arg "Error reading file"
let load_priv () =
let cert, key =
if Sys.file_exists "./certificates/server.pem" then
"./certificates/server.pem", "./certificates/server.key"
else
"server.pem", "server.key"
in
let cs1 = string_of_file cert
and cs2 = string_of_file key in
match
X509.Certificate.decode_pem_multiple cs1, X509.Private_key.decode_pem cs2
with
| Ok certs, Ok key -> certs, key
| Error (`Msg m), _ -> failwith ("can't parse certificates " ^ m)
| _, Error (`Msg m) -> failwith ("can't parse private key " ^ m)
let jump () loops size =
let certificate = load_priv () in
loop_chatter ~certificate ~loops ~size
let setup_log style_renderer level =
Fmt_tty.setup_std_outputs ?style_renderer ();
Logs.set_level level;
Logs.set_reporter (Logs_fmt.reporter ~dst:Format.std_formatter ())
open Cmdliner
let setup_log =
Term.(const setup_log
$ Fmt_cli.style_renderer ()
$ Logs_cli.level ())
let loops =
let doc = "Number of loops to take" in
Arg.(value & opt int 10 & info ~docv:"LOOPS" ~doc ["loops"])
let size =
let doc = "Bytes to exchange" in
Arg.(value & opt int 1024 & info ~docv:"SIZE" ~doc ["size"])
let cmd =
let term = Term.(const jump $ setup_log $ loops $ size)
and info = Cmd.info "feedback" ~version:"2.0.3"
in
Cmd.v info term
let () = exit (Cmd.eval_result cmd)

View file

@ -0,0 +1,89 @@
#!/bin/sh
port=4455
polarssl="/opt/bin/mbedtls_ssl_client2 auth_mode=none server_port="
extra_args=""
statfile="/tmp/test_server.status"
testit () {
/bin/sh -c "cd .. && ./_build/default/lwt/examples/test_server.exe $port > /dev/null && echo foo > $statfile" &
sleep 0.3
$polarssl$port $extra_args 2> /dev/null > /dev/null
sleep 0.3
if [ -e $statfile ]; then
result=$(cat $statfile)
if [ $result = "foo" ]; then
echo "success with $extra_args"
else
echo "failure with $polarssl$port $extra_args (statfile there)"
exit 1
fi
rm $statfile
else
echo "failure with $polarssl$port $extra_args"
exit 1
fi
sleep 0.3
port=$(expr $port + 1)
}
testit
extra_args="force_version=tls1"
testit
extra_args="force_version=tls1_1"
testit
extra_args="force_version=tls1_2"
testit
ciphers="
TLS-DHE-RSA-WITH-AES-256-CBC-SHA
TLS-DHE-RSA-WITH-AES-128-CBC-SHA
TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA
TLS-RSA-WITH-AES-256-CBC-SHA
TLS-RSA-WITH-AES-128-CBC-SHA
TLS-RSA-WITH-3DES-EDE-CBC-SHA
TLS-RSA-WITH-RC4-128-SHA
TLS-RSA-WITH-RC4-128-MD5"
for i in $ciphers; do
extra_args="force_ciphersuite=$i"
testit
extra_args="force_version=tls1 force_ciphersuite=$i"
testit
extra_args="force_version=tls1_1 force_ciphersuite=$i"
testit
extra_args="force_version=tls1_2 force_ciphersuite=$i"
testit
done
tls12_ciphers="
TLS-DHE-RSA-WITH-AES-256-CCM
TLS-DHE-RSA-WITH-AES-128-CCM
TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
TLS-DHE-RSA-WITH-AES-256-GCM-SHA384
TLS-DHE-RSA-WITH-AES-128-GCM-SHA256
TLS-RSA-WITH-AES-256-CCM
TLS-RSA-WITH-AES-128-CCM
TLS-RSA-WITH-AES-256-CBC-SHA256
TLS-RSA-WITH-AES-128-CBC-SHA256
TLS-RSA-WITH-AES-256-GCM-SHA384
TLS-RSA-WITH-AES-128-GCM-SHA256"
for i in $tls12_ciphers; do
extra_args="force_ciphersuite=$i"
testit
extra_args="force_version=tls1_2 force_ciphersuite=$i"
testit
done

View file

@ -0,0 +1,82 @@
#!/bin/sh
port=4455
s_client_args="s_client -quiet -connect 127.0.0.1:"
extra_args=""
statfile="/tmp/test_server.status"
testit () {
/bin/sh -c "cd ../ && ./_build/default/lwt/examples/test_server.exe $port > /dev/null && echo foo > $statfile" &
sleep 0.3
echo "GET /" | openssl $s_client_args$port $extra_args 2> /dev/null > /dev/null
sleep 0.3
if [ -e $statfile ]; then
result=$(cat $statfile)
if [ $result = "foo" ]; then
echo "success with $extra_args"
else
echo "failure with openssl $s_client_args $extra_args (statfile there)"
exit 1
fi
rm $statfile
else
echo "failure with openssl $s_client_args$port $extra_args (no statfile)"
exit 1
fi
sleep 0.3
port=$(expr $port + 1)
}
testit
extra_args="-tls1"
testit
extra_args="-tls1_1"
testit
extra_args="-tls1_2"
testit
extra_args="-tls1_3"
testit
ciphers="DHE-RSA-AES256-SHA AES256-SHA DHE-RSA-AES128-SHA AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA"
#OpenSSL <1.1.1:
#EDH-RSA-DES-CBC3-SHA DES-CBC3-SHA
for i in $ciphers; do
extra_args="-cipher $i"
testit
extra_args="-tls1 -cipher $i"
testit
extra_args="-tls1_1 -cipher $i"
testit
extra_args="-tls1_2 -cipher $i"
testit
done
tls12_ciphers="DHE-RSA-AES256-SHA256 AES256-SHA256 DHE-RSA-AES128-SHA256 AES128-SHA256 AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-CHACHA20-POLY1305 DHE-RSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-CHACHA20-POLY1305"
for i in $tls12_ciphers; do
extra_args="-cipher $i"
testit
extra_args="-tls1_2 -cipher $i"
testit
done
tls13_ciphers="TLS_AES_256_GCM_SHA384 TLS_AES_128_GCM_SHA256 TLS_CHACHA20_POLY1305_SHA256"
for i in $tls13_ciphers; do
extra_args="-ciphersuites $i"
testit
extra_args="-tls1_3 -ciphersuites $i"
testit
done

View file

@ -0,0 +1,124 @@
#!/bin/sh
s_server_args="s_server -quiet -key ../certificates/server.key -cert ../certificates/server.pem -www -dhparam dh.pem "
pidfile='/tmp/openssl.pid'
extra_args=""
testit () {
/bin/sh -c "echo \$\$ > $pidfile && exec openssl $s_server_args $extra_args" &
sleep 0.3
../_build/default/lwt/examples/test_client.exe > /dev/null
if [ $? -eq 0 ]; then
echo "success with $extra_args"
else
echo "failure with openssl $s_server_args $extra_args"
exit 1
fi
cat $pidfile | xargs kill
rm $pidfile
sleep 0.5
}
testit
extra_args="-tls1"
testit
extra_args="-tls1_1"
testit
extra_args="-tls1_2"
testit
extra_args="-tls1_3"
testit
ciphers="DHE-RSA-AES256-SHA AES256-SHA DHE-RSA-AES128-SHA AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA"
#OpenSSL <1.1.1:
#EDH-RSA-DES-CBC3-SHA DES-CBC3-SHA
for i in $ciphers; do
extra_args="-cipher $i"
testit
extra_args="-tls1 -cipher $i"
testit
extra_args="-tls1_1 -cipher $i"
testit
extra_args="-tls1_2 -cipher $i"
testit
done
tls12_ciphers="DHE-RSA-AES256-SHA256 AES256-SHA256 DHE-RSA-AES128-SHA256 AES128-SHA256 AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-CHACHA20-POLY1305 DHE-RSA-CHACHA20-POLY1305"
for i in $tls12_ciphers; do
extra_args="-cipher $i"
testit
extra_args="-tls1_2 -cipher $i"
testit
done
tls13_ciphers="TLS_AES_256_GCM_SHA384 TLS_AES_128_GCM_SHA256 TLS_CHACHA20_POLY1305_SHA256"
for i in $tls13_ciphers; do
extra_args="-ciphersuites $i"
testit
extra_args="-tls1_3 -ciphersuites $i"
testit
done
s_server_args="s_server -quiet -key ../certificates/server-ec.key -cert ../certificates/server-ec.pem -www -dhparam dh.pem "
ec_ciphers="ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA"
ec_ciphers12="ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-CHACHA20-POLY1305"
extra_args=""
testit
extra_args="-tls1"
testit
extra_args="-tls1_1"
testit
extra_args="-tls1_2"
testit
extra_args="-tls1_3"
testit
for i in $ec_ciphers; do
extra_args="-cipher $i"
testit
extra_args="-tls1 -cipher $i"
testit
extra_args="-tls1_1 -cipher $i"
testit
extra_args="-tls1_2 -cipher $i"
testit
done
for i in $ec_ciphers12; do
extra_args="-cipher $i"
testit
extra_args="-tls1_2 -cipher $i"
testit
done
tls13_ciphers="TLS_AES_256_GCM_SHA384 TLS_AES_128_GCM_SHA256 TLS_CHACHA20_POLY1305_SHA256"
for i in $tls13_ciphers; do
extra_args="-ciphersuites $i"
testit
extra_args="-tls1_3 -ciphersuites $i"
testit
done

View file

@ -0,0 +1,697 @@
(* key derivation example trace taken from draft-ietf-tls-tls13-vectors-07 *)
let cs =
let module M = struct
type t = string
let pp = Ohex.pp_hexdump ()
let equal = String.equal
end in (module M : Alcotest.TESTABLE with type t = M.t)
let secret0 = Ohex.decode {|
33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c e2
10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a
|}
let cipher = `AES_128_GCM_SHA256
let hash = Tls.Ciphersuite.hash13 cipher
let my_secret = ref None
let extract_secret_early () =
(* draft-ietf-tls-tls13-vectors-07 Sec 3*)
let salt = ""
and ikm = String.make 32 '\x00'
in
Alcotest.check cs __LOC__ secret0 (Hkdf.extract ~hash ~salt ikm) ;
let t = Tls.Handshake_crypto13.(derive (empty cipher) ikm) in
my_secret := Some t ;
Alcotest.check cs __LOC__ secret0 t.secret
let expand0 = Ohex.decode {|
6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba b6 97
16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba
|}
let derive_hs_secret () =
let module H = (val Digestif.module_of_hash' hash) in
let hash_val = H.(to_raw_string (digest_string "")) in
Alcotest.check cs __LOC__ expand0
(Tls.Handshake_crypto13.derive_secret_no_hash hash secret0 ~ctx:hash_val "derived")
let hs_secret = Ohex.decode {|
1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b 01
04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
|}
(* TODO: ikm should be computed (ECDHE) from the key share in client hello (see
below), and the private key written in the RFC. *)
let ikm = Ohex.decode {|
8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d
35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d
|}
let extract_handshake () =
Alcotest.check cs __LOC__ hs_secret (Hkdf.extract ~hash ~salt:expand0 ikm) ;
match !my_secret with
| None -> Alcotest.fail "expected some secret"
| Some t ->
let t' = Tls.Handshake_crypto13.derive t ikm in
my_secret := Some t' ;
Alcotest.check cs __LOC__ hs_secret t'.secret
let ch = Ohex.decode {|
01 00 00 c0 03 03 cb 34 ec b1 e7 81 63 ba 1c 38
c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef
62 83 02 4d ec e7 00 00 06 13 01 13 03 13 02 01
00 00 91 00 00 00 0b 00 09 00 00 06 73 65 72 76
65 72 ff 01 00 01 00 00 0a 00 14 00 12 00 1d 00
17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00
23 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d
e5 60 e4 bd 43 d2 3d 8e 43 5a 7d ba fe b3 c0 6e
51 c1 3c ae 4d 54 13 69 1e 52 9a af 2c 00 2b 00
03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01
04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c
00 02 40 01
|}
let sh = Ohex.decode {|
02 00 00 56 03 03 a6 af 06 a4 12 18 60 dc 5e 6e
60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55
77 2e d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24
00 1d 00 20 c9 82 88 76 11 20 95 fe 66 76 2b db
f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1 dd 69 b1 b0
4e 75 1f 0f 00 2b 00 02 03 04
|}
let c_hs_traffic_secret = Ohex.decode {|
b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e 2d 8f
3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21
|}
let read_handshake_key = Ohex.decode {|
db fa a6 93 d1 76 2c 5b 66 6a f5 d9 50 25 8d 01
|}
let read_handshake_iv = Ohex.decode {|
5b d3 c7 1b 83 6e 0b 76 bb 73 26 5f
|}
let derive_c_hs_traffic () =
let log = ch ^ sh in
let hash_val =
let module H = (val Digestif.module_of_hash' hash) in
H.(to_raw_string (digest_string log))
in
Alcotest.check cs __LOC__ c_hs_traffic_secret
(Tls.Handshake_crypto13.derive_secret_no_hash hash hs_secret ~ctx:hash_val "c hs traffic") ;
match !my_secret with
| None -> Alcotest.fail "expected my secret"
| Some t ->
let c_hs_traffic = Tls.Handshake_crypto13.derive_secret t "c hs traffic" log in
Alcotest.check cs __LOC__ c_hs_traffic_secret c_hs_traffic ;
let key, iv = Tls.Handshake_crypto13.traffic_key cipher c_hs_traffic in
Alcotest.check cs __LOC__ read_handshake_key key ;
Alcotest.check cs __LOC__ read_handshake_iv iv
let derive_read_handshake_keys () =
Alcotest.check cs __LOC__ read_handshake_key
(Tls.Handshake_crypto13.derive_secret_no_hash hash c_hs_traffic_secret ~length:16 "key") ;
Alcotest.check cs __LOC__ read_handshake_iv
(Tls.Handshake_crypto13.derive_secret_no_hash hash c_hs_traffic_secret ~length:12 "iv")
let s_hs_traffic_secret = Ohex.decode {|
b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d 37 b4
e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
|}
let write_handshake_key = Ohex.decode {|
3f ce 51 60 09 c2 17 27 d0 f2 e4 e8 6e e4 03 bc
|}
let write_handshake_iv = Ohex.decode {|
5d 31 3e b2 67 12 76 ee 13 00 0b 30
|}
let derive_s_hs_traffic () =
let log = ch ^ sh in
let hash_val =
let module H = (val Digestif.module_of_hash' hash) in
H.(to_raw_string (digest_string log))
in
Alcotest.check cs __LOC__ s_hs_traffic_secret
(Tls.Handshake_crypto13.derive_secret_no_hash hash hs_secret ~ctx:hash_val "s hs traffic") ;
match !my_secret with
| None -> Alcotest.fail "expected my secret"
| Some t ->
let s_hs_traffic = Tls.Handshake_crypto13.derive_secret t "s hs traffic" log in
Alcotest.check cs __LOC__ s_hs_traffic_secret s_hs_traffic ;
let key, iv = Tls.Handshake_crypto13.traffic_key cipher s_hs_traffic in
Alcotest.check cs __LOC__ write_handshake_key key ;
Alcotest.check cs __LOC__ write_handshake_iv iv
let derive_write_handshake_keys () =
Alcotest.check cs __LOC__ write_handshake_key
(Tls.Handshake_crypto13.derive_secret_no_hash hash s_hs_traffic_secret ~length:16 "key") ;
Alcotest.check cs __LOC__ write_handshake_iv
(Tls.Handshake_crypto13.derive_secret_no_hash hash s_hs_traffic_secret ~length:12"iv")
let finished_expanded = Ohex.decode {|
00 8d 3b 66 f8 16 ea 55 9f 96 b5 37 e8 85 c3 1f
c0 68 bf 49 2c 65 2f 01 f2 88 a1 d8 cd c1 9f c8
|}
let finished_key = Ohex.decode {|
9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4 de da
4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07 18
|}
let enc_ext = Ohex.decode {|
08 00 00 24 00 22 00 0a 00 14 00 12 00 1d 00 17
00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 1c
00 02 40 01 00 00 00 00
|}
let cert = Ohex.decode {|
0b 00 01 b9 00 00 01 b5 00 01 b0 30 82 01 ac 30
82 01 15 a0 03 02 01 02 02 01 02 30 0d 06 09 2a
86 48 86 f7 0d 01 01 0b 05 00 30 0e 31 0c 30 0a
06 03 55 04 03 13 03 72 73 61 30 1e 17 0d 31 36
30 37 33 30 30 31 32 33 35 39 5a 17 0d 32 36 30
37 33 30 30 31 32 33 35 39 5a 30 0e 31 0c 30 0a
06 03 55 04 03 13 03 72 73 61 30 81 9f 30 0d 06
09 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00
30 81 89 02 81 81 00 b4 bb 49 8f 82 79 30 3d 98
08 36 39 9b 36 c6 98 8c 0c 68 de 55 e1 bd b8 26
d3 90 1a 24 61 ea fd 2d e4 9a 91 d0 15 ab bc 9a
95 13 7a ce 6c 1a f1 9e aa 6a f9 8c 7c ed 43 12
09 98 e1 87 a8 0e e0 cc b0 52 4b 1b 01 8c 3e 0b
63 26 4d 44 9a 6d 38 e2 2a 5f da 43 08 46 74 80
30 53 0e f0 46 1c 8c a9 d9 ef bf ae 8e a6 d1 d0
3e 2b d1 93 ef f0 ab 9a 80 02 c4 74 28 a6 d3 5a
8d 88 d7 9f 7f 1e 3f 02 03 01 00 01 a3 1a 30 18
30 09 06 03 55 1d 13 04 02 30 00 30 0b 06 03 55
1d 0f 04 04 03 02 05 a0 30 0d 06 09 2a 86 48 86
f7 0d 01 01 0b 05 00 03 81 81 00 85 aa d2 a0 e5
b9 27 6b 90 8c 65 f7 3a 72 67 17 06 18 a5 4c 5f
8a 7b 33 7d 2d f7 a5 94 36 54 17 f2 ea e8 f8 a5
8c 8f 81 72 f9 31 9c f3 6b 7f d6 c5 5b 80 f2 1a
03 01 51 56 72 60 96 fd 33 5e 5e 67 f2 db f1 02
70 2e 60 8c ca e6 be c1 fc 63 a4 2a 99 be 5c 3e
b7 10 7c 3c 54 e9 b9 eb 2b d5 20 3b 1c 3b 84 e0
a8 b2 f7 59 40 9b a3 ea c9 d9 1d 40 2d cc 0c c8
f8 96 12 29 ac 91 87 b4 2b 4d e1 00 00
|}
let cert_verify = Ohex.decode {|
0f 00 00 84 08 04 00 80 5a 74 7c 5d 88 fa 9b d2
e5 5a b0 85 a6 10 15 b7 21 1f 82 4c d4 84 14 5a
b3 ff 52 f1 fd a8 47 7b 0b 7a bc 90 db 78 e2 d3
3a 5c 14 1a 07 86 53 fa 6b ef 78 0c 5e a2 48 ee
aa a7 85 c4 f3 94 ca b6 d3 0b be 8d 48 59 ee 51
1f 60 29 57 b1 54 11 ac 02 76 71 45 9e 46 44 5c
9e a5 8c 18 1e 81 8e 95 b8 c3 fb 0b f3 27 84 09
d3 be 15 2a 3d a5 04 3e 06 3d da 65 cd f5 ae a2
0d 53 df ac d4 2f 74 f3
|}
let derive_finished () =
let log = String.concat "" [ ch ; sh ; enc_ext ; cert ; cert_verify ] in
Alcotest.check cs __LOC__ finished_expanded
(Tls.Handshake_crypto13.derive_secret_no_hash hash s_hs_traffic_secret "finished") ;
let module H = (val Digestif.module_of_hash' hash) in
let hash_val = H.(to_raw_string (digest_string log)) in
Alcotest.check cs __LOC__ finished_key
H.(to_raw_string (hmac_string ~key:finished_expanded hash_val)) ;
match !my_secret with
| None -> Alcotest.fail "expected some secret"
| Some t ->
let s_hs_traffic = Tls.Handshake_crypto13.derive_secret t "s hs traffic" (ch ^ sh) in
Alcotest.check cs __LOC__ s_hs_traffic_secret s_hs_traffic ;
Alcotest.check cs __LOC__ finished_key
(Tls.Handshake_crypto13.finished t.hash s_hs_traffic log)
let finished = Ohex.decode {|
14 00 00 20 9b 9b 14 1d 90 63 37 fb d2 cb dc e7
1d f4 de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54
b7 8f 07 18
|}
let master = Ohex.decode {|
43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25 90 b5
31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4
|}
let derive_master () =
let module H = (val Digestif.module_of_hash' hash) in
let hash_val = H.(to_raw_string (digest_string "")) in
Alcotest.check cs __LOC__ master
(Tls.Handshake_crypto13.derive_secret_no_hash hash hs_secret ~ctx:hash_val "derived")
let master_secret = Ohex.decode {|
18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
|}
let extract_master () =
Alcotest.check cs __LOC__ master_secret (Hkdf.extract ~hash ~salt:master (String.make 32 '\x00')) ;
match !my_secret with
| None -> Alcotest.fail "expected my secret"
| Some t ->
let t' = Tls.Handshake_crypto13.derive t (String.make 32 '\x00') in
my_secret := Some t' ;
Alcotest.check cs __LOC__ master_secret t'.secret
let c_ap_traffic = Ohex.decode {|
9e 40 64 6c e7 9a 7f 9d c0 5a f8 88 9b ce 65 52
87 5a fa 0b 06 df 00 87 f7 92 eb b7 c1 75 04 a5
|}
let s_ap_traffic = Ohex.decode {|
a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9 50 32
82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43
|}
let exp_master = Ohex.decode {|
fe 22 f8 81 17 6e da 18 eb 8f 44 52 9e 67 92 c5
0c 9a 3f 89 45 2f 68 d8 ae 31 1b 43 09 d3 cf 50
|}
let app_write_key = Ohex.decode {|
9f 02 28 3b 6c 9c 07 ef c2 6b b9 f2 ac 92 e3 56
|}
let app_write_iv = Ohex.decode {|
cf 78 2b 88 dd 83 54 9a ad f1 e9 84
|}
let app_read_key = Ohex.decode {|
17 42 2d da 59 6e d5 d9 ac d8 90 e3 c6 3f 50 51
|}
let app_read_iv = Ohex.decode {|
5b 78 92 3d ee 08 57 90 33 e5 23 d9
|}
let derive_traffic_keys () =
let log = String.concat "" [ ch ; sh ; enc_ext ; cert ; cert_verify ; finished ] in
let module H = (val Digestif.module_of_hash' hash) in
let hash_val = H.(to_raw_string (digest_string log)) in
Alcotest.check cs __LOC__ c_ap_traffic
(Tls.Handshake_crypto13.derive_secret_no_hash hash master_secret ~ctx:hash_val "c ap traffic") ;
Alcotest.check cs __LOC__ s_ap_traffic
(Tls.Handshake_crypto13.derive_secret_no_hash hash master_secret ~ctx:hash_val "s ap traffic") ;
Alcotest.check cs __LOC__ exp_master
(Tls.Handshake_crypto13.derive_secret_no_hash hash master_secret ~ctx:hash_val "exp master") ;
match !my_secret with
| None -> Alcotest.fail "expected some secret"
| Some t ->
let c_ap_traffic' = Tls.Handshake_crypto13.derive_secret t "c ap traffic" log in
Alcotest.check cs __LOC__ c_ap_traffic c_ap_traffic' ;
let key, iv = Tls.Handshake_crypto13.traffic_key cipher c_ap_traffic' in
Alcotest.check cs __LOC__ app_read_key key ;
Alcotest.check cs __LOC__ app_read_iv iv ;
let s_ap_traffic' = Tls.Handshake_crypto13.derive_secret t "s ap traffic" log in
Alcotest.check cs __LOC__ s_ap_traffic s_ap_traffic' ;
let key, iv = Tls.Handshake_crypto13.traffic_key cipher s_ap_traffic' in
Alcotest.check cs __LOC__ app_write_key key ;
Alcotest.check cs __LOC__ app_write_iv iv
let appdata_write () =
Alcotest.check cs __LOC__ app_write_key
(Tls.Handshake_crypto13.derive_secret_no_hash hash s_ap_traffic ~length:16 "key") ;
Alcotest.check cs __LOC__ app_write_iv
(Tls.Handshake_crypto13.derive_secret_no_hash hash s_ap_traffic ~length:12 "iv")
let appdata_read () =
Alcotest.check cs __LOC__ app_read_key
(Tls.Handshake_crypto13.derive_secret_no_hash hash c_ap_traffic ~length:16 "key") ;
Alcotest.check cs __LOC__ app_read_iv
(Tls.Handshake_crypto13.derive_secret_no_hash hash c_ap_traffic ~length:12 "iv")
let server_payload = Ohex.decode {|
08 00 00 24 00 22 00 0a 00 14 00 12 00 1d 00 17
00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 1c
00 02 40 01 00 00 00 00 0b 00 01 b9 00 00 01 b5
00 01 b0 30 82 01 ac 30 82 01 15 a0 03 02 01 02
02 01 02 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b
05 00 30 0e 31 0c 30 0a 06 03 55 04 03 13 03 72
73 61 30 1e 17 0d 31 36 30 37 33 30 30 31 32 33
35 39 5a 17 0d 32 36 30 37 33 30 30 31 32 33 35
39 5a 30 0e 31 0c 30 0a 06 03 55 04 03 13 03 72
73 61 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01
01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 b4
bb 49 8f 82 79 30 3d 98 08 36 39 9b 36 c6 98 8c
0c 68 de 55 e1 bd b8 26 d3 90 1a 24 61 ea fd 2d
e4 9a 91 d0 15 ab bc 9a 95 13 7a ce 6c 1a f1 9e
aa 6a f9 8c 7c ed 43 12 09 98 e1 87 a8 0e e0 cc
b0 52 4b 1b 01 8c 3e 0b 63 26 4d 44 9a 6d 38 e2
2a 5f da 43 08 46 74 80 30 53 0e f0 46 1c 8c a9
d9 ef bf ae 8e a6 d1 d0 3e 2b d1 93 ef f0 ab 9a
80 02 c4 74 28 a6 d3 5a 8d 88 d7 9f 7f 1e 3f 02
03 01 00 01 a3 1a 30 18 30 09 06 03 55 1d 13 04
02 30 00 30 0b 06 03 55 1d 0f 04 04 03 02 05 a0
30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03
81 81 00 85 aa d2 a0 e5 b9 27 6b 90 8c 65 f7 3a
72 67 17 06 18 a5 4c 5f 8a 7b 33 7d 2d f7 a5 94
36 54 17 f2 ea e8 f8 a5 8c 8f 81 72 f9 31 9c f3
6b 7f d6 c5 5b 80 f2 1a 03 01 51 56 72 60 96 fd
33 5e 5e 67 f2 db f1 02 70 2e 60 8c ca e6 be c1
fc 63 a4 2a 99 be 5c 3e b7 10 7c 3c 54 e9 b9 eb
2b d5 20 3b 1c 3b 84 e0 a8 b2 f7 59 40 9b a3 ea
c9 d9 1d 40 2d cc 0c c8 f8 96 12 29 ac 91 87 b4
2b 4d e1 00 00 0f 00 00 84 08 04 00 80 5a 74 7c
5d 88 fa 9b d2 e5 5a b0 85 a6 10 15 b7 21 1f 82
4c d4 84 14 5a b3 ff 52 f1 fd a8 47 7b 0b 7a bc
90 db 78 e2 d3 3a 5c 14 1a 07 86 53 fa 6b ef 78
0c 5e a2 48 ee aa a7 85 c4 f3 94 ca b6 d3 0b be
8d 48 59 ee 51 1f 60 29 57 b1 54 11 ac 02 76 71
45 9e 46 44 5c 9e a5 8c 18 1e 81 8e 95 b8 c3 fb
0b f3 27 84 09 d3 be 15 2a 3d a5 04 3e 06 3d da
65 cd f5 ae a2 0d 53 df ac d4 2f 74 f3 14 00 00
20 9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4 de
da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07
18
|}
let payload_is_good () =
Alcotest.check cs __LOC__ server_payload
(String.concat "" [ enc_ext ; cert ; cert_verify ; finished ])
let server_payload_processed = Ohex.decode {|
17 03 03 02 a2 d1 ff 33 4a 56 f5 bf f6 59 4a 07
cc 87 b5 80 23 3f 50 0f 45 e4 89 e7 f3 3a f3 5e
df 78 69 fc f4 0a a4 0a a2 b8 ea 73 f8 48 a7 ca
07 61 2e f9 f9 45 cb 96 0b 40 68 90 51 23 ea 78
b1 11 b4 29 ba 91 91 cd 05 d2 a3 89 28 0f 52 61
34 aa dc 7f c7 8c 4b 72 9d f8 28 b5 ec f7 b1 3b
d9 ae fb 0e 57 f2 71 58 5b 8e a9 bb 35 5c 7c 79
02 07 16 cf b9 b1 18 3e f3 ab 20 e3 7d 57 a6 b9
d7 47 76 09 ae e6 e1 22 a4 cf 51 42 73 25 25 0c
7d 0e 50 92 89 44 4c 9b 3a 64 8f 1d 71 03 5d 2e
d6 5b 0e 3c dd 0c ba e8 bf 2d 0b 22 78 12 cb b3
60 98 72 55 cc 74 41 10 c4 53 ba a4 fc d6 10 92
8d 80 98 10 e4 b7 ed 1a 8f d9 91 f0 6a a6 24 82
04 79 7e 36 a6 a7 3b 70 a2 55 9c 09 ea d6 86 94
5b a2 46 ab 66 e5 ed d8 04 4b 4c 6d e3 fc f2 a8
94 41 ac 66 27 2f d8 fb 33 0e f8 19 05 79 b3 68
45 96 c9 60 bd 59 6e ea 52 0a 56 a8 d6 50 f5 63
aa d2 74 09 96 0d ca 63 d3 e6 88 61 1e a5 e2 2f
44 15 cf 95 38 d5 1a 20 0c 27 03 42 72 96 8a 26
4e d6 54 0c 84 83 8d 89 f7 2c 24 46 1a ad 6d 26
f5 9e ca ba 9a cb bb 31 7b 66 d9 02 f4 f2 92 a3
6a c1 b6 39 c6 37 ce 34 31 17 b6 59 62 22 45 31
7b 49 ee da 0c 62 58 f1 00 d7 d9 61 ff b1 38 64
7e 92 ea 33 0f ae ea 6d fa 31 c7 a8 4d c3 bd 7e
1b 7a 6c 71 78 af 36 87 90 18 e3 f2 52 10 7f 24
3d 24 3d c7 33 9d 56 84 c8 b0 37 8b f3 02 44 da
8c 87 c8 43 f5 e5 6e b4 c5 e8 28 0a 2b 48 05 2c
f9 3b 16 49 9a 66 db 7c ca 71 e4 59 94 26 f7 d4
61 e6 6f 99 88 2b d8 9f c5 08 00 be cc a6 2d 6c
74 11 6d bd 29 72 fd a1 fa 80 f8 5d f8 81 ed be
5a 37 66 89 36 b3 35 58 3b 59 91 86 dc 5c 69 18
a3 96 fa 48 a1 81 d6 b6 fa 4f 9d 62 d5 13 af bb
99 2f 2b 99 2f 67 f8 af e6 7f 76 91 3f a3 88 cb
56 30 c8 ca 01 e0 c6 5d 11 c6 6a 1e 2a c4 c8 59
77 b7 c7 a6 99 9b bf 10 dc 35 ae 69 f5 51 56 14
63 6c 0b 9b 68 c1 9e d2 e3 1c 0b 3b 66 76 30 38
eb ba 42 f3 b3 8e dc 03 99 f3 a9 f2 3f aa 63 97
8c 31 7f c9 fa 66 a7 3f 60 f0 50 4d e9 3b 5b 84
5e 27 55 92 c1 23 35 ee 34 0b bc 4f dd d5 02 78
40 16 e4 b3 be 7e f0 4d da 49 f4 b4 40 a3 0c b5
d2 af 93 98 28 fd 4a e3 79 4e 44 f9 4d f5 a6 31
ed e4 2c 17 19 bf da bf 02 53 fe 51 75 be 89 8e
75 0e dc 53 37 0d 2b
|}
let processed_payload () =
let buf =
let t = String.make 1 (Char.unsafe_chr (Tls.Packet.content_type_to_int Tls.Packet.HANDSHAKE)) in
server_payload ^ t
in
let nonce = Tls.Crypto.aead_nonce write_handshake_iv 0L in
let key = Mirage_crypto.AES.GCM.of_secret write_handshake_key in
let adata = Tls.Writer.assemble_hdr `TLS_1_2 (Tls.Packet.APPLICATION_DATA, "") in
Bytes.set_uint16_be (Bytes.unsafe_of_string adata) 3 (17 + String.length server_payload) ;
let res =
Mirage_crypto.AES.GCM.authenticate_encrypt ~key ~adata ~nonce buf
in
let data = Tls.Writer.assemble_hdr `TLS_1_2 (Tls.Packet.APPLICATION_DATA, res) in
Alcotest.check cs __LOC__ server_payload_processed data
let c_finished = Ohex.decode {|
14 00 00 20 a8 ec 43 6d 67 76 34 ae 52 5a c1 fc
eb e1 1a 03 9e c1 76 94 fa c6 e9 85 27 b6 42 f2
ed d5 ce 61
|}
let res_master = Ohex.decode {|
7d f2 35 f2 03 1d 2a 05 12 87 d0 2b 02 41 b0 bf
da f8 6c c8 56 23 1f 2d 5a ba 46 c4 34 ec 19 6c
|}
let resumption () =
let log = String.concat "" [ ch ; sh ; enc_ext ; cert ; cert_verify ; finished ; c_finished ] in
let module H = (val Digestif.module_of_hash' hash) in
let hash_val = H.(to_raw_string (digest_string log)) in
Alcotest.check cs __LOC__ res_master
(Tls.Handshake_crypto13.derive_secret_no_hash hash master_secret ~ctx:hash_val "res master") ;
match !my_secret with
| None -> Alcotest.fail "expected some secret"
| Some s -> Alcotest.check cs __LOC__ res_master (Tls.Handshake_crypto13.resumption s log)
let private_key =
let _modulus = Ohex.decode {|
b4 bb 49 8f 82 79 30 3d 98 08 36 39 9b 36 c6 98
8c 0c 68 de 55 e1 bd b8 26 d3 90 1a 24 61 ea fd
2d e4 9a 91 d0 15 ab bc 9a 95 13 7a ce 6c 1a f1
9e aa 6a f9 8c 7c ed 43 12 09 98 e1 87 a8 0e e0
cc b0 52 4b 1b 01 8c 3e 0b 63 26 4d 44 9a 6d 38
e2 2a 5f da 43 08 46 74 80 30 53 0e f0 46 1c 8c
a9 d9 ef bf ae 8e a6 d1 d0 3e 2b d1 93 ef f0 ab
9a 80 02 c4 74 28 a6 d3 5a 8d 88 d7 9f 7f 1e 3f
|}
and public_exponent = Ohex.decode "01 00 01"
and _private_exponent = Ohex.decode {|
04 de a7 05 d4 3a 6e a7 20 9d d8 07 21 11 a8 3c
81 e3 22 a5 92 78 b3 34 80 64 1e af 7c 0a 69 85
b8 e3 1c 44 f6 de 62 e1 b4 c2 30 9f 61 26 e7 7b
7c 41 e9 23 31 4b bf a3 88 13 05 dc 12 17 f1 6c
81 9c e5 38 e9 22 f3 69 82 8d 0e 57 19 5d 8c 84
88 46 02 07 b2 fa a7 26 bc f7 08 bb d7 db 7f 67
9f 89 34 92 fc 2a 62 2e 08 97 0a ac 44 1c e4 e0
c3 08 8d f2 5a e6 79 23 3d f8 a3 bd a2 ff 99 41
|}
and prime1 = Ohex.decode {|
e4 35 fb 7c c8 37 37 75 6d ac ea 96 ab 7f 59 a2
cc 10 69 db 7d eb 19 0e 17 e3 3a 53 2b 27 3f 30
a3 27 aa 0a aa bc 58 cd 67 46 6a f9 84 5f ad c6
75 fe 09 4a f9 2c 4b d1 f2 c1 bc 33 dd 2e 05 15
|}
and prime2 = Ohex.decode {|
ca bd 3b c0 e0 43 86 64 c8 d4 cc 9f 99 97 7a 94
d9 bb fe ad 8e 43 87 0a ba e3 f7 eb 8b 4e 0e ee
8a f1 d9 b4 71 9b a6 19 6c f2 cb ba ee eb f8 b3
49 0a fe 9e 9f fa 74 a8 8a a5 1f c6 45 62 93 03
|}
and _exponent1 = Ohex.decode {|
3f 57 34 5c 27 fe 1b 68 7e 6e 76 16 27 b7 8b 1b
82 64 33 dd 76 0f a0 be a6 a6 ac f3 94 90 aa 1b
47 cd a4 86 9d 68 f5 84 dd 5b 50 29 bd 32 09 3b
82 58 66 1f e7 15 02 5e 5d 70 a4 5a 08 d3 d3 19
|}
and _exponent2 = Ohex.decode {|
18 3d a0 13 63 bd 2f 28 85 ca cb dc 99 64 bf 47
64 f1 51 76 36 f8 64 01 28 6f 71 89 3c 52 cc fe
40 a6 c2 3d 0d 08 6b 47 c6 fb 10 d8 fd 10 41 e0
4d ef 7e 9a 40 ce 95 7c 41 77 94 e1 04 12 d1 39
|}
and _coefficient = Ohex.decode {|
83 9c a9 a0 85 e4 28 6b 2c 90 e4 66 99 7a 2c 68
1f 21 33 9a a3 47 78 14 e4 de c1 18 33 05 0e d5
0d d1 3c c0 38 04 8a 43 c5 9b 2a cc 41 68 89 c0
37 66 5f e5 af a6 05 96 9f 8c 01 df a5 ca 96 9d
|}
in
let e = Mirage_crypto_pk.Z_extra.of_octets_be public_exponent
and p = Mirage_crypto_pk.Z_extra.of_octets_be prime1
and q = Mirage_crypto_pk.Z_extra.of_octets_be prime2
in
match Mirage_crypto_pk.Rsa.priv_of_primes ~e ~p ~q with
| Ok p -> p
| Error (`Msg m) -> invalid_arg m
let log = String.concat "" [ ch ; sh ; enc_ext ; cert ]
and cert = match X509.Certificate.decode_der (String.sub cert 11 0x01b0) with
| Ok c -> Some c
| Error _ -> None
let self_signature () =
let module H = (val Digestif.module_of_hash' hash) in
match
Tls.Handshake_common.signature `TLS_1_3
~context_string:"TLS 1.3, server CertificateVerify"
H.(to_raw_string (digest_string log))
(Some [ `RSA_PSS_RSAENC_SHA256 ]) [ `RSA_PSS_RSAENC_SHA256 ]
(`RSA private_key)
with
| Error _ -> Alcotest.fail "expected sth"
| Ok data ->
match Tls.Handshake_common.verify_digitally_signed `TLS_1_3
~context_string:"TLS 1.3, server CertificateVerify"
[ `RSA_PSS_RSAENC_SHA256 ] data
H.(to_raw_string (digest_string log)) cert
with
| Ok () -> ()
| Error e -> Alcotest.fail ("self-verification failed " ^ Tls.Engine.string_of_failure e)
let wire_signature () =
(* let buf = Writer.assemble_handshake (CertificateVerify data) in
Alcotest.check cs __LOC__ cert_verify buf *)
let module H = (val Digestif.module_of_hash' hash) in
match Tls.Handshake_common.verify_digitally_signed `TLS_1_3
~context_string:"TLS 1.3, server CertificateVerify"
[ `RSA_PSS_RSAENC_SHA256 ] (String.sub cert_verify 4 (String.length cert_verify - 4))
H.(to_raw_string (digest_string log)) cert
with
| Ok () -> ()
| Error e -> Alcotest.fail ("trace-verification failed " ^ Tls.Engine.string_of_failure e)
let res_secret_00 = Ohex.decode {|
4e cd 0e b6 ec 3b 4d 87 f5 d6 02 8f 92 2c a4 c5
85 1a 27 7f d4 13 11 c9 e6 2d 2c 94 92 e1 c4 f3
|}
let res_secret () =
let nonce = String.make 2 '\x00' in
Alcotest.check cs __LOC__ res_secret_00
(Tls.Handshake_crypto13.derive_secret_no_hash hash res_master ~ctx:nonce "resumption") ;
Alcotest.check cs __LOC__ res_secret_00
(Tls.Handshake_crypto13.res_secret hash res_master nonce)
let early_secret1 = Ohex.decode {|
9b 21 88 e9 b2 fc 6d 64 d7 1d c3 29 90 0e 20 bb
41 91 50 00 f6 78 aa 83 9c bb 79 7c b7 d8 33 2c
|}
let early1 () =
let salt = ""
and ikm = res_secret_00
in
Alcotest.check cs __LOC__ early_secret1 (Hkdf.extract ~hash ~salt ikm) ;
let t = Tls.Handshake_crypto13.(derive (empty cipher) ikm) in
my_secret := Some t ;
Alcotest.check cs __LOC__ early_secret1 t.secret
let ch_res_prefix = Ohex.decode {|
01 00 01 fc 03 03 1b c3 ce b6 bb e3 9c ff 93 83
55 b5 a5 0a db 6d b2 1b 7a 6a f6 49 d7 b4 bc 41
9d 78 76 48 7d 95 00 00 06 13 01 13 03 13 02 01
00 01 cd 00 00 00 0b 00 09 00 00 06 73 65 72 76
65 72 ff 01 00 01 00 00 0a 00 14 00 12 00 1d 00
17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00
33 00 26 00 24 00 1d 00 20 e4 ff b6 8a c0 5f 8d
96 c9 9d a2 66 98 34 6c 6b e1 64 82 ba dd da fe
05 1a 66 b4 f1 8d 66 8f 0b 00 2a 00 00 00 2b 00
03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01
04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c
00 02 40 01 00 15 00 57 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
29 00 dd 00 b8 00 b2 2c 03 5d 82 93 59 ee 5f f7
af 4e c9 00 00 00 00 26 2a 64 94 dc 48 6d 2c 8a
34 cb 33 fa 90 bf 1b 00 70 ad 3c 49 88 83 c9 36
7c 09 a2 be 78 5a bc 55 cd 22 60 97 a3 a9 82 11
72 83 f8 2a 03 a1 43 ef d3 ff 5d d3 6d 64 e8 61
be 7f d6 1d 28 27 db 27 9c ce 14 50 77 d4 54 a3
66 4d 4e 6d a4 d2 9e e0 37 25 a6 a4 da fc d0 fc
67 d2 ae a7 05 29 51 3e 3d a2 67 7f a5 90 6c 5b
3f 7d 8f 92 f2 28 bd a4 0d da 72 14 70 f9 fb f2
97 b5 ae a6 17 64 6f ac 5c 03 27 2e 97 07 27 c6
21 a7 91 41 ef 5f 7d e6 50 5e 5b fb c3 88 e9 33
43 69 40 93 93 4a e4 d3 57 fa d6 aa cb
|}
let binder () =
let module H = (val Digestif.module_of_hash' hash) in
let binder_hash = Ohex.decode "63 22 4b 2e 45 73 f2 d3 45 4c a8 4b 9d 00 9a 04 f6 be 9e 05 71 1a 83 96 47 3a ef a0 1e 92 4a 14" in
Alcotest.check cs __LOC__ binder_hash H.(to_raw_string (digest_string ch_res_prefix)) ;
match !my_secret with
| None -> Alcotest.fail "expected secret"
| Some s ->
let prk = Ohex.decode "69 fe 13 1a 3b ba d5 d6 3c 64 ee bc c3 0e 39 5b 9d 81 07 72 6a 13 d0 74 e3 89 db c8 a4 e4 72 56" in
Alcotest.check cs __LOC__ prk (Tls.Handshake_crypto13.derive_secret s "res binder" "") ;
let finished = Ohex.decode "3a dd 4f b2 d8 fd f8 22 a0 ca 3c f7 67 8e f5 e8 8d ae 99 01 41 c5 92 4d 57 bb 6f a3 1b 9e 5f 9d" in
Alcotest.check cs __LOC__ finished (Tls.Handshake_crypto13.finished hash prk ch_res_prefix)
let x25519 () =
let c_priv = Ohex.decode {|
49 af 42 ba 7f 79 94 85 2d 71 3e f2 78 4b cb ca
a7 91 1d e2 6a dc 56 42 cb 63 45 40 e7 ea 50 05
|}
and c_keyshare = Ohex.decode {|
99 38 1d e5 60 e4 bd 43 d2 3d 8e 43 5a 7d ba fe
b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af 2c
|}
and s_priv = Ohex.decode {|
b1 58 0e ea df 6d d5 89 b8 ef 4f 2d 56 52 57 8c
c8 10 e9 98 01 91 ec 8d 05 83 08 ce a2 16 a2 1e
|}
and s_keyshare = Ohex.decode {|
c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6 72 e1
56 d6 cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f
|}
in
let check_pub pr pu =
match Mirage_crypto_ec.X25519.secret_of_octets pr with
| Ok (_, pub) -> Alcotest.check cs __LOC__ pu pub
| Error _ -> Alcotest.fail "couldn't decode DH secret"
in
let check_one p ks =
match Mirage_crypto_ec.X25519.secret_of_octets p with
| Error _ -> Alcotest.fail "couldn't decode DH secret"
| Ok (priv, _) ->
match Mirage_crypto_ec.X25519.key_exchange priv ks with
| Ok shared -> Alcotest.check cs __LOC__ ikm shared
| Error _ -> Alcotest.fail "bad kex"
in
check_one c_priv s_keyshare ;
check_one s_priv c_keyshare ;
check_pub c_priv c_keyshare ;
check_pub s_priv s_keyshare
let tests = [
"initial extract", `Quick, extract_secret_early ;
"initial derive", `Quick, derive_hs_secret ;
"handshake extract", `Quick, extract_handshake ;
"derive c hs", `Quick, derive_c_hs_traffic ;
"derive s hs", `Quick, derive_s_hs_traffic ;
"derive finished", `Quick, derive_finished ;
"derive master", `Quick, derive_master ;
"extract master", `Quick, extract_master ;
"derive handshake keys", `Quick, derive_write_handshake_keys ;
"derive traffic keys", `Quick, derive_traffic_keys ;
"application write keys", `Quick, appdata_write ;
"application read keys", `Quick, appdata_read ;
"hs read keys", `Quick, derive_read_handshake_keys ;
"resumption key", `Quick, resumption ;
"payload", `Quick, payload_is_good ;
"processed payload", `Quick, processed_payload ;
"self signature", `Quick, self_signature ;
"wire signature", `Quick, wire_signature ;
"res secret", `Quick, res_secret ;
"early resumed", `Quick, early1 ;
"binder", `Quick, binder ;
"x25519", `Quick, x25519 ;
]
let () =
Fmt_tty.setup_std_outputs ();
Logs.set_level (Some Logs.Debug);
Logs.set_reporter (Logs_fmt.reporter ~dst:Format.std_formatter ()) ;
Mirage_crypto_rng_unix.use_default () ;
Alcotest.run "Key derivation tests" [ "key extraction and derivation", tests ]

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,439 @@
open Tls
open OUnit2
open Testlib
let readerwriter_version v _ =
let buf = Writer.assemble_protocol_version v in
match Reader.parse_version buf with
| Ok ver ->
assert_equal v ver ;
(* lets get crazy and do it one more time *)
let buf' = Writer.assemble_protocol_version v in
(match Reader.parse_version buf' with
| Ok ver' -> assert_equal v ver'
| Error _ -> assert_failure "read and write version broken")
| Error _ -> assert_failure "read and write version broken"
let version_tests =
[ "ReadWrite version TLS-1.0" >:: readerwriter_version `TLS_1_0 ;
"ReadWrite version TLS-1.1" >:: readerwriter_version `TLS_1_1 ;
"ReadWrite version TLS-1.2" >:: readerwriter_version `TLS_1_2 ]
let readerwriter_header (v, ct, cs) _ =
let buf = Writer.assemble_hdr v (ct, cs) in
match Reader.parse_record buf with
| Ok (`Record ((hdr, payload), f)) ->
let open Core in
assert_equal 0 (String.length f) ;
assert_equal (v :> tls_any_version) hdr.version ;
assert_equal ct hdr.content_type ;
assert_cs_eq cs payload ;
let buf' = Writer.assemble_hdr v (hdr.content_type, payload) in
(match Reader.parse_record buf' with
| Ok (`Record ((hdr, payload), f)) ->
assert_equal 0 (String.length f) ;
assert_equal (v :> tls_any_version) hdr.version ;
assert_equal ct hdr.content_type ;
assert_cs_eq cs payload ;
| _ -> assert_failure "inner header broken")
| _ -> assert_failure "header broken"
let header_tests =
let a = list_to_cstruct [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 ] in
[ "ReadWrite header" >:: readerwriter_header (`TLS_1_0, Packet.HANDSHAKE, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_1, Packet.HANDSHAKE, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_2, Packet.HANDSHAKE, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_0, Packet.APPLICATION_DATA, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_1, Packet.APPLICATION_DATA, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_2, Packet.APPLICATION_DATA, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_0, Packet.CHANGE_CIPHER_SPEC, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_1, Packet.CHANGE_CIPHER_SPEC, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_2, Packet.CHANGE_CIPHER_SPEC, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_0, Packet.ALERT, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_1, Packet.ALERT, a) ;
"ReadWrite header" >:: readerwriter_header (`TLS_1_2, Packet.ALERT, a) ;
]
let readerwriter_alert (lvl, typ) _ =
let buf, expl = match lvl with
| None -> (Writer.assemble_alert typ, Packet.FATAL)
| Some l -> (Writer.assemble_alert ~level:l typ, l)
in
(match Reader.parse_alert buf with
| Ok (l', t') ->
assert_equal expl l' ;
assert_equal typ t' ;
(* lets get crazy and do it one more time *)
let buf' = Writer.assemble_alert ~level:l' t' in
(match Reader.parse_alert buf' with
| Ok (l'', t'') -> assert_equal expl l'' ; assert_equal typ t''
| Error _ -> assert_failure "inner read and write alert broken")
| Error _ -> assert_failure "read and write alert broken")
let rw_alert_tests = Packet.([
( None, CLOSE_NOTIFY ) ;
( None, UNEXPECTED_MESSAGE ) ;
( None, BAD_RECORD_MAC ) ;
( None, RECORD_OVERFLOW ) ;
( None, HANDSHAKE_FAILURE ) ;
( None, BAD_CERTIFICATE ) ;
( None, CERTIFICATE_EXPIRED ) ;
( None, DECODE_ERROR ) ;
( None, PROTOCOL_VERSION ) ;
( None, UNSUPPORTED_EXTENSION ) ;
( None, UNRECOGNIZED_NAME ) ;
( None, NO_APPLICATION_PROTOCOL ) ;
( Some FATAL, CLOSE_NOTIFY ) ;
( Some FATAL, UNEXPECTED_MESSAGE ) ;
( Some FATAL, BAD_RECORD_MAC ) ;
( Some FATAL, RECORD_OVERFLOW ) ;
( Some FATAL, HANDSHAKE_FAILURE ) ;
( Some FATAL, BAD_CERTIFICATE ) ;
( Some FATAL, CERTIFICATE_EXPIRED ) ;
( Some FATAL, DECODE_ERROR ) ;
( Some FATAL, PROTOCOL_VERSION ) ;
( Some FATAL, UNSUPPORTED_EXTENSION ) ;
( Some FATAL, UNRECOGNIZED_NAME ) ;
( Some FATAL, NO_APPLICATION_PROTOCOL ) ;
( Some WARNING, CLOSE_NOTIFY ) ;
(* ( Some WARNING, UNEXPECTED_MESSAGE ) ;
( Some WARNING, BAD_RECORD_MAC ) ;
( Some WARNING, DECRYPTION_FAILED ) ;
( Some WARNING, RECORD_OVERFLOW ) ;
( Some WARNING, DECOMPRESSION_FAILURE ) ;
( Some WARNING, HANDSHAKE_FAILURE ) ; *)
( Some FATAL, BAD_CERTIFICATE ) ;
( Some FATAL, CERTIFICATE_EXPIRED ) ;
(* ( Some WARNING, UNKNOWN_CA ) ;
( Some WARNING, ACCESS_DENIED ) ;
( Some WARNING, DECODE_ERROR ) ;
( Some WARNING, DECRYPT_ERROR ) ; *)
(* ( Some WARNING, PROTOCOL_VERSION ) ;
( Some WARNING, INSUFFICIENT_SECURITY ) ;
( Some WARNING, INTERNAL_ERROR ) ; *)
( Some WARNING, USER_CANCELED ) ;
( Some WARNING, NO_RENEGOTIATION ) ;
(* ( Some WARNING, UNSUPPORTED_EXTENSION ) ; *)
( Some FATAL, UNRECOGNIZED_NAME ) ;
])
let rw_alert_tests =
List.mapi
(fun i f -> "RW alert " ^ string_of_int i >:: readerwriter_alert f)
rw_alert_tests
let assert_dh_eq a b =
Core.(assert_cs_eq a.dh_p b.dh_p) ;
Core.(assert_cs_eq a.dh_g b.dh_g) ;
Core.(assert_cs_eq a.dh_Ys b.dh_Ys)
let readerwriter_dh_params params _ =
let buf = Writer.assemble_dh_parameters params in
match Reader.parse_dh_parameters buf with
| Ok (p, raw, rst) ->
assert_equal (String.length rst) 0 ;
assert_dh_eq p params ;
assert_equal buf raw ;
(* lets get crazy and do it one more time *)
let buf' = Writer.assemble_dh_parameters p in
(match Reader.parse_dh_parameters buf' with
| Ok (p', raw', rst') ->
assert_equal (String.length rst') 0 ;
assert_dh_eq p' params ;
assert_equal buf raw' ;
| Error _ -> assert_failure "inner read and write dh params broken")
| Error _ -> assert_failure "read and write dh params broken"
let rw_dh_params =
let a = list_to_cstruct [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 ] in
let emp = list_to_cstruct [] in
Core.([
{ dh_p = emp ; dh_g = emp ; dh_Ys = emp } ;
{ dh_p = a ; dh_g = emp ; dh_Ys = emp } ;
{ dh_p = emp ; dh_g = a ; dh_Ys = emp } ;
{ dh_p = emp ; dh_g = emp ; dh_Ys = a } ;
{ dh_p = a ^ a ; dh_g = a ^ a ; dh_Ys = a ^ a } ;
])
let rw_dh_tests =
List.mapi
(fun i f -> "RW dh_param " ^ string_of_int i >:: readerwriter_dh_params f)
rw_dh_params
let readerwriter_digitally_signed params _ =
let buf = Writer.assemble_digitally_signed params in
match Reader.parse_digitally_signed buf with
| Ok params' ->
assert_cs_eq params params' ;
(* lets get crazy and do it one more time *)
let buf' = Writer.assemble_digitally_signed params' in
(match Reader.parse_digitally_signed buf' with
| Ok params'' -> assert_cs_eq params params''
| Error _ -> assert_failure "inner read and write digitally signed broken")
| Error _ -> assert_failure "read and write digitally signed broken"
let rw_ds_params =
let a = list_to_cstruct [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 ] in
let emp = list_to_cstruct [] in
[ a ; a ^ a ; emp ; emp ^ a ]
let rw_ds_tests =
List.mapi
(fun i f -> "RW digitally signed " ^ string_of_int i >:: readerwriter_digitally_signed f)
rw_ds_params
let readerwriter_digitally_signed_1_2 (sigalg, params) _ =
let buf = Writer.assemble_digitally_signed_1_2 sigalg params in
match Reader.parse_digitally_signed_1_2 buf with
| Ok (sigalg', params') ->
assert_equal sigalg sigalg' ;
assert_cs_eq params params' ;
(* lets get crazy and do it one more time *)
let buf' = Writer.assemble_digitally_signed_1_2 sigalg' params' in
(match Reader.parse_digitally_signed_1_2 buf' with
| Ok (sigalg'', params'') ->
assert_equal sigalg sigalg'' ;
assert_cs_eq params params''
| Error _ -> assert_failure "inner read and write digitally signed 1.2 broken")
| Error _ -> assert_failure "read and write digitally signed 1.2 broken"
let rec cartesian_product f a b =
match b with
| [] -> []
| e::rt -> (List.map (fun x -> f x e) a) @ (cartesian_product f a rt)
let rw_ds_1_2_params =
let a = list_to_cstruct [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 ] in
let emp = list_to_cstruct [] in
let cs = [ a ; a ^ a ; emp ; emp ^ a ] in
let sig_algs = [
`RSA_PKCS1_MD5 ; `RSA_PKCS1_SHA1 ; `RSA_PKCS1_SHA224 ; `RSA_PKCS1_SHA256 ;
`RSA_PKCS1_SHA384 ; `RSA_PKCS1_SHA512 ;
`RSA_PSS_RSAENC_SHA256 ; `RSA_PSS_RSAENC_SHA384 ; `RSA_PSS_RSAENC_SHA512
] in
cartesian_product (fun sigalg c -> (sigalg, c)) sig_algs cs
let rw_ds_1_2_tests =
List.mapi
(fun i f -> "RW digitally signed 1.2 " ^ string_of_int i >:: readerwriter_digitally_signed_1_2 f)
rw_ds_1_2_params
let rw_handshake_no_data hs _ =
let buf = Writer.assemble_handshake hs in
match Reader.parse_handshake buf with
| Ok hs' ->
assert_equal hs hs' ;
(* lets get crazy and do it one more time *)
let buf' = Writer.assemble_handshake hs' in
(match Reader.parse_handshake buf' with
| Ok hs'' -> assert_equal hs hs''
| Error _ -> assert_failure "handshake no data inner failed")
| Error _ -> assert_failure "handshake no data failed"
let rw_handshakes_no_data_vals = [ Core.HelloRequest ; Core.ServerHelloDone ]
let rw_handshake_no_data_tests =
List.mapi
(fun i f -> "handshake no data " ^ string_of_int i >:: rw_handshake_no_data f)
rw_handshakes_no_data_vals
let rw_handshake_cstruct_data hs _ =
let buf = Writer.assemble_handshake hs in
match Reader.parse_handshake buf with
| Ok hs' ->
Readertests.cmp_handshake_cstruct hs hs' ;
(* lets get crazy and do it one more time *)
let buf' = Writer.assemble_handshake hs' in
(match Reader.parse_handshake buf' with
| Ok hs'' -> Readertests.cmp_handshake_cstruct hs hs''
| Error _ -> assert_failure "handshake cstruct data inner failed")
| Error _ -> assert_failure "handshake cstruct data failed"
let rw_handshake_cstruct_data_vals =
let data_cs = list_to_cstruct [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11 ] in
let emp = list_to_cstruct [ ] in
Core.([ ServerKeyExchange emp ;
ServerKeyExchange data_cs ;
Finished emp ;
Finished data_cs ;
ClientKeyExchange emp ;
ClientKeyExchange data_cs ;
Certificate (Writer.assemble_certificates []) ;
Certificate (Writer.assemble_certificates [data_cs]) ;
Certificate (Writer.assemble_certificates [data_cs; data_cs]) ;
Certificate (Writer.assemble_certificates [data_cs ; emp]) ;
Certificate (Writer.assemble_certificates [emp ; data_cs]) ;
Certificate (Writer.assemble_certificates [emp ; data_cs ; emp]) ;
Certificate (Writer.assemble_certificates [emp ; data_cs ; emp ; data_cs])
])
let rw_handshake_cstruct_data_tests =
List.mapi
(fun i f -> "handshake cstruct data " ^ string_of_int i >:: rw_handshake_cstruct_data f)
rw_handshake_cstruct_data_vals
let rw_handshake_client_hello hs _ =
let buf = Writer.assemble_handshake hs in
match Reader.parse_handshake buf with
| Ok hs' ->
Core.(match hs, hs' with
| ClientHello ch, ClientHello ch' ->
Readertests.cmp_client_hellos ch ch' ;
| _ -> assert_failure "handshake client hello broken") ;
(* lets get crazy and do it one more time *)
let buf' = Writer.assemble_handshake hs' in
(match Reader.parse_handshake buf' with
| Ok hs'' ->
Core.(match hs, hs'' with
| ClientHello ch, ClientHello ch'' ->
Readertests.cmp_client_hellos ch ch'' ;
| _ -> assert_failure "handshake client hello broken")
| Error _ -> assert_failure "handshake client hello inner failed")
| Error _ -> assert_failure "handshake client hello failed"
let rw_handshake_client_hello_vals =
let rnd = [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 ] in
let client_random = list_to_cstruct (rnd @ rnd) in
Core.(let ch : client_hello =
{ client_version = `TLS_1_2 ;
client_random ;
sessionid = None ;
ciphersuites = [] ;
extensions = []}
in
[
ClientHello ch ;
ClientHello { ch with client_version = `TLS_1_0 } ;
ClientHello { ch with client_version = `TLS_1_1 } ;
ClientHello { ch with ciphersuites = [ Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA ] } ;
ClientHello { ch with ciphersuites = Packet.([ TLS_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_RSA_WITH_AES_256_CBC_SHA ]) } ;
ClientHello { ch with sessionid = (Some (list_to_cstruct rnd)) } ;
ClientHello { ch with sessionid = (Some client_random) } ;
ClientHello { ch with
ciphersuites = Packet.([ TLS_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_RSA_WITH_AES_256_CBC_SHA ]) ;
sessionid = (Some client_random) } ;
ClientHello { ch with extensions = [ make_hostname_ext "foobar" ] } ;
ClientHello { ch with extensions = [ make_hostname_ext "foobarblubb" ] } ;
ClientHello { ch with extensions = [ make_hostname_ext "foobarblubb" ; `SupportedGroups Packet.([SECP521R1; SECP384R1]) ] } ;
ClientHello { ch with extensions = [ `ALPN ["h2"; "http/1.1"] ] } ;
ClientHello { ch with extensions = [
make_hostname_ext "foobarblubb" ;
`SupportedGroups Packet.([SECP521R1; SECP384R1]) ;
`SignatureAlgorithms [`RSA_PKCS1_MD5] ;
`ALPN ["h2"; "http/1.1"]
] } ;
ClientHello { ch with
ciphersuites = Packet.([ TLS_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_RSA_WITH_AES_256_CBC_SHA ]) ;
sessionid = (Some client_random) ;
extensions = [ make_hostname_ext "foobarblubb" ] } ;
ClientHello { ch with
ciphersuites = Packet.([ TLS_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_RSA_WITH_AES_256_CBC_SHA ]) ;
sessionid = (Some client_random) ;
extensions = [
make_hostname_ext "foobarblubb" ;
`SupportedGroups Packet.([SECP521R1; SECP384R1]) ;
`SignatureAlgorithms [`RSA_PKCS1_SHA1; `RSA_PKCS1_SHA512] ;
`ALPN ["h2"; "http/1.1"]
] } ;
ClientHello { ch with
ciphersuites = Packet.([ TLS_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_RSA_WITH_AES_256_CBC_SHA ]) ;
sessionid = (Some client_random) ;
extensions = [
make_hostname_ext "foobarblubb" ;
`SupportedGroups Packet.([SECP521R1; SECP384R1]) ;
`SignatureAlgorithms [`RSA_PKCS1_MD5; `RSA_PKCS1_SHA256] ;
`SecureRenegotiation client_random ;
`ALPN ["h2"; "http/1.1"]
] } ;
])
let rw_handshake_client_hello_tests =
List.mapi
(fun i f -> "handshake client hello " ^ string_of_int i >:: rw_handshake_client_hello f)
rw_handshake_client_hello_vals
let rw_handshake_server_hello hs _ =
let buf = Writer.assemble_handshake hs in
(match Reader.parse_handshake buf with
| Ok hs' ->
Core.(match hs, hs' with
| ServerHello sh, ServerHello sh' ->
Readertests.cmp_server_hellos sh sh' ;
| _ -> assert_failure "handshake server hello broken") ;
(* lets get crazy and do it one more time *)
let buf' = Writer.assemble_handshake hs' in
(match Reader.parse_handshake buf' with
| Ok hs'' ->
Core.(match hs, hs'' with
| ServerHello sh, ServerHello sh'' ->
Readertests.cmp_server_hellos sh sh'' ;
| _ -> assert_failure "handshake server hello broken")
| Error _ -> assert_failure "handshake server hello inner failed")
| Error _ -> assert_failure "handshake server hello failed")
let rw_handshake_server_hello_vals =
let rnd = [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 ] in
let server_random = list_to_cstruct (rnd @ rnd) in
Core.(let sh : server_hello =
{ server_version = `TLS_1_2 ;
server_random ;
sessionid = None ;
ciphersuite = `RSA_WITH_AES_256_CCM ;
extensions = []}
in
[
ServerHello sh ;
ServerHello { sh with server_version = `TLS_1_0 } ;
ServerHello { sh with server_version = `TLS_1_1 } ;
ServerHello { sh with sessionid = (Some server_random) } ;
ServerHello { sh with
sessionid = (Some server_random) ;
extensions = [`Hostname]
} ;
ServerHello { sh with
sessionid = (Some server_random) ;
extensions = [`Hostname ; `SecureRenegotiation server_random]
} ;
ServerHello { sh with
sessionid = (Some server_random) ;
extensions = [`Hostname ; `SecureRenegotiation server_random ; `ALPN "h2"]
} ;
])
let rw_handshake_server_hello_tests =
List.mapi
(fun i f -> "handshake server hello " ^ string_of_int i >:: rw_handshake_server_hello f)
rw_handshake_server_hello_vals
let readerwriter_tests =
version_tests @
header_tests @
rw_alert_tests @
rw_dh_tests @
rw_ds_tests @
rw_ds_1_2_tests @
rw_handshake_no_data_tests @
rw_handshake_cstruct_data_tests @
rw_handshake_client_hello_tests @
rw_handshake_server_hello_tests

View file

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC2QEje5rwhlD2iq162+Ng3AH9BfA/jNJLDqi9VPk1eMUNGicJv
K+aOANKIsOOr9v4RiEXZSYmFEvGSy+Sf1bCDHwHLLSdNs6Y49b77POgatrVZOTRE
BE/t1soVT3a/vVJWCLtVCjm70u0S5tcfn4S6IapeIYAVAmcaqwSa+GQNoQIDAQAB
AoGAd/CShG8g/JBMh9Nz/8KAuKHRHc2BvysIM1C62cSosgaFmdRrazJfBrEv3Nlc
2/0uc2dVYIxuvm8bIFqi2TWOdX9jWJf6oXwEPXCD0SaDbJTaoh0b+wjyHuaGlttY
Ztvmf8mK1BOhyl3vNMxh/8Re0dGvGgPZHpn8zanaqfGVz+ECQQDngieUpwzxA0QZ
GZKRYhHoLEaPiQzBaXphqWcCLLN7oAKxZlUCUckxRRe0tKINf0cB3Kr9gGQjPpm0
YoqXo8mNAkEAyYgdd+JDi9FH3Cz6ijvPU0hYkriwTii0V09+Ar5DvYQNzNEIEJu8
Q3Yte/TPRuK8zhnp97Bsy9v/Ji/LSWbtZQJBAJe9y8u3otfmWCBLjrIUIcCYJLe4
ENBFHp4ctxPJ0Ora+mjkthuLF+BfdSZQr1dBcX1a8giuuvQO+Bgv7r9t75ECQC7F
omEyaA7JEW5uGe9/Fgz0G2ph5rkdBU3GKy6jzcDsJu/EC6UfH8Bgawn7tSd0c/E5
Xm2Xyog9lKfeK8XrV2kCQQCTico5lQPjfIwjhvn45ALc/0OrkaK0hQNpXgUNFJFQ
tuX2WMD5flMyA5PCx5XBU8gEMHYa8Kr5d6uoixnbS0cZ
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICYzCCAcwCCQDLbE6ES1ih1DANBgkqhkiG9w0BAQUFADB2MQswCQYDVQQGEwJB
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMRUwEwYDVQQDDAxZT1VSIE5BTUUhISExGDAWBgkqhkiG9w0BCQEW
CW1lQGJhci5kZTAeFw0xNDAyMTcyMjA4NDVaFw0xNTAyMTcyMjA4NDVaMHYxCzAJ
BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
dCBXaWRnaXRzIFB0eSBMdGQxFTATBgNVBAMMDFlPVVIgTkFNRSEhITEYMBYGCSqG
SIb3DQEJARYJbWVAYmFyLmRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2
QEje5rwhlD2iq162+Ng3AH9BfA/jNJLDqi9VPk1eMUNGicJvK+aOANKIsOOr9v4R
iEXZSYmFEvGSy+Sf1bCDHwHLLSdNs6Y49b77POgatrVZOTREBE/t1soVT3a/vVJW
CLtVCjm70u0S5tcfn4S6IapeIYAVAmcaqwSa+GQNoQIDAQABMA0GCSqGSIb3DQEB
BQUAA4GBAIo4ZppIlp3JRyltRC1/AyCC0tsh5TdM3W7258wdoP3lEe08UlLwpnPc
aJ/cX8rMG4Xf4it77yrbVrU3MumBEGN5TW4jn4+iZyFbp6TT3OUF55nsXDjNHBbu
deDVpGuPTI6CZQVhU5qEMF3xmlokG+VV+HCDTglNQc+fdLM0LoNF
-----END CERTIFICATE-----

View file

@ -0,0 +1,65 @@
open OUnit2
let () = Mirage_crypto_rng_unix.use_default ()
let time f =
let t1 = Sys.time () in
let r = f () in
let t2 = Sys.time () in
( Printf.eprintf "[time] %f.04 s\n%!" (t2 -. t1) ; r )
let list_to_cstruct xs =
let buf = Bytes.create (List.length xs) in
List.iteri (Bytes.set_uint8 buf) xs ;
Bytes.unsafe_to_string buf
let uint16_to_cstruct i =
let buf = Bytes.create 2 in
Bytes.set_uint16_be buf 0 i;
buf
let hexdump_to_str cs =
Ohex.encode cs
let assert_cs_eq ?msg cs1 cs2 =
assert_equal
~cmp:String.equal
~printer:hexdump_to_str
?msg
cs1 cs2
let rec assert_lists_eq comparison a b =
match a, b with
| [], [] -> ()
| a::r1, b::r2 -> comparison a b ; assert_lists_eq comparison r1 r2
| _ -> assert_failure "lists not equal"
let assert_sessionid_equal a b =
match a, b with
| None, None -> ()
| Some x, Some y -> assert_cs_eq x y
| _ -> assert_failure "session id not equal"
let assert_client_extension_equal a b =
match a, b with
| `Hostname a, `Hostname b -> assert_equal a b
| `MaxFragmentLength a, `MaxFragmentLength b -> assert_equal a b
| `SupportedGroups a, `SupportedGroups b -> assert_lists_eq assert_equal a b
| `SecureRenegotiation a, `SecureRenegotiation b -> assert_cs_eq a b
| `Padding a, `Padding b -> assert_equal a b
| `SignatureAlgorithms a, `SignatureAlgorithms b ->
assert_lists_eq (fun sa sa' -> assert_equal sa sa') a b
| `ALPN a, `ALPN b -> assert_lists_eq assert_equal a b
| _ -> assert_failure "extensions did not match"
let assert_server_extension_equal a b =
match a, b with
| `Hostname, `Hostname -> ()
| `MaxFragmentLength a, `MaxFragmentLength b -> assert_equal a b
| `SecureRenegotiation a, `SecureRenegotiation b -> assert_cs_eq a b
| `ALPN a, `ALPN b -> assert_equal a b
| _ -> assert_failure "extensions did not match"
let make_hostname_ext h =
(`Hostname (Domain_name.of_string_exn h |> Domain_name.host_exn))

View file

@ -0,0 +1,3 @@
open OUnit2
let () = run_test_tt_main Unittests.suite

View file

@ -0,0 +1,8 @@
open OUnit2
let suite =
"All" >::: [
"Reader" >::: Readertests.reader_tests ;
"Writer" >::: Writertests.writer_tests ;
"ReaderWriter" >::: Readerwritertests.readerwriter_tests ;
]

View file

@ -0,0 +1,441 @@
open OUnit2
open Tls
open Testlib
let version_assembler (ver, res) _ =
let buf = Writer.assemble_protocol_version ver in
assert_cs_eq buf res
let version_assembler_tests = [
(`TLS_1_0, list_to_cstruct [3; 1]) ;
(`TLS_1_1, list_to_cstruct [3; 2]) ;
(`TLS_1_2, list_to_cstruct [3; 3]) ;
]
let version_tests =
List.mapi
(fun i f -> "Assemble version " ^ string_of_int i >:: version_assembler f)
version_assembler_tests
let hdr_assembler (ver, ct, cs, res) _ =
let buf = Writer.assemble_hdr ver (ct, (list_to_cstruct cs)) in
let res' = list_to_cstruct res in
assert_cs_eq buf res'
let hdr_assembler_tests = [
(`TLS_1_2, Packet.CHANGE_CIPHER_SPEC, [], [20; 3; 3; 0; 0]) ;
(`TLS_1_1, Packet.CHANGE_CIPHER_SPEC, [], [20; 3; 2; 0; 0]) ;
(`TLS_1_0, Packet.CHANGE_CIPHER_SPEC, [], [20; 3; 1; 0; 0]) ;
(`TLS_1_2, Packet.CHANGE_CIPHER_SPEC, [0; 0; 0], [20; 3; 3; 0; 3; 0; 0; 0]) ;
(`TLS_1_2, Packet.ALERT, [], [21; 3; 3; 0; 0]) ;
(`TLS_1_1, Packet.ALERT, [], [21; 3; 2; 0; 0]) ;
(`TLS_1_0, Packet.ALERT, [], [21; 3; 1; 0; 0]) ;
(`TLS_1_2, Packet.ALERT, [0; 0; 0], [21; 3; 3; 0; 3; 0; 0; 0]) ;
(`TLS_1_2, Packet.HANDSHAKE, [], [22; 3; 3; 0; 0]) ;
(`TLS_1_1, Packet.HANDSHAKE, [], [22; 3; 2; 0; 0]) ;
(`TLS_1_0, Packet.HANDSHAKE, [], [22; 3; 1; 0; 0]) ;
(`TLS_1_2, Packet.HANDSHAKE, [0; 0; 0], [22; 3; 3; 0; 3; 0; 0; 0]) ;
(`TLS_1_2, Packet.APPLICATION_DATA, [], [23; 3; 3; 0; 0]) ;
(`TLS_1_1, Packet.APPLICATION_DATA, [], [23; 3; 2; 0; 0]) ;
(`TLS_1_0, Packet.APPLICATION_DATA, [], [23; 3; 1; 0; 0]) ;
(`TLS_1_2, Packet.APPLICATION_DATA, [0; 0; 0], [23; 3; 3; 0; 3; 0; 0; 0]) ;
]
let hdr_tests =
List.mapi
(fun i f -> "Assemble header " ^ string_of_int i >:: hdr_assembler f)
hdr_assembler_tests
let alert_assembler (level, t, res) _ =
let buf = match level with
| None -> Writer.assemble_alert t
| Some l -> Writer.assemble_alert ~level:l t
in
let res' = list_to_cstruct res in
assert_cs_eq buf res'
let alert_assembler_tests = Packet.([
( None, CLOSE_NOTIFY , [ 2 ; 0; ] ) ;
( None, UNEXPECTED_MESSAGE , [ 2 ; 10; ] ) ;
( None, BAD_RECORD_MAC , [ 2 ; 20; ] ) ;
( None, RECORD_OVERFLOW , [ 2 ; 22; ] ) ;
( None, HANDSHAKE_FAILURE , [ 2 ; 40; ] ) ;
( None, BAD_CERTIFICATE , [ 2 ; 42; ] ) ;
( None, CERTIFICATE_EXPIRED , [ 2 ; 45; ] ) ;
( None, DECODE_ERROR , [ 2 ; 50; ] ) ;
( None, PROTOCOL_VERSION , [ 2 ; 70; ] ) ;
( None, USER_CANCELED , [ 2 ; 90; ] ) ;
( None, NO_RENEGOTIATION , [ 2 ; 100; ] ) ;
( None, UNSUPPORTED_EXTENSION , [ 2 ; 110; ] ) ;
( None, UNRECOGNIZED_NAME , [ 2 ; 112; ] ) ;
( None, NO_APPLICATION_PROTOCOL , [ 2 ; 120; ] ) ;
( Some FATAL, CLOSE_NOTIFY , [ 2 ; 0; ] ) ;
( Some FATAL, UNEXPECTED_MESSAGE , [ 2 ; 10; ] ) ;
( Some FATAL, BAD_RECORD_MAC , [ 2 ; 20; ] ) ;
( Some FATAL, RECORD_OVERFLOW , [ 2 ; 22; ] ) ;
( Some FATAL, HANDSHAKE_FAILURE , [ 2 ; 40; ] ) ;
( Some FATAL, BAD_CERTIFICATE , [ 2 ; 42; ] ) ;
( Some FATAL, CERTIFICATE_EXPIRED , [ 2 ; 45; ] ) ;
( Some FATAL, DECODE_ERROR , [ 2 ; 50; ] ) ;
( Some FATAL, PROTOCOL_VERSION , [ 2 ; 70; ] ) ;
( Some FATAL, USER_CANCELED , [ 2 ; 90; ] ) ;
( Some FATAL, NO_RENEGOTIATION , [ 2 ; 100; ] ) ;
( Some FATAL, UNSUPPORTED_EXTENSION , [ 2 ; 110; ] ) ;
( Some FATAL, UNRECOGNIZED_NAME , [ 2 ; 112; ] ) ;
( Some FATAL, NO_APPLICATION_PROTOCOL , [ 2 ; 120; ] ) ;
( Some WARNING, CLOSE_NOTIFY , [ 1 ; 0; ] ) ;
( Some WARNING, UNEXPECTED_MESSAGE , [ 1 ; 10; ] ) ;
( Some WARNING, BAD_RECORD_MAC , [ 1 ; 20; ] ) ;
( Some WARNING, RECORD_OVERFLOW , [ 1 ; 22; ] ) ;
( Some WARNING, HANDSHAKE_FAILURE , [ 1 ; 40; ] ) ;
( Some WARNING, BAD_CERTIFICATE , [ 1 ; 42; ] ) ;
( Some WARNING, CERTIFICATE_EXPIRED , [ 1 ; 45; ] ) ;
( Some WARNING, DECODE_ERROR , [ 1 ; 50; ] ) ;
( Some WARNING, PROTOCOL_VERSION , [ 1 ; 70; ] ) ;
( Some WARNING, USER_CANCELED , [ 1 ; 90; ] ) ;
( Some WARNING, NO_RENEGOTIATION , [ 1 ; 100; ] ) ;
( Some WARNING, UNSUPPORTED_EXTENSION , [ 1 ; 110; ] ) ;
( Some WARNING, UNRECOGNIZED_NAME , [ 1 ; 112; ] ) ;
])
let alert_tests =
List.mapi
(fun i f -> "Assemble alert " ^ string_of_int i >:: alert_assembler f)
alert_assembler_tests
let ccs_test _ =
let buf = Writer.assemble_change_cipher_spec in
assert_cs_eq buf (list_to_cstruct [1])
let dh_assembler (p, res) _ =
let buf = Writer.assemble_dh_parameters p in
assert_cs_eq buf res
let dh_assembler_tests =
let a = list_to_cstruct [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 ] in
let le = list_to_cstruct [ 0; 16 ] in
let le2 = list_to_cstruct [ 0; 32 ] in
let emp, empl = (list_to_cstruct [], list_to_cstruct [ 0; 0 ]) in
Core.([
( { dh_p = a ; dh_g = a ; dh_Ys = a },
le ^ a ^ le ^ a ^ le ^ a ) ;
( { dh_p = a ^ a ; dh_g = a ; dh_Ys = a ^ a },
le2 ^ a ^ a ^ le ^ a ^ le2 ^ a ^ a ) ;
( { dh_p = emp ; dh_g = emp ; dh_Ys = emp }, empl ^ empl ^ empl ) ;
( { dh_p = a ; dh_g = emp ; dh_Ys = emp }, le ^ a ^ empl ^ empl ) ;
( { dh_p = emp ; dh_g = a ; dh_Ys = emp }, empl ^ le ^ a ^ empl ) ;
( { dh_p = emp ; dh_g = emp ; dh_Ys = a }, empl ^ empl ^ le ^ a ) ;
( { dh_p = emp ; dh_g = a ; dh_Ys = a }, empl ^ le ^ a ^ le ^ a ) ;
( { dh_p = a ; dh_g = a ; dh_Ys = emp }, le ^ a ^ le ^ a ^ empl ) ;
( { dh_p = a ; dh_g = emp ; dh_Ys = a }, le ^ a ^ empl ^ le ^ a ) ;
])
let dh_tests =
List.mapi
(fun i f -> "Assemble dh parameters " ^ string_of_int i >:: dh_assembler f)
dh_assembler_tests
let ds_assembler (p, res) _ =
let buf = Writer.assemble_digitally_signed p in
assert_cs_eq buf res
let ds_assembler_tests =
let a = list_to_cstruct [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 ] in
let le = list_to_cstruct [ 0; 16 ] in
let le2 = list_to_cstruct [ 0; 32 ] in
let emp, empl = (list_to_cstruct [], list_to_cstruct [ 0; 0 ]) in
[
( a , le ^ a ) ;
( a ^ a , le2 ^ a ^ a ) ;
( emp , empl )
]
let ds_tests =
List.mapi
(fun i f -> "Assemble digitally signed " ^ string_of_int i >:: ds_assembler f)
ds_assembler_tests
let ds_1_2_assembler (sigalg, p, res) _ =
let buf = Writer.assemble_digitally_signed_1_2 sigalg p in
assert_cs_eq buf res
let ds_1_2_assembler_tests =
let a = list_to_cstruct [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 ] in
let le = list_to_cstruct [ 0; 16 ] in
let le2 = list_to_cstruct [ 0; 32 ] in
let emp, empl = (list_to_cstruct [], list_to_cstruct [0; 0]) in
[
( `RSA_PKCS1_MD5, a , list_to_cstruct [1; 1] ^ le ^ a ) ;
( `RSA_PKCS1_SHA1, a ^ a , list_to_cstruct [2; 1] ^ le2 ^ a ^ a ) ;
( `RSA_PSS_RSAENC_SHA256, emp , list_to_cstruct [8; 4] ^ empl )
]
let ds_1_2_tests =
List.mapi
(fun i f -> "Assemble digitally signed 1.2 " ^ string_of_int i >:: ds_1_2_assembler f)
ds_1_2_assembler_tests
let handshake_assembler (h, res) _ =
let res' = list_to_cstruct res in
let buf = Writer.assemble_handshake h in
assert_cs_eq buf res'
let handshake_assembler_tests =
let a_l = [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 ] in
let a_cs = list_to_cstruct a_l in
let le = [ 0; 0; 16 ] in
let le2 = [ 0; 0; 32 ] in
let emp, empl = (list_to_cstruct [], [ 0; 0; 0 ]) in
Core.([
( HelloRequest , [ 0; 0; 0; 0 ]) ;
( ServerHelloDone , [ 14; 0; 0; 0 ]) ;
( Finished a_cs , [ 20 ] @ le @ a_l ) ;
( Finished emp , [ 20 ] @ empl ) ;
( Finished (a_cs ^ a_cs) , [ 20 ] @ le2 @ a_l @ a_l ) ;
( ClientKeyExchange emp , [ 16; 0; 0; 0 ] ) ;
( ClientKeyExchange a_cs , [ 16; 0; 0; 16 ] @ a_l ) ;
( ClientKeyExchange (a_cs ^ a_cs) , [ 16; 0; 0; 32 ] @ a_l @ a_l ) ;
( ServerKeyExchange emp , [ 12 ] @ empl ) ;
( ServerKeyExchange a_cs , [ 12 ] @ le @ a_l ) ;
( ServerKeyExchange (a_cs ^ a_cs) , [ 12 ] @ le2 @ a_l @ a_l ) ;
( Certificate (Writer.assemble_certificates []) , [ 11; 0; 0; 3; 0; 0; 0 ] ) ;
( Certificate (Writer.assemble_certificates[emp]) , [ 11; 0; 0; 6; 0; 0; 3; 0; 0; 0 ] ) ;
( Certificate (Writer.assemble_certificates[emp ; emp]) , [ 11; 0; 0; 9; 0; 0; 6; 0; 0; 0; 0; 0; 0 ] ) ;
( Certificate (Writer.assemble_certificates[a_cs]) , [ 11; 0; 0; 22; 0; 0; 19 ] @ le @ a_l ) ;
( Certificate (Writer.assemble_certificates[a_cs ; emp]) , [ 11; 0; 0; 25; 0; 0; 22 ] @ le @ a_l @ [ 0; 0; 0 ] ) ;
( Certificate (Writer.assemble_certificates[emp ; a_cs]) , [ 11; 0; 0; 25; 0; 0; 22; 0; 0; 0] @ le @ a_l ) ;
( Certificate (Writer.assemble_certificates[emp ; a_cs ; emp]) , [ 11; 0; 0; 28; 0; 0; 25; 0; 0; 0 ] @ le @ a_l @ [ 0; 0; 0 ]) ;
( Certificate (Writer.assemble_certificates[a_cs ; emp ; a_cs]) , [ 11; 0; 0; 44; 0; 0; 41 ] @ le @ a_l @ [ 0; 0; 0 ] @ le @ a_l ) ;
( Certificate (Writer.assemble_certificates[a_cs ; emp ; a_cs ; emp]) , [ 11; 0; 0; 47; 0; 0; 44 ] @ le @ a_l @ [ 0; 0; 0 ] @ le @ a_l @ [ 0; 0; 0 ] ) ;
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [] ;
extensions = [] },
[ 1; 0; 0; 39; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 0; 1; 0 ] ) ;
( ClientHello { client_version = `TLS_1_1 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [] ;
extensions = [] },
[ 1; 0; 0; 39; 3; 2 ] @ a_l @ a_l @ [ 0; 0; 0; 1; 0 ] ) ;
( ClientHello { client_version = `TLS_1_0 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [] ;
extensions = [] },
[ 1; 0; 0; 39; 3; 1 ] @ a_l @ a_l @ [ 0; 0; 0; 1; 0 ] ) ;
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA] ;
extensions = [] },
[ 1; 0; 0; 41; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 2; 0; 0x0a; 1; 0 ] ) ;
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = Packet.([TLS_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_RSA_WITH_AES_128_CBC_SHA ; TLS_DHE_RSA_WITH_AES_128_CBC_SHA]);
extensions = [] },
[ 1; 0; 0; 47; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 8; 0; 0x0A; 0; 0x16; 0; 0x2F; 0; 0x33; 1; 0 ] ) ;
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = Packet.([TLS_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ; TLS_RSA_WITH_AES_128_CBC_SHA ; TLS_DHE_RSA_WITH_AES_128_CBC_SHA]);
extensions = [
`SignatureAlgorithms
[`RSA_PKCS1_SHA512 ;
`RSA_PKCS1_SHA384 ;
`RSA_PKCS1_SHA256 ;
`RSA_PKCS1_SHA224 ;
`RSA_PKCS1_SHA1 ] ] },
[ 1; 0; 0; 65; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 8; 0; 0x0A; 0; 0x16; 0; 0x2F; 0; 0x33; 1; 0 ; 0; 0x10 ;
0x00; 0x0d; 0x00; 0x0c; (* signature algorithms *)
0x00; 0x0a; 0x06; 0x01; 0x05; 0x01; 0x04; 0x01; 0x03; 0x01; 0x02; 0x01 ] ) ;
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA] ;
extensions = [`ALPN ["h2"; "http/1.1"]] },
[ 1; 0; 0; 61; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 2; 0; 0x0A; 1; 0; 0; 18; 0; 16; 0; 14; 0; 12; 2; 104; 50; 8; 104; 116; 116; 112; 47; 49; 46; 49 ] ) ;
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA] ;
extensions = [make_hostname_ext "foo"] },
[ 1; 0; 0; 55; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 2; 0; 0x0A; 1; 0; 0; 12; 0; 0; 0; 8; 0; 6; 0; 0; 3; 102; 111; 111 ] ) ;
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA] ;
extensions = [make_hostname_ext "foofoofoofoofoofoofoofoofoofoo"] },
[ 1; 0; 0; 82; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 2; 0; 0x0A; 1; 0; 0; 39; 0; 0; 0; 35; 0; 33; 0; 0; 30; 102; 111; 111; 102; 111; 111; 102; 111; 111; 102; 111; 111; 102; 111; 111; 102; 111; 111; 102; 111; 111; 102; 111; 111; 102; 111; 111; 102; 111; 111 ] ) ;
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA] ;
extensions = [make_hostname_ext "foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo.foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo.foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof"] },
[ 1; 0; 0; 232; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 2; 0; 0x0A; 1; 0; 0; 189; 0; 0; 0; 185; 0; 183; 0; 0; 180; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 46; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 46; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102 ] ) ;
(* this one is the smallest which needs extra padding
(due to its size being > 256 and < 511) *)
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA] ;
extensions = [make_hostname_ext "foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo.foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo.foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo.foofoofoofoofoofoofo"] },
[ 1; 0; 1; 0xFC; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 2; 0; 0x0A; 1; 0; 1; 0xD1; 0; 0; 0; 0xD0; 0; 0xCE; 0; 0; 0xCB; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 46; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 46; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 46; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111; 0; 21; 0; 0xF9; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0 ] ) ;
(* this one is the biggest which needs no extra padding *)
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA] ;
extensions = [make_hostname_ext "foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo.foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo.foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo.foofoofoofoofoof"] },
[ 1; 0; 0; 251; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 2; 0; 0x0A; 1; 0; 0; 208; 0; 0; 0; 204; 0; 202; 0; 0; 199; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 46; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 46; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 46; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102;111;111; 102 ] ) ;
(* this one is the biggest which needs no extra padding, and no exts *)
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;
Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;
Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;
Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA ] ;
extensions = [] },
[ 1; 0; 0; 251; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 212; 0; 0x0A;
0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A;
1; 0 ] ) ;
(* add one more, and we get into padding no exts *)
( ClientHello { client_version = `TLS_1_2 ;
client_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuites = [Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA; Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;
Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;
Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;
Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA;Packet.TLS_RSA_WITH_3DES_EDE_CBC_SHA ] ;
extensions = [] },
[ 1; 0; 1; 0xFC; 3; 3 ] @ a_l @ a_l @ [ 0; 0; 214; 0; 0x0A; 0; 0x0A;
0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A; 0;0x0A;0;0x0A;0;0x0A;0;0x0A;0;0x0A;
1; 0;
0;0xFD;0;0x15;0;0xF9;
0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
] ) ;
( ServerHello { server_version = `TLS_1_2 ;
server_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuite = `RSA_WITH_AES_128_CCM ;
extensions = []
} ,
[2; 0; 0; 38; 3; 3] @ a_l @ a_l @ [(* session id *) 0; (* cipher *) 0xc0; 0x9c; (* comp *) 0; (* exts *)] ) ;
( ServerHello { server_version = `TLS_1_1 ;
server_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuite = `RSA_WITH_AES_128_CCM ;
extensions = []
} ,
[2; 0; 0; 38; 3; 2] @ a_l @ a_l @ [(* session id *) 0; (* cipher *) 0xc0; 0x9c; (* comp *) 0; (* exts *)] ) ;
( ServerHello { server_version = `TLS_1_0 ;
server_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuite = `RSA_WITH_AES_128_CCM ;
extensions = []
} ,
[2; 0; 0; 38; 3; 1] @ a_l @ a_l @ [(* session id *) 0; (* cipher *) 0xc0; 0x9c; (* comp *) 0; (* exts *)] ) ;
( ServerHello { server_version = `TLS_1_0 ;
server_random = a_cs ^ a_cs ;
sessionid = Some a_cs ;
ciphersuite = `RSA_WITH_AES_128_CCM ;
extensions = []
} ,
[2; 0; 0; 54; 3; 1] @ a_l @ a_l @ (* session id *) [ 16 ] @ a_l @ [(* cipher *) 0xc0; 0x9c; (* comp *) 0; (* exts *)] ) ;
( ServerHello { server_version = `TLS_1_2 ;
server_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuite = `RSA_WITH_AES_128_CCM ;
extensions = [`Hostname]
} ,
[2; 0; 0; 44; 3; 3] @ a_l @ a_l @ [(* session id *) 0; (* cipher *) 0xc0; 0x9c; (* comp *) 0; (* exts *) 0; 4; 0; 0; 0; 0] ) ;
( ServerHello { server_version = `TLS_1_2 ;
server_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuite = `RSA_WITH_AES_128_CCM ;
extensions = [`SecureRenegotiation ("")]
} ,
[2; 0; 0; 45; 3; 3] @ a_l @ a_l @ [(* session id *) 0; (* cipher *) 0xc0; 0x9c; (* comp *) 0; (* exts *) 0; 5; 0xFF; 1; 0; 1; 0] ) ;
( ServerHello { server_version = `TLS_1_2 ;
server_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuite = `RSA_WITH_AES_128_CCM ;
extensions = [`Hostname ; `SecureRenegotiation ("")]
} ,
[2; 0; 0; 49; 3; 3] @ a_l @ a_l @ [(* session id *) 0; (* cipher *) 0xc0; 0x9c; (* comp *) 0; (* exts *) 0; 9; 0; 0; 0; 0; 0xFF; 1; 0; 1; 0] ) ;
( ServerHello { server_version = `TLS_1_2 ;
server_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuite = `RSA_WITH_AES_128_CCM ;
extensions = [`SecureRenegotiation (""); `Hostname ]
} ,
[2; 0; 0; 49; 3; 3] @ a_l @ a_l @ [(* session id *) 0; (* cipher *) 0xc0; 0x9c; (* comp *) 0; (* exts *) 0; 9; 0xFF; 1; 0; 1; 0; 0; 0; 0; 0] ) ;
( ServerHello { server_version = `TLS_1_2 ;
server_random = a_cs ^ a_cs ;
sessionid = None ;
ciphersuite = `RSA_WITH_AES_128_CCM ;
extensions = [`ALPN "h2"]
} ,
[2; 0; 0; 49; 3; 3] @ a_l @ a_l @ [(* session id *) 0; (* cipher *) 0xc0; 0x9c; (* comp *) 0; (* exts *) 0; 9; 0; 16; 0; 5; 0; 3; 2; 104; 50] ) ;
(* | CertificateRequest of certificate_request *)
])
let handshake_tests =
List.mapi
(fun i f -> "Assemble handshake " ^ string_of_int i >:: handshake_assembler f)
handshake_assembler_tests
let writer_tests =
version_tests @
hdr_tests @
alert_tests @
["CCS " >:: ccs_test] @
dh_tests @
ds_tests @
ds_1_2_tests @
handshake_tests