Skip to content

Commit 798779d

Browse files
Viktor Dukhovninhorman
authored andcommitted
With SSL_VERIFY_PEER client RPK should abort on X509 error
While RPK performs X.509 checks correctly, at the SSL layer the SSL_VERIFY_PEER flag was not honoured and connections were allowed to complete even when the server was not verified. The client can of course determine this by calling SSL_get_verify_result(), but some may not know to do this. Added tests to make sure this does not regress. Fixes CVE-2024-12797 Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Neil Horman <nhorman@openssl.org> (cherry picked from commit 87ebd20)
1 parent 0db27ec commit 798779d

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

ssl/statem/statem_clnt.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,6 +1909,7 @@ static WORK_STATE tls_post_process_server_rpk(SSL_CONNECTION *sc,
19091909
{
19101910
size_t certidx;
19111911
const SSL_CERT_LOOKUP *clu;
1912+
int v_ok;
19121913

19131914
if (sc->session->peer_rpk == NULL) {
19141915
SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER,
@@ -1918,9 +1919,19 @@ static WORK_STATE tls_post_process_server_rpk(SSL_CONNECTION *sc,
19181919

19191920
if (sc->rwstate == SSL_RETRY_VERIFY)
19201921
sc->rwstate = SSL_NOTHING;
1921-
if (ssl_verify_rpk(sc, sc->session->peer_rpk) > 0
1922-
&& sc->rwstate == SSL_RETRY_VERIFY)
1922+
1923+
ERR_set_mark();
1924+
v_ok = ssl_verify_rpk(sc, sc->session->peer_rpk);
1925+
if (v_ok <= 0 && sc->verify_mode != SSL_VERIFY_NONE) {
1926+
ERR_clear_last_mark();
1927+
SSLfatal(sc, ssl_x509err2alert(sc->verify_result),
1928+
SSL_R_CERTIFICATE_VERIFY_FAILED);
1929+
return WORK_ERROR;
1930+
}
1931+
ERR_pop_to_mark(); /* but we keep s->verify_result */
1932+
if (v_ok > 0 && sc->rwstate == SSL_RETRY_VERIFY) {
19231933
return WORK_MORE_A;
1934+
}
19241935

19251936
if ((clu = ssl_cert_lookup_by_pkey(sc->session->peer_rpk, &certidx,
19261937
SSL_CONNECTION_GET_CTX(sc))) == NULL) {

test/rpktest.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,14 @@ static int rpk_verify_server_cb(int ok, X509_STORE_CTX *ctx)
8989
* idx = 13 - resumption with client authentication
9090
* idx = 14 - resumption with client authentication, no ticket
9191
* idx = 15 - like 0, but use non-default libctx
92+
* idx = 16 - like 7, but with SSL_VERIFY_PEER connection should fail
93+
* idx = 17 - like 8, but with SSL_VERIFY_PEER connection should fail
9294
*
93-
* 16 * 2 * 4 * 2 * 2 * 2 * 2 = 2048 tests
95+
* 18 * 2 * 4 * 2 * 2 * 2 * 2 = 2048 tests
9496
*/
9597
static int test_rpk(int idx)
9698
{
97-
# define RPK_TESTS 16
99+
# define RPK_TESTS 18
98100
# define RPK_DIMS (2 * 4 * 2 * 2 * 2 * 2)
99101
SSL_CTX *cctx = NULL, *sctx = NULL;
100102
SSL *clientssl = NULL, *serverssl = NULL;
@@ -114,6 +116,7 @@ static int test_rpk(int idx)
114116
int idx_cert, idx_prot;
115117
int client_auth = 0;
116118
int resumption = 0;
119+
int want_error = SSL_ERROR_NONE;
117120
long server_verify_result = 0;
118121
long client_verify_result = 0;
119122
OSSL_LIB_CTX *test_libctx = NULL;
@@ -188,7 +191,7 @@ static int test_rpk(int idx)
188191
#ifdef OPENSSL_NO_ECDSA
189192
/* Can't get other_key if it's ECDSA */
190193
if (other_pkey == NULL && idx_cert == 0
191-
&& (idx == 4 || idx == 6 || idx == 7)) {
194+
&& (idx == 4 || idx == 6 || idx == 7 || idx == 16)) {
192195
testresult = TEST_skip("EDCSA disabled");
193196
goto end;
194197
}
@@ -266,8 +269,10 @@ static int test_rpk(int idx)
266269
goto end;
267270
/* Only a private key */
268271
if (idx == 1) {
269-
if (idx_server_server_rpk == 0 || idx_client_server_rpk == 0)
272+
if (idx_server_server_rpk == 0 || idx_client_server_rpk == 0) {
270273
expected = 0;
274+
want_error = SSL_ERROR_SSL;
275+
}
271276
} else {
272277
/* Add certificate */
273278
if (!TEST_int_eq(SSL_use_certificate_file(serverssl, cert_file, SSL_FILETYPE_PEM), 1))
@@ -333,12 +338,14 @@ static int test_rpk(int idx)
333338
client_expected = -1;
334339
if (!TEST_true(SSL_add_expected_rpk(clientssl, other_pkey)))
335340
goto end;
341+
SSL_set_verify(clientssl, SSL_VERIFY_NONE, rpk_verify_client_cb);
336342
client_verify_result = X509_V_ERR_DANE_NO_MATCH;
337343
break;
338344
case 8:
339345
if (idx_server_server_rpk == 1 && idx_client_server_rpk == 1)
340346
client_expected = -1;
341347
/* no peer keys */
348+
SSL_set_verify(clientssl, SSL_VERIFY_NONE, rpk_verify_client_cb);
342349
client_verify_result = X509_V_ERR_RPK_UNTRUSTED;
343350
break;
344351
case 9:
@@ -370,9 +377,13 @@ static int test_rpk(int idx)
370377
if (!TEST_int_eq(SSL_use_PrivateKey_file(clientssl, privkey_file, SSL_FILETYPE_PEM), 1))
371378
goto end;
372379
/* Since there's no cert, this is expected to fail without RPK support */
373-
if (!idx_server_client_rpk || !idx_client_client_rpk)
380+
if (!idx_server_client_rpk || !idx_client_client_rpk) {
374381
expected = 0;
375-
SSL_set_verify(serverssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, rpk_verify_server_cb);
382+
want_error = SSL_ERROR_SSL;
383+
SSL_set_verify(serverssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
384+
} else {
385+
SSL_set_verify(serverssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, rpk_verify_server_cb);
386+
}
376387
client_auth = 1;
377388
break;
378389
case 11:
@@ -449,12 +460,35 @@ static int test_rpk(int idx)
449460
if (!TEST_true(SSL_add_expected_rpk(clientssl, pkey)))
450461
goto end;
451462
break;
463+
case 16:
464+
if (idx_server_server_rpk == 1 && idx_client_server_rpk == 1) {
465+
/* wrong expected server key */
466+
expected = 0;
467+
want_error = SSL_ERROR_SSL;
468+
SSL_set_verify(serverssl, SSL_VERIFY_PEER, NULL);
469+
}
470+
if (!TEST_true(SSL_add_expected_rpk(clientssl, other_pkey)))
471+
goto end;
472+
break;
473+
case 17:
474+
if (idx_server_server_rpk == 1 && idx_client_server_rpk == 1) {
475+
/* no expected server keys */
476+
expected = 0;
477+
want_error = SSL_ERROR_SSL;
478+
SSL_set_verify(serverssl, SSL_VERIFY_PEER, NULL);
479+
}
480+
break;
452481
}
453482

454-
ret = create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE);
483+
ret = create_ssl_connection(serverssl, clientssl, want_error);
455484
if (!TEST_int_eq(expected, ret))
456485
goto end;
457486

487+
if (expected <= 0) {
488+
testresult = 1;
489+
goto end;
490+
}
491+
458492
/* Make sure client gets RPK or certificate as configured */
459493
if (expected == 1) {
460494
if (idx_server_server_rpk && idx_client_server_rpk) {

0 commit comments

Comments
 (0)