Skip to content
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

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

Merged
merged 11 commits into from
Jan 16, 2025
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]);

jmayclin marked this conversation as resolved.
Show resolved Hide resolved
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
jmayclin marked this conversation as resolved.
Show resolved Hide resolved
// TLS versions. If the protocol is not a recognized TLS version, pass it
// through.
jmayclin marked this conversation as resolved.
Show resolved Hide resolved
return s2nProtocol;
}
}
2 changes: 1 addition & 1 deletion tests/integrationv2/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
RSA_1024_SHA256 = Cert("RSA_1024_SHA256", "rsa_1024_sha256_client")
RSA_1024_SHA384 = Cert("RSA_1024_SHA384", "rsa_1024_sha384_client")
RSA_1024_SHA512 = Cert("RSA_1024_SHA512", "rsa_1024_sha512_client")
RSA_2048_SHA256 = Cert("RSA_2048_SHA256", "rsa_2048_sha256_client")

Check failure

Code scanning / CodeQL

Hard-coded credentials Critical test

This hardcoded value is
used as credentials
.
RSA_2048_SHA384 = Cert("RSA_2048_SHA384", "rsa_2048_sha384_client")
RSA_2048_SHA512 = Cert("RSA_2048_SHA512", "rsa_2048_sha512_client")
RSA_3072_SHA256 = Cert("RSA_3072_SHA256", "rsa_3072_sha256_client")
Expand Down Expand Up @@ -574,7 +574,7 @@
# 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
83 changes: 83 additions & 0 deletions tests/integrationv2/test_sslv2_client_hello.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
import copy
import pytest
Fixed Show fixed Hide fixed

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


@pytest.mark.flaky(reruns=5, reruns_delay=2)
@pytest.mark.uncollect_if(func=invalid_test_parameters)
@pytest.mark.parametrize(
# TLS 1.3 finally drops support for SSLv2 Client Hellos, and can not be negotiated
# SSLv2 logic entails different protocol parsing, so make sure we are negotiating
# the correct protocols.
"protocol",
[
Protocols.TLS12,
Protocols.TLS11,
Protocols.TLS10,
],
ids=get_parameter_name,
)
def test_s2n_server_sslv2_client_hello(managed_process, protocol):
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.ServerMode,
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=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 (
to_bytes("Actual protocol version: {}".format(protocol))
in server_results.stdout
jmayclin marked this conversation as resolved.
Show resolved Hide resolved
)
assert random_bytes in server_results.stdout
Loading