From d7785284a59d112cbeb0bc2017c3d94122230d9e Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 7 Sep 2023 17:36:13 +0100 Subject: [PATCH 01/79] Add a test for using a PSK with QUIC Check that we can set and use a PSK when establishing a QUIC connection. Fixes openssl/project#83 Reviewed-by: Hugo Landau Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22011) Signed-off-by: fly2x --- include/internal/quic_tserver.h | 4 ++ ssl/quic/quic_tserver.c | 12 ++++- test/helpers/ssltestlib.c | 38 ++++++++++++++ test/helpers/ssltestlib.h | 8 +++ test/quicapitest.c | 87 +++++++++++++++++++++++++++++++++ test/sslapitest.c | 47 ------------------ 6 files changed, 147 insertions(+), 49 deletions(-) diff --git a/include/internal/quic_tserver.h b/include/internal/quic_tserver.h index 9213f60666..4f358dd4e8 100644 --- a/include/internal/quic_tserver.h +++ b/include/internal/quic_tserver.h @@ -211,6 +211,10 @@ int ossl_quic_tserver_new_ticket(QUIC_TSERVER *srv); int ossl_quic_tserver_set_max_early_data(QUIC_TSERVER *srv, uint32_t max_early_data); +/* Set the find session callback for getting a server PSK */ +void ossl_quic_tserver_set_psk_find_session_cb(QUIC_TSERVER *srv, + SSL_psk_find_session_cb_func cb); + # endif #endif diff --git a/ssl/quic/quic_tserver.c b/ssl/quic/quic_tserver.c index 788d4780d8..92c17d10f3 100644 --- a/ssl/quic/quic_tserver.c +++ b/ssl/quic/quic_tserver.c @@ -99,10 +99,12 @@ QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args, if (srv->ctx == NULL) goto err; - if (SSL_CTX_use_certificate_file(srv->ctx, certfile, SSL_FILETYPE_PEM) <= 0) + if (certfile != NULL + && SSL_CTX_use_certificate_file(srv->ctx, certfile, SSL_FILETYPE_PEM) <= 0) goto err; - if (SSL_CTX_use_PrivateKey_file(srv->ctx, keyfile, SSL_FILETYPE_PEM) <= 0) + if (keyfile != NULL + && SSL_CTX_use_PrivateKey_file(srv->ctx, keyfile, SSL_FILETYPE_PEM) <= 0) goto err; SSL_CTX_set_alpn_select_cb(srv->ctx, alpn_select_cb, srv); @@ -556,3 +558,9 @@ int ossl_quic_tserver_set_max_early_data(QUIC_TSERVER *srv, { return SSL_set_max_early_data(srv->tls, max_early_data); } + +void ossl_quic_tserver_set_psk_find_session_cb(QUIC_TSERVER *srv, + SSL_psk_find_session_cb_func cb) +{ + SSL_set_psk_find_session_callback(srv->tls, cb); +} diff --git a/test/helpers/ssltestlib.c b/test/helpers/ssltestlib.c index 94a170b9a5..0b1e56f064 100644 --- a/test/helpers/ssltestlib.c +++ b/test/helpers/ssltestlib.c @@ -1247,3 +1247,41 @@ void shutdown_ssl_connection(SSL *serverssl, SSL *clientssl) SSL_free(serverssl); SSL_free(clientssl); } + +SSL_SESSION *create_a_psk(SSL *ssl, size_t mdsize) +{ + const SSL_CIPHER *cipher = NULL; + const unsigned char key[SHA384_DIGEST_LENGTH] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f + }; + SSL_SESSION *sess = NULL; + + if (mdsize == SHA384_DIGEST_LENGTH) { + cipher = SSL_CIPHER_find(ssl, TLS13_AES_256_GCM_SHA384_BYTES); + } else if (mdsize == SHA256_DIGEST_LENGTH) { + /* + * Any ciphersuite using SHA256 will do - it will be compatible with + * the actual ciphersuite selected as long as it too is based on SHA256 + */ + cipher = SSL_CIPHER_find(ssl, TLS13_AES_128_GCM_SHA256_BYTES); + } else { + /* Should not happen */ + return NULL; + } + sess = SSL_SESSION_new(); + if (!TEST_ptr(sess) + || !TEST_ptr(cipher) + || !TEST_true(SSL_SESSION_set1_master_key(sess, key, mdsize)) + || !TEST_true(SSL_SESSION_set_cipher(sess, cipher)) + || !TEST_true( + SSL_SESSION_set_protocol_version(sess, + TLS1_3_VERSION))) { + SSL_SESSION_free(sess); + return NULL; + } + return sess; +} diff --git a/test/helpers/ssltestlib.h b/test/helpers/ssltestlib.h index c8dcb8a82d..c513769ddd 100644 --- a/test/helpers/ssltestlib.h +++ b/test/helpers/ssltestlib.h @@ -12,6 +12,12 @@ # include +#define TLS13_AES_128_GCM_SHA256_BYTES ((const unsigned char *)"\x13\x01") +#define TLS13_AES_256_GCM_SHA384_BYTES ((const unsigned char *)"\x13\x02") +#define TLS13_CHACHA20_POLY1305_SHA256_BYTES ((const unsigned char *)"\x13\x03") +#define TLS13_AES_128_CCM_SHA256_BYTES ((const unsigned char *)"\x13\x04") +#define TLS13_AES_128_CCM_8_SHA256_BYTES ((const unsigned char *)"\x13\05") + int create_ssl_ctx_pair(OSSL_LIB_CTX *libctx, const SSL_METHOD *sm, const SSL_METHOD *cm, int min_proto_version, int max_proto_version, SSL_CTX **sctx, SSL_CTX **cctx, @@ -60,4 +66,6 @@ typedef struct mempacket_st MEMPACKET; DEFINE_STACK_OF(MEMPACKET) +SSL_SESSION *create_a_psk(SSL *ssl, size_t mdsize); + #endif /* OSSL_TEST_SSLTESTLIB_H */ diff --git a/test/quicapitest.c b/test/quicapitest.c index 87c134eb88..a24946a649 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -1061,6 +1061,92 @@ static int test_non_io_retry(int idx) return testresult; } +static int use_session_cb_cnt = 0; +static int find_session_cb_cnt = 0; +static const char *pskid = "Identity"; +static SSL_SESSION *serverpsk = NULL, *clientpsk = NULL; + +static int use_session_cb(SSL *ssl, const EVP_MD *md, const unsigned char **id, + size_t *idlen, SSL_SESSION **sess) +{ + use_session_cb_cnt++; + + if (clientpsk == NULL) + return 0; + + SSL_SESSION_up_ref(clientpsk); + + *sess = clientpsk; + *id = (const unsigned char *)pskid; + *idlen = strlen(pskid); + + return 1; +} + +static int find_session_cb(SSL *ssl, const unsigned char *identity, + size_t identity_len, SSL_SESSION **sess) +{ + find_session_cb_cnt++; + + if (serverpsk == NULL) + return 0; + + /* Identity should match that set by the client */ + if (strlen(pskid) != identity_len + || strncmp(pskid, (const char *)identity, identity_len) != 0) + return 0; + + SSL_SESSION_up_ref(serverpsk); + *sess = serverpsk; + + return 1; +} + +static int test_quic_psk(void) +{ + SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); + SSL *clientquic = NULL; + QUIC_TSERVER *qtserv = NULL; + int testresult = 0; + + if (!TEST_ptr(cctx) + /* No cert or private key for the server, i.e. PSK only */ + || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, NULL, + NULL, 0, &qtserv, + &clientquic, NULL))) + goto end; + + SSL_set_psk_use_session_callback(clientquic, use_session_cb); + ossl_quic_tserver_set_psk_find_session_cb(qtserv, find_session_cb); + use_session_cb_cnt = 0; + find_session_cb_cnt = 0; + + clientpsk = serverpsk = create_a_psk(clientquic, SHA384_DIGEST_LENGTH); + if (!TEST_ptr(clientpsk)) + goto end; + /* We already had one ref. Add another one */ + SSL_SESSION_up_ref(clientpsk); + + if (!TEST_true(qtest_create_quic_connection(qtserv, clientquic)) + || !TEST_int_eq(1, find_session_cb_cnt) + || !TEST_int_eq(1, use_session_cb_cnt) + /* Check that we actually used the PSK */ + || !TEST_true(SSL_session_reused(clientquic))) + goto end; + + testresult = 1; + + end: + SSL_free(clientquic); + ossl_quic_tserver_free(qtserv); + SSL_CTX_free(cctx); + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; + + return testresult; +} + OPT_TEST_DECLARE_USAGE("provider config certsdir datadir\n") int setup_tests(void) @@ -1131,6 +1217,7 @@ int setup_tests(void) ADD_TEST(test_back_pressure); ADD_TEST(test_multiple_dgrams); ADD_ALL_TESTS(test_non_io_retry, 2); + ADD_TEST(test_quic_psk); return 1; err: cleanup_tests(); diff --git a/test/sslapitest.c b/test/sslapitest.c index 756675c1dc..ec29157007 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -77,8 +77,6 @@ static int find_session_cb(SSL *ssl, const unsigned char *identity, static int use_session_cb_cnt = 0; static int find_session_cb_cnt = 0; - -static SSL_SESSION *create_a_psk(SSL *ssl, size_t mdsize); #endif static char *certsdir = NULL; @@ -3385,51 +3383,6 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, #define MSG6 "test" #define MSG7 "message." -#define TLS13_AES_128_GCM_SHA256_BYTES ((const unsigned char *)"\x13\x01") -#define TLS13_AES_256_GCM_SHA384_BYTES ((const unsigned char *)"\x13\x02") -#define TLS13_CHACHA20_POLY1305_SHA256_BYTES ((const unsigned char *)"\x13\x03") -#define TLS13_AES_128_CCM_SHA256_BYTES ((const unsigned char *)"\x13\x04") -#define TLS13_AES_128_CCM_8_SHA256_BYTES ((const unsigned char *)"\x13\05") - - -static SSL_SESSION *create_a_psk(SSL *ssl, size_t mdsize) -{ - const SSL_CIPHER *cipher = NULL; - const unsigned char key[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, - 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f /* SHA384_DIGEST_LENGTH bytes */ - }; - SSL_SESSION *sess = NULL; - - if (mdsize == SHA384_DIGEST_LENGTH) { - cipher = SSL_CIPHER_find(ssl, TLS13_AES_256_GCM_SHA384_BYTES); - } else if (mdsize == SHA256_DIGEST_LENGTH) { - /* - * Any ciphersuite using SHA256 will do - it will be compatible with - * the actual ciphersuite selected as long as it too is based on SHA256 - */ - cipher = SSL_CIPHER_find(ssl, TLS13_AES_128_GCM_SHA256_BYTES); - } else { - /* Should not happen */ - return NULL; - } - sess = SSL_SESSION_new(); - if (!TEST_ptr(sess) - || !TEST_ptr(cipher) - || !TEST_true(SSL_SESSION_set1_master_key(sess, key, mdsize)) - || !TEST_true(SSL_SESSION_set_cipher(sess, cipher)) - || !TEST_true( - SSL_SESSION_set_protocol_version(sess, - TLS1_3_VERSION))) { - SSL_SESSION_free(sess); - return NULL; - } - return sess; -} - static int artificial_ticket_time = 0; static int ed_gen_cb(SSL *s, void *arg) -- Gitee From 9f1106f58e697fa8d0730514e69c17e60f9e889b Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 7 Sep 2023 17:45:49 +0100 Subject: [PATCH 02/79] Fix the SSL_CIPHER_find() function when used with a QCSO Reviewed-by: Hugo Landau Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22011) Signed-off-by: fly2x --- include/internal/quic_ssl.h | 1 + ssl/quic/quic_impl.c | 10 ++++++++++ ssl/quic/quic_local.h | 2 +- ssl/s3_lib.c | 6 +++--- ssl/ssl_local.h | 3 +++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/internal/quic_ssl.h b/include/internal/quic_ssl.h index 260cef87b9..66cea1bfe1 100644 --- a/include/internal/quic_ssl.h +++ b/include/internal/quic_ssl.h @@ -36,6 +36,7 @@ __owur long ossl_quic_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void) __owur size_t ossl_quic_pending(const SSL *s); __owur int ossl_quic_key_update(SSL *s, int update_type); __owur int ossl_quic_get_key_update_type(const SSL *s); +__owur const SSL_CIPHER *ossl_quic_get_cipher_by_char(const unsigned char *p); __owur int ossl_quic_num_ciphers(void); __owur const SSL_CIPHER *ossl_quic_get_cipher(unsigned int u); int ossl_quic_renegotiate_check(SSL *ssl, int initok); diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index ca4ef0ebbb..b632ad22db 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -3535,6 +3535,16 @@ int ossl_quic_renegotiate_check(SSL *ssl, int initok) return 0; } +const SSL_CIPHER *ossl_quic_get_cipher_by_char(const unsigned char *p) +{ + const SSL_CIPHER *ciph = ssl3_get_cipher_by_char(p); + + if ((ciph->algorithm2 & SSL_QUIC) == 0) + return NULL; + + return ciph; +} + /* * These functions define the TLSv1.2 (and below) ciphers that are supported by * the SSL_METHOD. Since QUIC only supports TLSv1.3 we don't support any. diff --git a/ssl/quic/quic_local.h b/ssl/quic/quic_local.h index 517904d90f..063df7796a 100644 --- a/ssl/quic/quic_local.h +++ b/ssl/quic/quic_local.h @@ -321,7 +321,7 @@ const SSL_METHOD *func_name(void) \ NULL /* dispatch_alert */, \ ossl_quic_ctrl, \ ossl_quic_ctx_ctrl, \ - NULL /* get_cipher_by_char */, \ + ossl_quic_get_cipher_by_char, \ NULL /* put_cipher_by_char */, \ ossl_quic_pending, \ ossl_quic_num_ciphers, \ diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 29af55bc61..1f778c3423 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -47,7 +47,7 @@ static SSL_CIPHER tls13_ciphers[] = { TLS1_3_VERSION, TLS1_3_VERSION, 0, 0, SSL_HIGH, - SSL_HANDSHAKE_MAC_SHA256, + SSL_HANDSHAKE_MAC_SHA256 | SSL_QUIC, 128, 128, }, { @@ -62,7 +62,7 @@ static SSL_CIPHER tls13_ciphers[] = { TLS1_3_VERSION, TLS1_3_VERSION, 0, 0, SSL_HIGH, - SSL_HANDSHAKE_MAC_SHA384, + SSL_HANDSHAKE_MAC_SHA384 | SSL_QUIC, 256, 256, }, @@ -78,7 +78,7 @@ static SSL_CIPHER tls13_ciphers[] = { TLS1_3_VERSION, TLS1_3_VERSION, 0, 0, SSL_HIGH, - SSL_HANDSHAKE_MAC_SHA256, + SSL_HANDSHAKE_MAC_SHA256 | SSL_QUIC, 256, 256, }, diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 29715781ee..d1ef358932 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -236,6 +236,9 @@ */ # define TLS1_TLSTREE 0x20000 +/* Ciphersuite supported in QUIC */ +# define SSL_QUIC 0x00040000U + # define SSL_STRONG_MASK 0x0000001FU # define SSL_DEFAULT_MASK 0X00000020U -- Gitee From 469dc9a71d0fb4be23b79af72cb86e687e6a111b Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 8 Sep 2023 11:22:36 +0100 Subject: [PATCH 03/79] Add a test for SSL_CIPHER_find() when used with a QUIC SSL object Reviewed-by: Hugo Landau Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22011) Signed-off-by: fly2x --- test/quicapitest.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/quicapitest.c b/test/quicapitest.c index a24946a649..8c78e14de9 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -321,6 +321,49 @@ static int test_ciphersuites(void) return testresult; } +static int test_cipher_find(void) +{ + SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); + SSL *clientquic = NULL; + struct { + const unsigned char *cipherbytes; + int ok; + } testciphers[] = { + { TLS13_AES_128_GCM_SHA256_BYTES, 1 }, + { TLS13_AES_256_GCM_SHA384_BYTES, 1 }, + { TLS13_CHACHA20_POLY1305_SHA256_BYTES, 1 }, + { TLS13_AES_128_CCM_SHA256_BYTES, 0 }, + { TLS13_AES_128_CCM_8_SHA256_BYTES, 0 } + }; + size_t i; + int testresult = 0; + + if (!TEST_ptr(cctx)) + goto err; + + clientquic = SSL_new(cctx); + if (!TEST_ptr(clientquic)) + goto err; + + for (i = 0; i < OSSL_NELEM(testciphers); i++) + if (testciphers[i].ok) { + if (!TEST_ptr(SSL_CIPHER_find(clientquic, + testciphers[i].cipherbytes))) + goto err; + } else { + if (!TEST_ptr_null(SSL_CIPHER_find(clientquic, + testciphers[i].cipherbytes))) + goto err; + } + + testresult = 1; + err: + SSL_free(clientquic); + SSL_CTX_free(cctx); + + return testresult; +} + /* * Test that SSL_version, SSL_get_version, SSL_is_quic, SSL_is_tls and * SSL_is_dtls return the expected results for a QUIC connection. Compare with @@ -1205,6 +1248,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_quic_write_read, 3); ADD_TEST(test_fin_only_blocking); ADD_TEST(test_ciphersuites); + ADD_TEST(test_cipher_find); ADD_TEST(test_version); #if defined(DO_SSL_TRACE_TEST) ADD_TEST(test_ssl_trace); -- Gitee From d688c6dc766d24ac0f7322ef5e69d2a8682b7c58 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 29 Aug 2023 15:42:48 -0400 Subject: [PATCH 04/79] make inability to dup/clone ciphers an error There should be no reason that a cipher can't be duplicated Fixes #21887 Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21933) Signed-off-by: fly2x --- test/evp_test.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/test/evp_test.c b/test/evp_test.c index ea1ca65bcd..7447435f06 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -735,6 +735,9 @@ static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign, int ok = 0, tmplen, chunklen, tmpflen, i; EVP_CIPHER_CTX *ctx_base = NULL; EVP_CIPHER_CTX *ctx = NULL, *duped; + int fips_dupctx_supported = (fips_provider_version_ge(libctx, 3, 0, 11) + && fips_provider_version_lt(libctx, 3, 1, 0)) + || fips_provider_version_ge(libctx, 3, 1, 3); t->err = "TEST_FAILURE"; if (!TEST_ptr(ctx_base = EVP_CIPHER_CTX_new())) @@ -865,18 +868,30 @@ static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign, /* Test that the cipher dup functions correctly if it is supported */ ERR_set_mark(); - if (EVP_CIPHER_CTX_copy(ctx, ctx_base)) { - EVP_CIPHER_CTX_free(ctx_base); - ctx_base = NULL; - } else { - EVP_CIPHER_CTX_free(ctx); - ctx = ctx_base; + if (!EVP_CIPHER_CTX_copy(ctx, ctx_base)) { + if (fips_dupctx_supported) { + TEST_info("Doing a copy of Cipher %s Fails!\n", + EVP_CIPHER_get0_name(expected->cipher)); + ERR_print_errors_fp(stderr); + goto err; + } else { + TEST_info("Allowing copy fail as an old fips provider is in use."); + } } /* Likewise for dup */ duped = EVP_CIPHER_CTX_dup(ctx); if (duped != NULL) { EVP_CIPHER_CTX_free(ctx); ctx = duped; + } else { + if (fips_dupctx_supported) { + TEST_info("Doing a dup of Cipher %s Fails!\n", + EVP_CIPHER_get0_name(expected->cipher)); + ERR_print_errors_fp(stderr); + goto err; + } else { + TEST_info("Allowing dup fail as an old fips provider is in use."); + } } ERR_pop_to_mark(); @@ -1089,6 +1104,7 @@ static int cipher_test_run(EVP_TEST *t) int rv, frag, fragmax, in_place; size_t out_misalign, inp_misalign; + TEST_info("RUNNING TEST FOR CIPHER %s\n", EVP_CIPHER_get0_name(cdat->cipher)); if (!cdat->key) { t->err = "NO_KEY"; return 0; -- Gitee From 2a180cfc92aeb1e80ace42ac724aa299f7e00f3c Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 1 Sep 2023 09:10:35 -0400 Subject: [PATCH 05/79] Add dupctx support to aead ciphers Add dupctx method support to to ciphers implemented with IMPLEMENT_aead_cipher This includes: aes--gcm aria--ccm aria--gcm sm4--gcm Fixes #21887 Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21933) Signed-off-by: fly2x --- .../implementations/ciphers/cipher_aes_ccm.c | 20 +++++++++++++++++++ .../implementations/ciphers/cipher_aes_gcm.c | 9 +++++++++ .../implementations/ciphers/cipher_aria_ccm.c | 9 +++++++++ .../implementations/ciphers/cipher_aria_gcm.c | 9 +++++++++ .../implementations/ciphers/cipher_sm4_ccm.c | 9 +++++++++ .../implementations/ciphers/cipher_sm4_gcm.c | 9 +++++++++ .../include/prov/ciphercommon_aead.h | 5 +++++ 7 files changed, 70 insertions(+) diff --git a/providers/implementations/ciphers/cipher_aes_ccm.c b/providers/implementations/ciphers/cipher_aes_ccm.c index bb4b1e1e64..3930f52d60 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm.c +++ b/providers/implementations/ciphers/cipher_aes_ccm.c @@ -33,6 +33,26 @@ static void *aes_ccm_newctx(void *provctx, size_t keybits) return ctx; } +static void *aes_ccm_dupctx(void *provctx) +{ + PROV_AES_CCM_CTX *ctx = provctx; + PROV_AES_CCM_CTX *dupctx = NULL; + + if (ctx == NULL) + return NULL; + dupctx = OPENSSL_memdup(provctx, sizeof(*ctx)); + if (dupctx == NULL) + return NULL; + /* + * ossl_cm_initctx, via the ossl_prov_aes_hw_ccm functions assign a + * provctx->ccm.ks.ks to the ccm context key so we need to point it to + * the memduped copy + */ + dupctx->base.ccm_ctx.key = &dupctx->ccm.ks.ks; + + return dupctx; +} + static OSSL_FUNC_cipher_freectx_fn aes_ccm_freectx; static void aes_ccm_freectx(void *vctx) { diff --git a/providers/implementations/ciphers/cipher_aes_gcm.c b/providers/implementations/ciphers/cipher_aes_gcm.c index 0081ca6cd7..0a15693cc1 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm.c +++ b/providers/implementations/ciphers/cipher_aes_gcm.c @@ -34,6 +34,15 @@ static void *aes_gcm_newctx(void *provctx, size_t keybits) return ctx; } +static void *aes_gcm_dupctx(void *provctx) +{ + PROV_AES_GCM_CTX *ctx = provctx; + + if (ctx == NULL) + return NULL; + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static OSSL_FUNC_cipher_freectx_fn aes_gcm_freectx; static void aes_gcm_freectx(void *vctx) { diff --git a/providers/implementations/ciphers/cipher_aria_ccm.c b/providers/implementations/ciphers/cipher_aria_ccm.c index d6b5517ee0..39a96a6f14 100644 --- a/providers/implementations/ciphers/cipher_aria_ccm.c +++ b/providers/implementations/ciphers/cipher_aria_ccm.c @@ -28,6 +28,15 @@ static void *aria_ccm_newctx(void *provctx, size_t keybits) return ctx; } +static void *aria_ccm_dupctx(void *provctx) +{ + PROV_ARIA_CCM_CTX *ctx = provctx; + + if (ctx == NULL) + return NULL; + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static void aria_ccm_freectx(void *vctx) { PROV_ARIA_CCM_CTX *ctx = (PROV_ARIA_CCM_CTX *)vctx; diff --git a/providers/implementations/ciphers/cipher_aria_gcm.c b/providers/implementations/ciphers/cipher_aria_gcm.c index b412bd3202..6ffa0910fa 100644 --- a/providers/implementations/ciphers/cipher_aria_gcm.c +++ b/providers/implementations/ciphers/cipher_aria_gcm.c @@ -27,6 +27,15 @@ static void *aria_gcm_newctx(void *provctx, size_t keybits) return ctx; } +static void *aria_gcm_dupctx(void *provctx) +{ + PROV_ARIA_GCM_CTX *ctx = provctx; + + if (ctx == NULL) + return NULL; + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static OSSL_FUNC_cipher_freectx_fn aria_gcm_freectx; static void aria_gcm_freectx(void *vctx) { diff --git a/providers/implementations/ciphers/cipher_sm4_ccm.c b/providers/implementations/ciphers/cipher_sm4_ccm.c index f0295a5ca2..5fd7d1a114 100644 --- a/providers/implementations/ciphers/cipher_sm4_ccm.c +++ b/providers/implementations/ciphers/cipher_sm4_ccm.c @@ -28,6 +28,15 @@ static void *sm4_ccm_newctx(void *provctx, size_t keybits) return ctx; } +static void *sm4_ccm_dupctx(void *provctx) +{ + PROV_SM4_CCM_CTX *ctx = provctx; + + if (ctx == NULL) + return NULL; + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static void sm4_ccm_freectx(void *vctx) { PROV_SM4_CCM_CTX *ctx = (PROV_SM4_CCM_CTX *)vctx; diff --git a/providers/implementations/ciphers/cipher_sm4_gcm.c b/providers/implementations/ciphers/cipher_sm4_gcm.c index 7a936f00ee..79e1b556d4 100644 --- a/providers/implementations/ciphers/cipher_sm4_gcm.c +++ b/providers/implementations/ciphers/cipher_sm4_gcm.c @@ -29,6 +29,15 @@ static void *sm4_gcm_newctx(void *provctx, size_t keybits) return ctx; } +static void *sm4_gcm_dupctx(void *provctx) +{ + PROV_SM4_GCM_CTX *ctx = provctx; + + if (ctx == NULL) + return NULL; + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static void sm4_gcm_freectx(void *vctx) { PROV_SM4_GCM_CTX *ctx = (PROV_SM4_GCM_CTX *)vctx; diff --git a/providers/implementations/include/prov/ciphercommon_aead.h b/providers/implementations/include/prov/ciphercommon_aead.h index 0dd63cbe53..8d709f10ea 100644 --- a/providers/implementations/include/prov/ciphercommon_aead.h +++ b/providers/implementations/include/prov/ciphercommon_aead.h @@ -27,9 +27,14 @@ static void * alg##kbits##lc##_newctx(void *provctx) \ { \ return alg##_##lc##_newctx(provctx, kbits); \ } \ +static void * alg##kbits##lc##_dupctx(void *src) \ +{ \ + return alg##_##lc##_dupctx(src); \ +} \ const OSSL_DISPATCH ossl_##alg##kbits##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))alg##kbits##lc##_dupctx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_##lc##_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_##lc##_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_##lc##_stream_update }, \ -- Gitee From 5f407079b9ce707ba0b78cd2e47208e545c683e1 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 1 Sep 2023 11:28:33 -0400 Subject: [PATCH 06/79] implement dupctx for aes_WRAP methods create a dupctx method for aes_WRAP implementations of all sizes Fixes #21887 Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21933) Signed-off-by: fly2x --- .../implementations/ciphers/cipher_aes_wrp.c | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/providers/implementations/ciphers/cipher_aes_wrp.c b/providers/implementations/ciphers/cipher_aes_wrp.c index ecebf213e2..912a47e3fe 100644 --- a/providers/implementations/ciphers/cipher_aes_wrp.c +++ b/providers/implementations/ciphers/cipher_aes_wrp.c @@ -66,6 +66,26 @@ static void *aes_wrap_newctx(size_t kbits, size_t blkbits, return wctx; } +static void *aes_wrap_dupctx(void *wctx) +{ + PROV_AES_WRAP_CTX *ctx = wctx; + PROV_AES_WRAP_CTX *dctx = wctx; + + if (ctx == NULL) + return NULL; + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + + if (dctx != NULL && dctx->base.tlsmac != NULL && dctx->base.alloced) { + dctx->base.tlsmac = OPENSSL_memdup(dctx->base.tlsmac, + dctx->base.tlsmacsize); + if (dctx->base.tlsmac == NULL) { + OPENSSL_free(dctx); + dctx = NULL; + } + } + return dctx; +} + static void aes_wrap_freectx(void *vctx) { PROV_AES_WRAP_CTX *wctx = (PROV_AES_WRAP_CTX *)vctx; @@ -281,6 +301,7 @@ static int aes_wrap_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_##mode##_cipher }, \ { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_##mode##_final }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_##mode##_freectx }, \ + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_##mode##_dupctx }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void))aes_##kbits##_##fname##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ -- Gitee From 5dad40e90c94dc6c2ecd1600d197cf90fdbd8fd4 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 1 Sep 2023 12:13:19 -0400 Subject: [PATCH 07/79] Fix aes_gcm_siv dupctx function This cipher family has a dupctx function, but was failing because it was attempting to memdup a field only if it was null Fix the conditional check to get it working again Fixes #21887 Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21933) Signed-off-by: fly2x --- providers/implementations/ciphers/cipher_aes_gcm_siv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv.c b/providers/implementations/ciphers/cipher_aes_gcm_siv.c index 64f7f95039..2d4fd88658 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_siv.c +++ b/providers/implementations/ciphers/cipher_aes_gcm_siv.c @@ -71,7 +71,7 @@ static void *ossl_aes_gcm_siv_dupctx(void *vctx) ret->aad = NULL; ret->ecb_ctx = NULL; - if (in->aad == NULL) { + if (in->aad != NULL) { if ((ret->aad = OPENSSL_memdup(in->aad, UP16(ret->aad_len))) == NULL) goto err; } -- Gitee From 046bec9f73f6031bc6475bfc2bd66ac99cca0a2c Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 1 Sep 2023 13:22:03 -0400 Subject: [PATCH 08/79] implement dupctx for chacha20_poly1305 Same as chacha20 in the last commit, just clone the ctx and its underlying tlsmac array if its allocated Fixes #21887 Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21933) Signed-off-by: fly2x --- .../ciphers/cipher_chacha20_poly1305.c | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.c b/providers/implementations/ciphers/cipher_chacha20_poly1305.c index 662b4e03e5..d5d4e1a251 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305.c +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.c @@ -23,6 +23,7 @@ static OSSL_FUNC_cipher_newctx_fn chacha20_poly1305_newctx; static OSSL_FUNC_cipher_freectx_fn chacha20_poly1305_freectx; +static OSSL_FUNC_cipher_dupctx_fn chacha20_poly1305_dupctx; static OSSL_FUNC_cipher_encrypt_init_fn chacha20_poly1305_einit; static OSSL_FUNC_cipher_decrypt_init_fn chacha20_poly1305_dinit; static OSSL_FUNC_cipher_get_params_fn chacha20_poly1305_get_params; @@ -58,6 +59,25 @@ static void *chacha20_poly1305_newctx(void *provctx) return ctx; } +static void *chacha20_poly1305_dupctx(void *provctx) +{ + PROV_CHACHA20_POLY1305_CTX *ctx = provctx; + PROV_CHACHA20_POLY1305_CTX *dctx = NULL; + + if (ctx == NULL) + return NULL; + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.tlsmac != NULL && dctx->base.alloced) { + dctx->base.tlsmac = OPENSSL_memdup(dctx->base.tlsmac, + dctx->base.tlsmacsize); + if (dctx->base.tlsmac == NULL) { + OPENSSL_free(dctx); + dctx = NULL; + } + } + return dctx; +} + static void chacha20_poly1305_freectx(void *vctx) { PROV_CHACHA20_POLY1305_CTX *ctx = (PROV_CHACHA20_POLY1305_CTX *)vctx; @@ -310,6 +330,7 @@ static int chacha20_poly1305_final(void *vctx, unsigned char *out, size_t *outl, const OSSL_DISPATCH ossl_chacha20_ossl_poly1305_functions[] = { { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))chacha20_poly1305_newctx }, { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))chacha20_poly1305_freectx }, + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))chacha20_poly1305_dupctx }, { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))chacha20_poly1305_einit }, { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))chacha20_poly1305_dinit }, { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))chacha20_poly1305_update }, -- Gitee From 211ac036fe3e649e67d9ca79e3b38bee959e28d5 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 1 Sep 2023 13:47:15 -0400 Subject: [PATCH 09/79] Add dupctx support to rc4_hmac_md5 algo Pretty straightforward, just clone the requested context, no pointers to fixup Fixes #21887 Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21933) Signed-off-by: fly2x --- .../ciphers/cipher_aes_cbc_hmac_sha.c | 18 ++++++++++++++++++ .../ciphers/cipher_rc4_hmac_md5.c | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c index f0ebfb6836..28d3909c4d 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c @@ -334,6 +334,16 @@ static void *aes_cbc_hmac_sha1_newctx(void *provctx, size_t kbits, return ctx; } +static void *aes_cbc_hmac_sha1_dupctx(void *provctx) +{ + PROV_AES_HMAC_SHA1_CTX *ctx = provctx; + + if (ctx == NULL) + return NULL; + + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static void aes_cbc_hmac_sha1_freectx(void *vctx) { PROV_AES_HMAC_SHA1_CTX *ctx = (PROV_AES_HMAC_SHA1_CTX *)vctx; @@ -361,6 +371,13 @@ static void *aes_cbc_hmac_sha256_newctx(void *provctx, size_t kbits, return ctx; } +static void *aes_cbc_hmac_sha256_dupctx(void *provctx) +{ + PROV_AES_HMAC_SHA256_CTX *ctx = provctx; + + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static void aes_cbc_hmac_sha256_freectx(void *vctx) { PROV_AES_HMAC_SHA256_CTX *ctx = (PROV_AES_HMAC_SHA256_CTX *)vctx; @@ -386,6 +403,7 @@ static int nm##_##kbits##_##sub##_get_params(OSSL_PARAM params[]) \ const OSSL_DISPATCH ossl_##nm##kbits##sub##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))nm##_##kbits##_##sub##_newctx },\ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))nm##_##sub##_freectx }, \ + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))nm##_##sub##_dupctx}, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))nm##_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))nm##_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))nm##_update }, \ diff --git a/providers/implementations/ciphers/cipher_rc4_hmac_md5.c b/providers/implementations/ciphers/cipher_rc4_hmac_md5.c index 99d5dd7169..82ef7890b5 100644 --- a/providers/implementations/ciphers/cipher_rc4_hmac_md5.c +++ b/providers/implementations/ciphers/cipher_rc4_hmac_md5.c @@ -34,6 +34,7 @@ static OSSL_FUNC_cipher_encrypt_init_fn rc4_hmac_md5_einit; static OSSL_FUNC_cipher_decrypt_init_fn rc4_hmac_md5_dinit; static OSSL_FUNC_cipher_newctx_fn rc4_hmac_md5_newctx; static OSSL_FUNC_cipher_freectx_fn rc4_hmac_md5_freectx; +static OSSL_FUNC_cipher_dupctx_fn rc4_hmac_md5_dupctx; static OSSL_FUNC_cipher_get_ctx_params_fn rc4_hmac_md5_get_ctx_params; static OSSL_FUNC_cipher_gettable_ctx_params_fn rc4_hmac_md5_gettable_ctx_params; static OSSL_FUNC_cipher_set_ctx_params_fn rc4_hmac_md5_set_ctx_params; @@ -71,6 +72,15 @@ static void rc4_hmac_md5_freectx(void *vctx) OPENSSL_clear_free(ctx, sizeof(*ctx)); } +static void *rc4_hmac_md5_dupctx(void *vctx) +{ + PROV_RC4_HMAC_MD5_CTX *ctx = vctx; + + if (ctx == NULL) + return NULL; + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static int rc4_hmac_md5_einit(void *ctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen, const OSSL_PARAM params[]) @@ -214,6 +224,7 @@ static int rc4_hmac_md5_get_params(OSSL_PARAM params[]) const OSSL_DISPATCH ossl_rc4_hmac_ossl_md5_functions[] = { { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))rc4_hmac_md5_newctx }, { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))rc4_hmac_md5_freectx }, + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))rc4_hmac_md5_dupctx }, { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))rc4_hmac_md5_einit }, { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))rc4_hmac_md5_dinit }, { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))rc4_hmac_md5_update }, -- Gitee From 525a9de7d1b30020dd825c1e23fd058eab511e1b Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 11 Sep 2023 12:34:02 +0200 Subject: [PATCH 10/79] Fix a memleak in prepare_rsa_params This affects only RSA-PSS keys with params using negative salt legth, or in case of out of memory. This fixes a memory leak reported in #22049. Reviewed-by: Hugo Landau Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22061) Signed-off-by: fly2x --- providers/implementations/encode_decode/encode_key2any.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c index c1b0dea780..ae6d7d0a68 100644 --- a/providers/implementations/encode_decode/encode_key2any.c +++ b/providers/implementations/encode_decode/encode_key2any.c @@ -856,14 +856,17 @@ static int prepare_rsa_params(const void *rsa, int nid, int save, case 1: if ((str = OPENSSL_malloc(str_sz)) == NULL || !WPACKET_init_der(&pkt, str, str_sz)) { + WPACKET_cleanup(&pkt); goto err; } break; } if (!ossl_DER_w_RSASSA_PSS_params(&pkt, -1, pss) || !WPACKET_finish(&pkt) - || !WPACKET_get_total_written(&pkt, &str_sz)) + || !WPACKET_get_total_written(&pkt, &str_sz)) { + WPACKET_cleanup(&pkt); goto err; + } WPACKET_cleanup(&pkt); /* -- Gitee From af6f3a1577baaebd6528c32c537a97eca2f3ab5f Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 11 Sep 2023 13:27:05 +0200 Subject: [PATCH 11/79] Fix typos found by codespell Reviewed-by: Hugo Landau Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22063) Signed-off-by: fly2x --- apps/progs.pl | 2 +- crypto/bio/bio_print.c | 2 +- crypto/err/err.c | 2 +- crypto/evp/pmeth_gn.c | 2 +- doc/internal/man3/ossl_provider_new.pod | 2 +- doc/man3/EVP_MAC.pod | 2 +- doc/man3/EVP_SIGNATURE.pod | 2 +- doc/man5/x509v3_config.pod | 2 +- doc/man7/ossl-guide-quic-client-non-block.pod | 4 ++-- doc/man7/ossl-guide-quic-multi-stream.pod | 2 +- doc/man7/ossl-guide-tls-client-block.pod | 4 ++-- doc/man7/ossl-guide-tls-client-non-block.pod | 6 +++--- ssl/statem/statem_clnt.c | 2 +- 13 files changed, 17 insertions(+), 17 deletions(-) diff --git a/apps/progs.pl b/apps/progs.pl index f27ccfbba3..120ae05f07 100644 --- a/apps/progs.pl +++ b/apps/progs.pl @@ -104,7 +104,7 @@ EOF # The format of this table is: # [0] = alternative command to use instead # [1] = deprecented in this version -# [2] = preprocessor conditional for exclusing irrespective of deprecation +# [2] = preprocessor conditional for excluding irrespective of deprecation # rsa => [ "pkey", "3_0", "rsa" ], # genrsa => [ "genpkey", "3_0", "rsa" ], rsautl => [ "pkeyutl", "3_0", "rsa" ], diff --git a/crypto/bio/bio_print.c b/crypto/bio/bio_print.c index e5397c8b7a..5f2543030e 100644 --- a/crypto/bio/bio_print.c +++ b/crypto/bio/bio_print.c @@ -62,7 +62,7 @@ static int _dopr(char **sbuffer, char **buffer, #define DP_F_NUM (1 << 3) /* print leading zeroes */ #define DP_F_ZERO (1 << 4) -/* print HEX in UPPPERcase */ +/* print HEX in UPPERcase */ #define DP_F_UP (1 << 5) /* treat value as unsigned */ #define DP_F_UNSIGNED (1 << 6) diff --git a/crypto/err/err.c b/crypto/err/err.c index 3fc296929c..7b7f309951 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -831,7 +831,7 @@ void ERR_add_error_vdata(int num, va_list args) i = es->top; /* - * If err_data is allocated already, re-use the space. + * If err_data is allocated already, reuse the space. * Otherwise, allocate a small new buffer. */ if ((es->err_data_flags[i] & flags) == flags) { diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index c8981227d4..6a38fe511a 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -153,7 +153,7 @@ int EVP_PKEY_generate(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) goto legacy; /* - * Asssigning gentmp to ctx->keygen_info is something our legacy + * Assigning gentmp to ctx->keygen_info is something our legacy * implementations do. Because the provider implementations aren't * allowed to reach into our EVP_PKEY_CTX, we need to provide similar * space for backward compatibility. It's ok that we attach a local diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod index e170edf343..d30e400894 100644 --- a/doc/internal/man3/ossl_provider_new.pod +++ b/doc/internal/man3/ossl_provider_new.pod @@ -291,7 +291,7 @@ in a bitstring that's internal to I. ossl_provider_test_operation_bit() checks if the bit operation I is set (1) or not (0) in the internal I bitstring, and sets -I<*result> to 1 or 0 accorddingly. +I<*result> to 1 or 0 accordingly. ossl_provider_init_as_child() stores in the library context I references to the necessary upcalls for managing child providers. The I and I diff --git a/doc/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod index 13482ac5e1..8fd237599e 100644 --- a/doc/man3/EVP_MAC.pod +++ b/doc/man3/EVP_MAC.pod @@ -181,7 +181,7 @@ EVP_MAC_CTX_set_params() passes chosen parameters to the underlying context, given a context I. The set of parameters given with I determine exactly what parameters are passed down. -If I are NULL, the unterlying context should do nothing and return 1. +If I are NULL, the underlying context should do nothing and return 1. Note that a parameter that is unknown in the underlying context is simply ignored. Also, what happens when a needed parameter isn't passed down is diff --git a/doc/man3/EVP_SIGNATURE.pod b/doc/man3/EVP_SIGNATURE.pod index 6005220853..a4ee9c4807 100644 --- a/doc/man3/EVP_SIGNATURE.pod +++ b/doc/man3/EVP_SIGNATURE.pod @@ -61,7 +61,7 @@ EVP_SIGNATURE_get0_provider() returns the provider that I was fetched from. EVP_SIGNATURE_do_all_provided() traverses all SIGNATURE implemented by all -activated roviders in the given library context I, and for each of the +activated providers in the given library context I, and for each of the implementations, calls the given function I with the implementation method and the given I as argument. diff --git a/doc/man5/x509v3_config.pod b/doc/man5/x509v3_config.pod index 2440f23ddd..ab33b7e7af 100644 --- a/doc/man5/x509v3_config.pod +++ b/doc/man5/x509v3_config.pod @@ -93,7 +93,7 @@ numeric identifier, as shown here: email.2 = steve@example.org The syntax of raw extensions is defined by the source code that parses -the extension but should be documened. +the extension but should be documented. See L for an example of a raw extension. If an extension type is unsupported, then the I extension syntax diff --git a/doc/man7/ossl-guide-quic-client-non-block.pod b/doc/man7/ossl-guide-quic-client-non-block.pod index 8187bb9b77..0c2b916b80 100644 --- a/doc/man7/ossl-guide-quic-client-non-block.pod +++ b/doc/man7/ossl-guide-quic-client-non-block.pod @@ -43,7 +43,7 @@ L or L will return immediately with a non-fatal error if they are currently unable to read or write respectively. Since this page is building on the example developed on the -L page we assume that you are familar with it +L page we assume that you are familiar with it and we only explain how this example differs. =head2 Performing work while waiting for the socket @@ -407,7 +407,7 @@ L. Since our application is initiating the shutdown then we might expect to see L give a return value of 0, and then we should continue to call -it until we recieve a return value of 1 (meaning we have successfully completed +it until we receive a return value of 1 (meaning we have successfully completed the shutdown). Since we are using a nonblocking B object we might expect to have to retry this operation several times. If L returns a negative result then we must call L to work out what to do diff --git a/doc/man7/ossl-guide-quic-multi-stream.pod b/doc/man7/ossl-guide-quic-multi-stream.pod index 4e4d852b03..877d2208ae 100644 --- a/doc/man7/ossl-guide-quic-multi-stream.pod +++ b/doc/man7/ossl-guide-quic-multi-stream.pod @@ -96,7 +96,7 @@ When using a default stream OpenSSL will prevent new streams from being accepted. To override this behaviour you must call L to set the policy to B. See the man page for further details. This -is not relevant if the default stream has been disabed as described in +is not relevant if the default stream has been disabled as described in L above. Any stream may be bi-directional or uni-directional. If it is uni-directional diff --git a/doc/man7/ossl-guide-tls-client-block.pod b/doc/man7/ossl-guide-tls-client-block.pod index 865a5353b3..646b58081a 100644 --- a/doc/man7/ossl-guide-tls-client-block.pod +++ b/doc/man7/ossl-guide-tls-client-block.pod @@ -124,7 +124,7 @@ function and passing the B we created as an argument. =head2 Creating the socket and BIO TLS data is transmitted over an underlying transport layer. Normally a TCP -socket. It is the application's resonsibility for ensuring that the socket is +socket. It is the application's responsibility for ensuring that the socket is created and associated with an SSL object (via a BIO). Socket creation for use by a client is typically a 2 step process, i.e. @@ -549,7 +549,7 @@ intermediate CAs, or the issuer is simply unrecognised). =head1 FURTHER READING See L to read a tutorial on how to modify -the client devloped on this page to support a nonblocking socket. +the client developed on this page to support a nonblocking socket. See L to read a tutorial on how to modify the client developed on this page to support QUIC instead of TLS. diff --git a/doc/man7/ossl-guide-tls-client-non-block.pod b/doc/man7/ossl-guide-tls-client-non-block.pod index ea5e40bd1c..1eabcc0b57 100644 --- a/doc/man7/ossl-guide-tls-client-non-block.pod +++ b/doc/man7/ossl-guide-tls-client-non-block.pod @@ -41,7 +41,7 @@ behaviour is propagated up to the application so that OpenSSL I/O functions such as L or L will not block. Since this page is building on the example developed on the -L page we assume that you are familar with it +L page we assume that you are familiar with it and we only explain how this example differs. =head2 Setting the socket to be nonblocking @@ -162,7 +162,7 @@ Fatal errors that may occur are B and B. These indicate that the underlying connection has failed. You should not attempt to shut it down with L. B indicates that OpenSSL attempted to make a syscall that failed. You can consult B for -further details. B indicates that some OpenSSL error occured. You +further details. B indicates that some OpenSSL error occurred. You can consult the OpenSSL error stack for further details (for example by calling L to print out details of errors that have occurred). @@ -313,7 +313,7 @@ finished with it. If our application was initiating the shutdown then we would expect to see L give a return value of 0, and then we would continue to call -it until we recieved a return value of 1 (meaning we have successfully completed +it until we received a return value of 1 (meaning we have successfully completed the shutdown). In this particular example we don't expect SSL_shutdown() to return 0 because we have already received EOF from the server indicating that it has shutdown already. So we just keep calling it until SSL_shutdown() returns 1. diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 92c00ce4ae..cbf5a57beb 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -1793,7 +1793,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) * If we're not doing early-data and we're not going to send a dummy CCS * (i.e. no middlebox compat mode) then we can change the write keys * immediately. Otherwise we have to defer this until after all possible - * early data is written. We could just alway defer until the last + * early data is written. We could just always defer until the last * moment except QUIC needs it done at the same time as the read keys * are changed. Since QUIC doesn't do TLS early data or need middlebox * compat this doesn't cause a problem. -- Gitee From 552ea02dca5628057f8998677ab0cd386185da68 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 8 Sep 2023 17:36:38 +0100 Subject: [PATCH 12/79] Test we correctly handle missing ALPN from the server ALPN is a requirement for QUIC so it is an error if the server does not send it. Reviewed-by: Hugo Landau Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22066) Signed-off-by: fly2x --- test/quicfaultstest.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/test/quicfaultstest.c b/test/quicfaultstest.c index 3b80385584..a6ba0dc053 100644 --- a/test/quicfaultstest.c +++ b/test/quicfaultstest.c @@ -161,25 +161,27 @@ static int test_unknown_frame(void) * Test that a server that fails to provide transport params cannot be * connected to. */ -static int drop_transport_params_cb(QTEST_FAULT *fault, +static int drop_extensions_cb(QTEST_FAULT *fault, QTEST_ENCRYPTED_EXTENSIONS *ee, size_t eelen, void *encextcbarg) { - if (!qtest_fault_delete_extension(fault, - TLSEXT_TYPE_quic_transport_parameters, - ee->extensions, &ee->extensionslen)) + int *ext = (int *)encextcbarg; + + if (!qtest_fault_delete_extension(fault, *ext, ee->extensions, + &ee->extensionslen)) return 0; return 1; } -static int test_no_transport_params(void) +static int test_drop_extensions(int idx) { int testresult = 0; SSL_CTX *cctx = SSL_CTX_new(OSSL_QUIC_client_method()); QUIC_TSERVER *qtserv = NULL; SSL *cssl = NULL; QTEST_FAULT *fault = NULL; + int ext, err; if (!TEST_ptr(cctx)) goto err; @@ -188,9 +190,17 @@ static int test_no_transport_params(void) &qtserv, &cssl, &fault))) goto err; + if (idx == 0) { + ext = TLSEXT_TYPE_quic_transport_parameters; + err = QUIC_ERR_CRYPTO_MISSING_EXT; + } else { + ext = TLSEXT_TYPE_application_layer_protocol_negotiation; + err = QUIC_ERR_CRYPTO_NO_APP_PROTO; + } + if (!TEST_true(qtest_fault_set_hand_enc_ext_listener(fault, - drop_transport_params_cb, - NULL))) + drop_extensions_cb, + &ext))) goto err; /* @@ -200,8 +210,7 @@ static int test_no_transport_params(void) if (!TEST_false(qtest_create_quic_connection(qtserv, cssl))) goto err; - if (!TEST_true(qtest_check_server_transport_err(qtserv, - QUIC_ERR_CRYPTO_MISSING_EXT))) + if (!TEST_true(qtest_check_server_transport_err(qtserv, err))) goto err; testresult = 1; @@ -384,7 +393,7 @@ int setup_tests(void) ADD_TEST(test_basic); ADD_TEST(test_unknown_frame); - ADD_TEST(test_no_transport_params); + ADD_ALL_TESTS(test_drop_extensions, 2); ADD_ALL_TESTS(test_corrupted_data, 2); return 1; -- Gitee From f14be1d283caf61d343307c29d0171c61ae1c27f Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 11 Sep 2023 13:55:41 +0100 Subject: [PATCH 13/79] Ensure QUIC-TLS errors raised during channel start are available to caller TLS misconfiguration errors should be shown to the application to enable diagnosis of the problem. Otherwise you just get a generical "internal error" message. Reviewed-by: Hugo Landau Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22066) Signed-off-by: fly2x --- ssl/quic/quic_channel.c | 13 ++++++++++++- ssl/quic/quic_impl.c | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index ce938b70f0..7504f06dfc 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -44,6 +44,7 @@ */ #define DEFAULT_MAX_ACK_DELAY QUIC_DEFAULT_MAX_ACK_DELAY +static void ch_save_err_state(QUIC_CHANNEL *ch); static void ch_rx_pre(QUIC_CHANNEL *ch); static int ch_rx(QUIC_CHANNEL *ch); static int ch_tx(QUIC_CHANNEL *ch); @@ -2702,6 +2703,10 @@ int ossl_quic_channel_set_net_wbio(QUIC_CHANNEL *ch, BIO *net_wbio) */ int ossl_quic_channel_start(QUIC_CHANNEL *ch) { + uint64_t error_code; + const char *error_msg; + ERR_STATE *error_state = NULL; + if (ch->is_server) /* * This is not used by the server. The server moves to active @@ -2730,8 +2735,14 @@ int ossl_quic_channel_start(QUIC_CHANNEL *ch) ch->doing_proactive_ver_neg = 0; /* not currently supported */ /* Handshake layer: start (e.g. send CH). */ - if (!ossl_quic_tls_tick(ch->qtls)) + ossl_quic_tls_tick(ch->qtls); + + if (ossl_quic_tls_get_error(ch->qtls, &error_code, &error_msg, + &error_state)) { + ossl_quic_channel_raise_protocol_error_state(ch, error_code, 0, + error_msg, error_state); return 0; + } ossl_quic_reactor_tick(&ch->rtor, 0); /* best effort */ return 1; diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index b632ad22db..beec26c019 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -1524,6 +1524,7 @@ static int ensure_channel_started(QCTX *ctx) } if (!ossl_quic_channel_start(qc->ch)) { + ossl_quic_channel_restore_err_state(qc->ch); QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, "failed to start channel"); return 0; -- Gitee From 182a873ac5e9e11408fd36e19842c5be5c2ef40c Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 11 Sep 2023 13:57:35 +0100 Subject: [PATCH 14/79] Test that a client that does not supply ALPN fails as expected Reviewed-by: Hugo Landau Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22066) Signed-off-by: fly2x --- test/quicapitest.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/test/quicapitest.c b/test/quicapitest.c index 8c78e14de9..c471495aa2 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -1190,6 +1190,66 @@ static int test_quic_psk(void) return testresult; } +/* + * Test that we correctly handle ALPN supplied by the application + * Test 0: ALPN is provided + * Test 1: No ALPN is provided + */ +static int test_alpn(int idx) +{ + SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); + SSL *clientquic = NULL; + QUIC_TSERVER *qtserv = NULL; + int testresult = 0; + int ret; + + /* + * Ensure we only configure ciphersuites that are available with both the + * default and fips providers to get the same output in both cases + */ + if (!TEST_true(SSL_CTX_set_ciphersuites(cctx, "TLS_AES_128_GCM_SHA256"))) + goto err; + + if (!TEST_ptr(cctx) + || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, + privkey, + QTEST_FLAG_FAKE_TIME, + &qtserv, + &clientquic, NULL))) + goto err; + + if (idx == 0) { + /* + * Clear the ALPN we set in qtest_create_quic_objects. We use TEST_false + * because SSL_set_alpn_protos returns 0 for success. + */ + if (!TEST_false(SSL_set_alpn_protos(clientquic, NULL, 0))) + goto err; + } + + ret = SSL_connect(clientquic); + if (!TEST_int_le(ret, 0)) + goto err; + if (idx == 0) { + /* We expect an immediate error due to lack of ALPN */ + if (!TEST_int_eq(SSL_get_error(clientquic, ret), SSL_ERROR_SSL)) + goto err; + } else { + /* ALPN was provided so we expect the connection to succeed */ + if (!TEST_int_eq(SSL_get_error(clientquic, ret), SSL_ERROR_WANT_READ) + || !TEST_true(qtest_create_quic_connection(qtserv, clientquic))) + goto err; + } + + testresult = 1; + err: + ossl_quic_tserver_free(qtserv); + SSL_free(clientquic); + SSL_CTX_free(cctx); + + return testresult; +} + OPT_TEST_DECLARE_USAGE("provider config certsdir datadir\n") int setup_tests(void) @@ -1262,6 +1322,7 @@ int setup_tests(void) ADD_TEST(test_multiple_dgrams); ADD_ALL_TESTS(test_non_io_retry, 2); ADD_TEST(test_quic_psk); + ADD_ALL_TESTS(test_alpn, 2); return 1; err: cleanup_tests(); -- Gitee From 0040b43a20f287e98c47efe085c2445cd93949b6 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 11 Sep 2023 10:03:22 +0100 Subject: [PATCH 15/79] Fix a failure in bio_dgram_test on the NonStop platform The size of the datagram header is significantly larger that we might expect on NonStop (probably driven by sizeof(BIO_ADDR)). We adjust the size of the default buffer to take into account the header size and the mtu. Fixes #22013 Reviewed-by: Tom Cosgrove Reviewed-by: Tomas Mraz Reviewed-by: Hugo Landau Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22058) Signed-off-by: fly2x --- crypto/bio/bss_dgram_pair.c | 3 ++- test/bio_dgram_test.c | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/crypto/bio/bss_dgram_pair.c b/crypto/bio/bss_dgram_pair.c index 534a2216aa..08dd802d8f 100644 --- a/crypto/bio/bss_dgram_pair.c +++ b/crypto/bio/bss_dgram_pair.c @@ -279,8 +279,9 @@ static int dgram_pair_init(BIO *bio) if (b == NULL) return 0; - b->req_buf_len = 17*1024; /* default buffer size */ b->mtu = 1472; /* conservative default MTU */ + /* default buffer size */ + b->req_buf_len = 9 * (sizeof(struct dgram_hdr) + b->mtu); b->lock = CRYPTO_THREAD_lock_new(); if (b->lock == NULL) { diff --git a/test/bio_dgram_test.c b/test/bio_dgram_test.c index f6c3e30c14..70157493f9 100644 --- a/test/bio_dgram_test.c +++ b/test/bio_dgram_test.c @@ -559,8 +559,11 @@ static int test_bio_dgram_pair(int idx) goto err; /* - * Should be able to fit at least 9 datagrams in default write buffer size - * in worst case + * The number of datagrams we can fit depends on the size of the default + * write buffer size, the size of the datagram header and the size of the + * payload data we send in each datagram. The max payload data is based on + * the mtu. The default write buffer size is 9 * (sizeof(header) + mtu) so + * we expect at least 9 maximally sized datagrams to fit in the buffer. */ if (!TEST_int_ge(i, 9)) goto err; -- Gitee From c83699ce8871b7903c6ee4573e7eb8430b3c8484 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 12 Sep 2023 10:39:51 +0100 Subject: [PATCH 16/79] Further fix in bio_dgram_test for BIO_s_dgram_mem() When setting an explicit buffer size using BIO_s_dgram_mem() make sure we take into account the size of the header (which may be large on NonStop) Reviewed-by: Tom Cosgrove Reviewed-by: Tomas Mraz Reviewed-by: Hugo Landau Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22058) Signed-off-by: fly2x --- test/bio_dgram_test.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/test/bio_dgram_test.c b/test/bio_dgram_test.c index 70157493f9..aca016ca95 100644 --- a/test/bio_dgram_test.c +++ b/test/bio_dgram_test.c @@ -12,6 +12,7 @@ #include #include "testutil.h" #include "internal/sockets.h" +#include "internal/bio_addr.h" #if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK) @@ -519,14 +520,24 @@ static int test_bio_dgram_pair(int idx) } else { if (!TEST_ptr(bio1 = bio2 = BIO_new(BIO_s_dgram_mem()))) goto err; - if (idx == 1 && !TEST_true(BIO_set_write_buf_size(bio1, 20 * 1024))) - goto err; } mtu1 = BIO_dgram_get_mtu(bio1); if (!TEST_int_ge(mtu1, 1280)) goto err; + if (idx == 1) { + size_t bufsz; + + /* + * Assume the header contains 2 BIO_ADDR structures and a length. We + * set a buffer big enough for 9 full sized datagrams. + */ + bufsz = 9 * (mtu1 + (sizeof(BIO_ADDR) * 2) + sizeof(size_t)); + if (!TEST_true(BIO_set_write_buf_size(bio1, bufsz))) + goto err; + } + mtu2 = BIO_dgram_get_mtu(bio2); if (!TEST_int_ge(mtu2, 1280)) goto err; -- Gitee From db5b1d2b593ec326bbc8ede553d700575430029b Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 11 Sep 2023 17:23:46 +0200 Subject: [PATCH 17/79] d2i_ECPKParameters and i2d_ECPKParameters are not deprecated So do not document them as such. Fixes #22068 Reviewed-by: Paul Dale Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22069) Signed-off-by: fly2x --- doc/man3/d2i_RSAPrivateKey.pod | 2 -- doc/man3/d2i_X509.pod | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/man3/d2i_RSAPrivateKey.pod b/doc/man3/d2i_RSAPrivateKey.pod index b3ea95c692..08cd2c85e5 100644 --- a/doc/man3/d2i_RSAPrivateKey.pod +++ b/doc/man3/d2i_RSAPrivateKey.pod @@ -28,7 +28,6 @@ d2i_RSA_PUBKEY_fp, d2i_DHparams, d2i_DHparams_bio, d2i_DHparams_fp, -d2i_ECPKParameters, d2i_ECParameters, d2i_ECPrivateKey, d2i_ECPrivateKey_bio, @@ -56,7 +55,6 @@ i2d_DSA_PUBKEY, i2d_DSA_PUBKEY_bio, i2d_DSA_PUBKEY_fp, i2d_DSAparams, -i2d_ECPKParameters, i2d_ECParameters, i2d_ECPrivateKey, i2d_ECPrivateKey_bio, diff --git a/doc/man3/d2i_X509.pod b/doc/man3/d2i_X509.pod index c79a964e6d..9226ef77c3 100644 --- a/doc/man3/d2i_X509.pod +++ b/doc/man3/d2i_X509.pod @@ -53,6 +53,7 @@ d2i_DIST_POINT, d2i_DIST_POINT_NAME, d2i_DSA_SIG, d2i_ECDSA_SIG, +d2i_ECPKParameters, d2i_EDIPARTYNAME, d2i_ESS_CERT_ID, d2i_ESS_CERT_ID_V2, @@ -223,6 +224,7 @@ i2d_DIST_POINT, i2d_DIST_POINT_NAME, i2d_DSA_SIG, i2d_ECDSA_SIG, +i2d_ECPKParameters, i2d_EDIPARTYNAME, i2d_ESS_CERT_ID, i2d_ESS_CERT_ID_V2, -- Gitee From 4b5995795fbe0634f7eb2cc01b6eb1348f1f0896 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 11 Sep 2023 12:26:46 +0200 Subject: [PATCH 18/79] Fix memory leaks in ssl_old_test.c This fixes a few memory leaks reported in #22049. If SSL_CTX_set0_tmp_dh_pkey rejects the temp dh key due to security restrictions (even when @SECLEVEL=0 is used!) then the caller has to delete the PKEY object. That is different to how the deprecated SSL_CTX_set_tmp_dh_pkey was designed to work. Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22060) Signed-off-by: fly2x --- test/ssl_old_test.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/ssl_old_test.c b/test/ssl_old_test.c index 21834b1a36..fe168472d3 100644 --- a/test/ssl_old_test.c +++ b/test/ssl_old_test.c @@ -1535,8 +1535,10 @@ int main(int argc, char *argv[]) ERR_print_errors(bio_err); goto end; } - SSL_CTX_set0_tmp_dh_pkey(s_ctx, dhpkey); - SSL_CTX_set0_tmp_dh_pkey(s_ctx2, dhpkey); + if (!SSL_CTX_set0_tmp_dh_pkey(s_ctx, dhpkey)) + EVP_PKEY_free(dhpkey); + if (!SSL_CTX_set0_tmp_dh_pkey(s_ctx2, dhpkey)) + EVP_PKEY_free(dhpkey); } #endif -- Gitee From a1f50d48bf70c5267fc802c104b89bcba9de8f62 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 12 Sep 2023 15:07:29 +0200 Subject: [PATCH 19/79] Fix test/quic_tserver_test.c for slow machines OSSL_sleep(1) isn't enough of a wait for threads to process the next QUIC tick, so it gets increased to OSSL_sleep(100). This may be a tad much, perhaps, but for now, it gives a good margin. Reviewed-by: Hugo Landau Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22075) Signed-off-by: fly2x --- test/quic_tserver_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/quic_tserver_test.c b/test/quic_tserver_test.c index 3d1249863b..980c9a83ff 100644 --- a/test/quic_tserver_test.c +++ b/test/quic_tserver_test.c @@ -312,7 +312,7 @@ static int do_test(int use_thread_assist, int use_fake_time, int use_inject) ++idle_units_done; ossl_quic_conn_force_assist_thread_wake(c_ssl); - OSSL_sleep(1); /* Ensure CPU scheduling for test purposes */ + OSSL_sleep(100); /* Ensure CPU scheduling for test purposes */ } else { c_done_idle_test = 1; } -- Gitee From 56001c9738cbd6c751688a1bcde68f93167a7974 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Fri, 8 Sep 2023 13:08:10 +0100 Subject: [PATCH 20/79] QUIC MULTISTREAM TEST: Correct trivial bug Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22039) Signed-off-by: fly2x --- test/quic_multistream_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/quic_multistream_test.c b/test/quic_multistream_test.c index bc0ae12cdb..b401e78e32 100644 --- a/test/quic_multistream_test.c +++ b/test/quic_multistream_test.c @@ -4329,7 +4329,7 @@ static int script_61_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /* stream ID */ h->inject_word1)) || !TEST_true(WPACKET_quic_write_vlint(&wpkt, 123)) - || (h->inject_word1 == OSSL_QUIC_FRAME_TYPE_RESET_STREAM + || (h->inject_word0 == OSSL_QUIC_FRAME_TYPE_RESET_STREAM && !TEST_true(WPACKET_quic_write_vlint(&wpkt, 0)))) /* final size */ goto err; -- Gitee From 9f4d79cd64bc5ee66fac4d607694d17f69dbc8ba Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Fri, 8 Sep 2023 12:50:59 +0100 Subject: [PATCH 21/79] QUIC CHANNEL: Add missing duplicate TPARAM handling cases Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22039) Signed-off-by: fly2x --- ssl/quic/quic_channel.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index 7504f06dfc..3da0caa4ea 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -1270,6 +1270,8 @@ static int ch_on_transport_params(const unsigned char *params, int got_initial_max_stream_data_uni = 0; int got_initial_max_streams_bidi = 0; int got_initial_max_streams_uni = 0; + int got_stateless_reset_token = 0; + int got_preferred_addr = 0; int got_ack_delay_exp = 0; int got_max_ack_delay = 0; int got_max_udp_payload_size = 0; @@ -1574,6 +1576,11 @@ static int ch_on_transport_params(const unsigned char *params, break; case QUIC_TPARAM_STATELESS_RESET_TOKEN: + if (got_stateless_reset_token) { + reason = TP_REASON_DUP("STATELESS_RESET_TOKEN"); + goto malformed; + } + /* * We must ensure a client doesn't send them because we don't have * processing for them. @@ -1595,12 +1602,17 @@ static int ch_on_transport_params(const unsigned char *params, goto malformed; } + got_stateless_reset_token = 1; break; case QUIC_TPARAM_PREFERRED_ADDR: { /* TODO(QUIC FUTURE): Handle preferred address. */ QUIC_PREFERRED_ADDR pfa; + if (got_preferred_addr) { + reason = TP_REASON_DUP("PREFERRED_ADDR"); + goto malformed; + } /* * RFC 9000 s. 18.2: "A server that chooses a zero-length @@ -1629,6 +1641,8 @@ static int ch_on_transport_params(const unsigned char *params, reason = "zero-length CID in PREFERRED_ADDR"; goto malformed; } + + got_preferred_addr = 1; } break; -- Gitee From 789ccf07177cc8e1dc14ef82b1d56bed4c873c72 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 12 Sep 2023 14:58:03 +0200 Subject: [PATCH 22/79] Have legacy blake2 EVP structure use base blake2 implementation For some reason, the code here was made to got through the provider specific init functions. This is very very dangerous if the provider specific functions were to change in any way (such as changes to the implementation context structure). Instead, use the init functions from the base blake2 implementations directly. Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22079) Signed-off-by: fly2x --- crypto/evp/legacy_blake2.c | 28 ++++++++++++++++--- .../implementations/digests/blake2_prov.c | 4 +-- .../implementations/include/prov/blake2.h | 3 -- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/crypto/evp/legacy_blake2.c b/crypto/evp/legacy_blake2.c index 6a18e5fe01..4301ae4857 100644 --- a/crypto/evp/legacy_blake2.c +++ b/crypto/evp/legacy_blake2.c @@ -11,11 +11,31 @@ #include "prov/blake2.h" /* diverse BLAKE2 macros */ #include "legacy_meth.h" -#define ossl_blake2b_init ossl_blake2b512_init -#define ossl_blake2s_init ossl_blake2s256_init +/* + * Local hack to adapt the BLAKE2 init functions to what the + * legacy function signatures demand. + */ +static int blake2s_init(BLAKE2S_CTX *C) +{ + BLAKE2S_PARAM P; + + ossl_blake2s_param_init(&P); + return ossl_blake2s_init(C, &P); +} +static int blake2b_init(BLAKE2B_CTX *C) +{ + BLAKE2B_PARAM P; + + ossl_blake2b_param_init(&P); + return ossl_blake2b_init(C, &P); +} +#define blake2s_update ossl_blake2s_update +#define blake2b_update ossl_blake2b_update +#define blake2s_final ossl_blake2s_final +#define blake2b_final ossl_blake2b_final -IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2s_int, ossl_blake2s) -IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2b_int, ossl_blake2b) +IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2s_int, blake2s) +IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2b_int, blake2b) static const EVP_MD blake2b_md = { NID_blake2b512, diff --git a/providers/implementations/digests/blake2_prov.c b/providers/implementations/digests/blake2_prov.c index 2288286bbe..298bc66de6 100644 --- a/providers/implementations/digests/blake2_prov.c +++ b/providers/implementations/digests/blake2_prov.c @@ -12,7 +12,7 @@ #include "prov/digestcommon.h" #include "prov/implementations.h" -int ossl_blake2s256_init(void *ctx) +static int ossl_blake2s256_init(void *ctx) { BLAKE2S_PARAM P; @@ -20,7 +20,7 @@ int ossl_blake2s256_init(void *ctx) return ossl_blake2s_init((BLAKE2S_CTX *)ctx, &P); } -int ossl_blake2b512_init(void *ctx) +static int ossl_blake2b512_init(void *ctx) { struct blake2b_md_data_st *mdctx = ctx; diff --git a/providers/implementations/include/prov/blake2.h b/providers/implementations/include/prov/blake2.h index 4ec780c21f..bcd0bb9bcd 100644 --- a/providers/implementations/include/prov/blake2.h +++ b/providers/implementations/include/prov/blake2.h @@ -88,9 +88,6 @@ struct blake2b_md_data_st { BLAKE2B_PARAM params; }; -int ossl_blake2s256_init(void *ctx); -int ossl_blake2b512_init(void *ctx); - int ossl_blake2b_init(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P); int ossl_blake2b_init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P, const void *key); -- Gitee From 4fc563b3b18c6ee8e0bb5bbf747da90b30cf89ec Mon Sep 17 00:00:00 2001 From: Pauli Date: Wed, 13 Sep 2023 12:06:20 +1000 Subject: [PATCH 23/79] Use correct version of 3.1 build for FIPS provider. We're (currently) intending to validate 3.1.2 against FIPS 140-3. Reviewed-by: Tomas Mraz Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/22088) Signed-off-by: fly2x --- .github/workflows/provider-compatibility.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/provider-compatibility.yml b/.github/workflows/provider-compatibility.yml index b675e426c1..f118db1aee 100644 --- a/.github/workflows/provider-compatibility.yml +++ b/.github/workflows/provider-compatibility.yml @@ -179,7 +179,7 @@ jobs: # later providers. Problems in these situations ought to be # caught by cross branch testing before the release. tree_a: [ branch-master, branch-3.1, branch-3.0, - openssl-3.0.0, openssl-3.0.8, openssl-3.0.9, openssl-3.1.1 ] + openssl-3.0.0, openssl-3.0.8, openssl-3.0.9, openssl-3.1.2 ] tree_b: [ branch-master, branch-3.1, branch-3.0 ] steps: - name: early exit checks -- Gitee From f076179728001aaeddffb576d6264cda12391701 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 13 Sep 2023 08:29:17 +0200 Subject: [PATCH 24/79] Fix build of SHA3 on ARM64 with no-asm Fixes #22089 Reviewed-by: Matt Caswell Reviewed-by: Tom Cosgrove Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22090) Signed-off-by: fly2x --- providers/implementations/digests/sha3_prov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/implementations/digests/sha3_prov.c b/providers/implementations/digests/sha3_prov.c index 0c643f8238..423bed7983 100644 --- a/providers/implementations/digests/sha3_prov.c +++ b/providers/implementations/digests/sha3_prov.c @@ -249,7 +249,7 @@ static PROV_SHA3_METHOD kmac_s390x_md = } else { \ ctx->meth = sha3_generic_md; \ } -#elif defined(__aarch64__) +#elif defined(__aarch64__) && defined(KECCAK1600_ASM) # include "arm_arch.h" static sha3_absorb_fn armsha3_sha3_absorb; -- Gitee From 60d0f2a894a0cb8ec7f6840a0197570c2114a2dd Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 13 Sep 2023 10:31:46 +0100 Subject: [PATCH 25/79] Remove use of _Static_assert We had some use of the C11 _Static_assert feature which can cause some problems on some platforms. Everywhere we were using it, it is not really required so remove it. Fixes #22017 Reviewed-by: Tomas Mraz Reviewed-by: Richard Levitte Reviewed-by: Tom Cosgrove Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22091) Signed-off-by: fly2x --- include/internal/e_os.h | 9 --------- providers/implementations/kdfs/argon2.c | 11 +++-------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/include/internal/e_os.h b/include/internal/e_os.h index d0e903f653..d1ed62e890 100644 --- a/include/internal/e_os.h +++ b/include/internal/e_os.h @@ -22,15 +22,6 @@ * outside; this file e_os.h is not part of the exported interface. */ -/* ossl_static_assert_type_eq: gcc-only variable type static assertion */ -# if defined(__GNUC__) && !defined(__clang__) -# define ossl_static_assert_type_eq(type, x) \ - _Static_assert((__builtin_types_compatible_p(type, __typeof__(x))), \ - #x " type check failed, expected: " #type) -# else -# define ossl_static_assert_type_eq(type, x) -# endif - # if defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI) # define NO_CHMOD # define NO_SYSLOG diff --git a/providers/implementations/kdfs/argon2.c b/providers/implementations/kdfs/argon2.c index 323b0f3ab6..d93381c410 100644 --- a/providers/implementations/kdfs/argon2.c +++ b/providers/implementations/kdfs/argon2.c @@ -1185,8 +1185,7 @@ static int kdf_argon2_ctx_set_lanes(KDF_ARGON2 *ctx, uint32_t lanes) static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2 *ctx, uint32_t t_cost) { - /* ARGON2_MAX_MEMORY == max m_cost value, skip check, enforce type */ - ossl_static_assert_type_eq(uint32_t, t_cost); + /* ARGON2_MAX_MEMORY == max m_cost value, so skip check */ if (t_cost < ARGON2_MIN_TIME) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT, @@ -1200,8 +1199,7 @@ static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2 *ctx, uint32_t t_cost) static int kdf_argon2_ctx_set_m_cost(KDF_ARGON2 *ctx, uint32_t m_cost) { - /* ARGON2_MAX_MEMORY == max m_cost value, skip check, enforce type */ - ossl_static_assert_type_eq(uint32_t, m_cost); + /* ARGON2_MAX_MEMORY == max m_cost value, so skip check */ if (m_cost < ARGON2_MIN_MEMORY) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE, "min: %u", @@ -1218,11 +1216,8 @@ static int kdf_argon2_ctx_set_out_length(KDF_ARGON2 *ctx, uint32_t outlen) /* * ARGON2_MAX_OUT_LENGTH == max outlen value, so upper bounds checks * are always satisfied; to suppress compiler if statement tautology - * warnings, these checks are skipped; however, to ensure that these - * limits are met and implementation conforming to Argon2 RFC, we need - * to fix the type + * warnings, these checks are skipped. */ - ossl_static_assert_type_eq(uint32_t, outlen); if (outlen < ARGON2_MIN_OUT_LENGTH) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH, "min: %u", -- Gitee From 99cfdee4a4b2426d93d0f87053a788a8c916b4f4 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Tue, 5 Sep 2023 16:59:45 +0200 Subject: [PATCH 26/79] Fix engine cleanup error handling Error handling in engine_cleanup_add_first/last was broken and caused memory leaks. Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/21971) Signed-off-by: fly2x --- crypto/engine/eng_lib.c | 24 +++++++++++++++--------- crypto/engine/eng_list.c | 10 +++++++--- crypto/engine/eng_local.h | 4 ++-- crypto/engine/eng_table.c | 8 +++++--- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c index 8345f684c8..412363fa37 100644 --- a/crypto/engine/eng_lib.c +++ b/crypto/engine/eng_lib.c @@ -135,28 +135,34 @@ static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb) return item; } -void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb) +int engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb) { ENGINE_CLEANUP_ITEM *item; if (!int_cleanup_check(1)) - return; + return 0; item = int_cleanup_item(cb); - if (item != NULL) - if (sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0) <= 0) - OPENSSL_free(item); + if (item != NULL) { + if (sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0)) + return 1; + OPENSSL_free(item); + } + return 0; } -void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb) +int engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb) { ENGINE_CLEANUP_ITEM *item; + if (!int_cleanup_check(1)) - return; + return 0; item = int_cleanup_item(cb); if (item != NULL) { - if (sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item) <= 0) - OPENSSL_free(item); + if (sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item) > 0) + return 1; + OPENSSL_free(item); } + return 0; } /* The API function that performs all cleanup */ diff --git a/crypto/engine/eng_list.c b/crypto/engine/eng_list.c index 119e1c6045..a2c151d64a 100644 --- a/crypto/engine/eng_list.c +++ b/crypto/engine/eng_list.c @@ -89,12 +89,16 @@ static int engine_list_add(ENGINE *e) ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); return 0; } - engine_list_head = e; - e->prev = NULL; /* * The first time the list allocates, we should register the cleanup. */ - engine_cleanup_add_last(engine_list_cleanup); + if (!engine_cleanup_add_last(engine_list_cleanup)) { + CRYPTO_DOWN_REF(&e->struct_ref, &ref); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + engine_list_head = e; + e->prev = NULL; } else { /* We are adding to the tail of an existing list. */ if ((engine_list_tail == NULL) || (engine_list_tail->next != NULL)) { diff --git a/crypto/engine/eng_local.h b/crypto/engine/eng_local.h index 6f5d380d02..24920973e7 100644 --- a/crypto/engine/eng_local.h +++ b/crypto/engine/eng_local.h @@ -46,8 +46,8 @@ typedef struct st_engine_cleanup_item { ENGINE_CLEANUP_CB *cb; } ENGINE_CLEANUP_ITEM; DEFINE_STACK_OF(ENGINE_CLEANUP_ITEM) -void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb); -void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb); +int engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb); +int engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb); /* We need stacks of ENGINEs for use in eng_table.c */ DEFINE_STACK_OF(ENGINE) diff --git a/crypto/engine/eng_table.c b/crypto/engine/eng_table.c index 17225d0ad4..3138a15260 100644 --- a/crypto/engine/eng_table.c +++ b/crypto/engine/eng_table.c @@ -93,9 +93,11 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, added = 1; if (!int_table_check(table, 1)) goto end; - if (added) - /* The cleanup callback needs to be added */ - engine_cleanup_add_first(cleanup); + /* The cleanup callback needs to be added */ + if (added && !engine_cleanup_add_first(cleanup)) { + lh_ENGINE_PILE_free(&(*table)->piles); + *table = NULL; + } while (num_nids--) { tmplate.nid = *nids; fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); -- Gitee From 7f847085bf54c4caa60db39fec410e7e03622feb Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Mon, 28 Aug 2023 13:37:33 +0200 Subject: [PATCH 27/79] Store: API for deletion Reviewed-by: Richard Levitte Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21901) Signed-off-by: fly2x --- crypto/store/store_lib.c | 47 +++++++++++++++++++++++++++++++++ crypto/store/store_local.h | 1 + crypto/store/store_meth.c | 6 ++++- include/openssl/core_dispatch.h | 4 +++ include/openssl/store.h | 8 ++++++ 5 files changed, 65 insertions(+), 1 deletion(-) diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index df3180c048..a68e8e28b6 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -480,6 +480,53 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) return v; } +int OSSL_STORE_delete(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, + const UI_METHOD *ui_method, void *ui_data, + const OSSL_PARAM params[]) +{ + OSSL_STORE_LOADER *fetched_loader = NULL; + char scheme[256], *p; + int res = 0; + struct ossl_passphrase_data_st pwdata = {0}; + + OPENSSL_strlcpy(scheme, uri, sizeof(scheme)); + if ((p = strchr(scheme, ':')) != NULL) + *p++ = '\0'; + else /* We don't work without explicit scheme */ + return 0; + + if (ui_method != NULL + && (!ossl_pw_set_ui_method(&pwdata, ui_method, ui_data) + || !ossl_pw_enable_passphrase_caching(&pwdata))) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); + return 0; + } + + OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); + fetched_loader = OSSL_STORE_LOADER_fetch(libctx, scheme, propq); + + if (fetched_loader != NULL && fetched_loader->p_delete != NULL) { + const OSSL_PROVIDER *provider = + OSSL_STORE_LOADER_get0_provider(fetched_loader); + void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); + + /* + * It's assumed that the loader's delete() method reports its own + * errors + */ + OSSL_TRACE1(STORE, "Performing URI delete %s\n", uri); + res = fetched_loader->p_delete(provctx, uri, params, + ossl_pw_passphrase_callback_dec, + &pwdata); + } + /* Clear any internally cached passphrase */ + (void)ossl_pw_clear_passphrase_cache(&pwdata); + + OSSL_STORE_LOADER_free(fetched_loader); + + return res; +} + int OSSL_STORE_error(OSSL_STORE_CTX *ctx) { int ret = 1; diff --git a/crypto/store/store_local.h b/crypto/store/store_local.h index 223758ab2b..06c8c9b218 100644 --- a/crypto/store/store_local.h +++ b/crypto/store/store_local.h @@ -112,6 +112,7 @@ struct ossl_store_loader_st { OSSL_FUNC_store_eof_fn *p_eof; OSSL_FUNC_store_close_fn *p_close; OSSL_FUNC_store_export_object_fn *p_export_object; + OSSL_FUNC_store_delete_fn *p_delete; }; DEFINE_LHASH_OF_EX(OSSL_STORE_LOADER); diff --git a/crypto/store/store_meth.c b/crypto/store/store_meth.c index 7fc79e2989..766777c3a0 100644 --- a/crypto/store/store_meth.c +++ b/crypto/store/store_meth.c @@ -219,6 +219,10 @@ static void *loader_from_algorithm(int scheme_id, const OSSL_ALGORITHM *algodef, if (loader->p_export_object == NULL) loader->p_export_object = OSSL_FUNC_store_export_object(fns); break; + case OSSL_FUNC_STORE_DELETE: + if (loader->p_delete == NULL) + loader->p_delete = OSSL_FUNC_store_delete(fns); + break; } } @@ -226,7 +230,7 @@ static void *loader_from_algorithm(int scheme_id, const OSSL_ALGORITHM *algodef, || loader->p_load == NULL || loader->p_eof == NULL || loader->p_close == NULL) { - /* Only set_ctx_params is optionaal */ + /* Only set_ctx_params is optional */ OSSL_STORE_LOADER_free(loader); ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADER_INCOMPLETE); return NULL; diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index 7c48bd7f86..9631626ae3 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -936,6 +936,7 @@ OSSL_CORE_MAKE_FUNC(int, decoder_export_object, #define OSSL_FUNC_STORE_EOF 6 #define OSSL_FUNC_STORE_CLOSE 7 #define OSSL_FUNC_STORE_EXPORT_OBJECT 8 +#define OSSL_FUNC_STORE_DELETE 9 OSSL_CORE_MAKE_FUNC(void *, store_open, (void *provctx, const char *uri)) OSSL_CORE_MAKE_FUNC(void *, store_attach, (void *provctx, OSSL_CORE_BIO *in)) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, store_settable_ctx_params, @@ -951,6 +952,9 @@ OSSL_CORE_MAKE_FUNC(int, store_close, (void *loaderctx)) OSSL_CORE_MAKE_FUNC(int, store_export_object, (void *loaderctx, const void *objref, size_t objref_sz, OSSL_CALLBACK *export_cb, void *export_cbarg)) +OSSL_CORE_MAKE_FUNC(int, store_delete, + (void *provctx, const char *uri, const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)) # ifdef __cplusplus } diff --git a/include/openssl/store.h b/include/openssl/store.h index dafb16fd90..46fb4d40f0 100644 --- a/include/openssl/store.h +++ b/include/openssl/store.h @@ -98,6 +98,14 @@ OSSL_DEPRECATEDIN_3_0 int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, */ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx); +/* + * Deletes the object in the store by URI. + * Returns 1 on success, 0 otherwise. + */ +int OSSL_STORE_delete(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, + const UI_METHOD *ui_method, void *ui_data, + const OSSL_PARAM params[]); + /* * Check if end of data (end of file) is reached * Returns 1 on end, 0 otherwise. -- Gitee From c5e469b2744d58f1a3455048c1f301c6ac5d538a Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Mon, 28 Aug 2023 13:38:19 +0200 Subject: [PATCH 28/79] Store: API for deletion - make update Reviewed-by: Richard Levitte Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21901) Signed-off-by: fly2x --- util/libcrypto.num | 1 + 1 file changed, 1 insertion(+) diff --git a/util/libcrypto.num b/util/libcrypto.num index 2656df5d90..e4265b4cef 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5534,3 +5534,4 @@ OSSL_PROVIDER_try_load_ex ? 3_2_0 EXIST::FUNCTION: OSSL_ERR_STATE_save_to_mark ? 3_2_0 EXIST::FUNCTION: X509_STORE_CTX_set_get_crl ? 3_2_0 EXIST::FUNCTION: X509_STORE_CTX_set_current_reasons ? 3_2_0 EXIST::FUNCTION: +OSSL_STORE_delete ? 3_2_0 EXIST::FUNCTION: -- Gitee From 63d6470ce6aef6d31acd9e296661b1b3233872da Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Mon, 28 Aug 2023 13:38:33 +0200 Subject: [PATCH 29/79] Store: API for deletion - tests Reviewed-by: Richard Levitte Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21901) Signed-off-by: fly2x --- test/fake_rsaprov.c | 23 ++++++++++++- test/fake_rsaprov.h | 1 + test/provider_pkey_test.c | 72 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/test/fake_rsaprov.c b/test/fake_rsaprov.c index a4f81be023..9bc463b2c8 100644 --- a/test/fake_rsaprov.c +++ b/test/fake_rsaprov.c @@ -30,12 +30,18 @@ static int has_selection; static int imptypes_selection; static int exptypes_selection; static int query_id; +static int key_deleted; struct fake_rsa_keydata { int selection; int status; }; +void fake_rsa_restore_store_state(void) +{ + key_deleted = 0; +} + static void *fake_rsa_keymgmt_new(void *provctx) { struct fake_rsa_keydata *key; @@ -524,6 +530,7 @@ static OSSL_FUNC_store_set_ctx_params_fn fake_rsa_st_set_ctx_params; static OSSL_FUNC_store_load_fn fake_rsa_st_load; static OSSL_FUNC_store_eof_fn fake_rsa_st_eof; static OSSL_FUNC_store_close_fn fake_rsa_st_close; +static OSSL_FUNC_store_delete_fn fake_rsa_st_delete; static const char fake_rsa_scheme[] = "fake_rsa:"; @@ -570,6 +577,11 @@ static int fake_rsa_st_load(void *loaderctx, switch (*storectx) { case 0: + if (key_deleted == 1) { + *storectx = 1; + break; + } + /* Construct a new key using our keymgmt functions */ if (!TEST_ptr(key = fake_rsa_keymgmt_new(NULL))) break; @@ -600,13 +612,21 @@ static int fake_rsa_st_load(void *loaderctx, TEST_info("fake_rsa_load called - rv: %d", rv); - if (rv == 0) { + if (rv == 0 && key_deleted == 0) { fake_rsa_keymgmt_free(key); *storectx = 2; } return rv; } +static int fake_rsa_st_delete(void *loaderctx, const char *uri, + const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + key_deleted = 1; + return 1; +} + static int fake_rsa_st_eof(void *loaderctx) { unsigned char *storectx = loaderctx; @@ -629,6 +649,7 @@ static const OSSL_DISPATCH fake_rsa_store_funcs[] = { { OSSL_FUNC_STORE_LOAD, (void (*)(void))fake_rsa_st_load }, { OSSL_FUNC_STORE_EOF, (void (*)(void))fake_rsa_st_eof }, { OSSL_FUNC_STORE_CLOSE, (void (*)(void))fake_rsa_st_close }, + { OSSL_FUNC_STORE_DELETE, (void (*)(void))fake_rsa_st_delete }, OSSL_DISPATCH_END, }; diff --git a/test/fake_rsaprov.h b/test/fake_rsaprov.h index 190c46a285..53056fa59f 100644 --- a/test/fake_rsaprov.h +++ b/test/fake_rsaprov.h @@ -13,3 +13,4 @@ OSSL_PROVIDER *fake_rsa_start(OSSL_LIB_CTX *libctx); void fake_rsa_finish(OSSL_PROVIDER *p); OSSL_PARAM *fake_rsa_key_params(int priv); +void fake_rsa_restore_store_state(void); diff --git a/test/provider_pkey_test.c b/test/provider_pkey_test.c index 7e69f4bbd5..09b060642b 100644 --- a/test/provider_pkey_test.c +++ b/test/provider_pkey_test.c @@ -18,6 +18,7 @@ #include "fake_rsaprov.h" static OSSL_LIB_CTX *libctx = NULL; +extern int key_deleted; /* From fake_rsaprov.c */ /* Fetch SIGNATURE method using a libctx and propq */ static int fetch_sig(OSSL_LIB_CTX *ctx, const char *alg, const char *propq, @@ -288,6 +289,76 @@ end: return ret; } +static int test_pkey_delete(void) +{ + OSSL_PROVIDER *deflt = NULL; + OSSL_PROVIDER *fake_rsa = NULL; + int ret = 0; + EVP_PKEY *pkey = NULL; + OSSL_STORE_LOADER *loader = NULL; + OSSL_STORE_CTX *ctx = NULL; + OSSL_STORE_INFO *info; + const char *propq = "?provider=fake-rsa"; + + /* It's important to load the default provider first for this test */ + if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) + goto end; + + if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) + goto end; + + if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake_rsa", + propq))) + goto end; + + OSSL_STORE_LOADER_free(loader); + + /* First iteration: load key, check it, delete it */ + if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:test", libctx, propq, + NULL, NULL, NULL, NULL, NULL))) + goto end; + + while (!OSSL_STORE_eof(ctx) + && (info = OSSL_STORE_load(ctx)) != NULL + && pkey == NULL) { + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) + pkey = OSSL_STORE_INFO_get1_PKEY(info); + OSSL_STORE_INFO_free(info); + info = NULL; + } + + if (!TEST_ptr(pkey) || !TEST_int_eq(EVP_PKEY_is_a(pkey, "RSA"), 1)) + goto end; + EVP_PKEY_free(pkey); + pkey = NULL; + + if (!TEST_int_eq(OSSL_STORE_delete("fake_rsa:test", libctx, propq, + NULL, NULL, NULL), 1)) + goto end; + if (!TEST_int_eq(OSSL_STORE_close(ctx), 1)) + goto end; + + /* Second iteration: load key should fail */ + if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:test", libctx, propq, + NULL, NULL, NULL, NULL, NULL))) + goto end; + + while (!OSSL_STORE_eof(ctx)) { + info = OSSL_STORE_load(ctx); + if (!TEST_ptr_null(info)) + goto end; + } + + ret = 1; + +end: + fake_rsa_finish(fake_rsa); + OSSL_PROVIDER_unload(deflt); + OSSL_STORE_close(ctx); + fake_rsa_restore_store_state(); + return ret; +} + int setup_tests(void) { libctx = OSSL_LIB_CTX_new(); @@ -298,6 +369,7 @@ int setup_tests(void) ADD_TEST(test_alternative_keygen_init); ADD_TEST(test_pkey_eq); ADD_ALL_TESTS(test_pkey_store, 2); + ADD_TEST(test_pkey_delete); return 1; } -- Gitee From f00d6b32e53c4a9fa11b4f7e467f58cd895b7c09 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 31 Aug 2023 11:33:36 +0200 Subject: [PATCH 30/79] Store: API for deletion - documentation Reviewed-by: Richard Levitte Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21901) Signed-off-by: fly2x --- doc/man3/OSSL_STORE_open.pod | 14 ++++++++++---- doc/man7/provider-storemgmt.pod | 12 ++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/doc/man3/OSSL_STORE_open.pod b/doc/man3/OSSL_STORE_open.pod index fe51912e84..8e4a9a7926 100644 --- a/doc/man3/OSSL_STORE_open.pod +++ b/doc/man3/OSSL_STORE_open.pod @@ -4,7 +4,7 @@ OSSL_STORE_CTX, OSSL_STORE_post_process_info_fn, OSSL_STORE_open, OSSL_STORE_open_ex, -OSSL_STORE_ctrl, OSSL_STORE_load, OSSL_STORE_eof, +OSSL_STORE_ctrl, OSSL_STORE_load, OSSL_STORE_eof, OSSL_STORE_delete, OSSL_STORE_error, OSSL_STORE_close - Types and functions to read objects from a URI @@ -30,6 +30,9 @@ OSSL_STORE_error, OSSL_STORE_close OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx); int OSSL_STORE_eof(OSSL_STORE_CTX *ctx); + int OSSL_STORE_delete(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, + const UI_METHOD *ui_method, void *ui_data, + const OSSL_PARAM params[]); int OSSL_STORE_error(OSSL_STORE_CTX *ctx); int OSSL_STORE_close(OSSL_STORE_CTX *ctx); @@ -104,6 +107,8 @@ Any other value is an error. OSSL_STORE_load() takes a B and tries to load the next available object and return it wrapped with B. +OSSL_STORE_delete() deletes the object identified by I. + OSSL_STORE_eof() takes a B and checks if we've reached the end of data. @@ -152,7 +157,8 @@ or an error occurred, 0 otherwise. OSSL_STORE_error() returns 1 if an error occurred in an OSSL_STORE_load() call, otherwise 0. -OSSL_STORE_ctrl() and OSSL_STORE_close() returns 1 on success, or 0 on failure. +OSSL_STORE_delete(), OSSL_STORE_ctrl() and OSSL_STORE_close() return 1 on +success, or 0 on failure. =head1 SEE ALSO @@ -161,6 +167,8 @@ L =head1 HISTORY +OSSL_STORE_delete() was added in OpenSSL 3.2. + OSSL_STORE_open_ex() was added in OpenSSL 3.0. B, OSSL_STORE_post_process_info_fn(), OSSL_STORE_open(), @@ -170,8 +178,6 @@ were added in OpenSSL 1.1.1. Handling of NULL I argument for OSSL_STORE_close() was introduced in OpenSSL 1.1.1h. -OSSL_STORE_open_ex() was added in OpenSSL 3.0. - OSSL_STORE_ctrl() and OSSL_STORE_vctrl() were deprecated in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man7/provider-storemgmt.pod b/doc/man7/provider-storemgmt.pod index 615ff7ef8e..c58df619db 100644 --- a/doc/man7/provider-storemgmt.pod +++ b/doc/man7/provider-storemgmt.pod @@ -28,6 +28,10 @@ provider-storemgmt - The OSSL_STORE library E-E provider functions (void *loaderctx, const void *objref, size_t objref_sz, OSSL_CALLBACK *export_cb, void *export_cbarg); + int OSSL_FUNC_store_delete(void *provctx, const char *uri, + const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg); + =head1 DESCRIPTION The STORE operation is the provider side of the L API. @@ -70,6 +74,7 @@ in L, as follows: OSSL_FUNC_store_eof OSSL_FUNC_STORE_EOF OSSL_FUNC_store_close OSSL_FUNC_STORE_CLOSE OSSL_FUNC_store_export_object OSSL_FUNC_STORE_EXPORT_OBJECT + OSSL_FUNC_store_delete OSSL_FUNC_STORE_DELETE =head2 Functions @@ -114,6 +119,11 @@ OSSL_FUNC_store_export_object() should export the object of size I referenced by I as an L array and pass that to the I as well as the given I. +OSSL_FUNC_store_delete() deletes the object identified by the I. The +implementation is entirely responsible for the interpretation of the URI. In +case a passphrase needs to be prompted to remove an object, I should be +called. + =head2 Load Parameters =over 4 @@ -186,6 +196,8 @@ L The STORE interface was introduced in OpenSSL 3.0. +OSSL_FUNC_store_delete() callback was added in OpenSSL 3.2 + =head1 COPYRIGHT Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. -- Gitee From a1e133053e7d9f7723c758759a225e2b95ec2482 Mon Sep 17 00:00:00 2001 From: Olga Batyshkina Date: Mon, 7 Aug 2023 15:14:53 +0200 Subject: [PATCH 31/79] Fix PKCS#12 creation error when certificate contains auxiliary data Prefer friendly name passed by the caller and calculated local key id to ones found in certificate auxiliary data when creating PKCS#12. Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21675) Signed-off-by: fly2x --- crypto/pkcs12/p12_crt.c | 62 ++++++++++++++++++++++++------------ test/pkcs12_format_test.c | 66 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 20 deletions(-) diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c index 3246fbb7e8..7681731207 100644 --- a/crypto/pkcs12/p12_crt.c +++ b/crypto/pkcs12/p12_crt.c @@ -16,6 +16,12 @@ static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); static int pkcs12_remove_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); +static PKCS12_SAFEBAG *pkcs12_add_cert_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + X509 *cert, + const char *name, + int namelen, + unsigned char *keyid, + int keyidlen); static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) { @@ -39,6 +45,9 @@ PKCS12 *PKCS12_create_ex2(const char *pass, const char *name, EVP_PKEY *pkey, int i, cbret; unsigned char keyid[EVP_MAX_MD_SIZE]; unsigned int keyidlen = 0; + int namelen = -1; + unsigned char *pkeyid = NULL; + int pkeyidlen = -1; /* Set defaults */ if (nid_cert == NID_undef) @@ -63,11 +72,16 @@ PKCS12 *PKCS12_create_ex2(const char *pass, const char *name, EVP_PKEY *pkey, } if (cert) { - bag = PKCS12_add_cert(&bags, cert); - if (name && !PKCS12_add_friendlyname(bag, name, -1)) - goto err; - if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) - goto err; + if (name == NULL) + name = (char *)X509_alias_get0(cert, &namelen); + if (keyidlen > 0) { + pkeyid = keyid; + pkeyidlen = keyidlen; + } else { + pkeyid = X509_keyid_get0(cert, &pkeyidlen); + } + + bag = pkcs12_add_cert_bag(&bags, cert, name, namelen, pkeyid, pkeyidlen); if (cb != NULL) { cbret = cb(bag, cbarg); if (cbret == -1) { @@ -175,30 +189,23 @@ PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 * iter, mac_iter, keytype, NULL, NULL); } -PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert) +static PKCS12_SAFEBAG *pkcs12_add_cert_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + X509 *cert, + const char *name, + int namelen, + unsigned char *keyid, + int keyidlen) { PKCS12_SAFEBAG *bag = NULL; - char *name; - int namelen = -1; - unsigned char *keyid; - int keyidlen = -1; /* Add user certificate */ if ((bag = PKCS12_SAFEBAG_create_cert(cert)) == NULL) goto err; - /* - * Use friendlyName and localKeyID in certificate. (if present) - */ - - name = (char *)X509_alias_get0(cert, &namelen); - - if (name && !PKCS12_add_friendlyname(bag, name, namelen)) + if (name != NULL && !PKCS12_add_friendlyname(bag, name, namelen)) goto err; - keyid = X509_keyid_get0(cert, &keyidlen); - - if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) + if (keyid != NULL && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) goto err; if (!pkcs12_add_bag(pbags, bag)) @@ -209,7 +216,22 @@ PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert) err: PKCS12_SAFEBAG_free(bag); return NULL; +} + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert) +{ + char *name = NULL; + int namelen = -1; + unsigned char *keyid = NULL; + int keyidlen = -1; + + /* + * Use friendlyName and localKeyID in certificate. (if present) + */ + name = (char *)X509_alias_get0(cert, &namelen); + keyid = X509_keyid_get0(cert, &keyidlen); + return pkcs12_add_cert_bag(pbags, cert, name, namelen, keyid, keyidlen); } PKCS12_SAFEBAG *PKCS12_add_key_ex(STACK_OF(PKCS12_SAFEBAG) **pbags, diff --git a/test/pkcs12_format_test.c b/test/pkcs12_format_test.c index 507a9baf07..e2048bc27e 100644 --- a/test/pkcs12_format_test.c +++ b/test/pkcs12_format_test.c @@ -882,6 +882,70 @@ err: } #endif +static int pkcs12_recreate_test(void) +{ + int ret = 0; + X509 *cert = NULL; + X509 *cert_parsed = NULL; + EVP_PKEY *pkey = NULL; + EVP_PKEY *pkey_parsed = NULL; + PKCS12 *p12 = NULL; + PKCS12 *p12_parsed = NULL; + PKCS12 *p12_recreated = NULL; + const unsigned char *cert_bytes = CERT1; + const unsigned char *key_bytes = KEY1; + BIO *bio = NULL; + + cert = d2i_X509(NULL, &cert_bytes, sizeof(CERT1)); + if (!TEST_ptr(cert)) + goto err; + pkey = d2i_AutoPrivateKey(NULL, &key_bytes, sizeof(KEY1)); + if (!TEST_ptr(pkey)) + goto err; + p12 = PKCS12_create("pass", NULL, pkey, cert, NULL, NID_aes_256_cbc, + NID_aes_256_cbc, 2, 1, 0); + if (!TEST_ptr(p12)) + goto err; + if (!TEST_int_eq(ERR_peek_error(), 0)) + goto err; + + bio = BIO_new(BIO_s_mem()); + if (!TEST_ptr(bio)) + goto err; + if (!TEST_int_eq(i2d_PKCS12_bio(bio, p12), 1)) + goto err; + p12_parsed = PKCS12_init_ex(NID_pkcs7_data, testctx, NULL); + if (!TEST_ptr(p12_parsed)) + goto err; + p12_parsed = d2i_PKCS12_bio(bio, &p12_parsed); + if (!TEST_ptr(p12_parsed)) + goto err; + if (!TEST_int_eq(PKCS12_parse(p12_parsed, "pass", &pkey_parsed, + &cert_parsed, NULL), 1)) + goto err; + + /* cert_parsed also contains auxiliary data */ + p12_recreated = PKCS12_create("new_pass", NULL, pkey_parsed, cert_parsed, + NULL, NID_aes_256_cbc, NID_aes_256_cbc, + 2, 1, 0); + if (!TEST_ptr(p12_recreated)) + goto err; + if (!TEST_int_eq(ERR_peek_error(), 0)) + goto err; + + ret = 1; +err: + BIO_free(bio); + PKCS12_free(p12); + PKCS12_free(p12_parsed); + PKCS12_free(p12_recreated); + EVP_PKEY_free(pkey); + EVP_PKEY_free(pkey_parsed); + X509_free(cert); + X509_free(cert_parsed); + return ret; +} + typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, @@ -963,6 +1027,8 @@ int setup_tests(void) if (default_libctx) ADD_TEST(pkcs12_create_test); #endif + if (default_libctx) + ADD_TEST(pkcs12_recreate_test); ADD_ALL_TESTS(test_single_key_enc_pass, OSSL_NELEM(passwords)); ADD_ALL_TESTS(test_single_key_enc_iter, OSSL_NELEM(iters)); ADD_TEST(test_single_key_with_attrs); -- Gitee From 0a54ae4ccf84211959f1e20e72df5bbf0a82555c Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 12 Sep 2023 17:07:53 -0400 Subject: [PATCH 32/79] Fix regression in evp_test for provider compat CI If we ignore the faliure to copy on an old fips provider, we need to use ctx_base, rather than ctx Fixes #22076 Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22102) Signed-off-by: fly2x --- test/evp_test.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/evp_test.c b/test/evp_test.c index 7447435f06..f15b2c5a17 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -877,6 +877,11 @@ static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign, } else { TEST_info("Allowing copy fail as an old fips provider is in use."); } + EVP_CIPHER_CTX_free(ctx); + ctx = ctx_base; + } else { + EVP_CIPHER_CTX_free(ctx_base); + ctx_base = NULL; } /* Likewise for dup */ duped = EVP_CIPHER_CTX_dup(ctx); -- Gitee From 103c28e221d02beccf250a0ccd6cb7f7ff9ab5b6 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 12 Sep 2023 17:09:06 -0400 Subject: [PATCH 33/79] Fix a key repointing in various ciphers In the dupctx fixups I missed a pointer that needed to be repointed to the surrounding structures AES_KEY structure for the sm4/aes/aria ccm/gcm variants. This caused a colliding use of the key and possible use after free issues. Fixes #22076 Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22102) Signed-off-by: fly2x --- providers/implementations/ciphers/cipher_aes_gcm.c | 8 +++++++- providers/implementations/ciphers/cipher_aria_ccm.c | 8 +++++++- providers/implementations/ciphers/cipher_aria_gcm.c | 8 +++++++- providers/implementations/ciphers/cipher_sm4_ccm.c | 8 +++++++- providers/implementations/ciphers/cipher_sm4_gcm.c | 8 +++++++- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/providers/implementations/ciphers/cipher_aes_gcm.c b/providers/implementations/ciphers/cipher_aes_gcm.c index 0a15693cc1..edc3cc262e 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm.c +++ b/providers/implementations/ciphers/cipher_aes_gcm.c @@ -37,10 +37,16 @@ static void *aes_gcm_newctx(void *provctx, size_t keybits) static void *aes_gcm_dupctx(void *provctx) { PROV_AES_GCM_CTX *ctx = provctx; + PROV_AES_GCM_CTX *dctx = NULL; if (ctx == NULL) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.gcm.key != NULL) + dctx->base.gcm.key = &dctx->ks.ks; + + return dctx; } static OSSL_FUNC_cipher_freectx_fn aes_gcm_freectx; diff --git a/providers/implementations/ciphers/cipher_aria_ccm.c b/providers/implementations/ciphers/cipher_aria_ccm.c index 39a96a6f14..5fae593469 100644 --- a/providers/implementations/ciphers/cipher_aria_ccm.c +++ b/providers/implementations/ciphers/cipher_aria_ccm.c @@ -31,10 +31,16 @@ static void *aria_ccm_newctx(void *provctx, size_t keybits) static void *aria_ccm_dupctx(void *provctx) { PROV_ARIA_CCM_CTX *ctx = provctx; + PROV_ARIA_CCM_CTX *dctx = NULL; if (ctx == NULL) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.ccm_ctx.key != NULL) + dctx->base.ccm_ctx.key = &dctx->ks.ks; + + return dctx; } static void aria_ccm_freectx(void *vctx) diff --git a/providers/implementations/ciphers/cipher_aria_gcm.c b/providers/implementations/ciphers/cipher_aria_gcm.c index 6ffa0910fa..f9eb64cc19 100644 --- a/providers/implementations/ciphers/cipher_aria_gcm.c +++ b/providers/implementations/ciphers/cipher_aria_gcm.c @@ -30,10 +30,16 @@ static void *aria_gcm_newctx(void *provctx, size_t keybits) static void *aria_gcm_dupctx(void *provctx) { PROV_ARIA_GCM_CTX *ctx = provctx; + PROV_ARIA_GCM_CTX *dctx = NULL; if (ctx == NULL) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.gcm.key != NULL) + dctx->base.gcm.key = &dctx->ks.ks; + + return dctx; } static OSSL_FUNC_cipher_freectx_fn aria_gcm_freectx; diff --git a/providers/implementations/ciphers/cipher_sm4_ccm.c b/providers/implementations/ciphers/cipher_sm4_ccm.c index 5fd7d1a114..47fc6e103c 100644 --- a/providers/implementations/ciphers/cipher_sm4_ccm.c +++ b/providers/implementations/ciphers/cipher_sm4_ccm.c @@ -31,10 +31,16 @@ static void *sm4_ccm_newctx(void *provctx, size_t keybits) static void *sm4_ccm_dupctx(void *provctx) { PROV_SM4_CCM_CTX *ctx = provctx; + PROV_SM4_CCM_CTX *dctx = NULL; if (ctx == NULL) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.ccm_ctx.key != NULL) + dctx->base.ccm_ctx.key = &dctx->ks.ks; + + return dctx; } static void sm4_ccm_freectx(void *vctx) diff --git a/providers/implementations/ciphers/cipher_sm4_gcm.c b/providers/implementations/ciphers/cipher_sm4_gcm.c index 79e1b556d4..e8fcf5787e 100644 --- a/providers/implementations/ciphers/cipher_sm4_gcm.c +++ b/providers/implementations/ciphers/cipher_sm4_gcm.c @@ -32,10 +32,16 @@ static void *sm4_gcm_newctx(void *provctx, size_t keybits) static void *sm4_gcm_dupctx(void *provctx) { PROV_SM4_GCM_CTX *ctx = provctx; + PROV_SM4_GCM_CTX *dctx = NULL; if (ctx == NULL) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.gcm.key != NULL) + dctx->base.gcm.key = &dctx->ks.ks; + + return dctx; } static void sm4_gcm_freectx(void *vctx) -- Gitee From 01558d8fecce6c83e9f45486101d5a812bad5222 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 14 Sep 2023 16:59:47 +0200 Subject: [PATCH 34/79] coveralls.yml: Improve coverage mapping and remove 1.1.1 Reviewed-by: Matt Caswell Reviewed-by: Tom Cosgrove Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22104) Signed-off-by: fly2x --- .github/workflows/coveralls.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/coveralls.yml b/.github/workflows/coveralls.yml index 7771f5fd38..bdb576fd65 100644 --- a/.github/workflows/coveralls.yml +++ b/.github/workflows/coveralls.yml @@ -25,16 +25,14 @@ jobs: matrix: branches: [ { - branch: OpenSSL_1_1_1-stable - }, { branch: openssl-3.1, - extra_config: enable-fips + extra_config: no-afalgeng enable-fips enable-ssl-trace enable-trace enable-zlib enable-rc5 enable-md2 enable-weak-ssl-ciphers enable-ec_nistp_64_gcc_128 }, { branch: openssl-3.0, - extra_config: enable-fips + extra_config: no-afalgeng enable-fips enable-ssl-trace enable-trace enable-zlib enable-rc5 enable-md2 enable-weak-ssl-ciphers enable-ec_nistp_64_gcc_128 }, { branch: master, - extra_config: no-afalgeng enable-fips enable-tfo + extra_config: no-afalgeng enable-fips enable-ssl-trace enable-trace enable-zlib enable-rc5 enable-md2 enable-weak-ssl-ciphers enable-ec_nistp_64_gcc_128 enable-tfo } ] runs-on: ubuntu-latest -- Gitee From 2193bc28a8b614c7e147e7b9f1e442dac615cb38 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:50:11 +0200 Subject: [PATCH 35/79] Fix new typos found by codespell Reviewed-by: Tomas Mraz Reviewed-by: Hugo Landau Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22098) Signed-off-by: fly2x --- NEWS.md | 2 +- doc/man1/openssl-cms.pod.in | 2 +- doc/man7/ossl-guide-libraries-introduction.pod | 4 ++-- providers/implementations/rands/drbg_ctr.c | 8 ++++---- providers/implementations/rands/drbg_hash.c | 6 +++--- providers/implementations/rands/drbg_hmac.c | 4 ++-- providers/implementations/rands/drbg_local.h | 2 +- ssl/quic/quic_local.h | 2 +- test/helpers/handshake_srp.c | 5 +++-- test/testutil/tests.c | 2 +- 10 files changed, 19 insertions(+), 18 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6c440b68eb..d0312961df 100644 --- a/NEWS.md +++ b/NEWS.md @@ -135,7 +135,7 @@ OpenSSL 3.0 * Fixed a bug where the RC4-MD5 ciphersuite incorrectly used the AAD data as the MAC key ([CVE-2022-1434]) * Fix a bug in the OPENSSL_LH_flush() function that breaks reuse of the memory - occuppied by the removed hash table entries ([CVE-2022-1473]) + occupied by the removed hash table entries ([CVE-2022-1473]) ### Major changes between OpenSSL 3.0.1 and OpenSSL 3.0.2 [15 Mar 2022] diff --git a/doc/man1/openssl-cms.pod.in b/doc/man1/openssl-cms.pod.in index 50845b772e..a3ef9c0181 100644 --- a/doc/man1/openssl-cms.pod.in +++ b/doc/man1/openssl-cms.pod.in @@ -402,7 +402,7 @@ option. =item I ... This is an alternative to using the B<-recip> option when encrypting a message. -One or more certificate filennames may be given. +One or more certificate filenames may be given. =item B<-I> diff --git a/doc/man7/ossl-guide-libraries-introduction.pod b/doc/man7/ossl-guide-libraries-introduction.pod index 78e0853d8e..d54e98cd86 100644 --- a/doc/man7/ossl-guide-libraries-introduction.pod +++ b/doc/man7/ossl-guide-libraries-introduction.pod @@ -15,12 +15,12 @@ encryption, digital signatures, hash functions, etc. It additionally supplies supporting APIs for cryptography related standards, e.g. for reading and writing digital certificates (also known as X.509 certificates). Finally it also supplies various additional supporting APIs that are not directly cryptography -related but are nonetheless useful and dependended upon by other APIs. For +related but are nonetheless useful and depended upon by other APIs. For example the "BIO" functions provide capabilities for abstracting I/O, e.g. via a file or over a network. The C library provides functions to perform secure communication between -two peers across a network. Most signficiantly it implements support for the +two peers across a network. Most significantly it implements support for the SSL/TLS, DTLS and QUIC standards. The C library depends on and uses many of the capabilities supplied by diff --git a/providers/implementations/rands/drbg_ctr.c b/providers/implementations/rands/drbg_ctr.c index 2dc51d03c1..cc4ed25cfd 100644 --- a/providers/implementations/rands/drbg_ctr.c +++ b/providers/implementations/rands/drbg_ctr.c @@ -507,10 +507,10 @@ static int drbg_ctr_verify_zeroization(void *vdrbg) if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) return 0; - PROV_DRBG_VERYIFY_ZEROIZATION(ctr->K); - PROV_DRBG_VERYIFY_ZEROIZATION(ctr->V); - PROV_DRBG_VERYIFY_ZEROIZATION(ctr->bltmp); - PROV_DRBG_VERYIFY_ZEROIZATION(ctr->KX); + PROV_DRBG_VERIFY_ZEROIZATION(ctr->K); + PROV_DRBG_VERIFY_ZEROIZATION(ctr->V); + PROV_DRBG_VERIFY_ZEROIZATION(ctr->bltmp); + PROV_DRBG_VERIFY_ZEROIZATION(ctr->KX); if (ctr->bltmp_pos != 0) goto err; diff --git a/providers/implementations/rands/drbg_hash.c b/providers/implementations/rands/drbg_hash.c index 246aab58c9..a216910d83 100644 --- a/providers/implementations/rands/drbg_hash.c +++ b/providers/implementations/rands/drbg_hash.c @@ -405,9 +405,9 @@ static int drbg_hash_verify_zeroization(void *vdrbg) if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) return 0; - PROV_DRBG_VERYIFY_ZEROIZATION(hash->V); - PROV_DRBG_VERYIFY_ZEROIZATION(hash->C); - PROV_DRBG_VERYIFY_ZEROIZATION(hash->vtmp); + PROV_DRBG_VERIFY_ZEROIZATION(hash->V); + PROV_DRBG_VERIFY_ZEROIZATION(hash->C); + PROV_DRBG_VERIFY_ZEROIZATION(hash->vtmp); ret = 1; err: diff --git a/providers/implementations/rands/drbg_hmac.c b/providers/implementations/rands/drbg_hmac.c index ca190a740e..74d47886b4 100644 --- a/providers/implementations/rands/drbg_hmac.c +++ b/providers/implementations/rands/drbg_hmac.c @@ -298,8 +298,8 @@ static int drbg_hmac_verify_zeroization(void *vdrbg) if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) return 0; - PROV_DRBG_VERYIFY_ZEROIZATION(hmac->K); - PROV_DRBG_VERYIFY_ZEROIZATION(hmac->V); + PROV_DRBG_VERIFY_ZEROIZATION(hmac->K); + PROV_DRBG_VERIFY_ZEROIZATION(hmac->V); ret = 1; err: diff --git a/providers/implementations/rands/drbg_local.h b/providers/implementations/rands/drbg_local.h index dd46593a5f..50f98a0b61 100644 --- a/providers/implementations/rands/drbg_local.h +++ b/providers/implementations/rands/drbg_local.h @@ -206,7 +206,7 @@ OSSL_FUNC_rand_get_seed_fn ossl_drbg_get_seed; OSSL_FUNC_rand_clear_seed_fn ossl_drbg_clear_seed; /* Verify that an array of numeric values is all zero */ -#define PROV_DRBG_VERYIFY_ZEROIZATION(v) \ +#define PROV_DRBG_VERIFY_ZEROIZATION(v) \ { \ size_t i; \ \ diff --git a/ssl/quic/quic_local.h b/ssl/quic/quic_local.h index 063df7796a..928ae4c6bf 100644 --- a/ssl/quic/quic_local.h +++ b/ssl/quic/quic_local.h @@ -69,7 +69,7 @@ struct quic_xso_st { * b2 must equal b1 (validated unless ACCEPT_MOVING_WRITE_BUFFER) * l2 must equal l1 (always validated) * append into sstream from [b2 + aon_buf_pos, b2 + aon_buf_len) - * if done, aon_write_in_progess=0 + * if done, aon_write_in_progress=0 * */ /* Is an AON write in progress? */ diff --git a/test/helpers/handshake_srp.c b/test/helpers/handshake_srp.c index 43a5a4fd60..95fb101059 100644 --- a/test/helpers/handshake_srp.c +++ b/test/helpers/handshake_srp.c @@ -8,8 +8,9 @@ */ /* - * SRP is deprecated and there is no replacent. When SRP is removed, the code in - * this file can be removed too. Until then we have to use the deprecated APIs. + * SRP is deprecated and there is no replacement. When SRP is removed, + * the code in this file can be removed too. Until then we have to use + * the deprecated APIs. */ #define OPENSSL_SUPPRESS_DEPRECATED diff --git a/test/testutil/tests.c b/test/testutil/tests.c index 50d4e12e05..efc4fd2b64 100644 --- a/test/testutil/tests.c +++ b/test/testutil/tests.c @@ -18,7 +18,7 @@ /* * Output a failed test first line. - * All items are optional are generally not preinted if passed as NULL. + * All items are optional are generally not printed if passed as NULL. * The special cases are for prefix where "ERROR" is assumed and for left * and right where a non-failure message is produced if either is NULL. */ -- Gitee From 67f0dad60c03dd90cb02dd9a054e6259c9dc50f0 Mon Sep 17 00:00:00 2001 From: "Matthias St. Pierre" Date: Fri, 15 Sep 2023 15:32:25 +0200 Subject: [PATCH 36/79] APPS: remove duplicate definition of `trace_data_stack` Note: It seems like the C compiler doesn't care about the duplicate. (The first definition is eight lines above.) The C++ compiler however didn't like it when I reused the tracing code snippets elsewhere. Reviewed-by: Matt Caswell Reviewed-by: Tom Cosgrove Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22117) Signed-off-by: fly2x --- apps/openssl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openssl.c b/apps/openssl.c index dd41ac3a84..adf77096c7 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -157,8 +157,6 @@ static void tracedata_free(tracedata *data) OPENSSL_free(data); } -static STACK_OF(tracedata) *trace_data_stack; - static void cleanup_trace(void) { sk_tracedata_pop_free(trace_data_stack, tracedata_free); -- Gitee From adb9161f105f6ad411832e7009184071cb720757 Mon Sep 17 00:00:00 2001 From: Pan Lanlan Date: Sat, 9 Sep 2023 00:13:43 +0800 Subject: [PATCH 37/79] Update OPENSSL_buf2hexstr() to use DEFAULT_SEPARATOR. CLA: trivial Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22041) Signed-off-by: fly2x --- crypto/o_str.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/o_str.c b/crypto/o_str.c index 119d791e20..274b847614 100644 --- a/crypto/o_str.c +++ b/crypto/o_str.c @@ -279,13 +279,13 @@ char *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep) /* - * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its - * hex representation @@@ (Contents of buffer are always kept in ASCII, also - * on EBCDIC machines) + * Given a buffer of length 'buflen' return a OPENSSL_malloc'ed string with + * its hex representation @@@ (Contents of buffer are always kept in ASCII, + * also on EBCDIC machines) */ char *OPENSSL_buf2hexstr(const unsigned char *buf, long buflen) { - return ossl_buf2hexstr_sep(buf, buflen, ':'); + return ossl_buf2hexstr_sep(buf, buflen, DEFAULT_SEPARATOR); } int openssl_strerror_r(int errnum, char *buf, size_t buflen) -- Gitee From d29763df5cc19555fa366b74a6b46818514531a1 Mon Sep 17 00:00:00 2001 From: Sumitra Sharma Date: Tue, 12 Sep 2023 12:00:21 +0530 Subject: [PATCH 38/79] Enhance code safety and readability in SSL_get_shared_ciphers() This commit introduces two key improvements: 1. Improve code safety by replacing the conditional statement with `if (n >= size)` and using OPENSSL_strnlen() instead of strlen(). This change ensures proper buffer size handling and adheres to secure coding practices. 2. Enhance code readability by substituting `strcpy(p, c->name)` with `memcpy(p, c->name, n)`. This adjustment prioritizes code clarity and maintenance, even while mitigating a minimal buffer overflow risk. These enhancements bolster the code's robustness and comprehensibility, aligning with secure coding principles and best practices. Fixes #19837 Signed-off-by: Sumitra Sharma Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21934) Signed-off-by: fly2x --- ssl/ssl_lib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index b7fa9d78f7..fdc8b6b824 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -3397,14 +3397,14 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size) if (sk_SSL_CIPHER_find(srvrsk, c) < 0) continue; - n = strlen(c->name); - if (n + 1 > size) { + n = OPENSSL_strnlen(c->name, size); + if (n >= size) { if (p != buf) --p; *p = '\0'; return buf; } - strcpy(p, c->name); + memcpy(p, c->name, n); p += n; *(p++) = ':'; size -= n + 1; -- Gitee From 384f9c933d9b7e359b9ccc681c2d749fa8094f53 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 13 Sep 2023 16:56:58 +0200 Subject: [PATCH 39/79] Postponed further context duplication support for ciphers Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22094) Signed-off-by: fly2x --- test/evp_test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/evp_test.c b/test/evp_test.c index f15b2c5a17..ff424eac72 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -735,9 +735,9 @@ static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign, int ok = 0, tmplen, chunklen, tmpflen, i; EVP_CIPHER_CTX *ctx_base = NULL; EVP_CIPHER_CTX *ctx = NULL, *duped; - int fips_dupctx_supported = (fips_provider_version_ge(libctx, 3, 0, 11) - && fips_provider_version_lt(libctx, 3, 1, 0)) - || fips_provider_version_ge(libctx, 3, 1, 3); + int fips_dupctx_supported = (fips_provider_version_ge(libctx, 3, 0, 12) + && fips_provider_version_lt(libctx, 3, 1, 0)) + || fips_provider_version_ge(libctx, 3, 1, 4); t->err = "TEST_FAILURE"; if (!TEST_ptr(ctx_base = EVP_CIPHER_CTX_new())) -- Gitee From 78fadf1eac9b5bb3c9811ba04c61b54a80821696 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 23 Jan 2023 17:28:21 -0500 Subject: [PATCH 40/79] Allow to pass a passprase callback at store open Some PKCS11 modules require authentication early on to be able to preload objects, which we want to do to avoid costly roundtrips when the HSM is actually reached over a network (Cloud HSM). Unfortunately at open time we can't interact with the user becaue the callbacks are only passed at object load time. later on. This patch corrects this issue by providing a more feature rich open call for providers. Signed-off-by: Simo Sorce Reviewed-by: Dmitry Belyavskiy Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/20131) Signed-off-by: fly2x --- crypto/store/store_lib.c | 38 ++++++++++++++++++++++----------- crypto/store/store_local.h | 1 + crypto/store/store_meth.c | 4 ++++ include/openssl/core_dispatch.h | 4 ++++ 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index a68e8e28b6..d0561f636c 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -66,6 +66,7 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, OSSL_STORE_post_process_info_fn post_process, void *post_process_data) { + struct ossl_passphrase_data_st pwdata = { 0 }; const OSSL_STORE_LOADER *loader = NULL; OSSL_STORE_LOADER *fetched_loader = NULL; OSSL_STORE_LOADER_CTX *loader_ctx = NULL; @@ -102,6 +103,13 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, ERR_set_mark(); + if (ui_method != NULL + && (!ossl_pw_set_ui_method(&pwdata, ui_method, ui_data) + || !ossl_pw_enable_passphrase_caching(&pwdata))) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); + goto err; + } + /* * Try each scheme until we find one that could open the URI. * @@ -135,17 +143,28 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); no_loader_found = 0; - loader_ctx = fetched_loader->p_open(provctx, uri); + if (fetched_loader->p_open_ex != NULL) { + loader_ctx = + fetched_loader->p_open_ex(provctx, uri, params, + ossl_pw_passphrase_callback_dec, + &pwdata); + } else { + loader_ctx = fetched_loader->p_open(provctx, uri); + if (loader_ctx != NULL && + !loader_set_params(fetched_loader, loader_ctx, + params, propq)) { + (void)fetched_loader->p_close(loader_ctx); + loader_ctx = NULL; + } + } if (loader_ctx == NULL) { OSSL_STORE_LOADER_free(fetched_loader); fetched_loader = NULL; - } else if (!loader_set_params(fetched_loader, loader_ctx, - params, propq)) { - (void)fetched_loader->p_close(loader_ctx); - OSSL_STORE_LOADER_free(fetched_loader); - fetched_loader = NULL; } loader = fetched_loader; + + /* Clear any internally cached passphrase */ + (void)ossl_pw_clear_passphrase_cache(&pwdata); } } @@ -171,18 +190,13 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, || (ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) goto err; - if (ui_method != NULL - && (!ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data) - || !ossl_pw_enable_passphrase_caching(&ctx->pwdata))) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); - goto err; - } ctx->properties = propq_copy; ctx->fetched_loader = fetched_loader; ctx->loader = loader; ctx->loader_ctx = loader_ctx; ctx->post_process = post_process; ctx->post_process_data = post_process_data; + ctx->pwdata = pwdata; /* * If the attempt to open with the 'file' scheme loader failed and the diff --git a/crypto/store/store_local.h b/crypto/store/store_local.h index 06c8c9b218..6ad79180a0 100644 --- a/crypto/store/store_local.h +++ b/crypto/store/store_local.h @@ -113,6 +113,7 @@ struct ossl_store_loader_st { OSSL_FUNC_store_close_fn *p_close; OSSL_FUNC_store_export_object_fn *p_export_object; OSSL_FUNC_store_delete_fn *p_delete; + OSSL_FUNC_store_open_ex_fn *p_open_ex; }; DEFINE_LHASH_OF_EX(OSSL_STORE_LOADER); diff --git a/crypto/store/store_meth.c b/crypto/store/store_meth.c index 766777c3a0..6ac8fd5f93 100644 --- a/crypto/store/store_meth.c +++ b/crypto/store/store_meth.c @@ -223,6 +223,10 @@ static void *loader_from_algorithm(int scheme_id, const OSSL_ALGORITHM *algodef, if (loader->p_delete == NULL) loader->p_delete = OSSL_FUNC_store_delete(fns); break; + case OSSL_FUNC_STORE_OPEN_EX: + if (loader->p_open_ex == NULL) + loader->p_open_ex = OSSL_FUNC_store_open_ex(fns); + break; } } diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index 9631626ae3..73f040285c 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -937,6 +937,7 @@ OSSL_CORE_MAKE_FUNC(int, decoder_export_object, #define OSSL_FUNC_STORE_CLOSE 7 #define OSSL_FUNC_STORE_EXPORT_OBJECT 8 #define OSSL_FUNC_STORE_DELETE 9 +#define OSSL_FUNC_STORE_OPEN_EX 10 OSSL_CORE_MAKE_FUNC(void *, store_open, (void *provctx, const char *uri)) OSSL_CORE_MAKE_FUNC(void *, store_attach, (void *provctx, OSSL_CORE_BIO *in)) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, store_settable_ctx_params, @@ -955,6 +956,9 @@ OSSL_CORE_MAKE_FUNC(int, store_export_object, OSSL_CORE_MAKE_FUNC(int, store_delete, (void *provctx, const char *uri, const OSSL_PARAM params[], OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)) +OSSL_CORE_MAKE_FUNC(void *, store_open_ex, + (void *provctx, const char *uri, const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)) # ifdef __cplusplus } -- Gitee From c278df2126ec5c64354269cd1b725739d17419f9 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 14 Sep 2023 09:25:30 -0400 Subject: [PATCH 41/79] Add Test to verify open_ex password checking works Signed-off-by: Simo Sorce Reviewed-by: Dmitry Belyavskiy Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/20131) Signed-off-by: fly2x --- test/fake_rsaprov.c | 46 ++++++++++++++++++++++++++- test/fake_rsaprov.h | 2 ++ test/provider_pkey_test.c | 66 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/test/fake_rsaprov.c b/test/fake_rsaprov.c index 9bc463b2c8..c1b8e28286 100644 --- a/test/fake_rsaprov.c +++ b/test/fake_rsaprov.c @@ -525,6 +525,7 @@ static const OSSL_ALGORITHM fake_rsa_sig_algs[] = { }; static OSSL_FUNC_store_open_fn fake_rsa_st_open; +static OSSL_FUNC_store_open_ex_fn fake_rsa_st_open_ex; static OSSL_FUNC_store_settable_ctx_params_fn fake_rsa_st_settable_ctx_params; static OSSL_FUNC_store_set_ctx_params_fn fake_rsa_st_set_ctx_params; static OSSL_FUNC_store_load_fn fake_rsa_st_load; @@ -533,8 +534,13 @@ static OSSL_FUNC_store_close_fn fake_rsa_st_close; static OSSL_FUNC_store_delete_fn fake_rsa_st_delete; static const char fake_rsa_scheme[] = "fake_rsa:"; +static const char fake_rsa_openpwtest[] = "fake_rsa:openpwtest"; +static const char fake_rsa_prompt[] = "Fake Prompt Info"; -static void *fake_rsa_st_open(void *provctx, const char *uri) +static void *fake_rsa_st_open_ex(void *provctx, const char *uri, + const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, + void *pw_cbarg) { unsigned char *storectx = NULL; @@ -542,10 +548,47 @@ static void *fake_rsa_st_open(void *provctx, const char *uri) if (strncmp(uri, fake_rsa_scheme, sizeof(fake_rsa_scheme) - 1) != 0) return NULL; + if (strncmp(uri, fake_rsa_openpwtest, + sizeof(fake_rsa_openpwtest) - 1) == 0) { + const char *pw_check = FAKE_PASSPHRASE; + char fakepw[sizeof(FAKE_PASSPHRASE) + 1] = { 0 }; + size_t fakepw_len = 0; + OSSL_PARAM pw_params[2] = { + OSSL_PARAM_utf8_string(OSSL_PASSPHRASE_PARAM_INFO, + (void *)fake_rsa_prompt, + sizeof(fake_rsa_prompt) - 1), + OSSL_PARAM_END, + }; + + if (pw_cb == NULL) { + return NULL; + } + + if (!pw_cb(fakepw, sizeof(fakepw), &fakepw_len, pw_params, pw_cbarg)) { + TEST_info("fake_rsa_open_ex failed passphrase callback"); + return NULL; + } + if (strncmp(pw_check, fakepw, sizeof(pw_check) - 1) != 0) { + TEST_info("fake_rsa_open_ex failed passphrase check"); + return NULL; + } + } + storectx = OPENSSL_zalloc(1); if (!TEST_ptr(storectx)) return NULL; + TEST_info("fake_rsa_open_ex called"); + + return storectx; +} + +static void *fake_rsa_st_open(void *provctx, const char *uri) +{ + unsigned char *storectx = NULL; + + storectx = fake_rsa_st_open_ex(provctx, uri, NULL, NULL, NULL); + TEST_info("fake_rsa_open called"); return storectx; @@ -643,6 +686,7 @@ static int fake_rsa_st_close(void *loaderctx) static const OSSL_DISPATCH fake_rsa_store_funcs[] = { { OSSL_FUNC_STORE_OPEN, (void (*)(void))fake_rsa_st_open }, + { OSSL_FUNC_STORE_OPEN_EX, (void (*)(void))fake_rsa_st_open_ex }, { OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS, (void (*)(void))fake_rsa_st_settable_ctx_params }, { OSSL_FUNC_STORE_SET_CTX_PARAMS, (void (*)(void))fake_rsa_st_set_ctx_params }, diff --git a/test/fake_rsaprov.h b/test/fake_rsaprov.h index 53056fa59f..9c353b386f 100644 --- a/test/fake_rsaprov.h +++ b/test/fake_rsaprov.h @@ -9,6 +9,8 @@ #include +#define FAKE_PASSPHRASE "Passphrase Testing" + /* Fake RSA provider implementation */ OSSL_PROVIDER *fake_rsa_start(OSSL_LIB_CTX *libctx); void fake_rsa_finish(OSSL_PROVIDER *p); diff --git a/test/provider_pkey_test.c b/test/provider_pkey_test.c index 09b060642b..7d5fcfa647 100644 --- a/test/provider_pkey_test.c +++ b/test/provider_pkey_test.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "testutil.h" #include "fake_rsaprov.h" @@ -359,6 +360,70 @@ end: return ret; } +static int fake_pw_read_string(UI *ui, UI_STRING *uis) +{ + const char *passphrase = FAKE_PASSPHRASE; + + if (UI_get_string_type(uis) == UIT_PROMPT) { + UI_set_result(ui, uis, passphrase); + return 1; + } + + return 0; +} + +static int test_pkey_store_open_ex(void) +{ + OSSL_PROVIDER *deflt = NULL; + OSSL_PROVIDER *fake_rsa = NULL; + int ret = 0; + EVP_PKEY *pkey = NULL; + OSSL_STORE_LOADER *loader = NULL; + OSSL_STORE_CTX *ctx = NULL; + const char *propq = "?provider=fake-rsa"; + UI_METHOD *ui_method = NULL; + + /* It's important to load the default provider first for this test */ + if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) + goto end; + + if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) + goto end; + + if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake_rsa", + propq))) + goto end; + + OSSL_STORE_LOADER_free(loader); + + if (!TEST_ptr(ui_method= UI_create_method("PW Callbacks"))) + goto end; + + if (UI_method_set_reader(ui_method, fake_pw_read_string)) + goto end; + + if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:openpwtest", libctx, propq, + ui_method, NULL, NULL, NULL, NULL))) + goto end; + + /* retry w/o ui_method to ensure we actually enter pw checks and fail */ + OSSL_STORE_close(ctx); + if (!TEST_ptr_null(ctx = OSSL_STORE_open_ex("fake_rsa:openpwtest", libctx, + propq, NULL, NULL, NULL, NULL, + NULL))) + goto end; + + ret = 1; + +end: + UI_destroy_method(ui_method); + fake_rsa_finish(fake_rsa); + OSSL_PROVIDER_unload(deflt); + OSSL_STORE_close(ctx); + EVP_PKEY_free(pkey); + return ret; +} + int setup_tests(void) { libctx = OSSL_LIB_CTX_new(); @@ -370,6 +435,7 @@ int setup_tests(void) ADD_TEST(test_pkey_eq); ADD_ALL_TESTS(test_pkey_store, 2); ADD_TEST(test_pkey_delete); + ADD_TEST(test_pkey_store_open_ex); return 1; } -- Gitee From c4fe8af37eb81811b52c7b436907bd1c97c65a89 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 14 Sep 2023 16:55:32 -0400 Subject: [PATCH 42/79] Add provider documentation for the new open_ex Signed-off-by: Simo Sorce Reviewed-by: Dmitry Belyavskiy Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/20131) Signed-off-by: fly2x --- doc/man7/provider-storemgmt.pod | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/man7/provider-storemgmt.pod b/doc/man7/provider-storemgmt.pod index c58df619db..a8ce43c4bb 100644 --- a/doc/man7/provider-storemgmt.pod +++ b/doc/man7/provider-storemgmt.pod @@ -27,6 +27,10 @@ provider-storemgmt - The OSSL_STORE library E-E provider functions int OSSL_FUNC_store_export_object (void *loaderctx, const void *objref, size_t objref_sz, OSSL_CALLBACK *export_cb, void *export_cbarg); + void *OSSL_FUNC_store_open_ex(void *provctx, const char *uri, + const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, + void *pw_cbarg); int OSSL_FUNC_store_delete(void *provctx, const char *uri, const OSSL_PARAM params[], @@ -75,6 +79,7 @@ in L, as follows: OSSL_FUNC_store_close OSSL_FUNC_STORE_CLOSE OSSL_FUNC_store_export_object OSSL_FUNC_STORE_EXPORT_OBJECT OSSL_FUNC_store_delete OSSL_FUNC_STORE_DELETE + OSSL_FUNC_store_open_ex OSSL_FUNC_STORE_OPEN_EX =head2 Functions @@ -124,6 +129,13 @@ implementation is entirely responsible for the interpretation of the URI. In case a passphrase needs to be prompted to remove an object, I should be called. +OSSL_FUNC_store_open_ex() is an extended variant of OSSL_FUNC_store_open(). If +the provider does not implement this function the code internally falls back to +use the original OSSL_FUNC_store_open(). +This variant additionally accepts an L object and a I +callback that can be used to request a passphrase in cases where the whole +store needs to be unlocked before performing any load operation. + =head2 Load Parameters =over 4 -- Gitee From b366984fc4820231e5691d621929733e0b6e1607 Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Mon, 18 Sep 2023 16:02:21 +0200 Subject: [PATCH 43/79] enc: "bad decrypt" only in decryption CLA: trivial Signed-off-by: Mathieu Tortuyaux Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22134) Signed-off-by: fly2x --- apps/enc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/enc.c b/apps/enc.c index 26e009e437..d94f5236d7 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -701,7 +701,10 @@ int enc_main(int argc, char **argv) break; } if (!BIO_flush(wbio)) { - BIO_printf(bio_err, "bad decrypt\n"); + if (enc) + BIO_printf(bio_err, "bad encrypt\n"); + else + BIO_printf(bio_err, "bad decrypt\n"); goto end; } -- Gitee From 6582c34bee1f594f470f866412186d826accd327 Mon Sep 17 00:00:00 2001 From: Dmitry Misharov Date: Mon, 18 Sep 2023 10:53:00 +0200 Subject: [PATCH 44/79] os zoo ci Use a Github Actions expression to set value for the environment variable. Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22130) Signed-off-by: fly2x --- .github/workflows/os-zoo.yml | 111 +++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 38 deletions(-) diff --git a/.github/workflows/os-zoo.yml b/.github/workflows/os-zoo.yml index ee327f4c1b..98fe0c744c 100644 --- a/.github/workflows/os-zoo.yml +++ b/.github/workflows/os-zoo.yml @@ -15,80 +15,116 @@ permissions: contents: read jobs: - # This has to be a separate job, it seems, because we want to use a - # container for it. - unix-container: + alpine: strategy: fail-fast: false matrix: - image: ['alpine:edge', 'alpine:latest'] - cc: ['gcc', 'clang'] + tag: [edge, latest] + cc: [gcc, clang] + branch: [openssl-3.0, openssl-3.1, master] runs-on: ubuntu-latest container: - image: ${{ matrix.image }} + image: docker.io/library/alpine:${{ matrix.tag }} + env: + # https://www.openwall.com/lists/musl/2022/02/16/14 + EXTRA_CFLAGS: ${{ matrix.cc == 'clang' && '-Wno-sign-compare' || '' }} + CC: ${{ matrix.cc }} steps: - name: install packages - run: | - apk --no-cache add build-base perl linux-headers git ${{ matrix.cc }} - + run: apk --no-cache add build-base perl linux-headers ${{ matrix.cc }} - uses: actions/checkout@v4 - + with: + ref: ${{ matrix.branch }} - name: config run: | - cc="${{ matrix.cc }}" - - extra_cflags="" - if [[ ${cc} == "clang" ]] ; then - # https://www.openwall.com/lists/musl/2022/02/16/14 - extra_cflags="-Wno-sign-compare" - fi - - CC=${{ matrix.cc }} ./config --banner=Configured no-shared \ - -Wall -Werror enable-fips --strict-warnings -DOPENSSL_USE_IPV6=0 ${extra_cflags} - + ./config --banner=Configured no-shared -Wall -Werror enable-fips --strict-warnings -DOPENSSL_USE_IPV6=0 \ + ${EXTRA_CFLAGS} - name: config dump run: ./configdata.pm --dump - name: make run: make -s -j4 - name: make test run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - unix: + + linux: + strategy: + fail-fast: false + matrix: + branch: [openssl-3.0, openssl-3.1, master] + zoo: + - image: docker.io/library/debian:10 + install: apt-get update && apt-get install -y gcc make perl + - image: docker.io/library/debian:11 + install: apt-get update && apt-get install -y gcc make perl + - image: docker.io/library/debian:12 + install: apt-get update && apt-get install -y gcc make perl + - image: docker.io/library/ubuntu:20.04 + install: apt-get update && apt-get install -y gcc make perl + - image: docker.io/library/ubuntu:22.04 + install: apt-get update && apt-get install -y gcc make perl + - image: docker.io/library/fedora:38 + install: dnf install -y gcc make perl-core + - image: docker.io/library/fedora:39 + install: dnf install -y gcc make perl-core + - image: docker.io/library/centos:8 + install: | + sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* && \ + sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* && \ + dnf install -y gcc make perl-core + - image: docker.io/library/rockylinux:8 + install: dnf install -y gcc make perl-core + - image: docker.io/library/rockylinux:9 + install: dnf install -y gcc make perl-core + runs-on: ubuntu-latest + container: ${{ matrix.zoo.image }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ matrix.branch }} + - name: install packages + run: ${{ matrix.zoo.install }} + - name: config + run: ./config + - name: config dump + run: ./configdata.pm --dump + - name: make + run: make -j4 + - name: make test + run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} + + macos: strategy: fail-fast: false matrix: - os: [ - macos-11, - macos-12, - macos-13, - ubuntu-20.04, - ubuntu-22.04, - ] + branch: [openssl-3.0, openssl-3.1, master] + os: [macos-11, macos-12, macos-13] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 + with: + ref: ${{ matrix.branch }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config - run: | - CC=${{ matrix.zoo.cc }} ./config --banner=Configured \ - -Wall -Werror --strict-warnings enable-fips + run: ./config --banner=Configured -Wall -Werror --strict-warnings enable-fips - name: config dump run: ./configdata.pm --dump - name: make run: make -s -j4 - name: make test run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} + windows: strategy: fail-fast: false matrix: - os: [ - windows-2019, - windows-2022 - ] + branch: [openssl-3.0, openssl-3.1, master] + os: [windows-2019, windows-2022] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 + with: + ref: ${{ matrix.branch }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - uses: ilammy/msvc-dev-cmd@v1 @@ -98,8 +134,7 @@ jobs: run: mkdir _build - name: config working-directory: _build - run: | - perl ..\Configure --banner=Configured no-makedepend enable-fips + run: perl ..\Configure --banner=Configured no-makedepend enable-fips - name: config dump working-directory: _build run: ./configdata.pm --dump -- Gitee From 775d42db5263f23de278c457ed7d6325ee9352d9 Mon Sep 17 00:00:00 2001 From: Sumitra Sharma Date: Mon, 18 Sep 2023 16:38:11 +0530 Subject: [PATCH 45/79] Add documentation for the function SSL_CONF_CTX_finish. Add documentation for the function SSL_CONF_CTX_finish() in man3. Fixes #22084 Signed-off-by: Sumitra Sharma Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22128) Signed-off-by: fly2x --- doc/man3/SSL_CONF_CTX_set_ssl_ctx.pod | 8 ++++++++ util/missingssl.txt | 1 - 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/man3/SSL_CONF_CTX_set_ssl_ctx.pod b/doc/man3/SSL_CONF_CTX_set_ssl_ctx.pod index 06cc1e4ec5..b74c869b83 100644 --- a/doc/man3/SSL_CONF_CTX_set_ssl_ctx.pod +++ b/doc/man3/SSL_CONF_CTX_set_ssl_ctx.pod @@ -2,6 +2,7 @@ =head1 NAME +SSL_CONF_CTX_finish, SSL_CONF_CTX_set_ssl_ctx, SSL_CONF_CTX_set_ssl - set context to configure =head1 SYNOPSIS @@ -10,6 +11,7 @@ SSL_CONF_CTX_set_ssl_ctx, SSL_CONF_CTX_set_ssl - set context to configure void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx); void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl); + int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx); =head1 DESCRIPTION @@ -23,6 +25,10 @@ B structure B. Any previous B or B associated with B is cleared. Subsequent calls to SSL_CONF_cmd() will be sent to B. +The function SSL_CONF_CTX_finish() must be called after all configuration +operations have been completed. It is used to finalise any operations +or to process defaults. + =head1 NOTES The context need not be set or it can be set to B in which case only @@ -32,6 +38,8 @@ syntax checking of commands is performed, where possible. SSL_CONF_CTX_set_ssl_ctx() and SSL_CTX_set_ssl() do not return a value. +SSL_CONF_CTX_finish() returns 1 for success and 0 for failure. + =head1 SEE ALSO L, diff --git a/util/missingssl.txt b/util/missingssl.txt index 224eb84899..1338feed71 100644 --- a/util/missingssl.txt +++ b/util/missingssl.txt @@ -3,7 +3,6 @@ ERR_load_SSL_strings(3) SRP_Calc_A_param(3) SSL_COMP_get_name(3) SSL_COMP_set0_compression_methods(3) -SSL_CONF_CTX_finish(3) SSL_CTX_SRP_CTX_free(3) SSL_CTX_SRP_CTX_init(3) SSL_CTX_get0_certificate(3) -- Gitee From 65be7e2a8d60406e27cc561db8fd2db4bc7a36c5 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Wed, 6 Sep 2023 08:04:17 +0100 Subject: [PATCH 46/79] QUIC: Wire SSL_net_(read|write)_desired for TLS/DTLS Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/21979) Signed-off-by: fly2x --- ssl/ssl_lib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index fdc8b6b824..fec9124ce4 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -7344,11 +7344,11 @@ int SSL_net_read_desired(SSL *s) { #ifndef OPENSSL_NO_QUIC if (!IS_QUIC(s)) - return 0; + return SSL_want_read(s); return ossl_quic_get_net_read_desired(s); #else - return 0; + return SSL_want_read(s); #endif } @@ -7356,11 +7356,11 @@ int SSL_net_write_desired(SSL *s) { #ifndef OPENSSL_NO_QUIC if (!IS_QUIC(s)) - return 0; + return SSL_want_write(s); return ossl_quic_get_net_write_desired(s); #else - return 0; + return SSL_want_write(s); #endif } -- Gitee From e138e780f46764d0f6dd49d5e091393de6f8bcad Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Wed, 13 Sep 2023 13:46:27 +0100 Subject: [PATCH 47/79] QUIC APL: Wire SSL_get_[rw]poll_descriptor for TLS/DTLS Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/21979) Signed-off-by: fly2x --- ssl/ssl_lib.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index fec9124ce4..f15fe126a2 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -7318,26 +7318,32 @@ int SSL_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite) int SSL_get_rpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc) { -#ifndef OPENSSL_NO_QUIC - if (!IS_QUIC(s)) - return -1; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - return ossl_quic_get_rpoll_descriptor(s, desc); -#else - return -1; +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_get_rpoll_descriptor(s, desc); #endif + + if (sc == NULL || sc->rbio == NULL) + return 0; + + return BIO_get_rpoll_descriptor(sc->rbio, desc); } int SSL_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc) { -#ifndef OPENSSL_NO_QUIC - if (!IS_QUIC(s)) - return -1; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - return ossl_quic_get_wpoll_descriptor(s, desc); -#else - return -1; +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_get_wpoll_descriptor(s, desc); #endif + + if (sc == NULL || sc->wbio == NULL) + return 0; + + return BIO_get_wpoll_descriptor(sc->wbio, desc); } int SSL_net_read_desired(SSL *s) -- Gitee From f684afd259ab24dc13367b6122fa7128c9a31989 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Wed, 13 Sep 2023 13:46:44 +0100 Subject: [PATCH 48/79] QUIC: Update documentation for SSL_get_[rw]poll_descriptor, SSL_net_(read|write)_desired Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/21979) Signed-off-by: fly2x --- doc/man3/SSL_get_rpoll_descriptor.pod | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/man3/SSL_get_rpoll_descriptor.pod b/doc/man3/SSL_get_rpoll_descriptor.pod index 5e1879580e..3bdd0a924c 100644 --- a/doc/man3/SSL_get_rpoll_descriptor.pod +++ b/doc/man3/SSL_get_rpoll_descriptor.pod @@ -66,7 +66,14 @@ may change in response to any call to the SSL object other than SSL_net_read_desired(), SSL_net_write_desired(), SSL_get_rpoll_descriptor(), SSL_get_wpoll_descriptor() and SSL_get_event_timeout(). -These functions are not supported on non-QUIC SSL objects. +On non-QUIC SSL objects, calls to SSL_get_rpoll_descriptor() and +SSL_get_wpoll_descriptor() function the same as calls to +BIO_get_rpoll_descriptor() and BIO_get_wpoll_descriptor() on the respective read +and write BIOs configured on the SSL object. + +On non-QUIC SSL objects, calls to SSL_net_read_desired() and +SSL_net_write_desired() function identically to calls to SSL_want_read() and +SSL_want_write() respectively. =head1 RETURN VALUES -- Gitee From 329e553fb73e8d82ac27da579b8c22f451f21ec5 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Wed, 13 Sep 2023 13:47:13 +0100 Subject: [PATCH 49/79] SSL: Test SSL_get_[rw]poll_descriptor, SSL_net_(read|write)_desired Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/21979) Signed-off-by: fly2x --- test/helpers/ssltestlib.c | 22 ++++++++++++++++++++++ test/sslapitest.c | 13 +++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/test/helpers/ssltestlib.c b/test/helpers/ssltestlib.c index 0b1e56f064..3ae3e7d4ea 100644 --- a/test/helpers/ssltestlib.c +++ b/test/helpers/ssltestlib.c @@ -985,6 +985,7 @@ int create_ssl_objects2(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl, { SSL *serverssl = NULL, *clientssl = NULL; BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL; + BIO_POLL_DESCRIPTOR rdesc = {0}, wdesc = {0}; if (*sssl != NULL) serverssl = *sssl; @@ -999,8 +1000,29 @@ int create_ssl_objects2(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl, || !TEST_ptr(c_to_s_bio = BIO_new_socket(cfd, BIO_NOCLOSE))) goto error; + if (!TEST_false(SSL_get_rpoll_descriptor(clientssl, &rdesc) + || !TEST_false(SSL_get_wpoll_descriptor(clientssl, &wdesc)))) + goto error; + SSL_set_bio(clientssl, c_to_s_bio, c_to_s_bio); SSL_set_bio(serverssl, s_to_c_bio, s_to_c_bio); + + if (!TEST_true(SSL_get_rpoll_descriptor(clientssl, &rdesc)) + || !TEST_true(SSL_get_wpoll_descriptor(clientssl, &wdesc)) + || !TEST_int_eq(rdesc.type, BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) + || !TEST_int_eq(wdesc.type, BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) + || !TEST_int_eq(rdesc.value.fd, cfd) + || !TEST_int_eq(wdesc.value.fd, cfd)) + goto error; + + if (!TEST_true(SSL_get_rpoll_descriptor(serverssl, &rdesc)) + || !TEST_true(SSL_get_wpoll_descriptor(serverssl, &wdesc)) + || !TEST_int_eq(rdesc.type, BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) + || !TEST_int_eq(wdesc.type, BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) + || !TEST_int_eq(rdesc.value.fd, sfd) + || !TEST_int_eq(wdesc.value.fd, sfd)) + goto error; + *sssl = serverssl; *cssl = clientssl; return 1; diff --git a/test/sslapitest.c b/test/sslapitest.c index ec29157007..9539b4cf3a 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -6601,7 +6601,9 @@ static int test_key_update_peer_in_write(int tst) /* Write data that we know will fail with SSL_ERROR_WANT_WRITE */ if (!TEST_int_eq(SSL_write(peerwrite, mess, strlen(mess)), -1) - || !TEST_int_eq(SSL_get_error(peerwrite, 0), SSL_ERROR_WANT_WRITE)) + || !TEST_int_eq(SSL_get_error(peerwrite, 0), SSL_ERROR_WANT_WRITE) + || !TEST_true(SSL_want_write(peerwrite)) + || !TEST_true(SSL_net_write_desired(peerwrite))) goto end; /* Reinstate the original writing endpoint's write BIO */ @@ -6610,7 +6612,9 @@ static int test_key_update_peer_in_write(int tst) /* Now read some data - we will read the key update */ if (!TEST_int_eq(SSL_read(peerwrite, buf, sizeof(buf)), -1) - || !TEST_int_eq(SSL_get_error(peerwrite, 0), SSL_ERROR_WANT_READ)) + || !TEST_int_eq(SSL_get_error(peerwrite, 0), SSL_ERROR_WANT_READ) + || !TEST_true(SSL_want_read(peerwrite)) + || !TEST_true(SSL_net_read_desired(peerwrite))) goto end; /* @@ -6626,6 +6630,11 @@ static int test_key_update_peer_in_write(int tst) || !TEST_int_eq(SSL_read(peerupdate, buf, sizeof(buf)), strlen(mess))) goto end; + if (!TEST_false(SSL_net_read_desired(peerwrite)) + || !TEST_false(SSL_net_write_desired(peerwrite)) + || !TEST_int_eq(SSL_want(peerwrite), SSL_NOTHING)) + goto end; + testresult = 1; end: -- Gitee From baee591cd74e22e3f4c83c15b46632e92e89b417 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Thu, 14 Sep 2023 08:40:14 +0100 Subject: [PATCH 50/79] BIO: Wire poll descriptor functions in BIO_s_sock Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/21979) Signed-off-by: fly2x --- crypto/bio/bss_sock.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c index f64eb8c843..4ff4defadf 100644 --- a/crypto/bio/bss_sock.c +++ b/crypto/bio/bss_sock.c @@ -215,6 +215,20 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_FLUSH: ret = 1; break; + case BIO_CTRL_GET_RPOLL_DESCRIPTOR: + case BIO_CTRL_GET_WPOLL_DESCRIPTOR: + { + BIO_POLL_DESCRIPTOR *pd = ptr; + + if (!b->init) { + ret = 0; + break; + } + + pd->type = BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD; + pd->value.fd = b->num; + } + break; # ifndef OPENSSL_NO_KTLS case BIO_CTRL_SET_KTLS: crypto_info = (ktls_crypto_info_t *)ptr; -- Gitee From f8a429900b0ab57e54c247744927afe05385140f Mon Sep 17 00:00:00 2001 From: Pauli Date: Tue, 19 Sep 2023 11:07:21 +1000 Subject: [PATCH 51/79] coverity: NULL dereference Fixes coverity 1544699. Reviewed-by: Matt Caswell Reviewed-by: Tim Hudson Reviewed-by: Tomas Mraz Reviewed-by: Bernd Edlinger (Merged from https://github.com/openssl/openssl/pull/22138) Signed-off-by: fly2x --- crypto/engine/eng_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/engine/eng_table.c b/crypto/engine/eng_table.c index 3138a15260..9dc3144bbf 100644 --- a/crypto/engine/eng_table.c +++ b/crypto/engine/eng_table.c @@ -97,6 +97,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, if (added && !engine_cleanup_add_first(cleanup)) { lh_ENGINE_PILE_free(&(*table)->piles); *table = NULL; + goto end; } while (num_nids--) { tmplate.nid = *nids; -- Gitee From b66625e7330edbd21a415b6579a46fd8c71f7bd0 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 15 Sep 2023 14:29:05 +0100 Subject: [PATCH 52/79] Enable the ability to seed the test RNG without randomising test ordering Numerous tests use the test_random() function to get a random number. If a test fails then the seed that was used for the test RNG is displayed. Setting the seed to the same value in a future run is supposed to cause the same random numbers to be generated again. The way to set the RNG seed again is to use the `OPENSSL_TEST_RAND_ORDER` environment variable. However setting this environment variable *also* randomises the test ordering as well as seeding the RNG. This in itself calls test_random() so, in fact, when the test finally runs it gets different random numbers to when it originally run (defeating the repeatability objective). This means that only way repeatability can be obtained is if the test was originally run with `OPENSSL_TEST_RAND_ORDER` set to 0. If that wasn't done then the seed printed when the test failed is not useful. We introduce a new environment variable `OPENSSL_TEST_RAND_SEED` which can be used to independently seed the test RNG without randomising the test ordering. This can be used to get repeatability in cases where test ordering randomisation was not done in the first place. Reviewed-by: Dmitry Belyavskiy Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22118) Signed-off-by: fly2x --- test/testutil/driver.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/test/testutil/driver.c b/test/testutil/driver.c index 6427d235af..033be2fcc5 100644 --- a/test/testutil/driver.c +++ b/test/testutil/driver.c @@ -102,15 +102,18 @@ static void set_seed(int s) int setup_test_framework(int argc, char *argv[]) { - char *test_seed = getenv("OPENSSL_TEST_RAND_ORDER"); + char *test_rand_order = getenv("OPENSSL_TEST_RAND_ORDER"); + char *test_rand_seed = getenv("OPENSSL_TEST_RAND_SEED"); char *TAP_levels = getenv("HARNESS_OSSL_LEVEL"); if (TAP_levels != NULL) level = 4 * atoi(TAP_levels); test_adjust_streams_tap_level(level); - if (test_seed != NULL) { + if (test_rand_order != NULL) { rand_order = 1; - set_seed(atoi(test_seed)); + set_seed(atoi(test_rand_order)); + } else if (test_rand_seed != NULL) { + set_seed(atoi(test_rand_seed)); } else { set_seed(0); } @@ -264,8 +267,12 @@ PRINTF_FORMAT(2, 3) static void test_verdict(int verdict, test_flush_stdout(); test_flush_stderr(); - if (verdict == 0 && seed != 0) - test_printf_tapout("# OPENSSL_TEST_RAND_ORDER=%d\n", seed); + if (verdict == 0) { + if (rand_order) + test_printf_tapout("# OPENSSL_TEST_RAND_ORDER=%d\n", seed); + else + test_printf_tapout("# OPENSSL_TEST_RAND_SEED=%d\n", seed); + } test_printf_tapout("%s ", verdict != 0 ? "ok" : "not ok"); va_start(ap, description); test_vprintf_tapout(description, ap); -- Gitee From 23718ae8d06226a6150322bf9949d41d9f211624 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 15 Sep 2023 14:36:05 +0100 Subject: [PATCH 53/79] Document the OPENSSL_TEST_RAND_SEED environment variable Reviewed-by: Dmitry Belyavskiy Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22118) Signed-off-by: fly2x --- test/README.md | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/test/README.md b/test/README.md index 9a5c91953d..fe25bd8b4e 100644 --- a/test/README.md +++ b/test/README.md @@ -149,17 +149,33 @@ To run up to four tests in parallel at any given time: $ make HARNESS_JOBS=4 test +Random numbers in tests +----------------------- + +Some tests use random numbers as part of the test. In some cases a test failure +may occur for some random numbers, but not for others. The seed used for the +rand number generator can be set via the `OPENSSL_TEST_RAND_SEED` environment +variable. It can also be set via the `OPENSSL_TEST_RAND_ORDER` environment +variable which additionally randomises the order tests are run in (see below). + +When a test fails the test harness will display the seed used during the test +(displaying either the `OPENSSL_TEST_RAND_SEED` or `OPENSSL_TEST_RAND_ORDER` +environment variable value that must be used to recreate the results), e.g. + + $ make OPENSSL_TEST_RAND_SEED=42 test + Randomisation of Test Ordering ------------------------------ By default, the test harness will execute tests in the order they were added. By setting the `OPENSSL_TEST_RAND_ORDER` environment variable to zero, the -test ordering will be randomised. If a randomly ordered test fails, the -seed value used will be reported. Setting the `OPENSSL_TEST_RAND_ORDER` -environment variable to this value will rerun the tests in the same -order. This assures repeatability of randomly ordered test runs. -This repeatability is independent of the operating system, processor or -platform used. +test ordering will be randomised. This additionally seeds the random number +generator used within the tests as described in the section above. If a randomly +ordered test fails, the seed value used will be reported. Setting the +`OPENSSL_TEST_RAND_ORDER` environment variable to this value will rerun the +tests in the same order and will also seed the test random number generator. +This assures repeatability of randomly ordered test runs. This repeatability is +independent of the operating system, processor or platform used. To randomise the test ordering: -- Gitee From 2f569c015e496ff0d686043070e03b87443ad6ef Mon Sep 17 00:00:00 2001 From: "Matthias St. Pierre" Date: Fri, 8 Sep 2023 12:31:09 +0200 Subject: [PATCH 54/79] doc: suggestions for OSSL_PROVIDER_load_ex design document Late review comments for pull request #21604, sort of. Reviewed-by: Dmitry Belyavskiy Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22029) Signed-off-by: fly2x --- doc/designs/prov_loadex.md | 41 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/doc/designs/prov_loadex.md b/doc/designs/prov_loadex.md index 818f5cce2d..f28f6d2f4d 100644 --- a/doc/designs/prov_loadex.md +++ b/doc/designs/prov_loadex.md @@ -1,12 +1,12 @@ Providers run-time configuration ================================ -Currently any provider run-time activation requires presence of the +Currently any provider run-time activation requires the presence of the initialization parameters in the OpenSSL configuration file. Otherwise the -provider will be activated with some "default" settings, that may or may not +provider will be activated with some default settings, that may or may not work for a particular application. For real-world systems it may require -providing a specially designed OpenSSL config and passing it somehow (e.g. via -environment) that has its obvious drawbacks. +providing a specially designed OpenSSL configuration file and passing it somehow +(e.g. via environment), which has obvious drawbacks. We need a possibility to initialize providers on per-application level according to per-application parameters. It's necessary for example for PKCS#11 @@ -21,23 +21,23 @@ OSSL_PROVIDER *OSSL_PROVIDER_load_ex(OSSL_LIB_CTX *libctx, const char *name, OSSL_PARAM params[]); ``` -intended to configure the provider in load time. +intended to configure the provider at load time. It accepts only parameters of type `OSSL_PARAM_UTF8_STRING` because any provider can be initialized from the config file where the values are represented as strings and provider init function has to deal with it. -Explicitly configured parameters can contradict the parameters named in the +Explicitly configured parameters can differ from the parameters named in the configuration file. Here are the current design decisions and some possible future steps. Real-world cases ---------------- -Many applications use PKCS#11 API with a specific drivers. OpenSSL PKCS#11 +Many applications use PKCS#11 API with specific drivers. OpenSSL PKCS#11 provider also provides a set of -tweaks usable in particular situations. So there are at least several scenarios -I have in mind: +tweaks usable in particular situations. So there are several scenarios for which +the new API can be used: 1. Configure a provider in the config file, activate on demand 2. Load/activate a provider run-time with parameters @@ -45,26 +45,25 @@ I have in mind: Current design -------------- -When the provider is loaded in the current library context and activated, the -currently loaded provider will be returned as the result of -`OSSL_PROVIDER_load_ex` call. +When the provider is already loaded an activated in the current library context, +the `OSSL_PROVIDER_load_ex` call simply returns the active provider and the +extra parameters are ignored. -When the provider is loaded in the current library context and NOT activated, -the parameters provided int the `OSSL_PROVIDER_load_ex` call will have the -preference. +In all other cases, the extra parameters provided by the `OSSL_PROVIDER_load_ex` +call are applied and the values from the config file are ignored. Separate instances of the provider can be loaded in the separate library contexts. -Several instances of the same provider in the same context using different -section names, module names (e.g. via symlinks) and provider names. But unless -the provider does not support some configuration options, the algorithms in +Several instances of the same provider can be loaded in the same context using +different section names, module names (e.g. via symlinks) and provider names. +But unless the provider supports some configuration options, the algorithms in this case will have the same `provider` property and the result of fetching is not determined. We strongly discourage against this trick. -The run-time change of the loaded provider configuration is not supported. If -it is necessary, the calls to `OSSL_PROVIDER_unload` with the following call to -the `OSSL_PROVIDER_load` or `OSSL_PROVIDER_load_ex` should be used. +Changing the loaded provider configuration at runtime is not supported. If +it is necessary, the provider needs to be unloaded using `OSSL_PROVIDER_unload` +and reloaded using `OSSL_PROVIDER_load` or `OSSL_PROVIDER_load_ex` should be used. Possible future steps --------------------- -- Gitee From 5929e2549b2876391ade00a72d2f1a86adfe0e25 Mon Sep 17 00:00:00 2001 From: "Matthias St. Pierre" Date: Fri, 8 Sep 2023 12:35:57 +0200 Subject: [PATCH 55/79] doc: change name of OSSL_PROVIDER_load_ex design document Use dashes instead of underscores, to be more consistent with existing document names. And speaking of consistency, introduce a consistent name transformation, which will scale better when design documents start filling the folder ;-) OSSL_PROVIDER_load_ex -> ossl-provider-load-ex.md Reviewed-by: Dmitry Belyavskiy Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22029) Signed-off-by: fly2x --- doc/designs/{prov_loadex.md => ossl-provider-load-ex.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename doc/designs/{prov_loadex.md => ossl-provider-load-ex.md} (95%) diff --git a/doc/designs/prov_loadex.md b/doc/designs/ossl-provider-load-ex.md similarity index 95% rename from doc/designs/prov_loadex.md rename to doc/designs/ossl-provider-load-ex.md index f28f6d2f4d..62d5c8c327 100644 --- a/doc/designs/prov_loadex.md +++ b/doc/designs/ossl-provider-load-ex.md @@ -1,5 +1,5 @@ -Providers run-time configuration -================================ +OSSL_PROVIDER_load_ex - activating providers with run-time configuration +======================================================================== Currently any provider run-time activation requires the presence of the initialization parameters in the OpenSSL configuration file. Otherwise the -- Gitee From 353f638a2e89a9cd157afb60254e8b68ba0786a6 Mon Sep 17 00:00:00 2001 From: "Dr. David von Oheimb" Date: Thu, 6 May 2021 18:49:54 +0200 Subject: [PATCH 56/79] cmp_vfy.c: Use verification callback if cert_acceptable() finds expired cert Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/21656) Signed-off-by: fly2x --- crypto/cmp/cmp_vfy.c | 33 ++++++++++++++++++++++-------- doc/man3/OSSL_CMP_validate_msg.pod | 8 +++++--- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/crypto/cmp/cmp_vfy.c b/crypto/cmp/cmp_vfy.c index 2d7b2388ce..1869fae696 100644 --- a/crypto/cmp/cmp_vfy.c +++ b/crypto/cmp/cmp_vfy.c @@ -139,6 +139,24 @@ int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx, return valid; } +static int verify_cb_cert(X509_STORE *ts, X509 *cert, int err) +{ + X509_STORE_CTX_verify_cb verify_cb; + X509_STORE_CTX *csc; + int ok = 0; + + if (ts == NULL || (verify_cb = X509_STORE_get_verify_cb(ts)) == NULL) + return ok; + if ((csc = X509_STORE_CTX_new()) != NULL + && X509_STORE_CTX_init(csc, ts, cert, NULL)) { + X509_STORE_CTX_set_error(csc, err); + X509_STORE_CTX_set_current_cert(csc, cert); + ok = (*verify_cb)(0, csc); + } + X509_STORE_CTX_free(csc); + return ok; +} + /* Return 0 if expect_name != NULL and there is no matching actual_name */ static int check_name(const OSSL_CMP_CTX *ctx, int log_success, const char *actual_desc, const X509_NAME *actual_name, @@ -256,9 +274,14 @@ static int cert_acceptable(const OSSL_CMP_CTX *ctx, time_cmp = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert), X509_get0_notAfter(cert)); if (time_cmp != 0) { + int err = time_cmp > 0 ? X509_V_ERR_CERT_HAS_EXPIRED + : X509_V_ERR_CERT_NOT_YET_VALID; + ossl_cmp_warn(ctx, time_cmp > 0 ? "cert has expired" : "cert is not yet valid"); - return 0; + if (ctx->log_cb != NULL /* logging not temporarily disabled */ + && verify_cb_cert(ts, cert, err) <= 0) + return 0; } if (!check_name(ctx, 1, @@ -432,12 +455,6 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, return ret; } -static int no_log_cb(const char *func, const char *file, int line, - OSSL_CMP_severity level, const char *msg) -{ - return 1; -} - /*- * Verify message signature with any acceptable and valid candidate cert. * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert(). @@ -465,7 +482,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) /* enable clearing irrelevant errors in attempts to validate sender certs */ (void)ERR_set_mark(); - ctx->log_cb = no_log_cb; /* temporarily disable logging */ + ctx->log_cb = NULL; /* temporarily disable logging */ /* * try first cached scrt, used successfully earlier in same transaction, diff --git a/doc/man3/OSSL_CMP_validate_msg.pod b/doc/man3/OSSL_CMP_validate_msg.pod index 9fe7f4385f..7dbe3f74ca 100644 --- a/doc/man3/OSSL_CMP_validate_msg.pod +++ b/doc/man3/OSSL_CMP_validate_msg.pod @@ -30,10 +30,12 @@ is preferably the one provided by a call to L. If no such sender cert has been pinned then candidate sender certificates are taken from the list of certificates received in the I extraCerts, then any certificates provided before via L, and -then all trusted certificates provided via L, -where a candidate is acceptable only if has not expired, its subject DN matches +then all trusted certificates provided via L. +A candidate certificate is acceptable only if it is currently valid +(or the trust store contains a verification callback that overrides the verdict +that the certificate is expired or not yet valid), its subject DN matches the I sender DN (as far as present), and its subject key identifier -is present and matches the senderKID (as far as the latter present). +is present and matches the senderKID (as far as the latter is present). Each acceptable cert is tried in the given order to see if the message signature check succeeds and the cert and its path can be verified using any trust store set via L. -- Gitee From 6a8a8efdcbe0eee683a740aeb83a0637a7ac9064 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 11 Sep 2023 06:38:31 +0200 Subject: [PATCH 57/79] Fix some memory leaks in the openssl app In some error cases the normal cleanup did not happen, but instead an exit(1) which caused some memory leaks, as reported in #22049. Reviewed-by: Tom Cosgrove Reviewed-by: Nicola Tuveri (Merged from https://github.com/openssl/openssl/pull/22055) Signed-off-by: fly2x --- apps/dgst.c | 2 ++ apps/dhparam.c | 2 ++ apps/dsaparam.c | 2 ++ apps/gendsa.c | 2 ++ apps/genpkey.c | 2 ++ apps/genrsa.c | 2 ++ apps/lib/apps.c | 8 ++++---- apps/req.c | 2 ++ 8 files changed, 18 insertions(+), 4 deletions(-) diff --git a/apps/dgst.c b/apps/dgst.c index fe05b312d7..28123f813f 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -321,6 +321,8 @@ int dgst_main(int argc, char **argv) sigkey = app_keygen(mac_ctx, mac_name, 0, 0 /* not verbose */); /* Verbose output would make external-tests gost-engine fail */ EVP_PKEY_CTX_free(mac_ctx); + if (sigkey == NULL) + goto end; } if (hmac_key != NULL) { diff --git a/apps/dhparam.c b/apps/dhparam.c index a41e70fe38..d14c569503 100644 --- a/apps/dhparam.c +++ b/apps/dhparam.c @@ -233,6 +233,8 @@ int dhparam_main(int argc, char **argv) } tmppkey = app_paramgen(ctx, alg); + if (tmppkey == NULL) + goto end; EVP_PKEY_CTX_free(ctx); ctx = NULL; if (dsaparam) { diff --git a/apps/dsaparam.c b/apps/dsaparam.c index 4eb157042e..8bd2e1361b 100644 --- a/apps/dsaparam.c +++ b/apps/dsaparam.c @@ -232,6 +232,8 @@ int dsaparam_main(int argc, char **argv) goto end; } pkey = app_keygen(ctx, "DSA", numbits, verbose); + if (pkey == NULL) + goto end; assert(private); if (outformat == FORMAT_ASN1) i = i2d_PrivateKey_bio(out, pkey); diff --git a/apps/gendsa.c b/apps/gendsa.c index bd8aecedbd..b6d1d0f5b3 100644 --- a/apps/gendsa.c +++ b/apps/gendsa.c @@ -148,6 +148,8 @@ int gendsa_main(int argc, char **argv) goto end; } pkey = app_keygen(ctx, "DSA", nbits, verbose); + if (pkey == NULL) + goto end; assert(private); if (!PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, passout)) { diff --git a/apps/genpkey.c b/apps/genpkey.c index 5a59dae681..080f1f6075 100644 --- a/apps/genpkey.c +++ b/apps/genpkey.c @@ -234,6 +234,8 @@ int genpkey_main(int argc, char **argv) pkey = do_param ? app_paramgen(ctx, algname) : app_keygen(ctx, algname, 0, 0 /* not verbose */); + if (pkey == NULL) + goto end; if (do_param) { rv = PEM_write_bio_Parameters(out, pkey); diff --git a/apps/genrsa.c b/apps/genrsa.c index 3151de646b..f71bc6eeb1 100644 --- a/apps/genrsa.c +++ b/apps/genrsa.c @@ -204,6 +204,8 @@ opthelp: goto end; } pkey = app_keygen(ctx, "RSA", num, verbose); + if (pkey == NULL) + goto end; if (verbose) { BIGNUM *e = NULL; diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 8aad9a1ef7..6b2a4b86ce 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -3417,8 +3417,8 @@ EVP_PKEY *app_keygen(EVP_PKEY_CTX *ctx, const char *alg, int bits, int verbose) BIO_printf(bio_err, "Warning: generating random key material may take a long time\n" "if the system has a poor entropy source\n"); if (EVP_PKEY_keygen(ctx, &res) <= 0) - app_bail_out("%s: Error generating %s key\n", opt_getprog(), - alg != NULL ? alg : "asymmetric"); + BIO_printf(bio_err, "%s: Error generating %s key\n", opt_getprog(), + alg != NULL ? alg : "asymmetric"); return res; } @@ -3430,8 +3430,8 @@ EVP_PKEY *app_paramgen(EVP_PKEY_CTX *ctx, const char *alg) BIO_printf(bio_err, "Warning: generating random key parameters may take a long time\n" "if the system has a poor entropy source\n"); if (EVP_PKEY_paramgen(ctx, &res) <= 0) - app_bail_out("%s: Generating %s key parameters failed\n", - opt_getprog(), alg != NULL ? alg : "asymmetric"); + BIO_printf(bio_err, "%s: Generating %s key parameters failed\n", + opt_getprog(), alg != NULL ? alg : "asymmetric"); return res; } diff --git a/apps/req.c b/apps/req.c index c4c9ba292c..3ce2b38496 100644 --- a/apps/req.c +++ b/apps/req.c @@ -663,6 +663,8 @@ int req_main(int argc, char **argv) EVP_PKEY_CTX_set_cb(genctx, progress_cb); pkey = app_keygen(genctx, keyalgstr, newkey_len, verbose); + if (pkey == NULL) + goto end; EVP_PKEY_CTX_free(genctx); genctx = NULL; -- Gitee From 54bc3450dc5b1760894ec21ae08a890be90bd270 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Tue, 19 Sep 2023 20:15:18 +0200 Subject: [PATCH 58/79] Fix error handling in CRYPTO_get_ex_new_index If an out of memory error happens when the index zero is reserved in a newly created ip->meth stack object, that reservation is not done in a second attempt, which makes various X_set_ex_data overwrite the value of X_set_app_data. Reviewed-by: Paul Dale Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22149) Signed-off-by: fly2x --- crypto/ex_data.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crypto/ex_data.c b/crypto/ex_data.c index c9ec9d3337..0412f38e9b 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -171,6 +171,8 @@ int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index, * "app_data" routines use ex_data index zero. See RT 3710. */ if (ip->meth == NULL || !sk_EX_CALLBACK_push(ip->meth, NULL)) { + sk_EX_CALLBACK_free(ip->meth); + ip->meth = NULL; ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); goto err; } -- Gitee From 5918691cc833710898dd7f41c61c761c77c07684 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Wed, 20 Sep 2023 15:45:56 +0200 Subject: [PATCH 59/79] Fix error handling in lhash contract When the realloc fails in contract, this not a fatal error, since the memory is only shrinked. It is also no option to exit the function at this point, since that would leave the hash table in an inconsistent state. Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22154) Signed-off-by: fly2x --- crypto/lhash/lhash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c index 526af83026..9d2b284ae0 100644 --- a/crypto/lhash/lhash.c +++ b/crypto/lhash/lhash.c @@ -260,12 +260,12 @@ static void contract(OPENSSL_LHASH *lh) if (n == NULL) { /* fputs("realloc error in lhash", stderr); */ lh->error++; - return; + } else { + lh->b = n; } lh->num_alloc_nodes /= 2; lh->pmax /= 2; lh->p = lh->pmax - 1; - lh->b = n; } else lh->p--; -- Gitee From 67e128f9c1af4861d645590a252135292dc4ab43 Mon Sep 17 00:00:00 2001 From: Steffen Klee Date: Wed, 20 Sep 2023 00:04:18 +0200 Subject: [PATCH 60/79] Fix test_cms if DSA is not supported CLA: trivial Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22150) Signed-off-by: fly2x --- test/recipes/80-test_cms.t | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t index 21c683c404..3857916105 100644 --- a/test/recipes/80-test_cms.t +++ b/test/recipes/80-test_cms.t @@ -1144,9 +1144,13 @@ with({ exit_checker => sub { return shift == 6; } }, # Test case for return value mis-check reported in #21986 with({ exit_checker => sub { return shift == 3; } }, sub { - ok(run(app(['openssl', 'cms', '-sign', - '-in', srctop_file("test", "smcont.txt"), - '-signer', srctop_file("test/smime-certs", "smdsa1.pem"), - '-md', 'SHAKE256'])), - "issue#21986"); + SKIP: { + skip "DSA is not supported in this build", 1 if $no_dsa; + + ok(run(app(['openssl', 'cms', '-sign', + '-in', srctop_file("test", "smcont.txt"), + '-signer', srctop_file("test/smime-certs", "smdsa1.pem"), + '-md', 'SHAKE256'])), + "issue#21986"); + } }); -- Gitee From a7a02cd6500bc57273c62bae1fbacd7785b7cddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 12 Sep 2023 15:24:21 +0200 Subject: [PATCH 61/79] Add command line option for setting provider in evp_test Reviewed-by: Richard Levitte Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/22151) Signed-off-by: fly2x --- test/evp_test.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/evp_test.c b/test/evp_test.c index ff424eac72..f998c21426 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -73,10 +73,12 @@ typedef enum OPTION_choice { OPT_EOF = 0, OPT_CONFIG_FILE, OPT_IN_PLACE, + OPT_PROVIDER_NAME, OPT_TEST_ENUM } OPTION_CHOICE; static OSSL_PROVIDER *prov_null = NULL; +static OSSL_PROVIDER *libprov = NULL; static OSSL_LIB_CTX *libctx = NULL; /* List of public and private keys */ @@ -4117,6 +4119,8 @@ const OPTIONS *test_get_options(void) "The configuration file to use for the libctx" }, { "process", OPT_IN_PLACE, 's', "Mode for data processing by cipher tests [in_place/both], both by default"}, + { "provider", OPT_PROVIDER_NAME, 's', + "The provider to load (when no configuration file, the default value is 'default')" }, { OPT_HELP_STR, 1, '-', "file\tFile to run tests on.\n" }, { NULL } }; @@ -4127,6 +4131,7 @@ int setup_tests(void) { size_t n; char *config_file = NULL; + char *provider_name = NULL; OPTION_CHOICE o; @@ -4139,6 +4144,9 @@ int setup_tests(void) if ((process_mode_in_place = evp_test_process_mode(opt_arg())) == -1) return 0; break; + case OPT_PROVIDER_NAME: + provider_name = opt_arg(); + break; case OPT_TEST_CASES: break; default: @@ -4152,7 +4160,9 @@ int setup_tests(void) * Load the 'null' provider into the default library context to ensure that * the tests do not fallback to using the default provider. */ - if (!test_get_libctx(&libctx, &prov_null, config_file, NULL, NULL)) + if (config_file == NULL && provider_name == NULL) + provider_name = "default"; + if (!test_get_libctx(&libctx, &prov_null, config_file, &libprov, provider_name)) return 0; n = test_get_argument_count(); @@ -4165,6 +4175,7 @@ int setup_tests(void) void cleanup_tests(void) { + OSSL_PROVIDER_unload(libprov); OSSL_PROVIDER_unload(prov_null); OSSL_LIB_CTX_free(libctx); } -- Gitee From b28e4024f73497d1df5ec8cd10924603a466fb0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 8 Sep 2023 11:44:27 +0200 Subject: [PATCH 62/79] Add command line option for setting propquery in evp_test Reviewed-by: Richard Levitte Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/22151) Signed-off-by: fly2x --- test/evp_test.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/test/evp_test.c b/test/evp_test.c index f998c21426..309ab94c21 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -74,6 +74,7 @@ typedef enum OPTION_choice { OPT_CONFIG_FILE, OPT_IN_PLACE, OPT_PROVIDER_NAME, + OPT_PROV_PROPQUERY, OPT_TEST_ENUM } OPTION_CHOICE; @@ -116,6 +117,7 @@ static int memory_err_compare(EVP_TEST *t, const char *err, /* Option specific for evp test */ static int process_mode_in_place; +static const char *propquery = NULL; static int evp_test_process_mode(char *mode) { @@ -367,7 +369,7 @@ static int digest_test_init(EVP_TEST *t, const char *alg) return 1; } - if ((digest = fetched_digest = EVP_MD_fetch(libctx, alg, NULL)) == NULL + if ((digest = fetched_digest = EVP_MD_fetch(libctx, alg, propquery)) == NULL && (digest = EVP_get_digestbyname(alg)) == NULL) return 0; if (!TEST_ptr(mdat = OPENSSL_zalloc(sizeof(*mdat)))) @@ -596,7 +598,7 @@ static int cipher_test_init(EVP_TEST *t, const char *alg) } ERR_set_mark(); - if ((cipher = fetched_cipher = EVP_CIPHER_fetch(libctx, alg, NULL)) == NULL + if ((cipher = fetched_cipher = EVP_CIPHER_fetch(libctx, alg, propquery)) == NULL && (cipher = EVP_get_cipherbyname(alg)) == NULL) { /* a stitched cipher might not be available */ if (strstr(alg, "HMAC") != NULL) { @@ -1244,7 +1246,7 @@ static int mac_test_init(EVP_TEST *t, const char *alg) t->skip = 1; return 1; } - if ((mac = EVP_MAC_fetch(libctx, alg, NULL)) == NULL) { + if ((mac = EVP_MAC_fetch(libctx, alg, propquery)) == NULL) { /* * Since we didn't find an EVP_MAC, we check for known EVP_PKEY methods * For debugging purposes, we allow 'NNNN by EVP_PKEY' to force running @@ -1421,7 +1423,7 @@ static int mac_test_run_pkey(EVP_TEST *t) t->err = NULL; goto err; } - if (!TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, expected->alg, NULL))) { + if (!TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, expected->alg, propquery))) { t->err = "MAC_KEY_CREATE_ERROR"; goto err; } @@ -1794,7 +1796,7 @@ static int pkey_test_init(EVP_TEST *t, const char *name, return 0; } kdata->keyop = keyop; - if (!TEST_ptr(kdata->ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL))) { + if (!TEST_ptr(kdata->ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propquery))) { EVP_PKEY_free(pkey); OPENSSL_free(kdata); return 0; @@ -2293,7 +2295,7 @@ static int pbe_test_run(EVP_TEST *t) #endif } else if (expected->pbe_type == PBE_TYPE_PKCS12) { fetched_digest = EVP_MD_fetch(libctx, EVP_MD_get0_name(expected->md), - NULL); + propquery); if (fetched_digest == NULL) { t->err = "PKCS12_ERROR"; goto err; @@ -2533,7 +2535,7 @@ static int rand_test_init(EVP_TEST *t, const char *name) if (!EVP_RAND_CTX_set_params(rdata->parent, params)) goto err; - rand = EVP_RAND_fetch(libctx, name, NULL); + rand = EVP_RAND_fetch(libctx, name, propquery); if (rand == NULL) goto err; rdata->ctx = EVP_RAND_CTX_new(rand, rdata->parent); @@ -2785,7 +2787,7 @@ static int kdf_test_init(EVP_TEST *t, const char *name) kdata->p = kdata->params; *kdata->p = OSSL_PARAM_construct_end(); - kdf = EVP_KDF_fetch(libctx, name, NULL); + kdf = EVP_KDF_fetch(libctx, name, propquery); if (kdf == NULL) { OPENSSL_free(kdata); return 0; @@ -2994,7 +2996,7 @@ static int pkey_kdf_test_init(EVP_TEST *t, const char *name) if (!TEST_ptr(kdata = OPENSSL_zalloc(sizeof(*kdata)))) return 0; - kdata->ctx = EVP_PKEY_CTX_new_from_name(libctx, name, NULL); + kdata->ctx = EVP_PKEY_CTX_new_from_name(libctx, name, propquery); if (kdata->ctx == NULL || EVP_PKEY_derive_init(kdata->ctx) <= 0) goto err; @@ -3222,7 +3224,7 @@ static int keygen_test_init(EVP_TEST *t, const char *alg) t->skip = 1; return 1; } - if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, alg, NULL))) + if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, alg, propquery))) goto err; if (EVP_PKEY_keygen_init(genctx) <= 0) { @@ -4121,6 +4123,8 @@ const OPTIONS *test_get_options(void) "Mode for data processing by cipher tests [in_place/both], both by default"}, { "provider", OPT_PROVIDER_NAME, 's', "The provider to load (when no configuration file, the default value is 'default')" }, + { "propquery", OPT_PROV_PROPQUERY, 's', + "Property query used when fetching algorithms" }, { OPT_HELP_STR, 1, '-', "file\tFile to run tests on.\n" }, { NULL } }; @@ -4147,6 +4151,9 @@ int setup_tests(void) case OPT_PROVIDER_NAME: provider_name = opt_arg(); break; + case OPT_PROV_PROPQUERY: + propquery = opt_arg(); + break; case OPT_TEST_CASES: break; default: -- Gitee From 341845262dca02b45f4e7c493a0a69c7b6a09b5a Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 14 Sep 2023 10:59:47 +0100 Subject: [PATCH 63/79] Create a noisy dgram test Create a noisy dgram test that can drop/duplicate/reorder UDP packets and ensure that the QUIC connection is tolerant of this. At this stage we just create the outline of the test. Adding in the noise will come in future commits. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/build.info | 8 +-- test/helpers/noisydgrambio.c | 130 +++++++++++++++++++++++++++++++++++ test/helpers/quictestlib.c | 8 +++ test/helpers/quictestlib.h | 12 +++- test/quicapitest.c | 31 +++++++++ 5 files changed, 183 insertions(+), 6 deletions(-) create mode 100644 test/helpers/noisydgrambio.c diff --git a/test/build.info b/test/build.info index d897f726a8..4736e28c8b 100644 --- a/test/build.info +++ b/test/build.info @@ -339,7 +339,7 @@ IF[{- !$disabled{tests} -}] INCLUDE[quic_client_test]=../include ../apps/include DEPEND[quic_client_test]=../libcrypto.a ../libssl.a libtestutil.a - SOURCE[quic_multistream_test]=quic_multistream_test.c helpers/ssltestlib.c helpers/quictestlib.c + SOURCE[quic_multistream_test]=quic_multistream_test.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c INCLUDE[quic_multistream_test]=../include ../apps/include DEPEND[quic_multistream_test]=../libcrypto.a ../libssl.a libtestutil.a @@ -818,15 +818,15 @@ IF[{- !$disabled{tests} -}] INCLUDE[event_queue_test]=../include ../apps/include DEPEND[event_queue_test]=../libcrypto ../libssl.a libtestutil.a - SOURCE[quicfaultstest]=quicfaultstest.c helpers/ssltestlib.c helpers/quictestlib.c + SOURCE[quicfaultstest]=quicfaultstest.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c INCLUDE[quicfaultstest]=../include ../apps/include .. DEPEND[quicfaultstest]=../libcrypto.a ../libssl.a libtestutil.a - SOURCE[quicapitest]=quicapitest.c helpers/ssltestlib.c helpers/quictestlib.c + SOURCE[quicapitest]=quicapitest.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c INCLUDE[quicapitest]=../include ../apps/include DEPEND[quicapitest]=../libcrypto.a ../libssl.a libtestutil.a - SOURCE[quic_newcid_test]=quic_newcid_test.c helpers/ssltestlib.c helpers/quictestlib.c + SOURCE[quic_newcid_test]=quic_newcid_test.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c INCLUDE[quic_newcid_test]=../include ../apps/include .. DEPEND[quic_newcid_test]=../libcrypto.a ../libssl.a libtestutil.a ENDIF diff --git a/test/helpers/noisydgrambio.c b/test/helpers/noisydgrambio.c new file mode 100644 index 0000000000..890ff7904c --- /dev/null +++ b/test/helpers/noisydgrambio.c @@ -0,0 +1,130 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "quictestlib.h" + +static int noisy_dgram_read(BIO *bio, char *out, int outl) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static int noisy_dgram_write(BIO *bio, const char *in, int inl) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static long noisy_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + long ret; + BIO *next = BIO_next(bio); + + if (next == NULL) + return 0; + + switch (cmd) { + case BIO_CTRL_DUP: + ret = 0L; + break; + default: + ret = BIO_ctrl(next, cmd, num, ptr); + break; + } + return ret; +} + +static int noisy_dgram_gets(BIO *bio, char *buf, int size) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static int noisy_dgram_puts(BIO *bio, const char *str) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static int noisy_dgram_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ + BIO *next = BIO_next(bio); + + if (next == NULL) + return 0; + + /* + * We only introduce noise when receiving messages. We just pass this on + * to the underlying BIO. + */ + return BIO_sendmmsg(next, msg, stride, num_msg, flags, msgs_processed); +} + +static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ + BIO *next = BIO_next(bio); + + if (next == NULL) + return 0; + + /* + * We will introduce noise here. None implemented yet. + */ + return BIO_recvmmsg(next, msg, stride, num_msg, flags, msgs_processed); +} + +static int noisy_dgram_new(BIO *bio) +{ + BIO_set_init(bio, 1); + + return 1; +} + +static int noisy_dgram_free(BIO *bio) +{ + BIO_set_init(bio, 0); + + return 1; +} + +/* Choose a sufficiently large type likely to be unused for this custom BIO */ +#define BIO_TYPE_NOISY_DGRAM_FILTER (0x80 | BIO_TYPE_FILTER) + +static BIO_METHOD *method_noisy_dgram = NULL; + +/* Note: Not thread safe! */ +const BIO_METHOD *bio_f_noisy_dgram_filter(void) +{ + if (method_noisy_dgram == NULL) { + method_noisy_dgram = BIO_meth_new(BIO_TYPE_NOISY_DGRAM_FILTER, + "Nosiy datagram filter"); + if (method_noisy_dgram == NULL + || !BIO_meth_set_write(method_noisy_dgram, noisy_dgram_write) + || !BIO_meth_set_read(method_noisy_dgram, noisy_dgram_read) + || !BIO_meth_set_puts(method_noisy_dgram, noisy_dgram_puts) + || !BIO_meth_set_gets(method_noisy_dgram, noisy_dgram_gets) + || !BIO_meth_set_ctrl(method_noisy_dgram, noisy_dgram_ctrl) + || !BIO_meth_set_sendmmsg(method_noisy_dgram, noisy_dgram_sendmmsg) + || !BIO_meth_set_recvmmsg(method_noisy_dgram, noisy_dgram_recvmmsg) + || !BIO_meth_set_create(method_noisy_dgram, noisy_dgram_new) + || !BIO_meth_set_destroy(method_noisy_dgram, noisy_dgram_free)) + return NULL; + } + return method_noisy_dgram; +} + +void bio_f_noisy_dgram_filter_free(void) +{ + BIO_meth_free(method_noisy_dgram); +} diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index f0955559dc..bc135eec95 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -140,6 +140,14 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, goto err; } + if ((flags & QTEST_FLAG_NOISE) != 0) { + BIO *noisebio = BIO_new(bio_f_noisy_dgram_filter()); + + if (!TEST_ptr(noisebio)) + goto err; + cbio = BIO_push(noisebio, cbio); + } + SSL_set_bio(*cssl, cbio, cbio); if (!TEST_true(SSL_set_blocking_mode(*cssl, diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h index 45f6ebec79..7a72e352d9 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -27,9 +27,11 @@ typedef struct qtest_fault_encrypted_extensions { /* Flags for use with qtest_create_quic_objects() */ /* Indicates whether we are using blocking mode or not */ -#define QTEST_FLAG_BLOCK 1 +#define QTEST_FLAG_BLOCK (1 << 0) /* Use fake time rather than real time */ -#define QTEST_FLAG_FAKE_TIME 2 +#define QTEST_FLAG_FAKE_TIME (1 << 1) +/* Introduce noise in the BIO */ +#define QTEST_FLAG_NOISE (1 << 2) /* * Given an SSL_CTX for the client and filenames for the server certificate and @@ -230,3 +232,9 @@ int qtest_fault_set_datagram_listener(QTEST_FAULT *fault, * exceeds the over allocation. */ int qtest_fault_resize_datagram(QTEST_FAULT *fault, size_t newlen); + +/* BIO filter for simulating a noisy UDP socket */ +const BIO_METHOD *bio_f_noisy_dgram_filter(void); + +/* Free the BIO filter method object */ +void bio_f_noisy_dgram_filter_free(void); \ No newline at end of file diff --git a/test/quicapitest.c b/test/quicapitest.c index c471495aa2..ed11b73ba2 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -1250,6 +1250,34 @@ static int test_alpn(int idx) return testresult; } +static int test_noisy_dgram(void) +{ + SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); + SSL *clientquic = NULL; + QUIC_TSERVER *qtserv = NULL; + int testresult = 0; + + if (!TEST_ptr(cctx) + || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, + privkey, + QTEST_FLAG_NOISE, + &qtserv, + &clientquic, NULL))) + goto err; + + if (!TEST_true(qtest_create_quic_connection(qtserv, clientquic))) + goto err; + + testresult = 1; + err: + ossl_quic_tserver_free(qtserv); + SSL_free(clientquic); + SSL_CTX_free(cctx); + + return testresult; +} + + OPT_TEST_DECLARE_USAGE("provider config certsdir datadir\n") int setup_tests(void) @@ -1323,6 +1351,8 @@ int setup_tests(void) ADD_ALL_TESTS(test_non_io_retry, 2); ADD_TEST(test_quic_psk); ADD_ALL_TESTS(test_alpn, 2); + ADD_TEST(test_noisy_dgram); + return 1; err: cleanup_tests(); @@ -1331,6 +1361,7 @@ int setup_tests(void) void cleanup_tests(void) { + bio_f_noisy_dgram_filter_free(); OPENSSL_free(cert); OPENSSL_free(privkey); OSSL_PROVIDER_unload(defctxnull); -- Gitee From cc981700ae894ebad7c8320c3f84a03f37413d2a Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 14 Sep 2023 12:24:12 +0100 Subject: [PATCH 64/79] Add the ability to drop datagrams in the noisy dgram BIO Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/helpers/noisydgrambio.c | 126 ++++++++++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 3 deletions(-) diff --git a/test/helpers/noisydgrambio.c b/test/helpers/noisydgrambio.c index 890ff7904c..f55be83616 100644 --- a/test/helpers/noisydgrambio.c +++ b/test/helpers/noisydgrambio.c @@ -9,6 +9,11 @@ #include #include "quictestlib.h" +#include "../testutil.h" + +struct noisy_dgram_st { + size_t this_dgram; +}; static int noisy_dgram_read(BIO *bio, char *out, int outl) { @@ -69,23 +74,136 @@ static int noisy_dgram_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, return BIO_sendmmsg(next, msg, stride, num_msg, flags, msgs_processed); } +static int should_drop(BIO *bio) +{ + struct noisy_dgram_st *data = BIO_get_data(bio); + + if (data == NULL) + return 0; + + /* + * Drop datagram 1 for now. + * TODO(QUIC): Provide more control over this behaviour. + */ + if (data->this_dgram == 1) + return 1; + + return 0; +} + +/* There isn't a public function to do BIO_ADDR_copy() so we create one */ +static int bio_addr_copy(BIO_ADDR *dst, BIO_ADDR *src) +{ + size_t len; + void *data = NULL; + int res = 0; + int family; + + if (src == NULL || dst == NULL) + return 0; + + family = BIO_ADDR_family(src); + if (family == AF_UNSPEC) { + BIO_ADDR_clear(dst); + return 1; + } + + if (!BIO_ADDR_rawaddress(src, NULL, &len)) + return 0; + + if (len > 0) { + data = OPENSSL_malloc(len); + if (!TEST_ptr(data)) + return 0; + } + + if (!BIO_ADDR_rawaddress(src, data, &len)) + goto err; + + if (!BIO_ADDR_rawmake(src, family, data, len, BIO_ADDR_rawport(src))) + goto err; + + res = 1; + err: + OPENSSL_free(data); + return res; +} + static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, size_t num_msg, uint64_t flags, size_t *msgs_processed) { BIO *next = BIO_next(bio); + size_t i, data_len = 0, drop_cnt = 0; + BIO_MSG *src, *dst; + struct noisy_dgram_st *data; - if (next == NULL) + if (!TEST_ptr(next)) + return 0; + + data = BIO_get_data(bio); + if (!TEST_ptr(data)) return 0; /* - * We will introduce noise here. None implemented yet. + * For simplicity we assume that all elements in the msg array have the + * same data_len. They are not required to by the API, but it would be quite + * strange for that not to be the case - and our code that calls + * BIO_recvmmsg does do this (which is all that is important for this test + * code). We test the invariant here. */ - return BIO_recvmmsg(next, msg, stride, num_msg, flags, msgs_processed); + for (i = 0; i < num_msg; i++) { + if (i == 0) + data_len = msg[i].data_len; + else if (!TEST_size_t_eq(msg[i].data_len, data_len)) + return 0; + } + + if (!BIO_recvmmsg(next, msg, stride, num_msg, flags, msgs_processed)) + return 0; + + /* Drop any messages */ + for (i = 0, src = msg, dst = msg; + i < *msgs_processed; + i++, src++, data->this_dgram++) { + if (should_drop(bio)) { + drop_cnt++; + continue; + } + + if (src != dst) { + /* Copy the src BIO_MSG to the dst BIO_MSG */ + memcpy(dst->data, src->data, src->data_len); + dst->data_len = src->data_len; + dst->flags = src->flags; + if (src->local != NULL + && !TEST_true(bio_addr_copy(dst->local, src->local))) + return 0; + if (!TEST_true(bio_addr_copy(dst->peer, src->peer))) + return 0; + } + + dst++; + } + + *msgs_processed -= drop_cnt; + + if (*msgs_processed == 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_NON_FATAL); + return 0; + } + + return 1; } static int noisy_dgram_new(BIO *bio) { + struct noisy_dgram_st *data = OPENSSL_zalloc(sizeof(*data)); + + if (!TEST_ptr(data)) + return 0; + + BIO_set_data(bio, data); BIO_set_init(bio, 1); return 1; @@ -93,6 +211,8 @@ static int noisy_dgram_new(BIO *bio) static int noisy_dgram_free(BIO *bio) { + OPENSSL_free(BIO_get_data(bio)); + BIO_set_data(bio, NULL); BIO_set_init(bio, 0); return 1; -- Gitee From e44faadbfe07d6a528ea063bbefac92e72926f3d Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 14 Sep 2023 16:34:41 +0100 Subject: [PATCH 65/79] Extend the nosiy datagram test to send more data We send several messages between client and server, and server and client, and also create a new stream. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/quicapitest.c | 116 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/test/quicapitest.c b/test/quicapitest.c index ed11b73ba2..19b59951f6 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -1250,12 +1250,67 @@ static int test_alpn(int idx) return testresult; } +#define MAX_LOOPS 40 + +/* + * Keep retrying SSL_read_ex until it succeeds or we give up. Accept a stream + * if we don't already have one + */ +static int unreliable_client_read(SSL *clientquic, SSL **stream, void *buf, + size_t buflen, size_t *readbytes, + QUIC_TSERVER *qtserv) +{ + int abortctr; + + /* We just do this in a loop with a sleep for simplicity */ + for (abortctr = 0; abortctr < MAX_LOOPS; abortctr++) { + if (*stream == NULL) { + SSL_handle_events(clientquic); + *stream = SSL_accept_stream(clientquic, 0); + } + + if (*stream != NULL) { + if (SSL_read_ex(*stream, buf, buflen, readbytes)) + return 1; + if (SSL_get_error(*stream, 0) != SSL_ERROR_WANT_READ) + return 0; + } + ossl_quic_tserver_tick(qtserv); + OSSL_sleep(10); + } + + return 0; +} + +/* Keep retrying ossl_quic_tserver_read until it succeeds or we give up */ +static int unreliable_server_read(QUIC_TSERVER *qtserv, uint64_t sid, + void *buf, size_t buflen, size_t *readbytes, + SSL *clientquic) +{ + int abortctr; + + /* We just do this in a loop with a sleep for simplicity */ + for (abortctr = 0; abortctr < MAX_LOOPS; abortctr++) { + if (ossl_quic_tserver_read(qtserv, sid, buf, buflen, readbytes)) + return 1; + ossl_quic_tserver_tick(qtserv); + SSL_handle_events(clientquic); + OSSL_sleep(10); + } + + return 0; +} + static int test_noisy_dgram(void) { SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); - SSL *clientquic = NULL; + SSL *clientquic = NULL, *stream[2] = { NULL, NULL }; QUIC_TSERVER *qtserv = NULL; int testresult = 0; + uint64_t sid = 0; + char *msg = "Hello world!"; + size_t msglen = strlen(msg), written, readbytes, i, j; + unsigned char buf[80]; if (!TEST_ptr(cctx) || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, @@ -1268,9 +1323,68 @@ static int test_noisy_dgram(void) if (!TEST_true(qtest_create_quic_connection(qtserv, clientquic))) goto err; + if (!TEST_true(SSL_set_incoming_stream_policy(clientquic, + SSL_INCOMING_STREAM_POLICY_ACCEPT, + 0)) + || !TEST_true(SSL_set_default_stream_mode(clientquic, + SSL_DEFAULT_STREAM_MODE_NONE))) + goto err; + + for (j = 0; j < 2; j++) { + if (!TEST_true(ossl_quic_tserver_stream_new(qtserv, 0, &sid))) + goto err; + ossl_quic_tserver_tick(qtserv); + + /* + * Send data from the server to the client. Some datagrams may get lost, + * dropped or re-ordered. We repeat 10 times to ensure we are sending + * enough datagrams for problems to be noticed. + */ + for (i = 0; i < 10; i++) { + if (!TEST_true(ossl_quic_tserver_write(qtserv, sid, + (unsigned char *)msg, msglen, + &written)) + || !TEST_size_t_eq(msglen, written)) + goto err; + ossl_quic_tserver_tick(qtserv); + + /* + * Since the underlying BIO is now noisy we may get failures that + * need to be retried - so we use unreliable_client_read() to handle + * that + */ + if (!TEST_true(unreliable_client_read(clientquic, &stream[j], buf, + sizeof(buf), &readbytes, + qtserv)) + || !TEST_mem_eq(msg, msglen, buf, readbytes)) + goto err; + } + + /* Send data from the client to the server */ + for (i = 0; i < 10; i++) { + if (!TEST_true(SSL_write_ex(stream[j], (unsigned char *)msg, + msglen, &written)) + || !TEST_size_t_eq(msglen, written)) + goto err; + + ossl_quic_tserver_tick(qtserv); + /* + * Since the underlying BIO is now noisy we may get failures that + * need to be retried - so we use unreliable_server_read() to handle + * that + */ + if (!TEST_true(unreliable_server_read(qtserv, sid, buf, sizeof(buf), + &readbytes, clientquic)) + || !TEST_mem_eq(msg, msglen, buf, readbytes)) + goto err; + } + } + testresult = 1; err: ossl_quic_tserver_free(qtserv); + SSL_free(stream[0]); + SSL_free(stream[1]); SSL_free(clientquic); SSL_CTX_free(cctx); -- Gitee From 35f5161e17e7512577d3034b22903e702f342204 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 15 Sep 2023 15:35:56 +0100 Subject: [PATCH 66/79] Use test_random() to introduce better noise into the noisy dgram BIO We drop some datagrams, and we delay some datagrams. We can also duplicate some datagrams. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/helpers/noisydgrambio.c | 162 +++++++++++++++++++++++++++-------- test/quicapitest.c | 2 +- 2 files changed, 128 insertions(+), 36 deletions(-) diff --git a/test/helpers/noisydgrambio.c b/test/helpers/noisydgrambio.c index f55be83616..c1eb141ee5 100644 --- a/test/helpers/noisydgrambio.c +++ b/test/helpers/noisydgrambio.c @@ -11,8 +11,12 @@ #include "quictestlib.h" #include "../testutil.h" +#define MSG_DATA_LEN_MAX 1472 + struct noisy_dgram_st { - size_t this_dgram; + uint64_t this_dgram; + BIO_MSG msg; + uint64_t delayed_dgram; }; static int noisy_dgram_read(BIO *bio, char *out, int outl) @@ -74,21 +78,31 @@ static int noisy_dgram_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, return BIO_sendmmsg(next, msg, stride, num_msg, flags, msgs_processed); } -static int should_drop(BIO *bio) +static void get_noise(uint64_t *delay, int *should_drop) { - struct noisy_dgram_st *data = BIO_get_data(bio); + uint32_t type; - if (data == NULL) - return 0; + /* 20% of all datagrams should be noisy */ + if (test_random() % 5 != 0) { + *delay = 0; + *should_drop = 0; + return; + } + + type = test_random() % 3; + + /* Of noisy datagrams, 33% drop only, 33% delay only, 33% drop and delay */ + + *should_drop = (type == 0 || type == 1); + + /* Where a delay occurs we delay by 1 - 4 datagrams */ + *delay = (type == 0) ? 0 : (uint64_t)((test_random() % 4) + 1); /* - * Drop datagram 1 for now. - * TODO(QUIC): Provide more control over this behaviour. + * No point in delaying by 1 datagram if we are also dropping, so we delay + * by an extra datagram in that case */ - if (data->this_dgram == 1) - return 1; - - return 0; + *delay += (uint64_t)(*should_drop); } /* There isn't a public function to do BIO_ADDR_copy() so we create one */ @@ -129,13 +143,36 @@ static int bio_addr_copy(BIO_ADDR *dst, BIO_ADDR *src) return res; } +static int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src) +{ + /* + * Note it is assumed that the originally allocated data sizes for dst and + * src are the same + */ + memcpy(dst->data, src->data, src->data_len); + dst->data_len = src->data_len; + dst->flags = src->flags; + if (dst->local != NULL) { + if (src->local != NULL) { + if (!TEST_true(bio_addr_copy(dst->local, src->local))) + return 0; + } else { + BIO_ADDR_clear(dst->local); + } + } + if (!TEST_true(bio_addr_copy(dst->peer, src->peer))) + return 0; + + return 1; +} + static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, size_t num_msg, uint64_t flags, size_t *msgs_processed) { BIO *next = BIO_next(bio); - size_t i, data_len = 0, drop_cnt = 0; - BIO_MSG *src, *dst; + size_t i, j, data_len = 0, msg_cnt = 0; + BIO_MSG *thismsg; struct noisy_dgram_st *data; if (!TEST_ptr(next)) @@ -153,42 +190,76 @@ static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, * code). We test the invariant here. */ for (i = 0; i < num_msg; i++) { - if (i == 0) + if (i == 0) { data_len = msg[i].data_len; - else if (!TEST_size_t_eq(msg[i].data_len, data_len)) + if (!TEST_size_t_le(data_len, MSG_DATA_LEN_MAX)) + return 0; + } else if (!TEST_size_t_eq(msg[i].data_len, data_len)) { return 0; + } } if (!BIO_recvmmsg(next, msg, stride, num_msg, flags, msgs_processed)) return 0; - /* Drop any messages */ - for (i = 0, src = msg, dst = msg; - i < *msgs_processed; - i++, src++, data->this_dgram++) { - if (should_drop(bio)) { - drop_cnt++; - continue; + msg_cnt = *msgs_processed; + + /* Introduce noise */ + for (i = 0, thismsg = msg; + i < msg_cnt; + i++, thismsg++, data->this_dgram++) { + uint64_t delay; + int should_drop; + + /* If we have a delayed message ready insert it now */ + if (data->delayed_dgram > 0 + && data->delayed_dgram == data->this_dgram) { + if (msg_cnt < num_msg) { + /* Make space for the inserted message */ + for (j = msg_cnt; j > i; j--) { + if (!bio_msg_copy(&msg[j], &msg[j - 1])) + return 0; + } + if (!bio_msg_copy(thismsg, &data->msg)) + return 0; + msg_cnt++; + data->delayed_dgram = 0; + continue; + } /* else we have no space for the insertion, so just drop it */ + data->delayed_dgram = 0; } - if (src != dst) { - /* Copy the src BIO_MSG to the dst BIO_MSG */ - memcpy(dst->data, src->data, src->data_len); - dst->data_len = src->data_len; - dst->flags = src->flags; - if (src->local != NULL - && !TEST_true(bio_addr_copy(dst->local, src->local))) - return 0; - if (!TEST_true(bio_addr_copy(dst->peer, src->peer))) + get_noise(&delay, &should_drop); + + /* We ignore delay if a message is already delayed */ + if (delay > 0 && data->delayed_dgram == 0) { + /* + * Note that a message may be delayed *and* dropped, or delayed + * and *not* dropped. + * Delayed and dropped means the message will not be sent now and + * will only be sent after the delay. + * Delayed and not dropped means the message will be sent now and + * a duplicate will also be sent after the delay. + */ + + if (!bio_msg_copy(&data->msg, thismsg)) return 0; + + data->delayed_dgram = data->this_dgram + delay; } - dst++; + if (should_drop) { + for (j = i + 1; j < msg_cnt; j++) { + if (!bio_msg_copy(&msg[j - 1], &msg[j])) + return 0; + } + msg_cnt--; + } } - *msgs_processed -= drop_cnt; + *msgs_processed = msg_cnt; - if (*msgs_processed == 0) { + if (msg_cnt == 0) { ERR_raise(ERR_LIB_BIO, BIO_R_NON_FATAL); return 0; } @@ -196,6 +267,17 @@ static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, return 1; } +static void data_free(struct noisy_dgram_st *data) +{ + if (data == NULL) + return; + + OPENSSL_free(data->msg.data); + BIO_ADDR_free(data->msg.peer); + BIO_ADDR_free(data->msg.local); + OPENSSL_free(data); +} + static int noisy_dgram_new(BIO *bio) { struct noisy_dgram_st *data = OPENSSL_zalloc(sizeof(*data)); @@ -203,6 +285,16 @@ static int noisy_dgram_new(BIO *bio) if (!TEST_ptr(data)) return 0; + data->msg.data = OPENSSL_malloc(MSG_DATA_LEN_MAX); + data->msg.peer = BIO_ADDR_new(); + data->msg.local = BIO_ADDR_new(); + if (data->msg.data == NULL + || data->msg.peer == NULL + || data->msg.local == NULL) { + data_free(data); + return 0; + } + BIO_set_data(bio, data); BIO_set_init(bio, 1); @@ -211,7 +303,7 @@ static int noisy_dgram_new(BIO *bio) static int noisy_dgram_free(BIO *bio) { - OPENSSL_free(BIO_get_data(bio)); + data_free(BIO_get_data(bio)); BIO_set_data(bio, NULL); BIO_set_init(bio, 0); diff --git a/test/quicapitest.c b/test/quicapitest.c index 19b59951f6..0030c31082 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -1250,7 +1250,7 @@ static int test_alpn(int idx) return testresult; } -#define MAX_LOOPS 40 +#define MAX_LOOPS 2000 /* * Keep retrying SSL_read_ex until it succeeds or we give up. Accept a stream -- Gitee From ec370d9a8ba61c433f900f3d41baa8ba25fa9b48 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 18 Sep 2023 11:41:42 +0100 Subject: [PATCH 67/79] Add some optional debug output to the noisy dgram BIO Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/helpers/noisydgrambio.c | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/helpers/noisydgrambio.c b/test/helpers/noisydgrambio.c index c1eb141ee5..b42dbe6f4b 100644 --- a/test/helpers/noisydgrambio.c +++ b/test/helpers/noisydgrambio.c @@ -202,6 +202,16 @@ static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, if (!BIO_recvmmsg(next, msg, stride, num_msg, flags, msgs_processed)) return 0; +#ifdef OSSL_NOISY_DGRAM_DEBUG + printf("Pre-filter datagram list:\n"); + for (i = 0; i < *msgs_processed; i++) { + printf("Pre-filter Datagram:\n"); + BIO_dump_fp(stdout, msg[i].data, msg[i].data_len); + printf("\n"); + } + printf("End of pre-filter datagram list\nApplying noise filters:\n"); +#endif + msg_cnt = *msgs_processed; /* Introduce noise */ @@ -224,6 +234,11 @@ static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, return 0; msg_cnt++; data->delayed_dgram = 0; +#ifdef OSSL_NOISY_DGRAM_DEBUG + printf("**Inserting a delayed datagram\n"); + BIO_dump_fp(stdout, thismsg->data, thismsg->data_len); + printf("\n"); +#endif continue; } /* else we have no space for the insertion, so just drop it */ data->delayed_dgram = 0; @@ -246,9 +261,21 @@ static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, return 0; data->delayed_dgram = data->this_dgram + delay; + +#ifdef OSSL_NOISY_DGRAM_DEBUG + printf("**Delaying a datagram for %u messages%s\n", + (unsigned int)delay, should_drop ? "" : "(duplicating)"); + BIO_dump_fp(stdout, thismsg->data, thismsg->data_len); + printf("\n"); +#endif } if (should_drop) { +#ifdef OSSL_NOISY_DGRAM_DEBUG + printf("**Dropping a datagram\n"); + BIO_dump_fp(stdout, thismsg->data, thismsg->data_len); + printf("\n"); +#endif for (j = i + 1; j < msg_cnt; j++) { if (!bio_msg_copy(&msg[j - 1], &msg[j])) return 0; @@ -257,6 +284,16 @@ static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, } } +#ifdef OSSL_NOISY_DGRAM_DEBUG + printf("End of noise filters\nPost-filter datagram list:\n"); + for (i = 0; i < msg_cnt; i++) { + printf("Post-filter Datagram:\n"); + BIO_dump_fp(stdout, msg[i].data, msg[i].data_len); + printf("\n"); + } + printf("End of post-filter datagram list\n"); +#endif + *msgs_processed = msg_cnt; if (msg_cnt == 0) { -- Gitee From 2e2973486248ac90104d243eaab85b10e5308d1e Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 18 Sep 2023 16:55:52 +0100 Subject: [PATCH 68/79] Add support for timeouts into quictestlib.c Now that we have a noisy datagram BIO we cannot rely on datagrams always reliably being delivered in the test framework. We need to start taking notice of timeouts and handling them appropriately. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/helpers/quictestlib.c | 55 +++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index bc135eec95..28791267ed 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -66,6 +66,7 @@ struct qtest_fault { static void packet_plain_finish(void *arg); static void handshake_finish(void *arg); +static int using_fake_time = 0; static OSSL_TIME fake_now; static OSSL_TIME fake_now_cb(void *arg) @@ -180,11 +181,14 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, goto err; tserver_args.ctx = serverctx; if ((flags & QTEST_FLAG_FAKE_TIME) != 0) { + using_fake_time = 1; fake_now = ossl_time_zero(); /* zero time can have a special meaning, bump it */ qtest_add_time(1); tserver_args.now_cb = fake_now_cb; (void)ossl_quic_conn_set_override_now_cb(*cssl, fake_now_cb, NULL); + } else { + using_fake_time = 0; } if (!TEST_ptr(*qtserv = ossl_quic_tserver_new(&tserver_args, certfile, @@ -262,6 +266,47 @@ static void run_server_thread(void) } #endif +static int wait_for_timeout(SSL *s, QUIC_TSERVER *qtserv) +{ + struct timeval tv; + OSSL_TIME ctimeout, stimeout, mintimeout, now; + int cinf; + + /* We don't need to wait in blocking mode */ + if (s == NULL || qtserv == NULL) + return 1; + + /* Don't wait if either BIO has data waiting */ + if (BIO_pending(SSL_get_rbio(s)) > 0 + || BIO_pending(ossl_quic_tserver_get0_rbio(qtserv)) > 0) + return 1; + + /* + * Neither endpoint has data waiting to be read. We assume data transmission + * is instantaneous due to using mem based BIOs, so there is no data "in + * flight" and no more data will be sent by either endpoint until some time + * based event has occurred. Therefore, wait for a timeout to occur. This + * might happen if we are using the noisy BIO and datagrams have been lost. + */ + if (!SSL_get_event_timeout(s, &tv, &cinf)) + return 0; + if (using_fake_time) + now = fake_now; + else + now = ossl_time_now(); + ctimeout = cinf ? ossl_time_infinite() : ossl_time_from_timeval(tv); + stimeout = ossl_time_subtract(ossl_quic_tserver_get_deadline(qtserv), now); + mintimeout = ossl_time_min(ctimeout, stimeout); + if (ossl_time_is_infinite(mintimeout)) + return 0; + if (using_fake_time) + fake_now = ossl_time_add(now, mintimeout); + else + OSSL_sleep(ossl_time2ms(mintimeout)); + + return 1; +} + int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl, int wanterr) { @@ -327,13 +372,6 @@ int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl, } } - /* - * We're cheating. We don't take any notice of SSL_get_tick_timeout() - * and tick every time around the loop anyway. This is inefficient. We - * can get away with it in test code because we control both ends of - * the communications and don't expect network delays. This shouldn't - * be done in a real application. - */ if (!clienterr && retc <= 0) SSL_handle_events(clientssl); @@ -352,6 +390,9 @@ int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl, TEST_info("No progress made"); goto err; } + + if (!wait_for_timeout(clientssl, qtserv)) + goto err; } while ((retc <= 0 && !clienterr) || (rets <= 0 && !servererr #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) -- Gitee From 47ca6051e60e7f25149604b33ef3aeb90229cd9b Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 18 Sep 2023 17:06:31 +0100 Subject: [PATCH 69/79] Use fake time rather than real time in the noisy dgram test Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/quicapitest.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/quicapitest.c b/test/quicapitest.c index 0030c31082..023738a22b 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -1276,7 +1276,7 @@ static int unreliable_client_read(SSL *clientquic, SSL **stream, void *buf, return 0; } ossl_quic_tserver_tick(qtserv); - OSSL_sleep(10); + qtest_add_time(1); } return 0; @@ -1295,7 +1295,7 @@ static int unreliable_server_read(QUIC_TSERVER *qtserv, uint64_t sid, return 1; ossl_quic_tserver_tick(qtserv); SSL_handle_events(clientquic); - OSSL_sleep(10); + qtest_add_time(1); } return 0; @@ -1315,7 +1315,8 @@ static int test_noisy_dgram(void) if (!TEST_ptr(cctx) || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, privkey, - QTEST_FLAG_NOISE, + QTEST_FLAG_NOISE + | QTEST_FLAG_FAKE_TIME, &qtserv, &clientquic, NULL))) goto err; @@ -1334,6 +1335,7 @@ static int test_noisy_dgram(void) if (!TEST_true(ossl_quic_tserver_stream_new(qtserv, 0, &sid))) goto err; ossl_quic_tserver_tick(qtserv); + qtest_add_time(1); /* * Send data from the server to the client. Some datagrams may get lost, @@ -1347,6 +1349,7 @@ static int test_noisy_dgram(void) || !TEST_size_t_eq(msglen, written)) goto err; ossl_quic_tserver_tick(qtserv); + qtest_add_time(1); /* * Since the underlying BIO is now noisy we may get failures that @@ -1368,6 +1371,8 @@ static int test_noisy_dgram(void) goto err; ossl_quic_tserver_tick(qtserv); + qtest_add_time(1); + /* * Since the underlying BIO is now noisy we may get failures that * need to be retried - so we use unreliable_server_read() to handle -- Gitee From 15bfaca1d792e8e08eaf65e6336da09f5ca90026 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 19 Sep 2023 11:52:42 +0100 Subject: [PATCH 70/79] Add a packet splitting BIO Provide a BIO filter that can split QUIC datagrams containing multiple packets, such that each packet is in its own datagram. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/build.info | 10 ++- test/helpers/noisydgrambio.c | 61 ------------- test/helpers/pktsplitbio.c | 169 +++++++++++++++++++++++++++++++++++ test/helpers/quictestlib.c | 61 +++++++++++++ test/helpers/quictestlib.h | 17 +++- 5 files changed, 252 insertions(+), 66 deletions(-) create mode 100644 test/helpers/pktsplitbio.c diff --git a/test/build.info b/test/build.info index 4736e28c8b..4c81a2b779 100644 --- a/test/build.info +++ b/test/build.info @@ -339,7 +339,9 @@ IF[{- !$disabled{tests} -}] INCLUDE[quic_client_test]=../include ../apps/include DEPEND[quic_client_test]=../libcrypto.a ../libssl.a libtestutil.a - SOURCE[quic_multistream_test]=quic_multistream_test.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c + $QUICTESTHELPERS=helpers/quictestlib.c helpers/noisydgrambio.c helpers/pktsplitbio.c + + SOURCE[quic_multistream_test]=quic_multistream_test.c helpers/ssltestlib.c $QUICTESTHELPERS INCLUDE[quic_multistream_test]=../include ../apps/include DEPEND[quic_multistream_test]=../libcrypto.a ../libssl.a libtestutil.a @@ -818,15 +820,15 @@ IF[{- !$disabled{tests} -}] INCLUDE[event_queue_test]=../include ../apps/include DEPEND[event_queue_test]=../libcrypto ../libssl.a libtestutil.a - SOURCE[quicfaultstest]=quicfaultstest.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c + SOURCE[quicfaultstest]=quicfaultstest.c helpers/ssltestlib.c $QUICTESTHELPERS INCLUDE[quicfaultstest]=../include ../apps/include .. DEPEND[quicfaultstest]=../libcrypto.a ../libssl.a libtestutil.a - SOURCE[quicapitest]=quicapitest.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c + SOURCE[quicapitest]=quicapitest.c helpers/ssltestlib.c $QUICTESTHELPERS INCLUDE[quicapitest]=../include ../apps/include DEPEND[quicapitest]=../libcrypto.a ../libssl.a libtestutil.a - SOURCE[quic_newcid_test]=quic_newcid_test.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c + SOURCE[quic_newcid_test]=quic_newcid_test.c helpers/ssltestlib.c $QUICTESTHELPERS INCLUDE[quic_newcid_test]=../include ../apps/include .. DEPEND[quic_newcid_test]=../libcrypto.a ../libssl.a libtestutil.a ENDIF diff --git a/test/helpers/noisydgrambio.c b/test/helpers/noisydgrambio.c index b42dbe6f4b..7dc6a9cf35 100644 --- a/test/helpers/noisydgrambio.c +++ b/test/helpers/noisydgrambio.c @@ -105,67 +105,6 @@ static void get_noise(uint64_t *delay, int *should_drop) *delay += (uint64_t)(*should_drop); } -/* There isn't a public function to do BIO_ADDR_copy() so we create one */ -static int bio_addr_copy(BIO_ADDR *dst, BIO_ADDR *src) -{ - size_t len; - void *data = NULL; - int res = 0; - int family; - - if (src == NULL || dst == NULL) - return 0; - - family = BIO_ADDR_family(src); - if (family == AF_UNSPEC) { - BIO_ADDR_clear(dst); - return 1; - } - - if (!BIO_ADDR_rawaddress(src, NULL, &len)) - return 0; - - if (len > 0) { - data = OPENSSL_malloc(len); - if (!TEST_ptr(data)) - return 0; - } - - if (!BIO_ADDR_rawaddress(src, data, &len)) - goto err; - - if (!BIO_ADDR_rawmake(src, family, data, len, BIO_ADDR_rawport(src))) - goto err; - - res = 1; - err: - OPENSSL_free(data); - return res; -} - -static int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src) -{ - /* - * Note it is assumed that the originally allocated data sizes for dst and - * src are the same - */ - memcpy(dst->data, src->data, src->data_len); - dst->data_len = src->data_len; - dst->flags = src->flags; - if (dst->local != NULL) { - if (src->local != NULL) { - if (!TEST_true(bio_addr_copy(dst->local, src->local))) - return 0; - } else { - BIO_ADDR_clear(dst->local); - } - } - if (!TEST_true(bio_addr_copy(dst->peer, src->peer))) - return 0; - - return 1; -} - static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, size_t num_msg, uint64_t flags, size_t *msgs_processed) diff --git a/test/helpers/pktsplitbio.c b/test/helpers/pktsplitbio.c new file mode 100644 index 0000000000..a3c01b9506 --- /dev/null +++ b/test/helpers/pktsplitbio.c @@ -0,0 +1,169 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "quictestlib.h" +#include "../testutil.h" + +static int pkt_split_dgram_read(BIO *bio, char *out, int outl) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static int pkt_split_dgram_write(BIO *bio, const char *in, int inl) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static long pkt_split_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + long ret; + BIO *next = BIO_next(bio); + + if (next == NULL) + return 0; + + switch (cmd) { + case BIO_CTRL_DUP: + ret = 0L; + break; + default: + ret = BIO_ctrl(next, cmd, num, ptr); + break; + } + return ret; +} + +static int pkt_split_dgram_gets(BIO *bio, char *buf, int size) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static int pkt_split_dgram_puts(BIO *bio, const char *str) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static int pkt_split_dgram_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ + BIO *next = BIO_next(bio); + + if (next == NULL) + return 0; + + /* + * We only introduce noise when receiving messages. We just pass this on + * to the underlying BIO. + */ + return BIO_sendmmsg(next, msg, stride, num_msg, flags, msgs_processed); +} + +static int pkt_split_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ + BIO *next = BIO_next(bio); + size_t i, j, data_len = 0, msg_cnt = 0; + BIO_MSG *thismsg; + + if (!TEST_ptr(next)) + return 0; + + /* + * For simplicity we assume that all elements in the msg array have the + * same data_len. They are not required to by the API, but it would be quite + * strange for that not to be the case - and our code that calls + * BIO_recvmmsg does do this (which is all that is important for this test + * code). We test the invariant here. + */ + for (i = 0; i < num_msg; i++) { + if (i == 0) + data_len = msg[i].data_len; + else if (!TEST_size_t_eq(msg[i].data_len, data_len)) + return 0; + } + + if (!BIO_recvmmsg(next, msg, stride, num_msg, flags, msgs_processed)) + return 0; + + msg_cnt = *msgs_processed; + if (msg_cnt == num_msg) + return 1; /* We've used all our slots and can't split any more */ + assert(msg_cnt < num_msg); + + for (i = 0, thismsg = msg; i < msg_cnt; i++, thismsg++) { + QUIC_PKT_HDR hdr; + PACKET pkt; + size_t remain; + + if (!PACKET_buf_init(&pkt, thismsg->data, thismsg->data_len)) + return 0; + + /* Decode the packet header */ + /* + * TODO(QUIC SERVER): We need to query the short connection id len + * here, e.g. via some API SSL_get_short_conn_id_len() + */ + if (ossl_quic_wire_decode_pkt_hdr(&pkt, 0, 0, 0, &hdr, NULL) != 1) + return 0; + remain = PACKET_remaining(&pkt); + if (remain > 0) { + for (j = msg_cnt; j > i; j--) { + if (!bio_msg_copy(&msg[j], &msg[j - 1])) + return 0; + } + thismsg->data_len -= remain; + msg[i + 1].data_len = remain; + memmove(msg[i + 1].data, + (unsigned char *)msg[i + 1].data + thismsg->data_len, + remain); + msg_cnt++; + } + } + + *msgs_processed = msg_cnt; + return 1; +} + +/* Choose a sufficiently large type likely to be unused for this custom BIO */ +#define BIO_TYPE_PKT_SPLIT_DGRAM_FILTER (0x81 | BIO_TYPE_FILTER) + +static BIO_METHOD *method_pkt_split_dgram = NULL; + +/* Note: Not thread safe! */ +const BIO_METHOD *bio_f_pkt_split_dgram_filter(void) +{ + if (method_pkt_split_dgram == NULL) { + method_pkt_split_dgram = BIO_meth_new(BIO_TYPE_PKT_SPLIT_DGRAM_FILTER, + "Packet splitting datagram filter"); + if (method_pkt_split_dgram == NULL + || !BIO_meth_set_write(method_pkt_split_dgram, pkt_split_dgram_write) + || !BIO_meth_set_read(method_pkt_split_dgram, pkt_split_dgram_read) + || !BIO_meth_set_puts(method_pkt_split_dgram, pkt_split_dgram_puts) + || !BIO_meth_set_gets(method_pkt_split_dgram, pkt_split_dgram_gets) + || !BIO_meth_set_ctrl(method_pkt_split_dgram, pkt_split_dgram_ctrl) + || !BIO_meth_set_sendmmsg(method_pkt_split_dgram, + pkt_split_dgram_sendmmsg) + || !BIO_meth_set_recvmmsg(method_pkt_split_dgram, + pkt_split_dgram_recvmmsg)) + return NULL; + } + return method_pkt_split_dgram; +} + +void bio_f_pkt_split_dgram_filter_free(void) +{ + BIO_meth_free(method_pkt_split_dgram); +} diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index 28791267ed..6381d720ff 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -1044,3 +1044,64 @@ int qtest_fault_resize_datagram(QTEST_FAULT *fault, size_t newlen) return 1; } + +/* There isn't a public function to do BIO_ADDR_copy() so we create one */ +int bio_addr_copy(BIO_ADDR *dst, BIO_ADDR *src) +{ + size_t len; + void *data = NULL; + int res = 0; + int family; + + if (src == NULL || dst == NULL) + return 0; + + family = BIO_ADDR_family(src); + if (family == AF_UNSPEC) { + BIO_ADDR_clear(dst); + return 1; + } + + if (!BIO_ADDR_rawaddress(src, NULL, &len)) + return 0; + + if (len > 0) { + data = OPENSSL_malloc(len); + if (!TEST_ptr(data)) + return 0; + } + + if (!BIO_ADDR_rawaddress(src, data, &len)) + goto err; + + if (!BIO_ADDR_rawmake(src, family, data, len, BIO_ADDR_rawport(src))) + goto err; + + res = 1; + err: + OPENSSL_free(data); + return res; +} + +int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src) +{ + /* + * Note it is assumed that the originally allocated data sizes for dst and + * src are the same + */ + memcpy(dst->data, src->data, src->data_len); + dst->data_len = src->data_len; + dst->flags = src->flags; + if (dst->local != NULL) { + if (src->local != NULL) { + if (!TEST_true(bio_addr_copy(dst->local, src->local))) + return 0; + } else { + BIO_ADDR_clear(dst->local); + } + } + if (!TEST_true(bio_addr_copy(dst->peer, src->peer))) + return 0; + + return 1; +} diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h index 7a72e352d9..f18cd29481 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -233,8 +233,23 @@ int qtest_fault_set_datagram_listener(QTEST_FAULT *fault, */ int qtest_fault_resize_datagram(QTEST_FAULT *fault, size_t newlen); +/* Copy a BIO_ADDR */ +int bio_addr_copy(BIO_ADDR *dst, BIO_ADDR *src); + +/* Copy a BIO_MSG */ +int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src); + /* BIO filter for simulating a noisy UDP socket */ const BIO_METHOD *bio_f_noisy_dgram_filter(void); /* Free the BIO filter method object */ -void bio_f_noisy_dgram_filter_free(void); \ No newline at end of file +void bio_f_noisy_dgram_filter_free(void); + +/* + * BIO filter for splitting QUIC datagrams containing multiple packets into + * individual datagrams. + */ +const BIO_METHOD *bio_f_pkt_split_dgram_filter(void); + +/* Free the BIO filter method object */ +void bio_f_pkt_split_dgram_filter_free(void); -- Gitee From 1e26da45de612ec60c7de513b35a2aca7f82c1d4 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 19 Sep 2023 12:21:27 +0100 Subject: [PATCH 71/79] Extend the noisy dgram test so that packets are also affected by noise Where multiple packets are in a single datagram we split them so that all packets can be affected by the noise Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/helpers/quictestlib.c | 8 ++++++++ test/helpers/quictestlib.h | 2 ++ test/quicapitest.c | 21 ++++++++++++++++----- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index 6381d720ff..3c3cb73f96 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -141,6 +141,14 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, goto err; } + if ((flags & QTEST_FLAG_PACKET_SPLIT) != 0) { + BIO *pktsplitbio = BIO_new(bio_f_pkt_split_dgram_filter()); + + if (!TEST_ptr(pktsplitbio)) + goto err; + cbio = BIO_push(pktsplitbio, cbio); + } + if ((flags & QTEST_FLAG_NOISE) != 0) { BIO *noisebio = BIO_new(bio_f_noisy_dgram_filter()); diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h index f18cd29481..4e61b8965d 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -32,6 +32,8 @@ typedef struct qtest_fault_encrypted_extensions { #define QTEST_FLAG_FAKE_TIME (1 << 1) /* Introduce noise in the BIO */ #define QTEST_FLAG_NOISE (1 << 2) +/* Split datagrams such that each datagram contains one packet */ +#define QTEST_FLAG_PACKET_SPLIT (1 << 3) /* * Given an SSL_CTX for the client and filenames for the server certificate and diff --git a/test/quicapitest.c b/test/quicapitest.c index 023738a22b..cd006b4703 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -1301,7 +1301,15 @@ static int unreliable_server_read(QUIC_TSERVER *qtserv, uint64_t sid, return 0; } -static int test_noisy_dgram(void) +/* + * Create a connection and send data using an unreliable transport. We introduce + * random noise to drop, delay and duplicate datagrams. + * Test 0: Introduce random noise to datagrams + * Test 1: As with test 0 but also split datagrams containing multiple packets + * into individual datagrams so that individual packets can be affected + * by noise - not just a whole datagram. + */ +static int test_noisy_dgram(int idx) { SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); SSL *clientquic = NULL, *stream[2] = { NULL, NULL }; @@ -1311,12 +1319,14 @@ static int test_noisy_dgram(void) char *msg = "Hello world!"; size_t msglen = strlen(msg), written, readbytes, i, j; unsigned char buf[80]; + int flags = QTEST_FLAG_NOISE | QTEST_FLAG_FAKE_TIME; + + if (idx == 1) + flags |= QTEST_FLAG_PACKET_SPLIT; if (!TEST_ptr(cctx) || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, - privkey, - QTEST_FLAG_NOISE - | QTEST_FLAG_FAKE_TIME, + privkey, flags, &qtserv, &clientquic, NULL))) goto err; @@ -1470,7 +1480,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_non_io_retry, 2); ADD_TEST(test_quic_psk); ADD_ALL_TESTS(test_alpn, 2); - ADD_TEST(test_noisy_dgram); + ADD_ALL_TESTS(test_noisy_dgram, 2); return 1; err: @@ -1481,6 +1491,7 @@ int setup_tests(void) void cleanup_tests(void) { bio_f_noisy_dgram_filter_free(); + bio_f_pkt_split_dgram_filter_free(); OPENSSL_free(cert); OPENSSL_free(privkey); OSSL_PROVIDER_unload(defctxnull); -- Gitee From 49882ee2dcbf7f3d5e1c6b59e6d49784688033a6 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 19 Sep 2023 16:40:25 +0100 Subject: [PATCH 72/79] Add the ability to do client side tracing in quictestlib.c We add a new flag QTEST_FLAG_CLIENT_TRACE to get debug tracing output if required. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- .../quic-design/quic-fault-injector.md | 6 ++--- test/helpers/quictestlib.c | 17 ++++++++++++- test/helpers/quictestlib.h | 5 ++-- test/quic_newcid_test.c | 2 +- test/quicapitest.c | 24 ++++++++++--------- test/quicfaultstest.c | 8 +++---- 6 files changed, 40 insertions(+), 22 deletions(-) diff --git a/doc/designs/quic-design/quic-fault-injector.md b/doc/designs/quic-design/quic-fault-injector.md index 30db905ee8..bea36b98cb 100644 --- a/doc/designs/quic-design/quic-fault-injector.md +++ b/doc/designs/quic-design/quic-fault-injector.md @@ -215,7 +215,7 @@ typedef struct ossl_qf_encrypted_extensions { int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, SSL_CTX *serverctx, char *certfile, char *keyfile, int block, QUIC_TSERVER **qtserv, SSL **cssl, - OSSL_QUIC_FAULT **fault); + OSSL_QUIC_FAULT **fault, BIO **tracebio); /* * Free up a Fault Injector instance @@ -440,7 +440,7 @@ static int test_unknown_frame(void) goto err; if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0, - &qtserv, &cssl, &fault))) + &qtserv, &cssl, &fault, NULL))) goto err; if (!TEST_true(qtest_create_quic_connection(qtserv, cssl))) @@ -523,7 +523,7 @@ static int test_no_transport_params(void) goto err; if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0, - &qtserv, &cssl, &fault))) + &qtserv, &cssl, &fault, NULL))) goto err; if (!TEST_true(ossl_quic_fault_set_hand_enc_ext_listener(fault, diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index 3c3cb73f96..bb2ae9b3ba 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -77,7 +77,7 @@ static OSSL_TIME fake_now_cb(void *arg) int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, SSL_CTX *serverctx, char *certfile, char *keyfile, int flags, QUIC_TSERVER **qtserv, SSL **cssl, - QTEST_FAULT **fault) + QTEST_FAULT **fault, BIO **tracebio) { /* ALPN value as recognised by QUIC_TSERVER */ unsigned char alpn[] = { 8, 'o', 's', 's', 'l', 't', 'e', 's', 't' }; @@ -85,6 +85,7 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, BIO *cbio = NULL, *sbio = NULL, *fisbio = NULL; BIO_ADDR *peeraddr = NULL; struct in_addr ina = {0}; + BIO *tmpbio = NULL; *qtserv = NULL; if (fault != NULL) @@ -96,6 +97,17 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, return 0; } + if ((flags & QTEST_FLAG_CLIENT_TRACE) != 0) { + tmpbio = BIO_new_fp(stdout, BIO_NOCLOSE); + if (!TEST_ptr(tmpbio)) + goto err; + + SSL_set_msg_callback(*cssl, SSL_trace); + SSL_set_msg_callback_arg(*cssl, tmpbio); + } + if (tracebio != NULL) + *tracebio = tmpbio; + /* SSL_set_alpn_protos returns 0 for success! */ if (!TEST_false(SSL_set_alpn_protos(*cssl, alpn, sizeof(alpn)))) goto err; @@ -224,6 +236,9 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, ossl_quic_tserver_free(*qtserv); if (fault != NULL) OPENSSL_free(*fault); + BIO_free(tmpbio); + if (tracebio != NULL) + *tracebio = NULL; return 0; } diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h index 4e61b8965d..e5190c62b1 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -34,7 +34,8 @@ typedef struct qtest_fault_encrypted_extensions { #define QTEST_FLAG_NOISE (1 << 2) /* Split datagrams such that each datagram contains one packet */ #define QTEST_FLAG_PACKET_SPLIT (1 << 3) - +/* Turn on client side tracing */ +#define QTEST_FLAG_CLIENT_TRACE (1 << 4) /* * Given an SSL_CTX for the client and filenames for the server certificate and * keyfile, create a server and client instances as well as a fault injector @@ -43,7 +44,7 @@ typedef struct qtest_fault_encrypted_extensions { int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, SSL_CTX *serverctx, char *certfile, char *keyfile, int flags, QUIC_TSERVER **qtserv, SSL **cssl, - QTEST_FAULT **fault); + QTEST_FAULT **fault, BIO **tracebio); /* Where QTEST_FLAG_FAKE_TIME is used, add millis to the current time */ void qtest_add_time(uint64_t millis); diff --git a/test/quic_newcid_test.c b/test/quic_newcid_test.c index cda55abca3..80a15e1b7a 100644 --- a/test/quic_newcid_test.c +++ b/test/quic_newcid_test.c @@ -68,7 +68,7 @@ static int test_ncid_frame(int fail) goto err; if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0, - &qtserv, &cssl, &fault))) + &qtserv, &cssl, &fault, NULL))) goto err; if (!TEST_true(qtest_create_quic_connection(qtserv, cssl))) diff --git a/test/quicapitest.c b/test/quicapitest.c index cd006b4703..94562f3a5b 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -69,7 +69,7 @@ static int test_quic_write_read(int idx) ? QTEST_FLAG_BLOCK : 0, &qtserv, &clientquic, - NULL)) + NULL, NULL)) || !TEST_true(SSL_set_tlsext_host_name(clientquic, "localhost"))) goto end; @@ -220,7 +220,7 @@ static int test_fin_only_blocking(void) cert, privkey, QTEST_FLAG_BLOCK, &qtserv, &clientquic, - NULL)) + NULL, NULL)) || !TEST_true(SSL_set_tlsext_host_name(clientquic, "localhost"))) goto end; @@ -380,7 +380,7 @@ static int test_version(void) if (!TEST_ptr(cctx) || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, privkey, 0, &qtserv, - &clientquic, NULL)) + &clientquic, NULL, NULL)) || !TEST_true(qtest_create_quic_connection(qtserv, clientquic))) goto err; @@ -502,7 +502,7 @@ static int test_ssl_trace(void) privkey, QTEST_FLAG_FAKE_TIME, &qtserv, - &clientquic, NULL))) + &clientquic, NULL, NULL))) goto err; SSL_set_msg_callback(clientquic, SSL_trace); @@ -829,7 +829,8 @@ static int test_bio_ssl(void) goto err; if (!TEST_true(qtest_create_quic_objects(libctx, NULL, NULL, cert, privkey, - 0, &qtserv, &clientquic, NULL))) + 0, &qtserv, &clientquic, NULL, + NULL))) goto err; msglen = strlen(msg); @@ -946,7 +947,7 @@ static int test_back_pressure(void) if (!TEST_ptr(cctx) || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, privkey, 0, &qtserv, - &clientquic, NULL)) + &clientquic, NULL, NULL)) || !TEST_true(qtest_create_quic_connection(qtserv, clientquic))) goto err; @@ -1024,7 +1025,7 @@ static int test_multiple_dgrams(void) || !TEST_ptr(buf) || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, privkey, 0, &qtserv, - &clientquic, NULL)) + &clientquic, NULL, NULL)) || !TEST_true(qtest_create_quic_connection(qtserv, clientquic))) goto err; @@ -1088,7 +1089,8 @@ static int test_non_io_retry(int idx) flags = (idx >= 1) ? QTEST_FLAG_BLOCK : 0; if (!TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, privkey, - flags, &qtserv, &clientquic, NULL)) + flags, &qtserv, &clientquic, NULL, + NULL)) || !TEST_true(qtest_create_quic_connection_ex(qtserv, clientquic, SSL_ERROR_WANT_RETRY_VERIFY)) || !TEST_int_eq(SSL_want(clientquic), SSL_RETRY_VERIFY) @@ -1156,7 +1158,7 @@ static int test_quic_psk(void) /* No cert or private key for the server, i.e. PSK only */ || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, NULL, NULL, 0, &qtserv, - &clientquic, NULL))) + &clientquic, NULL, NULL))) goto end; SSL_set_psk_use_session_callback(clientquic, use_session_cb); @@ -1215,7 +1217,7 @@ static int test_alpn(int idx) privkey, QTEST_FLAG_FAKE_TIME, &qtserv, - &clientquic, NULL))) + &clientquic, NULL, NULL))) goto err; if (idx == 0) { @@ -1328,7 +1330,7 @@ static int test_noisy_dgram(int idx) || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, privkey, flags, &qtserv, - &clientquic, NULL))) + &clientquic, NULL, NULL))) goto err; if (!TEST_true(qtest_create_quic_connection(qtserv, clientquic))) diff --git a/test/quicfaultstest.c b/test/quicfaultstest.c index a6ba0dc053..28f52cd6f2 100644 --- a/test/quicfaultstest.c +++ b/test/quicfaultstest.c @@ -35,7 +35,7 @@ static int test_basic(void) goto err; if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0, - &qtserv, &cssl, NULL))) + &qtserv, &cssl, NULL, NULL))) goto err; if (!TEST_true(qtest_create_quic_connection(qtserv, cssl))) @@ -105,7 +105,7 @@ static int test_unknown_frame(void) goto err; if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0, - &qtserv, &cssl, &fault))) + &qtserv, &cssl, &fault, NULL))) goto err; if (!TEST_true(qtest_create_quic_connection(qtserv, cssl))) @@ -187,7 +187,7 @@ static int test_drop_extensions(int idx) goto err; if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0, - &qtserv, &cssl, &fault))) + &qtserv, &cssl, &fault, NULL))) goto err; if (idx == 0) { @@ -275,7 +275,7 @@ static int test_corrupted_data(int idx) if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, QTEST_FLAG_FAKE_TIME, &qtserv, - &cssl, &fault))) + &cssl, &fault, NULL))) goto err; if (idx == 0) { -- Gitee From 419faf5d8fe6f0f42f08541c7f796a45f9368e29 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 19 Sep 2023 16:52:00 +0100 Subject: [PATCH 73/79] Ensure client to server datagrams are noisy too So far we've only applied noise to the server to client datagrams. Do the same thing the other way around. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/helpers/quictestlib.c | 32 +++++++++++++++++++++++--------- test/helpers/quictestlib.h | 6 ++++++ test/quicapitest.c | 9 +++++++-- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index bb2ae9b3ba..6a72cc27be 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -159,6 +159,11 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, if (!TEST_ptr(pktsplitbio)) goto err; cbio = BIO_push(pktsplitbio, cbio); + + pktsplitbio = BIO_new(bio_f_pkt_split_dgram_filter()); + if (!TEST_ptr(pktsplitbio)) + goto err; + sbio = BIO_push(pktsplitbio, sbio); } if ((flags & QTEST_FLAG_NOISE) != 0) { @@ -167,6 +172,12 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, if (!TEST_ptr(noisebio)) goto err; cbio = BIO_push(noisebio, cbio); + + noisebio = BIO_new(bio_f_noisy_dgram_filter()); + + if (!TEST_ptr(noisebio)) + goto err; + sbio = BIO_push(noisebio, sbio); } SSL_set_bio(*cssl, cbio, cbio); @@ -228,9 +239,9 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, err: SSL_CTX_free(tserver_args.ctx); BIO_ADDR_free(peeraddr); - BIO_free(cbio); + BIO_free_all(cbio); BIO_free(fisbio); - BIO_free(sbio); + BIO_free_all(sbio); SSL_free(*cssl); *cssl = NULL; ossl_quic_tserver_free(*qtserv); @@ -289,14 +300,14 @@ static void run_server_thread(void) } #endif -static int wait_for_timeout(SSL *s, QUIC_TSERVER *qtserv) +int qtest_wait_for_timeout(SSL *s, QUIC_TSERVER *qtserv) { struct timeval tv; OSSL_TIME ctimeout, stimeout, mintimeout, now; int cinf; /* We don't need to wait in blocking mode */ - if (s == NULL || qtserv == NULL) + if (s == NULL || SSL_get_blocking_mode(s)) return 1; /* Don't wait if either BIO has data waiting */ @@ -395,12 +406,13 @@ int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl, } } - if (!clienterr && retc <= 0) + qtest_add_time(1); + if (clientssl != NULL) SSL_handle_events(clientssl); + if (qtserv != NULL) + ossl_quic_tserver_tick(qtserv); if (!servererr && rets <= 0) { - qtest_add_time(1); - ossl_quic_tserver_tick(qtserv); servererr = ossl_quic_tserver_is_term_any(qtserv); if (!servererr) rets = ossl_quic_tserver_is_handshake_confirmed(qtserv); @@ -414,8 +426,10 @@ int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl, goto err; } - if (!wait_for_timeout(clientssl, qtserv)) - goto err; + if ((retc <= 0 && !clienterr) || (rets <= 0 && !servererr)) { + if (!qtest_wait_for_timeout(clientssl, qtserv)) + goto err; + } } while ((retc <= 0 && !clienterr) || (rets <= 0 && !servererr #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h index e5190c62b1..844aec8a60 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -67,6 +67,12 @@ int qtest_supports_blocking(void); */ int qtest_create_quic_connection(QUIC_TSERVER *qtserv, SSL *clientssl); +/* + * Check if both client and server have no data to read and are waiting on a + * timeout. If so, wait until the timeout has expired. + */ +int qtest_wait_for_timeout(SSL *s, QUIC_TSERVER *qtserv); + /* * Same as qtest_create_quic_connection but will stop (successfully) if the * clientssl indicates SSL_ERROR_WANT_XXX as specified by |wanterr| diff --git a/test/quicapitest.c b/test/quicapitest.c index 94562f3a5b..b02db15d65 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -1274,13 +1274,15 @@ static int unreliable_client_read(SSL *clientquic, SSL **stream, void *buf, if (*stream != NULL) { if (SSL_read_ex(*stream, buf, buflen, readbytes)) return 1; - if (SSL_get_error(*stream, 0) != SSL_ERROR_WANT_READ) + if (!TEST_int_eq(SSL_get_error(*stream, 0), SSL_ERROR_WANT_READ)) return 0; } ossl_quic_tserver_tick(qtserv); qtest_add_time(1); + qtest_wait_for_timeout(clientquic, qtserv); } + TEST_error("No progress made"); return 0; } @@ -1293,13 +1295,16 @@ static int unreliable_server_read(QUIC_TSERVER *qtserv, uint64_t sid, /* We just do this in a loop with a sleep for simplicity */ for (abortctr = 0; abortctr < MAX_LOOPS; abortctr++) { - if (ossl_quic_tserver_read(qtserv, sid, buf, buflen, readbytes)) + if (ossl_quic_tserver_read(qtserv, sid, buf, buflen, readbytes) + && *readbytes > 1) return 1; ossl_quic_tserver_tick(qtserv); SSL_handle_events(clientquic); qtest_add_time(1); + qtest_wait_for_timeout(clientquic, qtserv); } + TEST_error("No progress made"); return 0; } -- Gitee From e5aa21fd09f02cff3d2e2a0b8d26b4c09f56b4cc Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 20 Sep 2023 13:25:42 +0100 Subject: [PATCH 74/79] Remove some redundant code from test helper BIOs Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/helpers/noisydgrambio.c | 28 ---------------------------- test/helpers/pktsplitbio.c | 28 ---------------------------- 2 files changed, 56 deletions(-) diff --git a/test/helpers/noisydgrambio.c b/test/helpers/noisydgrambio.c index 7dc6a9cf35..c93b6961ec 100644 --- a/test/helpers/noisydgrambio.c +++ b/test/helpers/noisydgrambio.c @@ -19,18 +19,6 @@ struct noisy_dgram_st { uint64_t delayed_dgram; }; -static int noisy_dgram_read(BIO *bio, char *out, int outl) -{ - /* We don't support this - not needed anyway */ - return -1; -} - -static int noisy_dgram_write(BIO *bio, const char *in, int inl) -{ - /* We don't support this - not needed anyway */ - return -1; -} - static long noisy_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr) { long ret; @@ -50,18 +38,6 @@ static long noisy_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr) return ret; } -static int noisy_dgram_gets(BIO *bio, char *buf, int size) -{ - /* We don't support this - not needed anyway */ - return -1; -} - -static int noisy_dgram_puts(BIO *bio, const char *str) -{ - /* We don't support this - not needed anyway */ - return -1; -} - static int noisy_dgram_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, size_t num_msg, uint64_t flags, size_t *msgs_processed) @@ -298,10 +274,6 @@ const BIO_METHOD *bio_f_noisy_dgram_filter(void) method_noisy_dgram = BIO_meth_new(BIO_TYPE_NOISY_DGRAM_FILTER, "Nosiy datagram filter"); if (method_noisy_dgram == NULL - || !BIO_meth_set_write(method_noisy_dgram, noisy_dgram_write) - || !BIO_meth_set_read(method_noisy_dgram, noisy_dgram_read) - || !BIO_meth_set_puts(method_noisy_dgram, noisy_dgram_puts) - || !BIO_meth_set_gets(method_noisy_dgram, noisy_dgram_gets) || !BIO_meth_set_ctrl(method_noisy_dgram, noisy_dgram_ctrl) || !BIO_meth_set_sendmmsg(method_noisy_dgram, noisy_dgram_sendmmsg) || !BIO_meth_set_recvmmsg(method_noisy_dgram, noisy_dgram_recvmmsg) diff --git a/test/helpers/pktsplitbio.c b/test/helpers/pktsplitbio.c index a3c01b9506..536e62f8a0 100644 --- a/test/helpers/pktsplitbio.c +++ b/test/helpers/pktsplitbio.c @@ -11,18 +11,6 @@ #include "quictestlib.h" #include "../testutil.h" -static int pkt_split_dgram_read(BIO *bio, char *out, int outl) -{ - /* We don't support this - not needed anyway */ - return -1; -} - -static int pkt_split_dgram_write(BIO *bio, const char *in, int inl) -{ - /* We don't support this - not needed anyway */ - return -1; -} - static long pkt_split_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr) { long ret; @@ -42,18 +30,6 @@ static long pkt_split_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr) return ret; } -static int pkt_split_dgram_gets(BIO *bio, char *buf, int size) -{ - /* We don't support this - not needed anyway */ - return -1; -} - -static int pkt_split_dgram_puts(BIO *bio, const char *str) -{ - /* We don't support this - not needed anyway */ - return -1; -} - static int pkt_split_dgram_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, size_t num_msg, uint64_t flags, size_t *msgs_processed) @@ -149,10 +125,6 @@ const BIO_METHOD *bio_f_pkt_split_dgram_filter(void) method_pkt_split_dgram = BIO_meth_new(BIO_TYPE_PKT_SPLIT_DGRAM_FILTER, "Packet splitting datagram filter"); if (method_pkt_split_dgram == NULL - || !BIO_meth_set_write(method_pkt_split_dgram, pkt_split_dgram_write) - || !BIO_meth_set_read(method_pkt_split_dgram, pkt_split_dgram_read) - || !BIO_meth_set_puts(method_pkt_split_dgram, pkt_split_dgram_puts) - || !BIO_meth_set_gets(method_pkt_split_dgram, pkt_split_dgram_gets) || !BIO_meth_set_ctrl(method_pkt_split_dgram, pkt_split_dgram_ctrl) || !BIO_meth_set_sendmmsg(method_pkt_split_dgram, pkt_split_dgram_sendmmsg) -- Gitee From 9f243df197f966667aef9b281ed7e70d891a03ec Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 20 Sep 2023 16:24:37 +0100 Subject: [PATCH 75/79] Ensure we up-ref the sbio before passing it to tserver We are actually passing two references to sbio: one as part of a BIO chain and one stand alone. Therefore we need two references. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/helpers/quictestlib.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index 6a72cc27be..f5a46efb6f 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -201,8 +201,12 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, BIO_set_data(fisbio, fault == NULL ? NULL : *fault); - if (!TEST_ptr(BIO_push(fisbio, sbio))) + if (!BIO_up_ref(sbio)) goto err; + if (!TEST_ptr(BIO_push(fisbio, sbio))) { + BIO_free(sbio); + goto err; + } tserver_args.libctx = libctx; tserver_args.net_rbio = sbio; @@ -240,7 +244,7 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, SSL_CTX_free(tserver_args.ctx); BIO_ADDR_free(peeraddr); BIO_free_all(cbio); - BIO_free(fisbio); + BIO_free_all(fisbio); BIO_free_all(sbio); SSL_free(*cssl); *cssl = NULL; -- Gitee From f05888c245f7937332357c77e8ff571f2a9ae6d2 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 20 Sep 2023 16:25:44 +0100 Subject: [PATCH 76/79] Ensure we free all the BIOs in a chain for QUIC like we do in TLS An application may pass in a whole BIO chain via SSL_set_bio(). When we free the BIO we should be using BIO_free_all() not BIO_free() like we do with TLS. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- ssl/quic/quic_impl.c | 8 ++++---- ssl/quic/quic_tserver.c | 4 ++-- test/quic_multistream_test.c | 6 ++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index beec26c019..cb927fa52d 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -545,8 +545,8 @@ void ossl_quic_free(SSL *s) ossl_quic_channel_free(ctx.qc->ch); - BIO_free(ctx.qc->net_rbio); - BIO_free(ctx.qc->net_wbio); + BIO_free_all(ctx.qc->net_rbio); + BIO_free_all(ctx.qc->net_wbio); /* Note: SSL_free calls OPENSSL_free(qc) for us */ @@ -876,7 +876,7 @@ void ossl_quic_conn_set0_net_rbio(SSL *s, BIO *net_rbio) if (!ossl_quic_channel_set_net_rbio(ctx.qc->ch, net_rbio)) return; - BIO_free(ctx.qc->net_rbio); + BIO_free_all(ctx.qc->net_rbio); ctx.qc->net_rbio = net_rbio; if (net_rbio != NULL) @@ -903,7 +903,7 @@ void ossl_quic_conn_set0_net_wbio(SSL *s, BIO *net_wbio) if (!ossl_quic_channel_set_net_wbio(ctx.qc->ch, net_wbio)) return; - BIO_free(ctx.qc->net_wbio); + BIO_free_all(ctx.qc->net_wbio); ctx.qc->net_wbio = net_wbio; if (net_wbio != NULL) diff --git a/ssl/quic/quic_tserver.c b/ssl/quic/quic_tserver.c index 92c17d10f3..3630577e70 100644 --- a/ssl/quic/quic_tserver.c +++ b/ssl/quic/quic_tserver.c @@ -159,8 +159,8 @@ void ossl_quic_tserver_free(QUIC_TSERVER *srv) return; ossl_quic_channel_free(srv->ch); - BIO_free(srv->args.net_rbio); - BIO_free(srv->args.net_wbio); + BIO_free_all(srv->args.net_rbio); + BIO_free_all(srv->args.net_wbio); OPENSSL_free(srv->ssl); SSL_free(srv->tls); SSL_CTX_free(srv->ctx); diff --git a/test/quic_multistream_test.c b/test/quic_multistream_test.c index b401e78e32..2ad4ef292e 100644 --- a/test/quic_multistream_test.c +++ b/test/quic_multistream_test.c @@ -746,10 +746,8 @@ static int helper_init(struct helper *h, int free_order, int blocking, BIO_set_data(h->s_qtf_wbio, h->qtf); } - if (!need_injector) - h->s_net_bio_own = NULL; - - h->s_qtf_wbio_own = NULL; + h->s_net_bio_own = NULL; + h->s_qtf_wbio_own = NULL; h->c_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); if (!TEST_int_ge(h->c_fd, 0)) -- Gitee From 3daa89f8c3390ce4872bb36d6a82155490c895b7 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 21 Sep 2023 10:25:00 +0100 Subject: [PATCH 77/79] Clarify the terminology in the noisy dgram BIO The previous terminology was quite confusing. We try to use drop, duplicate and delay more consistently and introduce the "reinject" terminology as a mechanism for implementing duplicates and delays. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) Signed-off-by: fly2x --- test/helpers/noisydgrambio.c | 107 +++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 36 deletions(-) diff --git a/test/helpers/noisydgrambio.c b/test/helpers/noisydgrambio.c index c93b6961ec..8b68726dd2 100644 --- a/test/helpers/noisydgrambio.c +++ b/test/helpers/noisydgrambio.c @@ -16,7 +16,7 @@ struct noisy_dgram_st { uint64_t this_dgram; BIO_MSG msg; - uint64_t delayed_dgram; + uint64_t reinject_dgram; }; static long noisy_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr) @@ -54,31 +54,66 @@ static int noisy_dgram_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, return BIO_sendmmsg(next, msg, stride, num_msg, flags, msgs_processed); } -static void get_noise(uint64_t *delay, int *should_drop) +/* 1 in NOISE_RATE datagrams will be noisy. With a value of 5 that is 20% */ +#define NOISE_RATE 5 + +/* + * We have 3 different types of noise: drop, duplicate and delay + * Each of these have equal probability. + */ +#define NOISE_TYPE_DROP 0 +#define NOISE_TYPE_DUPLICATE 1 +#define NOISE_TYPE_DELAY 2 +#define NUM_NOISE_TYPES 3 + +/* + * When a duplicate occurs we reinject the new datagram after up to + * MAX_DGRAM_REINJECT datagrams have been sent. A reinject of 1 means that the + * duplicate follows immediately after the original datagram. A reinject of 4 + * means that original datagram plus 3 other datagrams are sent before the + * reinjected datagram is inserted. + * This also controls when a delay (not a duplicate) occurs. In that case + * we add 1 to the number because there is no point in skipping the current + * datagram only to immediately reinject it in the next datagram. + */ +#define MAX_DGRAM_REINJECT 4 + +static void get_noise(uint64_t *reinject, int *should_drop) { uint32_t type; - /* 20% of all datagrams should be noisy */ - if (test_random() % 5 != 0) { - *delay = 0; + if (test_random() % NOISE_RATE != 0) { + *reinject = 0; *should_drop = 0; return; } - type = test_random() % 3; + type = test_random() % NUM_NOISE_TYPES; - /* Of noisy datagrams, 33% drop only, 33% delay only, 33% drop and delay */ - - *should_drop = (type == 0 || type == 1); + /* + * Of noisy datagrams, 33% drop, 33% duplicate, 33% delay + * A duplicated datagram keeps the current datagram and reinjects a new + * identical one after up to MAX_DGRAM_DELAY datagrams have been sent. + * A delayed datagram is implemented as both a reinject and a drop, i.e. an + * identical datagram is reinjected after the given number of datagrams have + * been sent and the current datagram is dropped. + */ + *should_drop = (type == NOISE_TYPE_DROP || type == NOISE_TYPE_DELAY); - /* Where a delay occurs we delay by 1 - 4 datagrams */ - *delay = (type == 0) ? 0 : (uint64_t)((test_random() % 4) + 1); + /* + * Where a duplicate occurs we reinject the copy of the datagram up to + * MAX_DGRAM_DELAY datagrams later + */ + *reinject = (type == NOISE_TYPE_DROP) + ? 0 + : (uint64_t)((test_random() % MAX_DGRAM_REINJECT) + 1); /* - * No point in delaying by 1 datagram if we are also dropping, so we delay - * by an extra datagram in that case + * No point in reinjecting after 1 datagram if the current datagram is also + * dropped (i.e. this is a delay not a duplicate), so we reinject after an + * extra datagram in that case */ - *delay += (uint64_t)(*should_drop); + *reinject += (uint64_t)(*should_drop); } static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, @@ -133,14 +168,14 @@ static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, for (i = 0, thismsg = msg; i < msg_cnt; i++, thismsg++, data->this_dgram++) { - uint64_t delay; + uint64_t reinject; int should_drop; - /* If we have a delayed message ready insert it now */ - if (data->delayed_dgram > 0 - && data->delayed_dgram == data->this_dgram) { + /* If we have a message to reinject then insert it now */ + if (data->reinject_dgram > 0 + && data->reinject_dgram == data->this_dgram) { if (msg_cnt < num_msg) { - /* Make space for the inserted message */ + /* Make space for the injected message */ for (j = msg_cnt; j > i; j--) { if (!bio_msg_copy(&msg[j], &msg[j - 1])) return 0; @@ -148,38 +183,38 @@ static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, if (!bio_msg_copy(thismsg, &data->msg)) return 0; msg_cnt++; - data->delayed_dgram = 0; + data->reinject_dgram = 0; #ifdef OSSL_NOISY_DGRAM_DEBUG - printf("**Inserting a delayed datagram\n"); + printf("**Injecting a datagram\n"); BIO_dump_fp(stdout, thismsg->data, thismsg->data_len); printf("\n"); #endif continue; - } /* else we have no space for the insertion, so just drop it */ - data->delayed_dgram = 0; + } /* else we have no space for the injection, so just drop it */ + data->reinject_dgram = 0; } - get_noise(&delay, &should_drop); + get_noise(&reinject, &should_drop); - /* We ignore delay if a message is already delayed */ - if (delay > 0 && data->delayed_dgram == 0) { + /* + * We ignore reinjection if a message is already waiting to be + * reinjected + */ + if (reinject > 0 && data->reinject_dgram == 0) { /* - * Note that a message may be delayed *and* dropped, or delayed - * and *not* dropped. - * Delayed and dropped means the message will not be sent now and - * will only be sent after the delay. - * Delayed and not dropped means the message will be sent now and - * a duplicate will also be sent after the delay. + * Both duplicated and delayed datagrams get reintroduced after the + * delay period. Datagrams that are delayed only (not duplicated) + * will also have the current copy of the datagram dropped (i.e + * should_drop below will be true). */ - if (!bio_msg_copy(&data->msg, thismsg)) return 0; - data->delayed_dgram = data->this_dgram + delay; + data->reinject_dgram = data->this_dgram + reinject; #ifdef OSSL_NOISY_DGRAM_DEBUG - printf("**Delaying a datagram for %u messages%s\n", - (unsigned int)delay, should_drop ? "" : "(duplicating)"); + printf("**Scheduling a reinject after %u messages%s\n", + (unsigned int)reinject, should_drop ? "" : "(duplicating)"); BIO_dump_fp(stdout, thismsg->data, thismsg->data_len); printf("\n"); #endif -- Gitee From 4d0248d5c44782a3fd2233c472e245bf0cf9219f Mon Sep 17 00:00:00 2001 From: Huiyue Xu Date: Thu, 14 Sep 2023 16:21:35 +0800 Subject: [PATCH 78/79] Do not include sparse_array.o in libssl sparse_array.o is not needed in libssl at 3.0.x version. Signed-off-by: Huiyue Xu Reviewed-by: Matt Caswell Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22111) (cherry picked from commit a31cd07af1ca34cdbbd2b077a933208d447ed0b2) Signed-off-by: fly2x --- crypto/build.info | 2 -- 1 file changed, 2 deletions(-) diff --git a/crypto/build.info b/crypto/build.info index ef568070c1..2d5b22fcff 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -102,8 +102,6 @@ $UTIL_COMMON=\ param_build_set.c der_writer.c threads_lib.c params_dup.c \ time.c params_idx.c -SHARED_SOURCE[../libssl]=sparse_array.c - SOURCE[../libcrypto]=$UTIL_COMMON \ mem.c mem_sec.c \ cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c o_dir.c \ -- Gitee From 4456ec796240b085169697c55fb318b003bee6c9 Mon Sep 17 00:00:00 2001 From: "Matthias St. Pierre" Date: Thu, 21 Sep 2023 16:43:43 +0200 Subject: [PATCH 79/79] no-engine: fix signing with legacy app method based keys Signing with an app method based key (i.e. an `EVP_PKEY` which wraps an `RSA` key with an application defined `RSA_METHOD`) used to work in 1.1.1. That feature was broken in commit 60488d2434, but later on fixed by @t8m in commit b247113c05 (see #14859). This commit corrects a minor flaw of the fix, which affects only `no-engine` builds: the special treatment for foreign keys is guarded by an `OPENSSL_NO_ENGINE` check. Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Dmitry Belyavskiy Reviewed-by: Todd Short (Merged from https://github.com/openssl/openssl/pull/22163) Signed-off-by: fly2x --- crypto/evp/pmeth_lib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 6bd9994072..268b1617e3 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -247,10 +247,11 @@ static EVP_PKEY_CTX *int_ctx_new(OSSL_LIB_CTX *libctx, */ if (e != NULL) pmeth = ENGINE_get_pkey_meth(e, id); - else if (pkey != NULL && pkey->foreign) + else +# endif /* OPENSSL_NO_ENGINE */ + if (pkey != NULL && pkey->foreign) pmeth = EVP_PKEY_meth_find(id); else -# endif app_pmeth = pmeth = evp_pkey_meth_find_added_by_application(id); /* END legacy */ -- Gitee