From 22f089b6b5ebe3be380c33c926990fe891ae0da9 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Mon, 9 Aug 2021 16:13:16 -0700 Subject: [PATCH] fixes #1478 mbedTLS 3.0 is not API compatible with 2.x --- cmake/FindmbedTLS.cmake | 62 +++++++++++++------------ src/supplemental/tls/mbedtls/tls.c | 42 ++++++++++++++--- src/supplemental/tls/tls_common.c | 2 +- src/supplemental/tls/tls_test.c | 6 ++- tests/tls.c | 73 ++++++++++++++++++------------ tests/trantest.h | 2 +- 6 files changed, 121 insertions(+), 66 deletions(-) diff --git a/cmake/FindmbedTLS.cmake b/cmake/FindmbedTLS.cmake index 8c25ec9c4..f01039d6c 100644 --- a/cmake/FindmbedTLS.cmake +++ b/cmake/FindmbedTLS.cmake @@ -31,50 +31,56 @@ set(_MBEDTLS_ROOT_HINTS ${MBEDTLS_ROOT_DIR} ENV MBEDTLS_ROOT_DIR) include(FindPackageHandleStandardArgs) find_path(MBEDTLS_INCLUDE_DIR - NAMES mbedtls/ssl.h - HINTS ${_MBEDTLS_ROOT_HINTS} - PATHS /usr/local - PATH_SUFFIXES include) + NAMES mbedtls/ssl.h + HINTS ${_MBEDTLS_ROOT_HINTS} + PATHS /usr/local + PATH_SUFFIXES include) find_library(MBEDTLS_CRYPTO_LIBRARY - NAMES mbedcrypto - HINTS ${_MBEDTLS_ROOT_HINTS} - PATHS /usr/local - PATH_SUFFIXES lib) + NAMES mbedcrypto + HINTS ${_MBEDTLS_ROOT_HINTS} + PATHS /usr/local + PATH_SUFFIXES lib) find_library(MBEDTLS_X509_LIBRARY - NAMES mbedx509 - HINTS ${_MBEDTLS_ROOT_HINTS} - PATHS /usr/local - PATH_SUFFIXES lib) + NAMES mbedx509 + HINTS ${_MBEDTLS_ROOT_HINTS} + PATHS /usr/local + PATH_SUFFIXES lib) find_library(MBEDTLS_TLS_LIBRARY - NAMES mbedtls - HINTS ${_MBEDTLS_ROOT_HINTS} - PATHS /usr/local - PATH_SUFFIXES lib) + NAMES mbedtls + HINTS ${_MBEDTLS_ROOT_HINTS} + PATHS /usr/local + PATH_SUFFIXES lib) set(MBEDTLS_LIBRARIES - ${MBEDTLS_TLS_LIBRARY} - ${MBEDTLS_X509_LIBRARY} - ${MBEDTLS_CRYPTO_LIBRARY}) + ${MBEDTLS_TLS_LIBRARY} + ${MBEDTLS_X509_LIBRARY} + ${MBEDTLS_CRYPTO_LIBRARY}) if (${MBEDTLS_TLS_LIBRARY-NOTFOUND}) message(FATAL_ERROR "Failed to find Mbed TLS library") -endif() +endif () mark_as_advanced( - MBEDSSL_INCLUDE_DIR - MBEDTLS_LIBRARIES - MBEDTLS_CRYPTO_LIBRARY - MBEDTLS_X509_LIBRARY - MBEDTLS_TLS_LIBRARY) + MBEDSSL_INCLUDE_DIR + MBEDTLS_LIBRARIES + MBEDTLS_CRYPTO_LIBRARY + MBEDTLS_X509_LIBRARY + MBEDTLS_TLS_LIBRARY) # Extract the version from the header... hopefully it matches the library. -file(STRINGS ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h _MBEDTLS_VERLINE - REGEX "^#define[ \t]+MBEDTLS_VERSION_STRING[\t ].*") +if (EXISTS ${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h) + file(STRINGS ${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h _MBEDTLS_VERLINE + REGEX "^#define[ \t]+MBEDTLS_VERSION_STRING[\t ].*") +else () + file(STRINGS ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h _MBEDTLS_VERLINE + REGEX "^#define[ \t]+MBEDTLS_VERSION_STRING[\t ].*") +endif () + string(REGEX REPLACE ".*MBEDTLS_VERSION_STRING[\t ]+\"(.*)\"" "\\1" MBEDTLS_VERSION ${_MBEDTLS_VERLINE}) find_package_handle_standard_args(mbedTLS - REQUIRED_VARS MBEDTLS_TLS_LIBRARY MBEDTLS_CRYPTO_LIBRARY MBEDTLS_X509_LIBRARY MBEDTLS_INCLUDE_DIR VERSION_VAR MBEDTLS_VERSION) + REQUIRED_VARS MBEDTLS_TLS_LIBRARY MBEDTLS_CRYPTO_LIBRARY MBEDTLS_X509_LIBRARY MBEDTLS_INCLUDE_DIR VERSION_VAR MBEDTLS_VERSION) diff --git a/src/supplemental/tls/mbedtls/tls.c b/src/supplemental/tls/mbedtls/tls.c index 1f9453c18..a216b3a69 100644 --- a/src/supplemental/tls/mbedtls/tls.c +++ b/src/supplemental/tls/mbedtls/tls.c @@ -1,5 +1,5 @@ // -// Copyright 2020 Staysail Systems, Inc. +// Copyright 2021 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // Copyright 2019 Devolutions // @@ -44,13 +44,13 @@ static nni_mtx rng_lock; #endif struct nng_tls_engine_conn { - void * tls; // parent conn + void *tls; // parent conn mbedtls_ssl_context ctx; }; struct nng_tls_engine_config { mbedtls_ssl_config cfg_ctx; - char * server_name; + char *server_name; mbedtls_x509_crt ca_certs; mbedtls_x509_crl crl; int min_ver; @@ -104,14 +104,29 @@ static struct { int tls; int nng; } tls_errs[] = { +#ifdef MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE { MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE, NNG_EPEERAUTH }, +#endif +#ifdef MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED { MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED, NNG_EPEERAUTH }, +#endif +#ifdef MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED { MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED, NNG_EPEERAUTH }, +#endif +#ifdef MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE { MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE, NNG_EPEERAUTH }, +#endif { MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY, NNG_ECONNREFUSED }, { MBEDTLS_ERR_SSL_ALLOC_FAILED, NNG_ENOMEM }, { MBEDTLS_ERR_SSL_TIMEOUT, NNG_ETIMEDOUT }, { MBEDTLS_ERR_SSL_CONN_EOF, NNG_ECLOSED }, +// MbedTLS 3.0 error codes +#ifdef MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE + { MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE, NNG_EPEERAUTH }, +#endif +#ifdef MBEDTLS_ERR_SSL_BAD_CERTIFICATE + { MBEDTLS_ERR_SSL_BAD_CERTIFICATE, NNG_EPEERAUTH }, +#endif // terminator { 0, 0 }, }; @@ -337,7 +352,7 @@ config_server_name(nng_tls_engine_config *cfg, const char *name) if ((dup = nni_strdup(name)) == NULL) { return (NNG_ENOMEM); } - if (cfg->server_name) { + if (cfg->server_name != NULL) { nni_strfree(cfg->server_name); } cfg->server_name = dup; @@ -395,7 +410,7 @@ config_own_cert(nng_tls_engine_config *cfg, const char *cert, const char *key, { size_t len; const uint8_t *pem; - pair * p; + pair *p; int rv; if ((p = NNI_ALLOC_STRUCT(p)) == NULL) { @@ -413,8 +428,13 @@ config_own_cert(nng_tls_engine_config *cfg, const char *cert, const char *key, pem = (const uint8_t *) key; len = strlen(key) + 1; - rv = mbedtls_pk_parse_key(&p->key, pem, len, (const uint8_t *) pass, - pass != NULL ? strlen(pass) : 0); +#if MBEDTLS_VERSION_MAJOR < 3 + rv = mbedtls_pk_parse_key(&p->key, pem, len, (const uint8_t *) pass, + pass != NULL ? strlen(pass) : 0); +#else + rv = mbedtls_pk_parse_key(&p->key, pem, len, (const uint8_t *) pass, + pass != NULL ? strlen(pass) : 0, tls_random, NULL); +#endif if (rv != 0) { rv = tls_mk_err(rv); goto err; @@ -448,12 +468,16 @@ config_version(nng_tls_engine_config *cfg, nng_tls_version min_ver, return (NNG_ENOTSUP); } switch (min_ver) { +#ifdef MBEDTLS_SSL_MINOR_VERSION_1 case NNG_TLS_1_0: v1 = MBEDTLS_SSL_MINOR_VERSION_1; break; +#endif +#ifdef MBEDTLS_SSL_MINOR_VERSION_2 case NNG_TLS_1_1: v1 = MBEDTLS_SSL_MINOR_VERSION_2; break; +#endif case NNG_TLS_1_2: v1 = MBEDTLS_SSL_MINOR_VERSION_3; break; @@ -462,12 +486,16 @@ config_version(nng_tls_engine_config *cfg, nng_tls_version min_ver, } switch (max_ver) { +#ifdef MBEDTLS_SSL_MINOR_VERSION_1 case NNG_TLS_1_0: v2 = MBEDTLS_SSL_MINOR_VERSION_1; break; +#endif +#ifdef MBEDTLS_SSL_MINOR_VERSION_2 case NNG_TLS_1_1: v2 = MBEDTLS_SSL_MINOR_VERSION_2; break; +#endif case NNG_TLS_1_2: case NNG_TLS_1_3: // We lack support for 1.3, so treat as 1.2. v2 = MBEDTLS_SSL_MINOR_VERSION_3; diff --git a/src/supplemental/tls/tls_common.c b/src/supplemental/tls/tls_common.c index 2ae50f157..404a8cf76 100644 --- a/src/supplemental/tls/tls_common.c +++ b/src/supplemental/tls/tls_common.c @@ -1374,7 +1374,7 @@ nng_tls_config_alloc(nng_tls_config **cfg_p, nng_tls_mode mode) return (NNG_ENOTSUP); } - size = NNI_ALIGN_UP(sizeof(*cfg) + eng->config_ops->size); + size = NNI_ALIGN_UP(sizeof(*cfg)) + eng->config_ops->size; if ((cfg = nni_zalloc(size)) == NULL) { return (NNG_ENOMEM); diff --git a/src/supplemental/tls/tls_test.c b/src/supplemental/tls/tls_test.c index 244f68ca9..96d95fb63 100644 --- a/src/supplemental/tls/tls_test.c +++ b/src/supplemental/tls/tls_test.c @@ -28,7 +28,10 @@ test_tls_config_version(void) NUTS_FAIL(nng_tls_config_version(cfg, NNG_TLS_1_0, NNG_TLS_1_3 + 1), NNG_ENOTSUP); - // Verify that we *can* configure some various ranges. + // Verify that we *can* configure some various ranges starting with + // TLS v1.2. Note that some libraries no longer support TLS 1.0 + // and TLS 1.1, so we don't test for them. +#if 0 NUTS_PASS(nng_tls_config_version(cfg, NNG_TLS_1_0, NNG_TLS_1_0)); NUTS_PASS(nng_tls_config_version(cfg, NNG_TLS_1_0, NNG_TLS_1_1)); NUTS_PASS(nng_tls_config_version(cfg, NNG_TLS_1_0, NNG_TLS_1_2)); @@ -36,6 +39,7 @@ test_tls_config_version(void) NUTS_PASS(nng_tls_config_version(cfg, NNG_TLS_1_1, NNG_TLS_1_1)); NUTS_PASS(nng_tls_config_version(cfg, NNG_TLS_1_1, NNG_TLS_1_2)); NUTS_PASS(nng_tls_config_version(cfg, NNG_TLS_1_1, NNG_TLS_1_3)); +#endif NUTS_PASS(nng_tls_config_version(cfg, NNG_TLS_1_2, NNG_TLS_1_2)); NUTS_PASS(nng_tls_config_version(cfg, NNG_TLS_1_2, NNG_TLS_1_3)); diff --git a/tests/tls.c b/tests/tls.c index c6d5da6e4..6eaa002c8 100644 --- a/tests/tls.c +++ b/tests/tls.c @@ -27,40 +27,57 @@ // The certificate is valid for 100 years, because I don't want to // have to regenerate it ever again. The CN is 127.0.0.1, and self-signed. // -// Generated using openssl: -// -// % openssl ecparam -name secp224r1 -genkey -out key.key -// % openssl req -new -key key.key -out cert.csr -sha256 -// % openssl x509 -req -in cert.csr -days 36500 -out cert.crt -// -signkey key.key -sha256 -// -// Secp224r1 chosen as a least common denominator recommended by NIST-800. -// -// static const char cert[] = "-----BEGIN CERTIFICATE-----\n" - "MIIBzDCCAXkCCQCNJMf8eYUHxTAKBggqhkjOPQQDAjB2MQswCQYDVQQGEwJVUzEL\n" - "MAkGA1UECAwCQ0ExEjAQBgNVBAcMCVNhbiBEaWVnbzEUMBIGA1UECgwLbmFub21z\n" - "Zy5vcmcxHDAaBgNVBAsME1NhbXBsZSBDZXJ0aWZpY2F0ZXMxEjAQBgNVBAMMCWxv\n" - "Y2FsaG9zdDAgFw0yMDAyMjMxODMwMDZaGA8yMTIwMDEzMDE4MzAwNlowdjELMAkG\n" - "A1UEBhMCVVMxCzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlTYW4gRGllZ28xFDASBgNV\n" - "BAoMC25hbm9tc2cub3JnMRwwGgYDVQQLDBNTYW1wbGUgQ2VydGlmaWNhdGVzMRIw\n" - "EAYDVQQDDAlsb2NhbGhvc3QwTjAQBgcqhkjOPQIBBgUrgQQAIQM6AAS9hA5gYo10\n" - "jx+gzJdzYbxHzigJYXawdHtyoAud/TT/dUCt0ycpOzTMiO3CoDNxep+/mkmgxjfp\n" - "ujAKBggqhkjOPQQDAgNBADA+Ah0A9b+GcfbhzzmI2NcYb4auE6XTYJPkPzHt6Adi\n" - "fwIdAMJO2LEr6WHH6JGLlishVqjF78TtkuB5t+kzneQ=\n" + "MIIDRzCCAi8CFCOIJGs6plMawgBYdDuCRV7UuJuyMA0GCSqGSIb3DQEBCwUAMF8x\n" + "CzAJBgNVBAYTAlhYMQ8wDQYDVQQIDAZVdG9waWExETAPBgNVBAcMCFBhcmFkaXNl\n" + "MRgwFgYDVQQKDA9OTkcgVGVzdHMsIEluYy4xEjAQBgNVBAMMCWxvY2FsaG9zdDAg\n" + "Fw0yMDA1MjMyMzMxMTlaGA8yMTIwMDQyOTIzMzExOVowXzELMAkGA1UEBhMCWFgx\n" + "DzANBgNVBAgMBlV0b3BpYTERMA8GA1UEBwwIUGFyYWRpc2UxGDAWBgNVBAoMD05O\n" + "RyBUZXN0cywgSW5jLjESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0B\n" + "AQEFAAOCAQ8AMIIBCgKCAQEAyPdnRbMrQj9902TGQsmMbG6xTSl9XKbJr55BcnyZ\n" + "ifsrqA7BbNSkndVw9Qq+OJQIDBTfRhGdG+o9j3h6SDVvIb62fWtwJ5Fe0eUmeYwP\n" + "c1PKQzOmMFlMYekXiZsx60yu5LeuUhGlb84+csImH+m3NbutInPJcStSq0WfSV6V\n" + "Nk6DN3535ex66zV2Ms6ikys1vCC434YqIpe1VxUh+IC2widJcLDCxmmJt3TOlx5f\n" + "9OcKMkxuH4fMAzgjIEpIrUjdb19CGNVvsNrEEB2CShBMgBdqMaAnKFxpKgfzS0JF\n" + "ulxRGNtpsrweki+j+a4sJXTv40kELkRQS6uB6wWZNjcPywIDAQABMA0GCSqGSIb3\n" + "DQEBCwUAA4IBAQA86Fqrd4aiih6R3fwiMLwV6IQJv+u5rQeqA4D0xu6v6siP42SJ\n" + "YMaI2DkNGrWdSFVSHUK/efceCrhnMlW7VM8I1cyl2F/qKMfnT72cxqqquiKtQKdT\n" + "NDTzv61QMUP9n86HxMzGS7jg0Pknu55BsIRNK6ndDvI3D/K/rzZs4xbqWSSfNfQs\n" + "fNFBbOuDrkS6/1h3p8SY1uPM18WLVv3GO2T3aeNMHn7YJAKSn+sfaxzAPyPIK3UT\n" + "W8ecGQSHOqBJJQELyUfMu7lx/FCYKUhN7/1uhU5Qf1pCR8hkIMegtqr64yVBNMOn\n" + "248fuiHbs9BRknuA/PqjxIDDZTwtDrfVSO/S\n" "-----END CERTIFICATE-----\n"; static const char key[] = - "-----BEGIN EC PARAMETERS-----\n" - "gUrgQQAIQ==\n" - "-----END EC PARAMETERS-----\n" - "-----BEGIN EC PRIVATE KEY-----\n" - "MGgCAQEEHChK068x8MWcBzhpO7qANvW4iTo7E0yzMYFXGn+gBwYFK4EEACGhPAM6\n" - "AAS9hA5gYo10jx+gzJdzYbxHzigJYXawdHtyoAud/TT/dUCt0ycpOzTMiO3CoDNx\n" - "ep+/mkmgxjfpug==\n" - "-----END EC PRIVATE KEY-----\n"; + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEowIBAAKCAQEAyPdnRbMrQj9902TGQsmMbG6xTSl9XKbJr55BcnyZifsrqA7B\n" + "bNSkndVw9Qq+OJQIDBTfRhGdG+o9j3h6SDVvIb62fWtwJ5Fe0eUmeYwPc1PKQzOm\n" + "MFlMYekXiZsx60yu5LeuUhGlb84+csImH+m3NbutInPJcStSq0WfSV6VNk6DN353\n" + "5ex66zV2Ms6ikys1vCC434YqIpe1VxUh+IC2widJcLDCxmmJt3TOlx5f9OcKMkxu\n" + "H4fMAzgjIEpIrUjdb19CGNVvsNrEEB2CShBMgBdqMaAnKFxpKgfzS0JFulxRGNtp\n" + "srweki+j+a4sJXTv40kELkRQS6uB6wWZNjcPywIDAQABAoIBAQCGSUsot+BgFCzv\n" + "5JbWafb7Pbwb421xS8HZJ9Zzue6e1McHNVTqc+zLyqQAGX2iMMhvykKnf32L+anJ\n" + "BKgxOANaeSVYCUKYLfs+JfDfp0druMGexhR2mjT/99FSkfF5WXREQLiq/j+dxiLU\n" + "bActq+5QaWf3bYddp6VF7O/TBvCNqBfD0+S0o0wtBdvxXItrKPTD5iKr9JfLWdAt\n" + "YNAk2QgFywFtY5zc2wt4queghF9GHeBzzZCuVj9QvPA4WdVq0mePaPTmvTYQUD0j\n" + "GT6X5j9JhqCwfh7trb/HfkmLHwwc62zPDFps+Dxao80+vss5b/EYZ4zY3S/K3vpG\n" + "f/e42S2BAoGBAP51HQYFJGC/wsNtOcX8RtXnRo8eYmyboH6MtBFrZxWl6ERigKCN\n" + "5Tjni7EI3nwi3ONg0ENPFkoQ8h0bcVFS7iW5kz5te73WaOFtpkU9rmuFDUz37eLP\n" + "d+JLZ5Kwfn2FM9HoiSAZAHowE0MIlmmIEXSnFtqA2zzorPQLO/4QlR+VAoGBAMov\n" + "R0yaHg3qPlxmCNyLXKiGaGNzvsvWjYw825uCGmVZfhzDhOiCFMaMb51BS5Uw/gwm\n" + "zHxmJjoqak8JjxaQ1qKPoeY1TJ5ps1+TRq9Wzm2/zGqJHOXnRPlqwBQ6AFllAMgt\n" + "Rlp5uqb8QJ+YEo6/1kdGhw9kZWCZEEue6MNQjxnfAoGARLkUkZ+p54di7qz9QX+V\n" + "EghYgibOpk6R1hviNiIvwSUByhZgbvxjwC6pB7NBg31W8wIevU8K0g4plbrnq/Md\n" + "5opsPhwLo4XY5albkq/J/7f7k6ISWYN2+WMsIe4Q+42SJUsMXeLiwh1h1mTnWrEp\n" + "JbxK69CJZbXhoDe4iDGqVNECgYAjlgS3n9ywWE1XmAHxR3osk1OmRYYMfJv3VfLV\n" + "QSYCNqkyyNsIzXR4qdkvVYHHJZNhcibFsnkB/dsuRCFyOFX+0McPLMxqiXIv3U0w\n" + "qVe2C28gRTfX40fJmpdqN/c9xMBJe2aJoClRIM8DCBIkG/HMI8a719DcGrS6iqKv\n" + "VeuKAwKBgEgD+KWW1KtoSjCBlS0NP8HjC/Rq7j99YhKE6b9h2slIa7JTO8RZKCa0\n" + "qbuomdUeJA3R8h+5CFkEKWqO2/0+dUdLNOjG+CaTFHaUJevzHOzIjpn+VsfCLV13\n" + "yupGzHG+tGtdrWgLn9Dzdp67cDfSnsSh+KODPECAAFfo+wPvD8DS\n" + "-----END RSA PRIVATE KEY-----\n"; static int check_props_v4(nng_msg *msg) diff --git a/tests/trantest.h b/tests/trantest.h index 93f902dad..e56d755d1 100644 --- a/tests/trantest.h +++ b/tests/trantest.h @@ -232,7 +232,7 @@ trantest_listen_accept(trantest *tt) So(trantest_listen(tt, &l) == 0); So(nng_listener_id(l) > 0); - nng_msleep(200); + nng_msleep(500); So(trantest_dial(tt, &d) == 0); So(nng_dialer_id(d) > 0); So(nng_dialer_id(d0) < 0);