Beispiel #1
0
def test_s2nd_tls13_negotiates_tls12(managed_process, cipher, curve, protocol,
                                     provider, certificate):
    port = next(available_ports)

    random_bytes = data_bytes(24)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     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.protocol = Protocols.TLS13

    # Allow the server to use all ciphers, don't limit to TLS13 even though we are
    # forcing the protocol to be TLS13
    server_options.extra_flags = ['-c', 'test_all']

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    server_version = get_expected_s2n_version(Protocols.TLS13, provider)
    actual_version = get_expected_s2n_version(protocol, provider)

    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        if provider is S2N:
            # The client will get the server version from the SERVER HELLO, which will be the negotiated version
            assert bytes("Server protocol version: {}".format(
                actual_version).encode('utf-8')) in results.stdout
            assert bytes("Actual protocol version: {}".format(
                actual_version).encode('utf-8')) in results.stdout
        elif provider is OpenSSL:
            # This check cares about other providers because we want to know that they did negotiate the version
            # that our S2N server intended to negotiate.
            openssl_version = get_expected_openssl_version(protocol)
            assert bytes("Protocol  : {}".format(openssl_version).encode(
                'utf-8')) in results.stdout

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Server protocol version: {}".format(
            server_version).encode('utf-8')) in results.stdout
        assert bytes("Actual protocol version: {}".format(
            actual_version).encode('utf-8')) in results.stdout
        assert random_bytes in results.stdout
Beispiel #2
0
def test_s2nc_tls13_negotiates_tls12(managed_process, cipher, curve,
                                     certificate, protocol, provider,
                                     other_provider):
    port = next(available_ports)

    random_bytes = data_bytes(24)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     data_to_send=random_bytes,
                                     insecure=True,
                                     protocol=Protocols.TLS13)

    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.protocol = protocol

    kill_marker = None
    if provider == GnuTLS:
        kill_marker = random_bytes

    server = managed_process(provider,
                             server_options,
                             timeout=5,
                             kill_marker=kill_marker)
    client = managed_process(S2N, client_options, timeout=5)

    client_version = get_expected_s2n_version(Protocols.TLS13, provider)
    actual_version = get_expected_s2n_version(protocol, provider)

    for results in client.get_results():
        results.assert_success()
        assert to_bytes("Client protocol version: {}".format(
            client_version)) in results.stdout
        assert to_bytes("Actual protocol version: {}".format(
            actual_version)) in results.stdout

    for results in server.get_results():
        results.assert_success()
        if provider is S2N:
            # The server is only TLS12, so it reads the version from the CLIENT_HELLO, which is never above TLS12
            # This check only cares about S2N. Trying to maintain expected output of other providers doesn't
            # add benefit to whether the S2N client was able to negotiate a lower TLS version.
            assert to_bytes("Client protocol version: {}".format(
                actual_version)) in results.stdout
            assert to_bytes("Actual protocol version: {}".format(
                actual_version)) in results.stdout

        assert any([
            random_bytes[1:] in stream for stream in results.output_streams()
        ])
Beispiel #3
0
def test_s2nd_tls13_negotiates_tls12(managed_process, cipher, curve,
                                     certificate, protocol, provider,
                                     other_provider):
    port = next(available_ports)

    random_bytes = data_bytes(24)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     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
    # When the protocol is set to TLS13, the s2n server provider will default to using
    # all ciphers, not just the TLS13 ciphers. This is the desired behavior for this test.
    server_options.protocol = Protocols.TLS13

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    server_version = get_expected_s2n_version(Protocols.TLS13, provider)
    actual_version = get_expected_s2n_version(protocol, provider)

    for results in client.get_results():
        results.assert_success()
        if provider is S2N:
            # The client will get the server version from the SERVER HELLO, which will be the negotiated version
            assert to_bytes("Server protocol version: {}".format(
                actual_version)) in results.stdout
            assert to_bytes("Actual protocol version: {}".format(
                actual_version)) in results.stdout
        elif provider is OpenSSL:
            # This check cares about other providers because we want to know that they did negotiate the version
            # that our S2N server intended to negotiate.
            openssl_version = get_expected_openssl_version(protocol)
            assert to_bytes(
                "Protocol  : {}".format(openssl_version)) in results.stdout
        elif provider is GnuTLS:
            gnutls_version = get_expected_gnutls_version(protocol)
            assert to_bytes(f"Version: {gnutls_version}") in results.stdout

    for results in server.get_results():
        results.assert_success()
        assert (to_bytes("Server protocol version: {}".format(server_version))
                in results.stdout)
        assert (to_bytes("Actual protocol version: {}".format(actual_version))
                in results.stdout)
        assert random_bytes[1:] in results.stdout
Beispiel #4
0
def test_s2nc_tls13_negotiates_tls12(managed_process, cipher, curve, protocol,
                                     provider, certificate):
    port = next(available_ports)

    random_bytes = data_bytes(24)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     data_to_send=random_bytes,
                                     insecure=True,
                                     protocol=Protocols.TLS13)

    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.protocol = protocol

    server = managed_process(provider, server_options, timeout=5)
    client = managed_process(S2N, client_options, timeout=5)

    client_version = get_expected_s2n_version(Protocols.TLS13, provider)
    actual_version = get_expected_s2n_version(protocol, provider)

    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Client protocol version: {}".format(
            client_version).encode('utf-8')) in results.stdout
        assert bytes("Actual protocol version: {}".format(
            actual_version).encode('utf-8')) in results.stdout

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        if provider is S2N:
            # The server is only TLS12, so it reads the version from the CLIENT_HELLO, which is never above TLS12
            # This check only cares about S2N. Trying to maintain expected output of other providers doesn't
            # add benefit to whether the S2N client was able to negotiate a lower TLS version.
            assert bytes("Client protocol version: {}".format(
                actual_version).encode('utf-8')) in results.stdout
            assert bytes("Actual protocol version: {}".format(
                actual_version).encode('utf-8')) in results.stdout

        assert random_bytes in results.stdout
Beispiel #5
0
def test_s2n_server_low_latency(managed_process, multi_cipher, provider, protocol, certificate):
    if provider is OpenSSL and 'openssl-1.0.2' in provider.get_version():
        pytest.skip('{} does not allow setting max fragmentation for packets'.format(provider))

    port = next(available_ports)

    random_bytes = data_bytes(65519)
    client_options = ProviderOptions(
        mode=Provider.ClientMode,
        port=port,
        cipher=multi_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.extra_flags = ['--prefer-low-latency']
    server_options.key = certificate.key
    server_options.cert = certificate.cert
    server_options.cipher = None

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    for results in client.get_results():
        results.assert_success()

    expected_version = get_expected_s2n_version(protocol, provider)

    for results in server.get_results():
        results.assert_success()
        assert to_bytes("Actual protocol version: {}".format(expected_version)) in results.stdout
        assert random_bytes in results.stdout
Beispiel #6
0
def test_s2n_server_low_latency(managed_process, multi_cipher, provider,
                                protocol, certificate):
    port = next(available_ports)

    random_bytes = data_bytes(65519)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=multi_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.extra_flags = ['--prefer-low-latency']
    server_options.key = certificate.key
    server_options.cert = certificate.cert

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0

    expected_version = get_expected_s2n_version(protocol, provider)

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(
            expected_version).encode('utf-8')) in results.stdout
        assert random_bytes in results.stdout
Beispiel #7
0
def test_tls13_session_resumption_s2n_client(managed_process, cipher, curve,
                                             protocol, provider, certificate):
    port = str(next(available_ports))

    # The reconnect option for s2nc allows the client to reconnect automatically
    # five times. In this test we expect one full connection and five resumption
    # connections.
    num_full_connections = 1
    num_resumed_connections = 5

    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     insecure=True,
                                     use_session_ticket=True,
                                     reconnect=True,
                                     protocol=protocol)

    server_options = copy.copy(client_options)
    server_options.mode = Provider.ServerMode
    server_options.key = certificate.key
    server_options.cert = certificate.cert
    server_options.reconnects_before_exit = num_resumed_connections + num_full_connections

    server = managed_process(provider, server_options, timeout=5)
    client = managed_process(S2N, client_options, timeout=5)

    s2n_version = get_expected_s2n_version(protocol, provider)

    # s2nc indicates the number of resumed connections in its output
    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert not results.stderr
        assert results.stdout.count(
            b'Resumed session') == num_resumed_connections
        assert bytes("Actual protocol version: {}".format(s2n_version).encode(
            'utf-8')) in results.stdout

    server_accepts_str = str(num_resumed_connections + num_full_connections
                             ) + " server accepts that finished"

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        if provider is S2N:
            assert not results.stderr
            assert results.stdout.count(
                b'Resumed session') == num_resumed_connections
            assert bytes("Actual protocol version: {}".format(
                s2n_version).encode('utf-8')) in results.stdout
        else:
            assert bytes(server_accepts_str.encode('utf-8')) in results.stdout
            # s_server only writes one certificate message in all of the connections
            assert results.stderr.count(
                b'SSL_accept:SSLv3/TLS write certificate'
            ) == num_full_connections
Beispiel #8
0
def test_s2n_client_happy_path(managed_process, cipher, provider, curve,
                               protocol, certificate):
    port = next(available_ports)

    # We can only send 4096 - 1 (\n at the end) bytes here because of the
    # way some servers chunk output (when writing to stdout). If we send
    # 8192 bytes, then openssl will print some debugging information in
    # the middle of our chunk. We still want that debugging data in case
    # of a failure, so we just send less data, rather than lose debug
    # information.
    random_bytes = data_bytes(4095)
    client_options = ProviderOptions(
        mode=Provider.ClientMode,
        port=port,
        cipher=cipher,
        curve=curve,
        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

    kill_marker = None
    if provider == GnuTLS:
        kill_marker = random_bytes

    # 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,
                             kill_marker=kill_marker)
    client = managed_process(S2N, client_options, timeout=5)

    expected_version = get_expected_s2n_version(protocol, provider)

    # The client is always S2N in this test, so we can examine
    # the stdout reliably.
    for client_results in client.get_results():
        client_results.assert_success()
        assert to_bytes("Actual protocol version: {}".format(
            expected_version)) in client_results.stdout

    # The server will be one of all supported providers. We
    # just want to make sure there was no exception and that
    # the client exited cleanly.
    for server_results in server.get_results():
        server_results.assert_success()
        # Avoid debugging information that sometimes gets inserted after the first character.
        assert any([
            random_bytes[1:] in stream
            for stream in server_results.output_streams()
        ])
def test_s2n_client_signature_algorithms(managed_process, cipher, provider,
                                         protocol, certificate, signature,
                                         client_auth):
    port = next(available_ports)

    random_bytes = data_bytes(64)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     data_to_send=random_bytes,
                                     insecure=True,
                                     use_client_auth=client_auth,
                                     key=certificate.key,
                                     cert=certificate.cert,
                                     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.trust_store = certificate.cert
    server_options.extra_flags = ['-sigalgs', signature.name]

    if client_auth is True:
        client_options.trust_store = Certificates.RSA_2048_SHA256_WILDCARD.cert
        server_options.key = Certificates.RSA_2048_SHA256_WILDCARD.key
        server_options.cert = Certificates.RSA_2048_SHA256_WILDCARD.cert

        if signature.sig_type == 'RSA-PSS':
            client_options.trust_store = Certificates.RSA_PSS_2048_SHA256.cert
            server_options.key = Certificates.RSA_PSS_2048_SHA256.key
            server_options.cert = Certificates.RSA_PSS_2048_SHA256.cert
        elif signature.sig_type == 'ECDSA':
            client_options.trust_store = Certificates.ECDSA_256.cert
            server_options.key = Certificates.ECDSA_256.key
            server_options.cert = Certificates.ECDSA_256.cert

    server = managed_process(provider, server_options, timeout=5)
    client = managed_process(S2N, client_options, timeout=5)

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes('Shared Signature Algorithms: {}+{}'.format(
            signature.sig_type,
            signature.sig_digest).encode('utf-8')) in results.stdout
        assert random_bytes in results.stdout

    expected_version = get_expected_s2n_version(protocol, provider)

    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(
            expected_version).encode('utf-8')) in results.stdout
Beispiel #10
0
def assert_s2n_handshake_complete(results,
                                  protocol,
                                  provider,
                                  is_complete=True):
    expected_version = get_expected_s2n_version(protocol, provider)
    if is_complete:
        assert to_bytes("Actual protocol version: {}".format(
            expected_version)) in results.stdout
    else:
        assert to_bytes("Actual protocol version: {}".format(
            expected_version)) not in results.stdout
Beispiel #11
0
def test_s2n_server_happy_path(managed_process, cipher, provider, curve,
                               protocol, certificate):
    port = next(available_ports)

    # s2nd can receive large amounts of data because all the data is
    # echo'd to stdout unmodified. This lets us compare received to
    # expected easily.
    # We purposefully send a non block aligned number to make sure
    # nothing blocks waiting for more data.
    random_bytes = data_bytes(65519)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     cert=certificate,
                                     curve=curve,
                                     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

    # 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 will be one of all supported providers. We
    # just want to make sure there was no exception and that
    # the client exited cleanly.
    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0

    expected_version = get_expected_s2n_version(protocol, provider)

    # The server is always S2N in this test, so we can examine
    # the stdout reliably.
    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(
            expected_version).encode('utf-8')) in results.stdout
        assert random_bytes in results.stdout

        if provider is not S2N:
            assert bytes("Cipher negotiated: {}".format(
                cipher.name).encode('utf-8')) in results.stdout
Beispiel #12
0
def test_s2n_client_happy_path(managed_process, cipher, provider, curve,
                               protocol, certificate):
    port = next(available_ports)

    # We can only send 4096 bytes here because of the way some servers chunk
    # output (when writing to stdout). If we send 8192 bytes, then openssl
    # will print some debugging information in the middle of our chunk.
    # We still want that debugging data in case of a failure, so we just
    # send less data, rather than lose debug information.
    random_bytes = data_bytes(4096)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     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

    # 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)

    expected_version = get_expected_s2n_version(protocol, provider)

    # The client is always S2N in this test, so we can examine
    # the stdout reliably.
    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(
            expected_version).encode('utf-8')) in results.stdout

    # The server will be one of all supported providers. We
    # just want to make sure there was no exception and that
    # the client exited cleanly.
    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        # Avoid debugging information that sometimes gets inserted after the first character
        assert random_bytes[1:] in results.stdout
def test_s2n_client_signature_algorithms(managed_process, cipher, provider, protocol, certificate, signature, client_auth):
    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,
        use_client_auth=client_auth,
        key=certificate.key,
        cert=certificate.cert,
        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.trust_store = certificate.cert
    server_options.extra_flags=['-sigalgs', signature.name]

    server = managed_process(provider, server_options, timeout=5)
    client = managed_process(S2N, client_options, timeout=5)

    for results in server.get_results():
        results.assert_success()
        assert random_bytes in results.stdout

    expected_version = get_expected_s2n_version(protocol, provider)

    # In versions before TLS1.3, the server uses the negotiated signature scheme for the
    # ServerKeyExchange message. The server only sends the ServerKeyExchange message when using
    # a key exchange method that provides forward secrecy, ie, NOT static RSA.
    # So if using RSA key exchange, there is no actual "negotiated" signature scheme, because
    # the server never sends the client a signature scheme.
    #
    # This mostly has to be inferred from the RFCs, but this blog post is a pretty good summary
    # of the situation: https://timtaubert.de/blog/2016/07/the-evolution-of-signatures-in-tls/
    server_sigalg_used = not cipher.iana_standard_name.startswith("TLS_RSA_WITH_")

    for results in client.get_results():
        results.assert_success()
        assert to_bytes("Actual protocol version: {}".format(expected_version)) in results.stdout
        assert signature_marker(Provider.ServerMode, signature) in results.stdout or not server_sigalg_used
        assert (signature_marker(Provider.ClientMode, signature) in results.stdout) == client_auth
def test_s2n_client_dynamic_record(custom_mtu, managed_process, cipher, curve,
                                   provider, protocol, certificate):
    host = "localhost"
    port = next(available_ports)

    # 16384 bytes is enough to reliably get a packet that will exceed the MTU
    bytes_to_send = data_bytes(16384)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     data_to_send=bytes_to_send,
                                     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

    expected_version = get_expected_s2n_version(protocol, provider)

    # This test shouldn't last longer than 5 seconds, even though
    # Tcpdump tends to take a second to startup.
    tcpdump = managed_process(Tcpdump, client_options, timeout=5)
    server = managed_process(provider, server_options, timeout=5)
    client = managed_process(S2N, client_options, timeout=5)

    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(
            expected_version).encode('utf-8')) in results.stdout

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0

    # The Tcpdump provider only captures 12 packets. This is enough
    # to detect a packet larger than the MTU, but less than the
    # total packets sent. This is important because it lets Tcpdump
    # exit cleanly, which means all the output is available for us
    # to examine.
    for results in tcpdump.get_results():
        assert results.exit_code == 0
        assert find_fragmented_packet(results.stdout) is True
Beispiel #15
0
def test_s2n_server_framented_data(managed_process, cipher, provider,
                                   other_provider, protocol, certificate,
                                   frag_len):
    if provider is OpenSSL and 'openssl-1.0.2' in provider.get_version():
        pytest.skip(
            '{} does not allow setting max fragmentation for packets'.format(
                provider))

    port = next(available_ports)

    random_bytes = data_bytes(65519)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     port=port,
                                     cipher=cipher,
                                     data_to_send=random_bytes,
                                     insecure=True,
                                     record_size=frag_len,
                                     protocol=protocol)

    server_options = copy.copy(client_options)
    server_options.extra_flags = None
    server_options.data_to_send = None
    server_options.mode = Provider.ServerMode
    server_options.key = certificate.key
    server_options.cert = certificate.cert
    server_options.cipher = None

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    for client_results in client.get_results():
        client_results.assert_success()

    expected_version = get_expected_s2n_version(protocol, provider)

    for server_results in server.get_results():
        server_results.assert_success()
        assert to_bytes("Actual protocol version: {}".format(
            expected_version)) in server_results.stdout

        if provider == GnuTLS:
            # GnuTLS ignores data sent through stdin past frag_len up to the application data
            # packet length of 4096. so, just check to make sure data up to frag_len was received.
            assert random_bytes[:frag_len] in server_results.stdout
        else:
            assert random_bytes in server_results.stdout
Beispiel #16
0
def test_client_auth_with_s2n_server(managed_process, cipher, provider, curve, protocol, certificate):
    host = "localhost"
    port = next(available_ports)

    # NOTE: Client Auth is failing for ECDSA client certs
    if 'ecdsa' in certificate.cert:
        pytest.skip("Skipping known failure, ECDSA client auth certificate")

    random_bytes = data_bytes(64)
    client_options = ProviderOptions(
        mode=Provider.ClientMode,
        host="localhost",
        port=port,
        cipher=cipher,
        curve=curve,
        data_to_send=random_bytes,
        use_client_auth=True,
        client_key_file=certificate.key,
        client_certificate_file=certificate.cert,
        insecure=False,
        protocol=protocol)

    server_options = copy.copy(client_options)
    server_options.data_to_send = None
    server_options.mode = Provider.ServerMode
    server_options.key = "../pems/rsa_2048_sha256_wildcard_key.pem"
    server_options.cert = "../pems/rsa_2048_sha256_wildcard_cert.pem"

    # 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 client.get_results():
        assert results.exception is None
        assert results.exit_code == 0

    expected_version = get_expected_s2n_version(protocol, provider)

    # S2N should indicate the procotol version in a successful connection.
    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(expected_version).encode('utf-8')) in results.stdout
        assert random_bytes in results.stdout
def test_s2n_server_signature_algorithms(managed_process, cipher, provider,
                                         protocol, certificate, signature,
                                         client_auth):
    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=False,
                                     use_client_auth=client_auth,
                                     key=certificate.key,
                                     cert=certificate.cert,
                                     signature_algorithm=signature,
                                     protocol=protocol)

    if provider == GnuTLS:
        # GnuTLS fails the CA verification. It must be run with this check disabled.
        client_options.extra_flags = ["--no-ca-verification"]

    server_options = copy.copy(client_options)
    server_options.extra_flags = None
    server_options.data_to_send = None
    server_options.mode = Provider.ServerMode
    server_options.key = certificate.key
    server_options.cert = certificate.cert

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    for results in client.get_results():
        results.assert_success()

    expected_version = get_expected_s2n_version(protocol, provider)

    for results in server.get_results():
        results.assert_success()
        assert to_bytes("Actual protocol version: {}".format(
            expected_version)) in results.stdout
        assert signature_marker(Provider.ServerMode,
                                signature) in results.stdout
        assert (signature_marker(Provider.ClientMode, signature)
                in results.stdout) == client_auth
        assert random_bytes in results.stdout
def test_s2n_server_signature_algorithms(managed_process, cipher, provider,
                                         protocol, certificate, signature,
                                         client_auth):
    port = next(available_ports)

    random_bytes = data_bytes(64)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     data_to_send=random_bytes,
                                     insecure=False,
                                     use_client_auth=client_auth,
                                     key=certificate.key,
                                     cert=certificate.cert,
                                     extra_flags=['-sigalgs', signature.name],
                                     protocol=protocol)

    server_options = copy.copy(client_options)
    server_options.extra_flags = None
    server_options.data_to_send = None
    server_options.mode = Provider.ServerMode
    server_options.key = certificate.key
    server_options.cert = certificate.cert

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes('Peer signing digest: {}'.format(
            signature.sig_digest).encode('utf-8')) in results.stdout
        assert bytes('Peer signature type: {}'.format(
            signature.sig_type).encode('utf-8')) in results.stdout

    expected_version = get_expected_s2n_version(protocol, provider)

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(
            expected_version).encode('utf-8')) in results.stdout
        assert random_bytes in results.stdout
Beispiel #19
0
def test_oqs_openssl_as_client(managed_process, vector):
    host = "localhost"
    port = next(available_ports)

    # We are manually passing the cipher flag to s2nc and s2nd.
    # This is because PQ ciphers are specific to S2N at this point
    # in time.
    client_options = ProviderOptions(
        mode=Provider.ClientMode,
        host=host,
        port=port,
        insecure=True,
        cipher=vector['client_ciphers'],
        protocol=Protocols.TLS12,
        env_overrides=get_oqs_openssl_override_env_vars())

    server_options = ProviderOptions(mode=Provider.ServerMode,
                                     host=host,
                                     port=port,
                                     cipher=vector['server_ciphers'],
                                     protocol=Protocols.TLS12,
                                     cert=Certificates.RSA_4096_SHA512.cert,
                                     key=Certificates.RSA_4096_SHA512.key)

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(OpenSSL, client_options, timeout=5)

    # OQS OpenSSL is Client, so just check that it had a valid exit code
    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0

    expected_version = get_expected_s2n_version(Protocols.TLS12, S2N)

    # Validate S2N Server results were what was expected
    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(
            expected_version).encode('utf-8')) in results.stdout
        assert bytes("KEM: {}".format(
            vector['expected_kem']).encode('utf-8')) in results.stdout
        assert bytes("Cipher negotiated: {}".format(
            vector['expected_cipher']).encode('utf-8')) in results.stdout
Beispiel #20
0
def test_s2n_server_framented_data(managed_process, multi_cipher, provider,
                                   protocol, frag_len, certificate):
    if provider is OpenSSL and 'openssl-1.0.2' in provider.get_version():
        pytest.skip(
            '{} does not allow setting max fragmentation for packets'.format(
                provider))

    port = next(available_ports)

    random_bytes = data_bytes(65519)
    client_options = ProviderOptions(
        mode=Provider.ClientMode,
        host="localhost",
        port=port,
        cipher=multi_cipher,
        data_to_send=random_bytes,
        insecure=True,
        extra_flags=['-max_send_frag', str(frag_len)],
        protocol=protocol)

    server_options = copy.copy(client_options)
    server_options.extra_flags = None
    server_options.data_to_send = None
    server_options.mode = Provider.ServerMode
    server_options.key = certificate.key
    server_options.cert = certificate.cert
    server_options.cipher = None

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0

    expected_version = get_expected_s2n_version(protocol, provider)

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(
            expected_version).encode('utf-8')) in results.stdout
        assert random_bytes in results.stdout
Beispiel #21
0
def test_sni_match(managed_process, provider, protocol, cert_test_case):
    host = "localhost"
    port = next(available_ports)

    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host=host,
                                     port=port,
                                     insecure=False,
                                     verify_hostname=True,
                                     server_name=cert_test_case.client_sni,
                                     cipher=cert_test_case.client_ciphers,
                                     protocol=protocol)

    server_options = ProviderOptions(mode=Provider.ServerMode,
                                     host=host,
                                     port=port,
                                     extra_flags=[],
                                     protocol=protocol)

    # Setup the certificate chain for S2ND based on the multicert test case
    cert_key_list = [(cert[0], cert[1])
                     for cert in cert_test_case.server_certs]
    for cert_key_path in cert_key_list:
        server_options.extra_flags.extend(['--cert', cert_key_path[0]])
        server_options.extra_flags.extend(['--key', cert_key_path[1]])

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0

    expected_version = get_expected_s2n_version(protocol, provider)

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(
            expected_version).encode('utf-8')) in results.stdout
        if cert_test_case.client_sni is not None:
            assert bytes("Server name: {}".format(
                cert_test_case.client_sni).encode('utf-8')) in results.stdout
def test_session_resumption_s2n_server(managed_process, cipher, curve,
                                       protocol, provider, certificate,
                                       use_ticket):
    host = "localhost"
    port = next(available_ports)

    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     insecure=True,
                                     reconnect=True,
                                     protocol=protocol)

    server_options = copy.copy(client_options)
    server_options.reconnects_before_exit = 6
    server_options.mode = Provider.ServerMode
    server_options.use_session_ticket = use_ticket,
    server_options.key = certificate.key
    server_options.cert = certificate.cert

    # 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 client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert results.stdout.count(bytes("Session-ID:".encode('utf-8'))) == 6

    expected_version = get_expected_s2n_version(protocol, OpenSSL)

    # S2N should indicate the procotol version in a successful connection.
    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert results.stdout.count(
            bytes("Actual protocol version: {}".format(
                expected_version).encode('utf-8'))) == 6
Beispiel #23
0
def test_pq_handshake(managed_process, vector):
    host = "localhost"
    port = next(available_ports)

    # We are manually passing the cipher flag to s2nc and s2nd.
    # This is because PQ ciphers are specific to S2N at this point
    # in time.
    client_options = ProviderOptions(
        mode=Provider.ClientMode,
        host=host,
        port=port,
        insecure=True,
        cipher=None,
        extra_flags=['--ciphers', vector['client_ciphers'].name],
        protocol=Protocols.TLS12)

    server_options = ProviderOptions(
        mode=Provider.ServerMode,
        host=host,
        port=port,
        cipher=None,
        extra_flags=['--ciphers', vector['server_ciphers'].name],
        protocol=Protocols.TLS12)

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(S2N, client_options, timeout=5)

    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0

    expected_version = get_expected_s2n_version(Protocols.TLS12, S2N)

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("Actual protocol version: {}".format(
            expected_version).encode('utf-8')) in results.stdout
        assert bytes("KEM: {}".format(
            vector['expected_kem']).encode('utf-8')) in results.stdout
        assert bytes("Cipher negotiated: {}".format(
            vector['expected_cipher']).encode('utf-8')) in results.stdout
Beispiel #24
0
def test_session_resumption_s2n_client(managed_process, cipher, curve,
                                       protocol, provider, certificate,
                                       use_ticket):
    port = next(available_ports)

    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     insecure=True,
                                     reconnect=True,
                                     use_session_ticket=use_ticket,
                                     protocol=protocol)

    server_options = copy.copy(client_options)
    server_options.reconnects_before_exit = 6
    server_options.mode = Provider.ServerMode
    server_options.key = certificate.key
    server_options.cert = certificate.cert
    server_options.use_session_ticket = False

    # 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)

    expected_version = get_expected_s2n_version(protocol, OpenSSL)
    for results in client.get_results():
        results.assert_success()
        assert results.stdout.count(
            to_bytes(
                "Actual protocol version: {}".format(expected_version))) == 6

    for results in server.get_results():
        results.assert_success()
        assert results.stdout.count(to_bytes("6 server accepts that finished"))
Beispiel #25
0
def test_tls13_session_resumption_s2n_server(managed_process, tmp_path, cipher,
                                             curve, protocol, provider,
                                             certificate):
    port = str(next(available_ports))

    # Use temp directory to store session tickets
    p = tmp_path / 'ticket.pem'
    path_to_ticket = str(p)

    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     insecure=True,
                                     reconnect=False,
                                     data_to_send=data_bytes(4069),
                                     extra_flags=['-sess_out', path_to_ticket],
                                     protocol=protocol)

    server_options = copy.copy(client_options)
    server_options.mode = Provider.ServerMode
    server_options.key = certificate.key
    server_options.cert = certificate.cert
    server_options.use_session_ticket = True
    server_options.extra_flags = None

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    # The client should have received a session ticket
    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert b'Post-Handshake New Session Ticket arrived:' in results.stdout

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        # The first connection is a full handshake
        assert b'Resumed session' not in results.stdout

    # Client inputs received session ticket to resume a session
    assert os.path.exists(path_to_ticket)
    client_options.extra_flags = ['-sess_in', path_to_ticket]

    port = str(next(available_ports))
    client_options.port = port
    server_options.port = port

    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    s2n_version = get_expected_s2n_version(protocol, provider)

    # Client has not read server certificate message as this is a resumed session
    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("SSL_connect:SSLv3/TLS read server certificate".encode(
            'utf-8')) not in results.stderr

    # The server should indicate a session has been resumed
    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert not results.stderr
        assert b'Resumed session' in results.stdout
        assert bytes("Actual protocol version: {}".format(s2n_version).encode(
            'utf-8')) in results.stdout
Beispiel #26
0
def test_s2nd_falls_back_to_full_connection(managed_process, tmp_path, cipher,
                                            curve, protocol, provider,
                                            certificate):
    port = str(next(available_ports))

    # Use temp directory to store session tickets
    p = tmp_path / 'ticket.pem'
    path_to_ticket = str(p)
    """
    This test will set up a full connection with an Openssl client and server to obtain
    a valid Openssl session ticket. Then, the Openssl client attempts to send the 
    received session ticket to an s2n server to resume a session. s2nd will fallback to
    a full connection as it does not recognize the session ticket.
    """
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host="localhost",
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     insecure=True,
                                     reconnect=False,
                                     extra_flags=['-sess_out', path_to_ticket],
                                     data_to_send=data_bytes(4069),
                                     protocol=protocol)

    server_options = copy.copy(client_options)
    server_options.mode = Provider.ServerMode
    server_options.key = certificate.key
    server_options.cert = certificate.cert
    server_options.extra_flags = None

    server = managed_process(provider, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    # The client should have received a session ticket
    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert b'Post-Handshake New Session Ticket arrived:' in results.stdout

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        # Server should have sent certificate message as this is a full connection
        assert b'SSL_accept:SSLv3/TLS write certificate' in results.stderr

    # Client inputs received session ticket to resume a session
    assert os.path.exists(path_to_ticket)
    client_options.extra_flags = ['-sess_in', path_to_ticket]

    port = str(next(available_ports))
    client_options.port = port
    server_options.port = port

    # Switch providers so now s2n is the server
    server = managed_process(S2N, server_options, timeout=5)
    client = managed_process(provider, client_options, timeout=5)

    s2n_version = get_expected_s2n_version(protocol, provider)

    # Client has read server certificate because this is a full connection
    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert bytes("SSL_connect:SSLv3/TLS read server certificate".encode(
            'utf-8')) in results.stderr

    # The server should indicate a session has not been resumed
    for results in server.get_results():
        assert results.exception is None
        assert not results.stderr
        assert results.exit_code == 0
        assert b'Resumed session' not in results.stdout
        assert bytes("Actual protocol version: {}".format(s2n_version).encode(
            'utf-8')) in results.stdout