Skip to content

test: add sslv2 client hello test w/ jvm #5019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bin/s2nd.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ int handle_connection(int fd, struct s2n_config *config, struct conn_settings se
GUARD_RETURN(wait_for_shutdown(conn, fd), "Error closing connection");
}

if (s2n_connection_get_client_hello_version(conn) == S2N_SSLv2) {
fprintf(stdout, "Warning: deprecated SSLv2-style ClientHello");
}

GUARD_RETURN(s2n_connection_wipe(conn), "Error wiping connection");

GUARD_RETURN(s2n_connection_free(conn), "Error freeing connection");
Expand Down
2 changes: 1 addition & 1 deletion codebuild/spec/buildspec_ubuntu_integrationv2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ batch:
- openssl-1.1.1_gcc9
- openssl-3.0
INTEGV2_TEST:
- "test_dynamic_record_sizes test_sslyze"
- "test_dynamic_record_sizes test_sslyze test_sslv2_client_hello"

env:
variables:
Expand Down
16 changes: 11 additions & 5 deletions tests/integrationv2/bin/SSLSocketClient.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.security.KeyStore;
import java.io.FileInputStream;
import java.io.OutputStream;
Expand All @@ -18,14 +19,16 @@ public class SSLSocketClient {
public static void main(String[] args) throws Exception {
int port = Integer.parseInt(args[0]);
String certificatePath = args[1];
String protocol = sslProtocols(args[2]);
String[] protocolList = new String[] {protocol};
String[] cipher = new String[] {args[3]};
String[] cipher = new String[] {args[2]};
String[] protocolList = Arrays.copyOfRange(args, 3, args.length);
for (int i = 0; i < protocolList.length; i++) {
protocolList[i] = sslProtocols(protocolList[i]);
}

String host = "localhost";
byte[] buffer = new byte[100];

SSLSocketFactory socketFactory = createSocketFactory(certificatePath, protocol);
SSLSocketFactory socketFactory = createSocketFactory(certificatePath, protocolList[0]);

try (
SSLSocket socket = (SSLSocket)socketFactory.createSocket(host, port);
Expand Down Expand Up @@ -94,6 +97,9 @@ public static String sslProtocols(String s2nProtocol) {
return "TLSv1.0";
}

return null;
// "Protocols" are other used for other configuration, outside of explicit
// TLS versions. If the protocol is not a recognized TLS version, pass it
// through.
return s2nProtocol;
}
}
2 changes: 1 addition & 1 deletion tests/integrationv2/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ def __init__(
# Boolean whether to use a resumption ticket
self.use_session_ticket = use_session_ticket

# Boolean whether to allow insecure certificates
# Boolean whether to disable x509 verification
self.insecure = insecure

# Which protocol to use with this provider
Expand Down
8 changes: 6 additions & 2 deletions tests/integrationv2/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,12 +602,16 @@ def setup_client(self):
cmd_line.extend([self.options.trust_store])
elif self.options.cert:
cmd_line.extend([self.options.cert])
if self.options.cipher.iana_standard_name is not None:
cmd_line.extend([self.options.cipher.iana_standard_name])

if self.options.protocol is not None:
cmd_line.extend([self.options.protocol.name])
# SSLv2ClientHello is a "protocol" for Java TLS, so we append it next to
# the existing protocol.
if self.options.extra_flags is not None:
cmd_line.extend(self.options.extra_flags)

if self.options.cipher.iana_standard_name is not None:
cmd_line.extend([self.options.cipher.iana_standard_name])

# Clients are always ready to connect
self.set_provider_ready()
Expand Down
73 changes: 73 additions & 0 deletions tests/integrationv2/test_sslv2_client_hello.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
import copy

from configuration import available_ports
from common import Certificates, Ciphers, Protocols, ProviderOptions, data_bytes
from fixtures import managed_process # lgtm [py/unused-import]
from providers import Provider, S2N, JavaSSL
from utils import (
to_bytes,
)

SSLV2_CLIENT_HELLO_MARKER = "Warning: deprecated SSLv2-style ClientHello"


def test_s2n_server_sslv2_client_hello(managed_process):
# TLS 1.3: not supported by SSLv2 ClientHellos
# TLS 1.2: supported
# TLS 1.0 - TLS 1.1: not supported by Java
TEST_PROTOCOL = Protocols.TLS12

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)

certificate = Certificates.RSA_2048_SHA256

client_options = ProviderOptions(
mode=Provider.ClientMode,
port=port,
# The cipher must use RSA key exchange. ECDHE is not supported with
# SSLv2 formatted client hellos.
cipher=Ciphers.AES256_SHA256,
cert=certificate.cert,
data_to_send=random_bytes,
insecure=True,
protocol=TEST_PROTOCOL,
extra_flags="SSLv2Hello",
)

server_options = copy.copy(client_options)
server_options.mode = Provider.ServerMode
server_options.data_to_send = None
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(JavaSSL, 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 client_results in client.get_results():
client_results.assert_success()

# The server is always S2N in this test, so we can examine
# the stdout reliably.
for server_results in server.get_results():
server_results.assert_success()
assert SSLV2_CLIENT_HELLO_MARKER in server_results.stdout
assert (
to_bytes("Actual protocol version: {}".format(TEST_PROTOCOL.value))
in server_results.stdout
)
assert random_bytes in server_results.stdout
Loading