Skip to content

Commit 2cb0d7e

Browse files
tls: test multiple certificates with client preference selection
Add tests to verify that when multiple certificates (RSA and ECDSA) are configured, the server correctly selects the certificate based on the client's signature algorithm preferences. Assisted-by: Claude <noreply@anthropic.com>
1 parent 1ce3504 commit 2cb0d7e

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

src/tls/test-server.c

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
/* this has a corresponding mock-server.key */
3232
#define CERTFILE SRCDIR "/test/data/mock-server.crt"
3333
#define KEYFILE SRCDIR "/test/data/mock-server.key"
34+
#define ECC_CERTFILE SRCDIR "/test/data/mock-ecc.crt"
35+
#define ECC_KEYFILE SRCDIR "/test/data/mock-ecc.key"
3436

3537
#define CLIENT_CERTFILE SRCDIR "/src/tls/ca/alice.pem"
3638
#define CLIENT_KEYFILE SRCDIR "/src/tls/ca/alice.key"
@@ -50,11 +52,15 @@ typedef struct {
5052
typedef struct {
5153
const char *certfile;
5254
const char *keyfile;
55+
const char *certfile2;
56+
const char *keyfile2;
5357
int cert_request_mode;
5458
int idle_timeout;
5559
const char *client_crt;
5660
const char *client_key;
5761
const char *client_fingerprint;
62+
const char *priority;
63+
int expected_pk_algo;
5864
} TestFixture;
5965

6066
static const TestFixture fixture_separate_crt_key = {
@@ -93,6 +99,24 @@ static const TestFixture fixture_run_idle = {
9399
.idle_timeout = 1,
94100
};
95101

102+
static const TestFixture fixture_multiple_certs_ecdsa = {
103+
.certfile = CERTFILE,
104+
.keyfile = KEYFILE,
105+
.certfile2 = ECC_CERTFILE,
106+
.keyfile2 = ECC_KEYFILE,
107+
.priority = "NORMAL:-SIGN-ALL:+SIGN-ECDSA-SECP256R1-SHA256",
108+
.expected_pk_algo = GNUTLS_PK_ECDSA,
109+
};
110+
111+
static const TestFixture fixture_multiple_certs_rsa = {
112+
.certfile = CERTFILE,
113+
.keyfile = KEYFILE,
114+
.certfile2 = ECC_CERTFILE,
115+
.keyfile2 = ECC_KEYFILE,
116+
.priority = "NORMAL:-SIGN-ALL:+SIGN-RSA-SHA256:+SIGN-RSA-PSS-RSAE-SHA256",
117+
.expected_pk_algo = GNUTLS_PK_RSA,
118+
};
119+
96120
/* for forking test cases, where server's SIGCHLD handling gets in the way */
97121
static void
98122
block_sigchld (void)
@@ -296,7 +320,10 @@ assert_https_outcome (TestCase *tc,
296320

297321
g_assert_cmpint (gnutls_init (&session, GNUTLS_CLIENT), ==, GNUTLS_E_SUCCESS);
298322
gnutls_transport_set_int (session, fd);
299-
g_assert_cmpint (gnutls_set_default_priority (session), ==, GNUTLS_E_SUCCESS);
323+
if (fixture && fixture->priority)
324+
g_assert_cmpint (gnutls_priority_set_direct (session, fixture->priority, NULL), ==, GNUTLS_E_SUCCESS);
325+
else
326+
g_assert_cmpint (gnutls_set_default_priority (session), ==, GNUTLS_E_SUCCESS);
300327
gnutls_handshake_set_timeout(session, 5000);
301328
g_assert_cmpint (gnutls_certificate_allocate_credentials (&xcred), ==, GNUTLS_E_SUCCESS);
302329
g_assert_cmpint (gnutls_certificate_set_x509_system_trust (xcred), >=, 0);
@@ -325,6 +352,17 @@ assert_https_outcome (TestCase *tc,
325352
g_assert (server_certs);
326353
g_assert_cmpuint (server_certs_len, ==, expected_server_certs);
327354

355+
/* check server certificate algorithm if requested */
356+
if (fixture && fixture->expected_pk_algo)
357+
{
358+
gnutls_x509_crt_t cert;
359+
g_assert_cmpint (gnutls_x509_crt_init (&cert), ==, GNUTLS_E_SUCCESS);
360+
g_assert_cmpint (gnutls_x509_crt_import (cert, &server_certs[0], GNUTLS_X509_FMT_DER),
361+
==, GNUTLS_E_SUCCESS);
362+
g_assert_cmpint (gnutls_x509_crt_get_pk_algorithm (cert, NULL), ==, fixture->expected_pk_algo);
363+
gnutls_x509_crt_deinit (cert);
364+
}
365+
328366
/* send request, read response */
329367
len = gnutls_record_send (session, request, sizeof (request));
330368
if (len < 0 && expect_tls_failure)
@@ -443,6 +481,15 @@ setup (TestCase *tc, gconstpointer data)
443481
g_assert_cmpint (symlink (fixture->certfile, cert_link), ==, 0);
444482
g_assert_cmpint (symlink (fixture->keyfile, key_link), ==, 0);
445483

484+
/* Set up secondary certificate if present */
485+
if (fixture->certfile2)
486+
{
487+
g_autofree gchar *cert_link2 = g_build_filename (certs_dir, "1.crt", NULL);
488+
g_autofree gchar *key_link2 = g_build_filename (certs_dir, "1.key", NULL);
489+
g_assert_cmpint (symlink (fixture->certfile2, cert_link2), ==, 0);
490+
g_assert_cmpint (symlink (fixture->keyfile2, key_link2), ==, 0);
491+
}
492+
446493
int cert_dirfd = open (certs_dir, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
447494
g_assert_cmpint (cert_dirfd, >=, 0);
448495
connection_crypto_init (cert_dirfd, false, fixture->cert_request_mode);
@@ -500,8 +547,12 @@ teardown (TestCase *tc, gconstpointer data)
500547
{
501548
g_autofree gchar *cert_file = g_build_filename (certs_dir, "0.crt", NULL);
502549
g_autofree gchar *key_file = g_build_filename (certs_dir, "0.key", NULL);
550+
g_autofree gchar *cert_file2 = g_build_filename (certs_dir, "1.crt", NULL);
551+
g_autofree gchar *key_file2 = g_build_filename (certs_dir, "1.key", NULL);
503552
g_unlink (cert_file);
504553
g_unlink (key_file);
554+
g_unlink (cert_file2);
555+
g_unlink (key_file2);
505556
g_assert_cmpint (g_rmdir (certs_dir), ==, 0);
506557
}
507558

@@ -911,6 +962,10 @@ main (int argc, char *argv[])
911962
setup, test_tls_blocked_handshake, teardown);
912963
g_test_add ("/server/mixed-protocols", TestCase, &fixture_separate_crt_key,
913964
setup, test_mixed_protocols, teardown);
965+
g_test_add ("/server/tls/multiple-certs/ecdsa", TestCase, &fixture_multiple_certs_ecdsa,
966+
setup, test_tls_no_client_cert, teardown);
967+
g_test_add ("/server/tls/multiple-certs/rsa", TestCase, &fixture_multiple_certs_rsa,
968+
setup, test_tls_no_client_cert, teardown);
914969
g_test_add ("/server/run-idle", TestCase, &fixture_run_idle,
915970
setup, test_run_idle, teardown);
916971
g_test_add ("/server/ipv4/connection", TestCase, NULL,

0 commit comments

Comments
 (0)