Skip to content

Commit

Permalink
Merge branch 'main' into generate_fix
Browse files Browse the repository at this point in the history
  • Loading branch information
lrstewart authored Jan 27, 2024
2 parents 1add887 + dcdb0ed commit 6f7778f
Show file tree
Hide file tree
Showing 16 changed files with 263 additions and 16 deletions.
6 changes: 4 additions & 2 deletions crypto/s2n_hmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,10 @@ bool s2n_hmac_is_available(s2n_hmac_algorithm hmac_alg)
case S2N_HMAC_MD5:
case S2N_HMAC_SSLv3_MD5:
case S2N_HMAC_SSLv3_SHA1:
/* Set is_available to 0 if in FIPS mode, as MD5/SSLv3 algs are not available in FIPS mode. */
return !s2n_is_in_fips_mode();
/* Some libcryptos, such as OpenSSL, disable MD5 by default when in FIPS mode, which is
* required in order to negotiate SSLv3. However, this is supported in AWS-LC.
*/
return !s2n_is_in_fips_mode() || s2n_libcrypto_is_awslc();
case S2N_HMAC_NONE:
case S2N_HMAC_SHA1:
case S2N_HMAC_SHA224:
Expand Down
1 change: 1 addition & 0 deletions error/s2n_errno.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ static const char *no_such_error = "Internal s2n error";
ERR_ENTRY(S2N_ERR_KTLS_RENEG, "kTLS does not support secure renegotiation") \
ERR_ENTRY(S2N_ERR_KTLS_KEYUPDATE, "Received KeyUpdate from peer, but kernel does not support updating tls keys") \
ERR_ENTRY(S2N_ERR_KTLS_KEY_LIMIT, "Reached key encryption limit, but kernel does not support updating tls keys") \
ERR_ENTRY(S2N_ERR_UNEXPECTED_CERT_REQUEST, "Client does not support mutual authentication") \
/* clang-format on */

#define ERR_STR_CASE(ERR, str) \
Expand Down
1 change: 1 addition & 0 deletions error/s2n_errno.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ typedef enum {
S2N_ERR_ENCRYPT = S2N_ERR_T_PROTO_START,
S2N_ERR_DECRYPT,
S2N_ERR_BAD_MESSAGE,
S2N_ERR_UNEXPECTED_CERT_REQUEST,
S2N_ERR_KEY_INIT,
S2N_ERR_KEY_DESTROY,
S2N_ERR_DH_SERIALIZING,
Expand Down
1 change: 1 addition & 0 deletions tests/cbmc/proofs/s2n_hmac_is_available/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ HARNESS_FILE = $(HARNESS_ENTRY).c
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE)
PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c
PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c
PROOF_SOURCES += $(PROOF_STUB)/s2n_libcrypto_is_awslc.c

PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hmac.c

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "crypto/s2n_fips.h"
#include "crypto/s2n_hmac.h"
#include "crypto/s2n_openssl.h"

#include <assert.h>

Expand All @@ -33,7 +34,7 @@ void s2n_hmac_is_available_harness()
case S2N_HASH_MD5:
case S2N_HMAC_SSLv3_MD5:
case S2N_HMAC_SSLv3_SHA1:
assert(is_available == !s2n_is_in_fips_mode()); break;
assert(is_available == !s2n_is_in_fips_mode() || s2n_libcrypto_is_awslc()); break;
case S2N_HASH_NONE:
case S2N_HASH_SHA1:
case S2N_HASH_SHA224:
Expand Down
31 changes: 31 additions & 0 deletions tests/cbmc/stubs/s2n_libcrypto_is_awslc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
* this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <cbmc_proof/nondet.h>

#include <stdbool.h>
#include "crypto/s2n_openssl.h"

static int flag = 0;
static bool s2n_awslc_flag = 0;

bool s2n_libcrypto_is_awslc()
{
if (flag == 0) {
s2n_awslc_flag = nondet_bool() ? 1 : 0;
flag = 1;
}
return s2n_awslc_flag;
}
7 changes: 5 additions & 2 deletions tests/integrationv2/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,11 @@ class Curves(object):
"""
X25519 = Curve("X25519", Protocols.TLS13)
P256 = Curve("P-256")
P384 = Curve("P-384")
P521 = Curve("P-521")
# Our only SSLv3 provider doesn't support extensions
# so there is no way to negotiate a curve other than the
# default P-256 in SSLv3.
P384 = Curve("P-384", Protocols.TLS10)
P521 = Curve("P-521", Protocols.TLS10)
SecP256r1Kyber768Draft00 = Curve("SecP256r1Kyber768Draft00")
X25519Kyber768Draft00 = Curve("X25519Kyber768Draft00")

Expand Down
1 change: 1 addition & 0 deletions tests/integrationv2/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
Protocols.TLS12,
Protocols.TLS11,
Protocols.TLS10,
Protocols.SSLv3,
]


Expand Down
38 changes: 37 additions & 1 deletion tests/integrationv2/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,15 @@ def supports_protocol(cls, protocol, with_cert=None):
# e.g. "openssl-1.0" in "openssl-1.0.2-fips"
if unsupported_lc in current_libcrypto:
return False

# SSLv3 cannot be negotiated in FIPS mode with libcryptos other than AWS-LC.
if all([
protocol == Protocols.SSLv3,
get_flag(S2N_FIPS_MODE),
"awslc" not in get_flag(S2N_PROVIDER_VERSION)
]):
return False

return True

@classmethod
Expand Down Expand Up @@ -468,6 +477,9 @@ def get_version(cls):

@classmethod
def supports_protocol(cls, protocol, with_cert=None):
if protocol is Protocols.SSLv3:
return False

return True

@classmethod
Expand Down Expand Up @@ -507,6 +519,8 @@ def setup_client(self):
cmd_line.append('-tls1_1')
elif self.options.protocol == Protocols.TLS10:
cmd_line.append('-tls1')
elif self.options.protocol == Protocols.SSLv3:
cmd_line.append('-ssl3')

if self.options.cipher is not None:
cmd_line.extend(self._cipher_to_cmdline(self.options.cipher))
Expand Down Expand Up @@ -582,6 +596,8 @@ def setup_server(self):
cmd_line.append('-tls1_1')
elif self.options.protocol == Protocols.TLS10:
cmd_line.append('-tls1')
elif self.options.protocol == Protocols.SSLv3:
cmd_line.append('-ssl3')

if self.options.cipher is not None:
cmd_line.extend(self._cipher_to_cmdline(self.options.cipher))
Expand All @@ -607,6 +623,26 @@ def setup_server(self):
return cmd_line


class SSLv3Provider(OpenSSL):
def __init__(self, options: ProviderOptions):
OpenSSL.__init__(self, options)
self._override_libssl(options)

def _override_libssl(self, options: ProviderOptions):
install_dir = os.environ["OPENSSL_1_0_2_INSTALL_DIR"]

override_env_vars = dict()
override_env_vars["PATH"] = install_dir + "/bin"
override_env_vars["LD_LIBRARY_PATH"] = install_dir + "/lib"
options.env_overrides = override_env_vars

@classmethod
def supports_protocol(cls, protocol, with_cert=None):
if protocol is Protocols.SSLv3:
return True
return False


class JavaSSL(Provider):
"""
NOTE: Only a Java SSL client has been set up. The server has not been
Expand All @@ -623,7 +659,7 @@ def get_send_marker(cls):
@classmethod
def supports_protocol(cls, protocol, with_cert=None):
# https://aws.amazon.com/blogs/opensource/tls-1-0-1-1-changes-in-openjdk-and-amazon-corretto/
if protocol is Protocols.TLS10 or protocol is Protocols.TLS11:
if protocol is Protocols.SSLv3 or protocol is Protocols.TLS10 or protocol is Protocols.TLS11:
return False

return True
Expand Down
12 changes: 5 additions & 7 deletions tests/integrationv2/test_happy_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@
from configuration import available_ports, ALL_TEST_CIPHERS, ALL_TEST_CURVES, ALL_TEST_CERTS, PROTOCOLS
from common import ProviderOptions, data_bytes
from fixtures import managed_process # lgtm [py/unused-import]
from providers import Provider, S2N, OpenSSL, JavaSSL, GnuTLS
from providers import Provider, S2N, OpenSSL, JavaSSL, GnuTLS, SSLv3Provider
from utils import invalid_test_parameters, get_parameter_name, get_expected_s2n_version, to_bytes


@pytest.mark.uncollect_if(func=invalid_test_parameters)
@pytest.mark.parametrize("cipher", ALL_TEST_CIPHERS, ids=get_parameter_name)
@pytest.mark.parametrize("provider", [S2N, OpenSSL, GnuTLS, JavaSSL])
@pytest.mark.parametrize("other_provider", [S2N], ids=get_parameter_name)
@pytest.mark.parametrize("provider", [S2N, OpenSSL, GnuTLS, JavaSSL, SSLv3Provider])
@pytest.mark.parametrize("curve", ALL_TEST_CURVES, ids=get_parameter_name)
@pytest.mark.parametrize("protocol", PROTOCOLS, ids=get_parameter_name)
@pytest.mark.parametrize("certificate", ALL_TEST_CERTS, ids=get_parameter_name)
def test_s2n_server_happy_path(managed_process, cipher, provider, other_provider, curve, protocol, certificate):
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
Expand Down Expand Up @@ -69,12 +68,11 @@ def test_s2n_server_happy_path(managed_process, cipher, provider, other_provider

@pytest.mark.uncollect_if(func=invalid_test_parameters)
@pytest.mark.parametrize("cipher", ALL_TEST_CIPHERS, ids=get_parameter_name)
@pytest.mark.parametrize("provider", [S2N, OpenSSL, GnuTLS])
@pytest.mark.parametrize("other_provider", [S2N], ids=get_parameter_name)
@pytest.mark.parametrize("provider", [S2N, OpenSSL, GnuTLS, SSLv3Provider])
@pytest.mark.parametrize("curve", ALL_TEST_CURVES, ids=get_parameter_name)
@pytest.mark.parametrize("protocol", PROTOCOLS, ids=get_parameter_name)
@pytest.mark.parametrize("certificate", ALL_TEST_CERTS, ids=get_parameter_name)
def test_s2n_client_happy_path(managed_process, cipher, provider, other_provider, curve, protocol, certificate):
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
Expand Down
2 changes: 1 addition & 1 deletion tests/integrationv2/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ skipsdist = True
[testenv]
# install pytest in the virtualenv where commands will be executed
setenv = S2N_INTEG_TEST = 1
passenv = DYLD_LIBRARY_PATH, LD_LIBRARY_PATH, OQS_OPENSSL_1_1_1_INSTALL_DIR, HOME, TOX_TEST_NAME
passenv = DYLD_LIBRARY_PATH, LD_LIBRARY_PATH, OQS_OPENSSL_1_1_1_INSTALL_DIR, OPENSSL_1_0_2_INSTALL_DIR, HOME, TOX_TEST_NAME
ignore_errors=False
deps =
pytest==7
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/s2n_client_auth_handshake_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ int main(int argc, char **argv)

EXPECT_SUCCESS(s2n_enable_tls13_in_test());

DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL,
s2n_cert_chain_and_key_ptr_free);
EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY));

/* client_auth handshake negotiation */
{
struct s2n_config *server_config, *client_config;
Expand Down Expand Up @@ -358,5 +363,31 @@ int main(int argc, char **argv)
s2n_test_client_auth_message_by_message(0);
};

/* Test unexpected certificate request */
{
DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT),
s2n_connection_ptr_free);
EXPECT_NOT_NULL(client);

DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free);
EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));

DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER),
s2n_connection_ptr_free);
EXPECT_NOT_NULL(server);
EXPECT_SUCCESS(s2n_connection_set_blinding(server, S2N_SELF_SERVICE_BLINDING));
EXPECT_SUCCESS(s2n_connection_set_config(server, config));

/* Enable client auth on the server, but not on the client */
EXPECT_SUCCESS(s2n_connection_set_client_auth_type(server, S2N_CERT_AUTH_OPTIONAL));

DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
EXPECT_SUCCESS(s2n_io_pair_init_non_blocking(&io_pair));
EXPECT_SUCCESS(s2n_connections_set_io_pair(client, server, &io_pair));

EXPECT_FAILURE_WITH_ERRNO(s2n_negotiate_test_server_and_client(server, client),
S2N_ERR_UNEXPECTED_CERT_REQUEST);
};

END_TEST();
}
2 changes: 1 addition & 1 deletion tests/unit/s2n_self_talk_ktls_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ int main(int argc, char **argv)

DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER),
s2n_connection_ptr_free);
EXPECT_NOT_NULL(client);
EXPECT_NOT_NULL(server);
EXPECT_SUCCESS(s2n_connection_set_config(server, config));

DEFER_CLEANUP(struct s2n_test_io_pair io_pair = { 0 }, s2n_io_pair_close);
Expand Down
Loading

0 comments on commit 6f7778f

Please sign in to comment.