Exemplo n.º 1
0
def test_well_known_endpoints(managed_process, protocol, endpoint, provider,
                              cipher):
    port = "443"

    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host=endpoint,
                                     port=port,
                                     insecure=False,
                                     trust_store=TRUST_STORE_BUNDLE,
                                     protocol=protocol,
                                     cipher=cipher)

    if get_flag(S2N_FIPS_MODE) is True:
        client_options.trust_store = "../integration/trust-store/ca-bundle.trust.crt"
    else:
        client_options.trust_store = "../integration/trust-store/ca-bundle.crt"

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

    expected_result = EXPECTED_RESULTS.get((endpoint, cipher), None)

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

        if expected_result is not None:
            assert bytes(
                expected_result['cipher'].encode('utf-8')) in results.stdout
            assert bytes(
                expected_result['kem'].encode('utf-8')) in results.stdout
Exemplo n.º 2
0
def test_well_known_endpoints(managed_process, protocol, endpoint):
    port = "443"

    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host=endpoint['endpoint'],
                                     port=port,
                                     insecure=False,
                                     client_trust_store=TRUST_STORE_BUNDLE,
                                     protocol=protocol)

    if get_flag(S2N_FIPS_MODE) is True:
        client_options.client_trust_store = "../integration/trust-store/ca-bundle.trust.crt"
    else:
        client_options.client_trust_store = "../integration/trust-store/ca-bundle.crt"

    if 'cipher_preference_version' in endpoint:
        client_options.cipher = endpoint['cipher_preference_version']

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

    for results in client.get_results():
        if results.exception is not None or results.exit_code != 0:
            assert endpoint['endpoint'] in expected_failures

        if 'expected_cipher' in endpoint:
            assert bytes(
                endpoint['expected_cipher'].encode('utf-8')) in results.stdout
Exemplo n.º 3
0
def test_oqs_openssl_to_s2nd_pq_handshake(managed_process, protocol, cipher,
                                          kem_group):
    # If PQ is not enabled in s2n, there is no reason to test against oqs_openssl
    if not pq_enabled():
        return

    port = next(available_ports)

    client_options = ProviderOptions(
        mode=Provider.ClientMode,
        port=port,
        protocol=protocol,
        env_overrides=get_oqs_openssl_override_env_vars(),
        extra_flags=['-groups', kem_group.oqs_name])

    server_options = ProviderOptions(mode=Provider.ServerMode,
                                     port=port,
                                     protocol=protocol,
                                     cipher=cipher,
                                     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)

    expected_result = EXPECTED_RESULTS.get((kem_group, cipher), None)

    for results in client.get_results():
        # Client is OQS OpenSSL; just ensure the process exited successfully
        results.assert_success()

    for results in server.get_results():
        # Server is s2n; can make meaningful assertions about negotiation
        results.assert_success()
        assert_s2n_negotiation_parameters(results, expected_result)
Exemplo n.º 4
0
def test_well_known_endpoints(managed_process, protocol, endpoint, provider,
                              cipher):
    port = "443"

    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host=endpoint,
                                     port=port,
                                     insecure=False,
                                     trust_store=TRUST_STORE_BUNDLE,
                                     protocol=protocol,
                                     cipher=cipher)

    if get_flag(S2N_FIPS_MODE) is True:
        client_options.trust_store = "../integration/trust-store/ca-bundle.trust.crt"
    else:
        client_options.trust_store = "../integration/trust-store/ca-bundle.crt"

    # expect_stderr=True because S2N sometimes receives OCSP responses:
    # https://github.com/aws/s2n-tls/blob/14ed186a13c1ffae7fbb036ed5d2849ce7c17403/bin/echo.c#L180-L184
    client = managed_process(provider,
                             client_options,
                             timeout=5,
                             expect_stderr=True)

    expected_result = EXPECTED_RESULTS.get((endpoint, cipher), None)

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

        if expected_result is not None:
            assert to_bytes(expected_result['cipher']) in results.stdout
            assert to_bytes(expected_result['kem']) in results.stdout
Exemplo n.º 5
0
def test_s2n_server_ocsp_response(managed_process, cipher, provider,
                                  other_provider, curve, protocol,
                                  certificate):
    port = next(available_ports)

    random_bytes = data_bytes(128)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     protocol=protocol,
                                     insecure=True,
                                     data_to_send=random_bytes,
                                     enable_client_ocsp=True)

    server_options = ProviderOptions(
        mode=Provider.ServerMode,
        port=port,
        cipher=cipher,
        curve=curve,
        protocol=protocol,
        insecure=True,
        key=certificate.key,
        cert=certificate.cert,
        ocsp_response={
            "RSA": TEST_OCSP_DIRECTORY + "ocsp_response.der",
            "EC": TEST_OCSP_DIRECTORY + "ocsp_ecdsa_response.der"
        }.get(certificate.algorithm),
    )

    kill_marker = None
    if provider == GnuTLS:
        # The GnuTLS client hangs for a while after sending. Speed up the tests by killing
        # it immediately after sending the message.
        kill_marker = b"Sent: "

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

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

        assert any([{
            GnuTLS:
            b"OCSP Response Information:\n\tResponse Status: Successful",
            OpenSSL: b"OCSP Response Status: successful"
        }.get(provider) in stream
                    for stream in client_results.output_streams()])

    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()
        ])
Exemplo n.º 6
0
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
Exemplo n.º 7
0
def test_s2n_client_ocsp_response(managed_process, cipher, provider,
                                  other_provider, curve, protocol,
                                  certificate):
    if "boringssl" in get_flag(S2N_PROVIDER_VERSION):
        pytest.skip("s2n-tls client with boringssl does not support ocsp")

    port = next(available_ports)

    random_bytes = data_bytes(128)
    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     port=port,
                                     cipher=cipher,
                                     curve=curve,
                                     protocol=protocol,
                                     insecure=True,
                                     data_to_send=random_bytes,
                                     enable_client_ocsp=True)

    server_options = ProviderOptions(
        mode=Provider.ServerMode,
        port=port,
        cipher=cipher,
        curve=curve,
        protocol=protocol,
        key=certificate.key,
        cert=certificate.cert,
        ocsp_response={
            "RSA": TEST_OCSP_DIRECTORY + "ocsp_response.der",
            "EC": TEST_OCSP_DIRECTORY + "ocsp_ecdsa_response.der"
        }.get(certificate.algorithm),
    )

    kill_marker = None

    if provider == GnuTLS:
        kill_marker = random_bytes

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

    for client_results in client.get_results():
        client_results.assert_success()
        assert b"OCSP response received" in client_results.stdout

    for server_results in server.get_results():
        server_results.assert_success()
        # Avoid debugging information that sometimes gets inserted after the first character.
        assert random_bytes[1:] in server_results.stdout or random_bytes[
            1:] in server_results.stderr
Exemplo n.º 8
0
def test_s2nc_to_s2nd_pq_handshake(managed_process, protocol, certificate,
                                   client_cipher, server_cipher, provider,
                                   other_provider):
    # Incorrect cipher is negotiated when both ciphers are PQ_TLS_1_0_2020_12 with
    # openssl 1.0.2, boringssl, and libressl libcryptos
    if all([
            client_cipher == Ciphers.PQ_TLS_1_0_2020_12,
            server_cipher == Ciphers.PQ_TLS_1_0_2020_12,
            any([
                libcrypto in get_flag(S2N_PROVIDER_VERSION)
                for libcrypto in ["boringssl", "libressl", "openssl-1.0.2"]
            ])
    ]):
        pytest.skip()

    port = next(available_ports)

    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     port=port,
                                     insecure=True,
                                     cipher=client_cipher,
                                     protocol=protocol)

    server_options = ProviderOptions(mode=Provider.ServerMode,
                                     port=port,
                                     protocol=protocol,
                                     cipher=server_cipher,
                                     cert=certificate.cert,
                                     key=certificate.key)

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

    if pq_enabled():
        expected_result = EXPECTED_RESULTS.get((client_cipher, server_cipher),
                                               None)
    else:
        # If PQ is not enabled in s2n, we expect classic handshakes to be negotiated.
        # Leave the expected cipher blank, as there are multiple possibilities - the
        # important thing is that kem and kem_group are NONE.
        expected_result = {"cipher": "", "kem": "NONE", "kem_group": "NONE"}

    # Client and server are both s2n; can make meaningful assertions about negotiation for both
    for results in client.get_results():
        results.assert_success()
        assert_s2n_negotiation_parameters(results, expected_result)

    for results in server.get_results():
        results.assert_success()
        assert_s2n_negotiation_parameters(results, expected_result)
Exemplo n.º 9
0
def test_s2n_client_with_early_data_rejected_via_hrr(managed_process, tmp_path,
                                                     cipher, curve,
                                                     certificate, protocol,
                                                     provider, other_provider,
                                                     early_data_size):
    if provider == S2N:
        pytest.skip(
            "S2N does not respect ProviderOptions.curve, so does not trigger a retry"
        )

    early_data_file = str(tmp_path / EARLY_DATA_FILE)
    early_data = get_early_data_bytes(early_data_file, early_data_size)

    options = ProviderOptions(
        port=next(available_ports),
        cipher=cipher,
        curve=curve,
        protocol=protocol,
        insecure=True,
        use_session_ticket=True,
        reconnect=True,
    )
    options.ticket_file = None
    options.early_data_file = early_data_file
    options.max_early_data = MAX_EARLY_DATA

    client_options = copy.copy(options)
    client_options.mode = Provider.ClientMode

    server_options = copy.copy(options)
    server_options.mode = Provider.ServerMode
    server_options.key = certificate.key  # Required for the initial connection
    server_options.cert = certificate.cert  # Required for the initial connection
    server_options.reconnects_before_exit = NUM_CONNECTIONS

    server = managed_process(provider, server_options, timeout=10)
    s2n_client = managed_process(S2N, client_options, timeout=10)

    for results in s2n_client.get_results():
        results.assert_success()
        assert S2N_EARLY_DATA_MARKER not in results.stdout
        assert S2N_HRR_MARKER in results.stdout
        assert results.stdout.count(
            to_bytes(S2N_EARLY_DATA_REJECTED_MARKER)) == NUM_RESUMES

    for results in server.get_results():
        results.assert_success()
        assert early_data not in results.stdout
def test_s2n_client_happy_path(managed_process, cipher, curve, provider):
    host = "localhost"
    port = next(available_ports)

    client_options = ProviderOptions(
        mode="client",
        host="localhost",
        port=port,
        cipher=cipher,
        insecure=True,
        tls13=True)

    server_options = copy.copy(client_options)
    server_options.mode = "server"
    server_options.key = "../pems/ecdsa_p384_pkcs1_key.pem"
    server_options.cert = "../pems/ecdsa_p384_pkcs1_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(provider, server_options, timeout=5)
    client = managed_process(S2N, client_options, timeout=5)

    # 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 b"Actual protocol version: 34" 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
Exemplo n.º 11
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
Exemplo n.º 12
0
def setup_provider_options(mode, port, cipher, curve, certificate,
                           data_to_send, client_psk_params):
    options = ProviderOptions(host="localhost",
                              port=port,
                              cipher=cipher,
                              curve=curve,
                              insecure=True,
                              protocol=Protocols.TLS13,
                              data_to_send=data_to_send,
                              mode=mode,
                              extra_flags=client_psk_params)
    if certificate:
        options.key = certificate.key
        options.cert = certificate.cert
        options.trust_store = certificate.cert
    return options
Exemplo n.º 13
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
Exemplo n.º 14
0
def test_sslyze_certificate_scans(managed_process, protocol, certificate):
    port = next(available_ports)

    server_options = ProviderOptions(mode=S2N.ServerMode,
                                     host=HOST,
                                     port=port,
                                     protocol=protocol,
                                     key=certificate.key,
                                     cert=certificate.cert,
                                     insecure=True,
                                     extra_flags=["--parallelize"])
    server = managed_process(S2N, server_options, timeout=30)

    scans = [CIPHER_SUITE_SCANS.get(protocol.value)]

    # sslyze curves scan errors when given ECDSA certs
    if "ECDSA" not in certificate.name:
        scans.append(sslyze.ScanCommand.ELLIPTIC_CURVES)

    scan_attempt_results = run_sslyze_scan(HOST, port, scans)

    for scan_attempt_result in scan_attempt_results:
        assert_scan_result_completed(scan_attempt_result)

        scan_result = scan_attempt_result.scan_result
        scan_attempts = get_scan_attempts(scan_result)
        for scan_attempt in scan_attempts:
            validate_scan_result(scan_attempt, protocol, certificate)

    server.kill()
Exemplo n.º 15
0
def test_sslyze_certificate_scans(managed_process, protocol, certificate,
                                  provider, certificate_scan):
    port = next(available_ports)

    server_options = ProviderOptions(mode=S2N.ServerMode,
                                     host=HOST,
                                     port=port,
                                     protocol=protocol,
                                     key=certificate.key,
                                     cert=certificate.cert,
                                     insecure=True,
                                     extra_flags=["--parallelize"])
    server = managed_process(S2N, server_options, timeout=30)

    scan = {
        CertificateScan.CIPHER_SUITE_SCAN:
        CIPHER_SUITE_SCANS.get(protocol.value),
        CertificateScan.ELLIPTIC_CURVE_SCAN: sslyze.ScanCommand.ELLIPTIC_CURVES
    }.get(certificate_scan)

    scan_attempt_results = run_sslyze_scan(HOST, port, [scan])

    for scan_attempt_result in scan_attempt_results:
        assert_scan_result_completed(scan_attempt_result)

        scan_result = scan_attempt_result.scan_result
        scan_attempts = get_scan_attempts(scan_result)
        for scan_attempt in scan_attempts:
            validate_scan_result(scan_attempt, protocol, certificate)

    server.kill()
Exemplo n.º 16
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
Exemplo n.º 17
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()
        ])
Exemplo n.º 18
0
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
Exemplo n.º 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
Exemplo n.º 20
0
def test_s2n_server_with_early_data_rejected_via_hrr(managed_process, tmp_path,
                                                     cipher, curve,
                                                     certificate, protocol,
                                                     provider, other_provider,
                                                     early_data_size):
    ticket_file = str(tmp_path / TICKET_FILE)
    early_data_file = str(tmp_path / EARLY_DATA_FILE)
    early_data = get_early_data_bytes(early_data_file, early_data_size)

    options = ProviderOptions(
        port=next(available_ports),
        cipher=cipher,
        curve=(S2N_UNSUPPORTED_CURVE + ":" + str(curve)),
        protocol=protocol,
        insecure=True,
        use_session_ticket=True,
        data_to_send=DATA_TO_SEND,
    )
    options.ticket_file = ticket_file
    options.early_data_file = early_data_file
    options.max_early_data = MAX_EARLY_DATA

    get_ticket_from_s2n_server(options, managed_process, provider, certificate)

    client_options = copy.copy(options)
    client_options.mode = Provider.ClientMode

    server_options = copy.copy(options)
    server_options.mode = Provider.ServerMode

    s2n_server = managed_process(S2N, server_options, timeout=10)
    client = managed_process(provider, client_options, timeout=10)

    for results in client.get_results():
        results.assert_success()
        assert early_data not in results.stdout

    for results in s2n_server.get_results():
        results.assert_success()
        assert S2N_EARLY_DATA_MARKER not in results.stdout
        assert S2N_HRR_MARKER in results.stdout
        assert to_bytes(S2N_EARLY_DATA_RECV_MARKER) not in results.stdout
        assert to_bytes(S2N_EARLY_DATA_REJECTED_MARKER) in results.stdout
        assert DATA_TO_SEND in results.stdout
Exemplo n.º 21
0
def test_s2n_client_key_update(managed_process, cipher):
    host = "localhost"
    port = next(available_ports)

    update_requested = b"K\n"
    server_data = data_bytes(10)
    client_data = data_bytes(10)
    # Last statement printed out by Openssl after handshake
    starting_marker = "Secure Renegotiation IS supported"
    key_update_marker = "TLSv1.3 write server key update"
    read_key_update_marker = b"TLSv1.3 read client key update"

    send_marker_list = [starting_marker, key_update_marker]

    client_options = ProviderOptions(
        mode=Provider.ClientMode,
        host=host,
        port=port,
        cipher=cipher,
        data_to_send=[client_data],
        insecure=True,
        protocol=Protocols.TLS13,
    )

    server_options = copy.copy(client_options)

    server_options.mode = Provider.ServerMode
    server_options.key = "../pems/ecdsa_p384_pkcs1_key.pem"
    server_options.cert = "../pems/ecdsa_p384_pkcs1_cert.pem"
    server_options.data_to_send = [update_requested, server_data]

    server = managed_process(
        OpenSSL,
        server_options,
        send_marker=send_marker_list,
        close_marker=str(client_data),
        timeout=5,
    )
    client = managed_process(
        S2N,
        client_options,
        send_marker=[str(server_data)],
        close_marker=str(server_data),
        timeout=5,
    )

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

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert read_key_update_marker in results.stderr
        assert client_data in results.stdout
Exemplo n.º 22
0
def test_s2n_new_server_old_ticket(managed_process, tmp_path, cipher, curve,
                                   certificate, protocol, provider,
                                   other_provider):
    ticket_file = str(tmp_path / TICKET_FILE)
    assert not os.path.exists(ticket_file)

    options = ProviderOptions(
        port=next(available_ports),
        cipher=cipher,
        curve=curve,
        protocol=protocol,
        insecure=True,
        use_session_ticket=True,
    )

    client_options = copy.copy(options)
    client_options.mode = Provider.ClientMode
    client_options.extra_flags = ['-sess_out', ticket_file]

    server_options = copy.copy(options)
    server_options.mode = Provider.ServerMode
    server_options.use_mainline_version = True
    server_options.key = certificate.key
    server_options.cert = certificate.cert
    server_options.data_to_send = CLOSE_MARKER_BYTES

    s2n_server = managed_process(S2N,
                                 server_options,
                                 send_marker=S2N.get_send_marker())
    client = managed_process(provider,
                             client_options,
                             close_marker=str(CLOSE_MARKER_BYTES))

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

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

    assert os.path.exists(ticket_file)
    client_options.extra_flags = ['-sess_in', ticket_file]
    server_options.use_mainline_version = False

    s2n_server = managed_process(S2N,
                                 server_options,
                                 send_marker=S2N.get_send_marker())
    client = managed_process(provider,
                             client_options,
                             close_marker=str(CLOSE_MARKER_BYTES))

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

    for results in s2n_server.get_results():
        results.assert_success()
        assert S2N_RESUMPTION_MARKER in results.stdout
Exemplo n.º 23
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
Exemplo n.º 24
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()
        ])
Exemplo n.º 25
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
Exemplo n.º 26
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
Exemplo n.º 27
0
def test_s2nc_to_s2nd_pq_handshake(managed_process, protocol, client_cipher,
                                   server_cipher):
    host = "localhost"
    port = next(available_ports)

    client_options = ProviderOptions(mode=Provider.ClientMode,
                                     host=host,
                                     port=port,
                                     insecure=True,
                                     cipher=client_cipher,
                                     protocol=protocol)

    server_options = ProviderOptions(mode=Provider.ServerMode,
                                     host=host,
                                     port=port,
                                     protocol=protocol,
                                     cipher=server_cipher,
                                     cert=Certificates.RSA_4096_SHA512.cert,
                                     key=Certificates.RSA_4096_SHA512.key)

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

    if pq_enabled():
        expected_result = EXPECTED_RESULTS.get((client_cipher, server_cipher),
                                               None)
    else:
        # If PQ is not enabled in s2n, we expect classic handshakes to be negotiated.
        # Leave the expected cipher blank, as there are multiple possibilities - the
        # important thing is that kem and kem_group are NONE.
        expected_result = {"cipher": "", "kem": "NONE", "kem_group": "NONE"}

    # Client and server are both s2n; can make meaningful assertions about negotiation for both
    for results in client.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert_s2n_negotiation_parameters(results, expected_result)

    for results in server.get_results():
        assert results.exception is None
        assert results.exit_code == 0
        assert_s2n_negotiation_parameters(results, expected_result)
Exemplo n.º 28
0
def test_hrr_with_s2n_as_server(managed_process, cipher, provider, curve,
                                protocol, certificate):
    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,
        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():
        assert results.exception is None
        assert results.exit_code == 0
        assert random_bytes in results.stdout
        assert bytes("Curve: {}".format(
            CURVE_NAMES[curve.name]).encode('utf-8')) in results.stdout
        assert random_bytes 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():
        assert results.exception is None
        assert results.exit_code == 0
        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
Exemplo n.º 29
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
Exemplo n.º 30
0
def test_s2n_server_with_early_data(managed_process, tmp_path, cipher, curve,
                                    protocol, provider, certificate,
                                    early_data_size):
    ticket_file = str(tmp_path / TICKET_FILE)
    early_data_file = str(tmp_path / EARLY_DATA_FILE)
    early_data = get_early_data_bytes(early_data_file, early_data_size)

    options = ProviderOptions(
        port=next(available_ports),
        cipher=cipher,
        curve=curve,
        protocol=protocol,
        insecure=True,
        use_session_ticket=True,
        data_to_send=DATA_TO_SEND,
    )
    options.ticket_file = ticket_file
    options.early_data_file = early_data_file
    options.max_early_data = MAX_EARLY_DATA

    get_ticket_from_s2n_server(options, managed_process, provider, certificate)

    client_options = copy.copy(options)
    client_options.mode = Provider.ClientMode

    server_options = copy.copy(options)
    server_options.mode = Provider.ServerMode

    s2n_server = managed_process(S2N, server_options)
    client = managed_process(provider, client_options)

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

    for results in s2n_server.get_results():
        results.assert_success()
        assert S2N_EARLY_DATA_MARKER in results.stdout
        assert (to_bytes(S2N_EARLY_DATA_RECV_MARKER) +
                early_data) in results.stdout
        assert to_bytes(S2N_EARLY_DATA_ACCEPTED_MARKER) in results.stdout
        assert DATA_TO_SEND in results.stdout