aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/supplemental/tls/tls_test.c84
-rw-r--r--src/testing/certs.c96
-rw-r--r--src/testing/nuts.h5
3 files changed, 184 insertions, 1 deletions
diff --git a/src/supplemental/tls/tls_test.c b/src/supplemental/tls/tls_test.c
index 5eb981ac..43ce0c85 100644
--- a/src/supplemental/tls/tls_test.c
+++ b/src/supplemental/tls/tls_test.c
@@ -144,6 +144,89 @@ test_tls_large_message(void)
}
void
+test_tls_ecdsa(void)
+{
+ nng_stream_listener *l;
+ nng_stream_dialer *d;
+ nng_aio *aio1, *aio2;
+ nng_stream *s1;
+ nng_stream *s2;
+ nng_tls_config *c1;
+ nng_tls_config *c2;
+ char addr[32];
+ uint8_t *buf1;
+ uint8_t *buf2;
+ size_t size = 8000;
+ void *t1;
+ void *t2;
+ int port;
+
+ NUTS_ENABLE_LOG(NNG_LOG_DEBUG);
+ // allocate messages
+ NUTS_ASSERT((buf1 = nng_alloc(size)) != NULL);
+ NUTS_ASSERT((buf2 = nng_alloc(size)) != NULL);
+
+ for (size_t i = 0; i < size; i++) {
+ buf1[i] = rand() & 0xff;
+ }
+
+ NUTS_PASS(nng_aio_alloc(&aio1, NULL, NULL));
+ NUTS_PASS(nng_aio_alloc(&aio2, NULL, NULL));
+ nng_aio_set_timeout(aio1, 5000);
+ nng_aio_set_timeout(aio2, 5000);
+
+ // Allocate the listener first. We use a wild-card port.
+ NUTS_PASS(nng_stream_listener_alloc(&l, "tls+tcp://127.0.0.1:0"));
+ NUTS_PASS(nng_tls_config_alloc(&c1, NNG_TLS_MODE_SERVER));
+ NUTS_PASS(nng_tls_config_own_cert(
+ c1, nuts_ecdsa_server_crt, nuts_ecdsa_server_key, NULL));
+ NUTS_PASS(nng_stream_listener_set_tls(l, c1));
+ NUTS_PASS(nng_stream_listener_listen(l));
+ NUTS_PASS(
+ nng_stream_listener_get_int(l, NNG_OPT_TCP_BOUND_PORT, &port));
+ NUTS_TRUE(port > 0);
+ NUTS_TRUE(port < 65536);
+
+ snprintf(addr, sizeof(addr), "tls+tcp://127.0.0.1:%d", port);
+ NUTS_PASS(nng_stream_dialer_alloc(&d, addr));
+ NUTS_PASS(nng_tls_config_alloc(&c2, NNG_TLS_MODE_CLIENT));
+ NUTS_PASS(nng_tls_config_ca_chain(c2, nuts_ecdsa_server_crt, NULL));
+ NUTS_PASS(nng_tls_config_server_name(c2, "localhost"));
+
+ NUTS_PASS(nng_stream_dialer_set_tls(d, c2));
+
+ nng_stream_listener_accept(l, aio1);
+ nng_stream_dialer_dial(d, aio2);
+
+ nng_aio_wait(aio1);
+ nng_aio_wait(aio2);
+
+ NUTS_PASS(nng_aio_result(aio1));
+ NUTS_PASS(nng_aio_result(aio2));
+
+ NUTS_TRUE((s1 = nng_aio_get_output(aio1, 0)) != NULL);
+ NUTS_TRUE((s2 = nng_aio_get_output(aio2, 0)) != NULL);
+
+ t1 = nuts_stream_send_start(s1, buf1, size);
+ t2 = nuts_stream_recv_start(s2, buf2, size);
+
+ NUTS_PASS(nuts_stream_wait(t1));
+ NUTS_PASS(nuts_stream_wait(t2));
+ NUTS_TRUE(memcmp(buf1, buf2, size) == 0);
+
+ nng_free(buf1, size);
+ nng_free(buf2, size);
+ nng_stream_free(s1);
+ nng_stream_free(s2);
+ nng_stream_dialer_free(d);
+ nng_stream_listener_free(l);
+ nng_tls_config_free(c1);
+ nng_tls_config_free(c2);
+ nng_aio_free(aio1);
+ nng_aio_free(aio2);
+}
+
+void
test_tls_garbled_cert(void)
{
nng_stream_listener *l;
@@ -469,6 +552,7 @@ TEST_LIST = {
{ "tls config version", test_tls_config_version },
{ "tls conn refused", test_tls_conn_refused },
{ "tls large message", test_tls_large_message },
+ { "tls ecdsa", test_tls_ecdsa },
#ifndef NNG_TLS_ENGINE_WOLFSSL // wolfSSL doesn't validate certas until use
{ "tls garbled cert", test_tls_garbled_cert },
#endif
diff --git a/src/testing/certs.c b/src/testing/certs.c
index 5ad44e33..01fb0b92 100644
--- a/src/testing/certs.c
+++ b/src/testing/certs.c
@@ -1,5 +1,5 @@
//
-// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
@@ -52,6 +52,7 @@ const char *nuts_server_key =
"-----END RSA PRIVATE KEY-----\n";
const char *nuts_server_crt =
+
"-----BEGIN CERTIFICATE-----\n"
"MIIDRzCCAi8CFCOIJGs6plMawgBYdDuCRV7UuJuyMA0GCSqGSIb3DQEBCwUAMF8x\n"
"CzAJBgNVBAYTAlhYMQ8wDQYDVQQIDAZVdG9waWExETAPBgNVBAcMCFBhcmFkaXNl\n"
@@ -147,3 +148,96 @@ const char *nuts_garbled_crt =
"sxUMa5kT+zc17q57ZcgNq/sSGI3BU4b/E/8ntIwiui2xWSf/4JR6xtanih8uY5Pu\n"
"QTgg9qTtFgtu4WWUP7JhreoINTw6O4/g5Z18\n"
"-----END CERTIFICATE-----\n";
+
+// TLS certificates using ECDSA. These are pre-generated, and should not be
+// used outside of these test cases. They are all using prime256v1 with
+// SHA256. All certs are signed by the root key (making the root self-signed).
+// They all expire in about 100 years -- so we don't have to worry about
+// expiration.
+//
+// The server cert uses CN 127.0.0.1, and an alt name of "localhost".
+//
+// Country = XX
+// State = Utopia
+// Locality = Paradise
+// Organization = NNG Tests, Inc.
+//
+
+// clang-format off
+/*
+The following shell script was used:
+
+#!/bin/sh
+
+server_key=server_key.pem
+server_crt=server_crt.pem
+client_key=client_key.pem
+client_csr=client_csr.csr
+client_crt=client_crt.pem
+
+openssl ecparam -name secp521r1 -genkey -out $server_key
+openssl req -new -key $server_key -x509 -nodes -days 36500 -subj "/C=XX/ST=Utopia/O=NNG Tests, Inc./CN=127.0.0.1" -addext 'subjectAltName=DNS:localhost' -out $server_crt
+openssl ecparam -name secp521r1 -genkey -out $client_key
+openssl req -new -key $client_key -subj "/C=XX/ST=Utopia/O=NNG Tests, Inc./CN=client" -out $client_csr
+openssl x509 -req -days 36500 -in $client_csr -CA $server_crt -CAkey $server_key -out $client_crt -set_serial 01 -sha256
+*/
+// clang-format on
+
+const char *nuts_ecdsa_server_key =
+ "-----BEGIN EC PARAMETERS-----\n"
+ "BgUrgQQAIw==\n"
+ "-----END EC PARAMETERS-----\n"
+ "-----BEGIN EC PRIVATE KEY-----\n"
+ "MIHcAgEBBEIAHONw87DNkoisqZx1AE/VVe78AVmrVHLoRZ08om1/oU/MV0UVcr14\n"
+ "gHPuRMI+FAt77Vku/4DSxCl5Oll3q4LAGtugBwYFK4EEACOhgYkDgYYABACJ1c9q\n"
+ "go6SycHu8JWgHzltARvXdsWOHbhsnNJTVydvfKHKQRPVpRXOAl51DdvVCE5i9/TE\n"
+ "/76+NonSG7QAQ9xToQAkQ+mOX/qzCOYW/1xtrIX4G5KwnshUIuR5bYx9Gg/Bn/wC\n"
+ "9oEuM1hGe1eGRP+ZjF/fRtqdLLsW7ODnuH1ore+KHA==\n"
+ "-----END EC PRIVATE KEY-----\n";
+
+const char *nuts_ecdsa_server_crt =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIICjTCCAe6gAwIBAgIUStuZM66kGOnQVoiqV5c+yycyljwwCgYIKoZIzj0EAwIw\n"
+ "TDELMAkGA1UEBhMCWFgxDzANBgNVBAgMBlV0b3BpYTEYMBYGA1UECgwPTk5HIFRl\n"
+ "c3RzLCBJbmMuMRIwEAYDVQQDDAkxMjcuMC4wLjEwIBcNMjQxMTE2MjMyNjMzWhgP\n"
+ "MjEyNDEwMjMyMzI2MzNaMEwxCzAJBgNVBAYTAlhYMQ8wDQYDVQQIDAZVdG9waWEx\n"
+ "GDAWBgNVBAoMD05ORyBUZXN0cywgSW5jLjESMBAGA1UEAwwJMTI3LjAuMC4xMIGb\n"
+ "MBAGByqGSM49AgEGBSuBBAAjA4GGAAQAidXPaoKOksnB7vCVoB85bQEb13bFjh24\n"
+ "bJzSU1cnb3yhykET1aUVzgJedQ3b1QhOYvf0xP++vjaJ0hu0AEPcU6EAJEPpjl/6\n"
+ "swjmFv9cbayF+BuSsJ7IVCLkeW2MfRoPwZ/8AvaBLjNYRntXhkT/mYxf30banSy7\n"
+ "Fuzg57h9aK3vihyjaTBnMB0GA1UdDgQWBBTZf991Br/NIUq7yO10jupUbYTVjTAf\n"
+ "BgNVHSMEGDAWgBTZf991Br/NIUq7yO10jupUbYTVjTAPBgNVHRMBAf8EBTADAQH/\n"
+ "MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggqhkjOPQQDAgOBjAAwgYgCQgCTqfIP\n"
+ "wV8e6nHVAEBt4NDx1dLG0Ap86YXtIsrwxzydziEKqexxWrJa8T24ugHA8tp4t1YG\n"
+ "sc5sfBWROZ5bAvh1TwJCAc511cMRnDX362CWJeu6cxoFVgf8c5I+oC/1+4c9eFpN\n"
+ "fAlJehKFp7zI2FrywMLqtoWlKrPh3ondzRH952OCMOqS\n"
+ "-----END CERTIFICATE-----\n";
+
+const char *nuts_ecdsa_client_key =
+ "-----BEGIN EC PARAMETERS-----\n"
+ "BgUrgQQAIw==\n"
+ "-----END EC PARAMETERS-----\n"
+ "-----BEGIN EC PRIVATE KEY-----\n"
+ "MIHcAgEBBEIBpOYclp7j7CZ0pk9JemQBtXZW1/MReB7RGl3F8zTU0U9asgF5aP/5\n"
+ "99uOuxOycnCN7GRdcAGCSRlxG4w0AzzkjRWgBwYFK4EEACOhgYkDgYYABAHmhUnU\n"
+ "kQB1Y4saF3l3sKfPBMSRUYqo6NzQFrwLdf/4XjIjRttO0ToLww8Ip1snzr6HwwL+\n"
+ "iemjAut+HR74BbgfzwC/YSsVbhR/beoFYhFzZBgU0TefENhh/cDdZWLAxkmrMIv4\n"
+ "ClCTjZK65yewbh2FE7jJM5+XhT9zSutcTTiCK8OCsg==\n"
+ "-----END EC PRIVATE KEY-----\n";
+
+const char *nuts_ecdsa_client_crt =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIICUDCCAbGgAwIBAgIBATAKBggqhkjOPQQDAjBMMQswCQYDVQQGEwJYWDEPMA0G\n"
+ "A1UECAwGVXRvcGlhMRgwFgYDVQQKDA9OTkcgVGVzdHMsIEluYy4xEjAQBgNVBAMM\n"
+ "CTEyNy4wLjAuMTAgFw0yNDExMTYyMzI2MzNaGA8yMTI0MTAyMzIzMjYzM1owSTEL\n"
+ "MAkGA1UEBhMCWFgxDzANBgNVBAgMBlV0b3BpYTEYMBYGA1UECgwPTk5HIFRlc3Rz\n"
+ "LCBJbmMuMQ8wDQYDVQQDDAZjbGllbnQwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYA\n"
+ "BAHmhUnUkQB1Y4saF3l3sKfPBMSRUYqo6NzQFrwLdf/4XjIjRttO0ToLww8Ip1sn\n"
+ "zr6HwwL+iemjAut+HR74BbgfzwC/YSsVbhR/beoFYhFzZBgU0TefENhh/cDdZWLA\n"
+ "xkmrMIv4ClCTjZK65yewbh2FE7jJM5+XhT9zSutcTTiCK8OCsqNCMEAwHQYDVR0O\n"
+ "BBYEFItNESy93oLtgsOjs3jB8UtVKuRKMB8GA1UdIwQYMBaAFNl/33UGv80hSrvI\n"
+ "7XSO6lRthNWNMAoGCCqGSM49BAMCA4GMADCBiAJCAe0mobaBx+A2A9w033LSsDoD\n"
+ "8sqtb3cRksEyF4c2EhP6XstQ3fxJ2rce1cWzeb67CwJpxQ6t/HBy8ahUDGyNu/H+\n"
+ "AkIA0SKehR/cXZvqTy/IMfqLCqwjUIYO8vCY9ed5fnx4G7aSndRczGWvxcfS/wPQ\n"
+ "cyOgzDRQnlaotZq/aYmymIE4UdY=\n"
+ "-----END CERTIFICATE-----\n";
diff --git a/src/testing/nuts.h b/src/testing/nuts.h
index 1c1f4595..a61968b8 100644
--- a/src/testing/nuts.h
+++ b/src/testing/nuts.h
@@ -114,6 +114,11 @@ extern const char *nuts_server_crt;
extern const char *nuts_client_key;
extern const char *nuts_client_crt;
extern const char *nuts_garbled_crt;
+// These ones use ecdsa with prime256v1.
+extern const char *nuts_ecdsa_server_key;
+extern const char *nuts_ecdsa_server_crt;
+extern const char *nuts_ecdsa_client_key;
+extern const char *nuts_ecdsa_client_crt;
// NUTS_SUCCESS tests for NNG success. It reports the failure if it
// did not.