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
|
import copy
import pytest
import re
from configuration import available_ports, TLS13_CIPHERS, ALL_TEST_CURVES, ALL_TEST_CERTS
from common import ProviderOptions, Protocols, data_bytes, Curves
from fixtures import managed_process # lgtm [py/unused-import]
from providers import Provider, S2N, OpenSSL
from utils import invalid_test_parameters, get_parameter_name, to_bytes
S2N_DEFAULT_CURVE = Curves.X25519
S2N_HRR_MARKER = to_bytes("HELLO_RETRY_REQUEST")
# Mapping list of curve_names for hello retry requests server side test.
CURVE_NAMES = {
"X25519": "x25519",
"P-256": "secp256r1",
"P-384": "secp384r1",
"P-521": "secp521r1"
}
def test_nothing():
"""
Sometimes the hello retry test parameters in combination with the s2n libcrypto
results in no test cases existing. In this case, pass a nothing test to avoid
marking the entire codebuild run as failed.
"""
assert True
@pytest.mark.uncollect_if(func=invalid_test_parameters)
@pytest.mark.parametrize("cipher", TLS13_CIPHERS, ids=get_parameter_name)
@pytest.mark.parametrize("provider", [OpenSSL])
@pytest.mark.parametrize("other_provider", [S2N], ids=get_parameter_name)
@pytest.mark.parametrize("curve", ALL_TEST_CURVES, ids=get_parameter_name)
@pytest.mark.parametrize("protocol", [Protocols.TLS13], ids=get_parameter_name)
@pytest.mark.parametrize("certificate", ALL_TEST_CERTS, ids=get_parameter_name)
def test_hrr_with_s2n_as_client(managed_process, cipher, provider, other_provider, curve, protocol, certificate):
if curve == S2N_DEFAULT_CURVE:
pytest.skip("No retry if server curve matches client curve")
port = next(available_ports)
random_bytes = data_bytes(64)
client_options = ProviderOptions(
mode=Provider.ClientMode,
port=port,
cipher=cipher,
data_to_send=random_bytes,
insecure=True,
protocol=protocol)
server_options = copy.copy(client_options)
server_options.data_to_send = None
server_options.mode = Provider.ServerMode
server_options.key = certificate.key
server_options.cert = certificate.cert
server_options.extra_flags = None
server_options.curve = curve
# Passing the type of client and server as a parameter will
# allow us to use a fixture to enumerate all possibilities.
server = managed_process(provider, server_options, timeout=5)
client = managed_process(S2N, client_options, timeout=5)
# The client should connect and return without error
for results in client.get_results():
results.assert_success()
assert to_bytes("Curve: {}".format(
CURVE_NAMES[curve.name])) in results.stdout
assert S2N_HRR_MARKER in results.stdout
marker_part1 = b"cf 21 ad 74 e5"
marker_part2 = b"9a 61 11 be 1d"
for results in server.get_results():
results.assert_success()
assert marker_part1 in results.stdout and marker_part2 in results.stdout
# The "test_all" s2n security policy includes draft Hybrid PQ groups that Openssl server prints as hex values
assert re.search(b'Supported Elliptic Groups: [x0-9A-F:]*X25519:P-256:P-384', results.stdout) is not None
assert to_bytes("Shared Elliptic groups: {}".format(
server_options.curve)) in results.stdout
assert random_bytes in results.stdout
@pytest.mark.uncollect_if(func=invalid_test_parameters)
@pytest.mark.parametrize("cipher", TLS13_CIPHERS, ids=get_parameter_name)
@pytest.mark.parametrize("provider", [OpenSSL])
@pytest.mark.parametrize("other_provider", [S2N], ids=get_parameter_name)
@pytest.mark.parametrize("curve", ALL_TEST_CURVES, ids=get_parameter_name)
@pytest.mark.parametrize("protocol", [Protocols.TLS13], ids=get_parameter_name)
@pytest.mark.parametrize("certificate", ALL_TEST_CERTS, ids=get_parameter_name)
def test_hrr_with_s2n_as_server(managed_process, cipher, provider, other_provider, curve, protocol, certificate):
port = next(available_ports)
random_bytes = data_bytes(64)
client_options = ProviderOptions(
mode=Provider.ClientMode,
port=port,
cipher=cipher,
data_to_send=random_bytes,
insecure=True,
curve=curve,
extra_flags=['-msg', '-curves', 'X448:'+str(curve)],
protocol=protocol)
server_options = copy.copy(client_options)
server_options.data_to_send = None
server_options.mode = Provider.ServerMode
server_options.key = certificate.key
server_options.cert = certificate.cert
server_options.extra_flags = None
# Passing the type of client and server as a parameter will
# allow us to use a fixture to enumerate all possibilities.
server = managed_process(S2N, server_options, timeout=5)
client = managed_process(provider, client_options, timeout=5)
# The client should connect and return without error
for results in server.get_results():
results.assert_success()
assert random_bytes in results.stdout
assert to_bytes("Curve: {}".format(
CURVE_NAMES[curve.name])) in results.stdout
assert random_bytes in results.stdout
assert S2N_HRR_MARKER in results.stdout
client_hello_count = 0
server_hello_count = 0
finished_count = 0
# HRR random data Refer: https://tools.ietf.org/html/rfc8446#section-4.1.3
marker = b"cf 21 ad 74 e5 9a 61 11 be 1d"
for results in client.get_results():
results.assert_success()
assert marker in results.stdout
client_hello_count = results.stdout.count(b'ClientHello')
server_hello_count = results.stdout.count(b'ServerHello')
finished_count = results.stdout.count(b'Finished')
assert client_hello_count == 2
assert server_hello_count == 2
assert finished_count == 2
# Default Keyshare for TLS v1.3 is x25519
TEST_CURVES = ALL_TEST_CURVES[1:]
@pytest.mark.uncollect_if(func=invalid_test_parameters)
@pytest.mark.parametrize("cipher", TLS13_CIPHERS, ids=get_parameter_name)
@pytest.mark.parametrize("provider", [OpenSSL])
@pytest.mark.parametrize("other_provider", [S2N], ids=get_parameter_name)
@pytest.mark.parametrize("curve", TEST_CURVES, ids=get_parameter_name)
@pytest.mark.parametrize("protocol", [Protocols.TLS13], ids=get_parameter_name)
@pytest.mark.parametrize("certificate", ALL_TEST_CERTS, ids=get_parameter_name)
def test_hrr_with_default_keyshare(managed_process, cipher, provider, other_provider, curve, protocol, certificate):
port = next(available_ports)
random_bytes = data_bytes(64)
client_options = ProviderOptions(
mode=Provider.ClientMode,
port=port,
cipher=cipher,
data_to_send=random_bytes,
insecure=True,
protocol=protocol)
server_options = copy.copy(client_options)
server_options.data_to_send = None
server_options.mode = Provider.ServerMode
server_options.key = certificate.key
server_options.cert = certificate.cert
server_options.extra_flags = None
server_options.curve = curve
# Passing the type of client and server as a parameter will
# allow us to use a fixture to enumerate all possibilities.
server = managed_process(provider, server_options, timeout=5)
client = managed_process(S2N, client_options, timeout=5)
# The client should connect and return without error
for results in client.get_results():
results.assert_success()
assert to_bytes("Curve: {}".format(
CURVE_NAMES[curve.name])) in results.stdout
assert S2N_HRR_MARKER in results.stdout
marker_part1 = b"cf 21 ad 74 e5"
marker_part2 = b"9a 61 11 be 1d"
for results in server.get_results():
results.assert_success()
assert marker_part1 in results.stdout and marker_part2 in results.stdout
# The "test_all" s2n security policy includes draft Hybrid PQ groups that Openssl server prints as hex values
assert re.search(b'Supported Elliptic Groups: [x0-9A-F:]*X25519:P-256:P-384', results.stdout) is not None
assert to_bytes("Shared Elliptic groups: {}".format(
server_options.curve)) in results.stdout
assert random_bytes in results.stdout
|