[sans-io] TLS: add handshake fuzzing

This commit is contained in:
Maximilian Hils 2020-12-11 15:49:17 +01:00
parent 3a85c7d15d
commit 21293edce0
4 changed files with 39 additions and 7 deletions

View File

@ -85,7 +85,10 @@ def parse_client_hello(data: bytes) -> Optional[net_tls.ClientHello]:
# Check if ClientHello is complete # Check if ClientHello is complete
client_hello = get_client_hello(data) client_hello = get_client_hello(data)
if client_hello: if client_hello:
return net_tls.ClientHello(client_hello[4:]) try:
return net_tls.ClientHello(client_hello[4:])
except EOFError as e:
raise ValueError("Invalid ClientHello") from e
return None return None

View File

@ -1,4 +1,7 @@
import os
import pytest import pytest
from hypothesis import settings
from mitmproxy import options from mitmproxy import options
from mitmproxy.addons.core import Core from mitmproxy.addons.core import Core
@ -21,3 +24,8 @@ def tctx() -> context.Context:
), ),
opts opts
) )
settings.register_profile("fast", max_examples=10)
settings.register_profile("deep", max_examples=100_000, deadline=None)
settings.load_profile(os.getenv("HYPOTHESIS_PROFILE", "fast"))

View File

@ -1,9 +1,8 @@
import os
from typing import Tuple, Dict, Any from typing import Tuple, Dict, Any
import pytest import pytest
from h2.settings import SettingCodes from h2.settings import SettingCodes
from hypothesis import example, given, settings from hypothesis import example, given
from hypothesis.strategies import binary, booleans, composite, dictionaries, integers, lists, sampled_from, sets, text, \ from hypothesis.strategies import binary, booleans, composite, dictionaries, integers, lists, sampled_from, sets, text, \
data data
@ -21,10 +20,6 @@ from test.mitmproxy.proxy2.layers.http.test_http2 import make_h2, example_respon
start_h2_client start_h2_client
from test.mitmproxy.proxy2.tutils import Placeholder, Playbook, reply, _TracebackInPlaybook, _eq from test.mitmproxy.proxy2.tutils import Placeholder, Playbook, reply, _TracebackInPlaybook, _eq
settings.register_profile("fast", max_examples=10)
settings.register_profile("deep", max_examples=100_000, deadline=None)
settings.load_profile(os.getenv("HYPOTHESIS_PROFILE", "fast"))
opts = options.Options() opts = options.Options()
Proxyserver().load(opts) Proxyserver().load(opts)

View File

@ -0,0 +1,26 @@
from hypothesis import given, example
from hypothesis.strategies import binary, integers
from mitmproxy.net.tls import ClientHello
from mitmproxy.proxy2.layers.tls import parse_client_hello
client_hello_with_extensions = bytes.fromhex(
"16030300bb" # record layer
"010000b7" # handshake layer
"03033b70638d2523e1cba15f8364868295305e9c52aceabda4b5147210abc783e6e1000022c02bc02fc02cc030"
"cca9cca8cc14cc13c009c013c00ac014009c009d002f0035000a0100006cff0100010000000010000e00000b65"
"78616d706c652e636f6d0017000000230000000d00120010060106030501050304010403020102030005000501"
"00000000001200000010000e000c02683208687474702f312e3175500000000b00020100000a00080006001d00"
"170018"
)
@given(i=integers(0, len(client_hello_with_extensions)), data=binary())
@example(i=183, data=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00')
def test_fuzz_h2_request_chunks(i, data):
try:
ch = parse_client_hello(client_hello_with_extensions[:i] + data)
except ValueError:
pass
else:
assert ch is None or isinstance(ch, ClientHello)