diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/bio_enc_test.c | 73 | ||||
-rw-r--r-- | test/bio_pw_callback_test.c | 402 | ||||
-rw-r--r-- | test/bioprinttest.c | 156 | ||||
-rw-r--r-- | test/dhtest.c | 12 | ||||
-rw-r--r-- | test/ectest.c | 12 | ||||
-rw-r--r-- | test/endecode_test.c | 25 | ||||
-rw-r--r-- | test/evp_extra_test.c | 9 | ||||
-rw-r--r-- | test/evp_libctx_test.c | 17 | ||||
-rw-r--r-- | test/evp_pkey_provided_test.c | 50 | ||||
-rw-r--r-- | test/evp_test.c | 8 | ||||
-rw-r--r-- | test/nocache-and-default.cnf | 18 | ||||
-rw-r--r-- | test/params_api_test.c | 30 | ||||
-rw-r--r-- | test/rand_test.c | 11 | ||||
-rw-r--r-- | test/recipes/20-test_nocache.t | 34 | ||||
-rw-r--r-- | test/recipes/25-test_verify.t | 41 | ||||
-rw-r--r-- | test/recipes/61-test_bio_pw_callback.t | 20 | ||||
-rw-r--r-- | test/recipes/61-test_bio_pw_callback_data/private_key.pem | 30 | ||||
-rw-r--r-- | test/recipes/70-test_tls13downgrade.t | 158 | ||||
-rw-r--r-- | test/recipes/80-test_ca.t | 13 | ||||
-rw-r--r-- | test/recipes/80-test_cmp_http.t | 6 | ||||
-rw-r--r-- | test/recipes/80-test_cms.t | 10 | ||||
-rw-r--r-- | test/sslapitest.c | 74 | ||||
-rw-r--r-- | test/testutil/testutil_init.c | 3 | ||||
-rw-r--r-- | test/tls-provider.c | 7 |
24 files changed, 1055 insertions, 164 deletions
diff --git a/test/bio_enc_test.c b/test/bio_enc_test.c index accb74e7df41..cf72b5e6a89d 100644 --- a/test/bio_enc_test.c +++ b/test/bio_enc_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 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 @@ -132,7 +132,17 @@ static int do_bio_cipher(const EVP_CIPHER* cipher, const unsigned char* key, if (!TEST_ptr(mem)) goto err; BIO_push(b, mem); +#if 0 + /* + * This is wrong to do, it always fails, and incorrectly ends up + * calling `EVP_CipherFinal()` and setting ctx->finished = 1, ... + * all of which are unwanted. But just deleting this is less + * instructive to future readers of the code. Don't call BIO_flush + * until you're done either reading or writing and want to finalise + * the state. + */ (void)BIO_flush(b); +#endif memset(out, 0, sizeof(out)); len = BIO_read(b, out, sizeof(out)); BIO_free_all(b); @@ -250,6 +260,66 @@ static int test_bio_enc_chacha20_poly1305(int idx) # endif # endif +static int test_bio_enc_eof_read_flush(void) +{ + /* Length chosen to ensure base64 encoding employs padding */ + const unsigned char pbuf[] = "Attack at dawn"; + unsigned char cbuf[16]; /* At least as long as pbuf */ + const EVP_CIPHER *cipher = EVP_aes_256_gcm(); + EVP_CIPHER_CTX *ctx = NULL; + BIO *mem = NULL, *b64 = NULL, *cbio = NULL; + unsigned char tag[16]; + size_t key_size, iv_size; + int n, ret = 0; + + memset(tag, 0, sizeof(tag)); + if (!TEST_ptr(cipher) + || !TEST_int_gt((key_size = EVP_CIPHER_key_length(cipher)), 0) + || !TEST_int_gt((iv_size = EVP_CIPHER_iv_length(cipher)), 0) + || !TEST_ptr(mem = BIO_new(BIO_s_mem())) + || !TEST_ptr(b64 = BIO_new(BIO_f_base64())) + || !TEST_ptr(cbio = BIO_new(BIO_f_cipher())) + || !TEST_ptr(BIO_push(b64, mem)) + || !TEST_ptr(BIO_push(cbio, b64)) + || !TEST_int_gt(BIO_get_cipher_ctx(cbio, &ctx), 0) + || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, KEY, IV, ENCRYPT)) + || !TEST_int_gt(BIO_write(cbio, pbuf, sizeof(pbuf) - 1), 0) + || !TEST_int_gt(BIO_flush(cbio), 0) + || !TEST_int_gt(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, + sizeof(tag), tag), 0)) + goto end; + BIO_free(cbio); + BIO_free(b64); + b64 = cbio = NULL; + + BIO_set_mem_eof_return(mem, 0); + BIO_set_flags(mem, BIO_FLAGS_NONCLEAR_RST); + if (!TEST_int_gt(BIO_reset(mem), 0) + || !TEST_ptr(b64 = BIO_new(BIO_f_base64())) + || !TEST_ptr(cbio = BIO_new(BIO_f_cipher())) + || !TEST_ptr(BIO_push(b64, mem)) + || !TEST_ptr(BIO_push(cbio, b64)) + || !TEST_int_gt(BIO_get_cipher_ctx(cbio, &ctx), 0) + || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, KEY, IV, DECRYPT)) + || !TEST_int_gt(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, + sizeof(tag), tag), 0) + || !TEST_int_gt((n = BIO_read(cbio, cbuf, sizeof(cbuf))), 0) + || !TEST_true(BIO_get_cipher_status(cbio)) + /* Evaluate both and report whether either or both failed */ + || (!TEST_int_gt(BIO_flush(cbio), 0) + + !TEST_true(BIO_get_cipher_status(cbio))) + || !TEST_mem_eq(cbuf, n, pbuf, sizeof(pbuf) - 1)) + goto end; + + ret = 1; + + end: + BIO_free(cbio); + BIO_free(b64); + BIO_free(mem); + return ret; +} + int setup_tests(void) { ADD_ALL_TESTS(test_bio_enc_aes_128_cbc, 2); @@ -262,5 +332,6 @@ int setup_tests(void) ADD_ALL_TESTS(test_bio_enc_chacha20_poly1305, 2); # endif # endif + ADD_TEST(test_bio_enc_eof_read_flush); return 1; } diff --git a/test/bio_pw_callback_test.c b/test/bio_pw_callback_test.c new file mode 100644 index 000000000000..e11368454a8c --- /dev/null +++ b/test/bio_pw_callback_test.c @@ -0,0 +1,402 @@ +/* + * Copyright 2024 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 "testutil.h" + +#include <openssl/bio.h> +#include <openssl/pem.h> + +/* dummy data that needs to be passed to the callback */ +typedef struct CallbackData { + char magic; + int result; +} CALLBACK_DATA; + +/* constants */ +static const char weak_password[] = "weak_password"; +static const char a0a_password[] = "aaaaaaaa\0aaaaaaaa"; +static const char a0b_password[] = "aaaaaaaa\0bbbbbbbb"; +static const char cb_magic = 'p'; + +/* shared working data for all tests */ +static char *key_file = NULL; +static EVP_PKEY *original_pkey = NULL; + +/* the test performed by the callback */ +typedef enum CallbackTest { + CB_TEST_NEGATIVE = 0, + CB_TEST_ZERO_LENGTH, + CB_TEST_WEAK, + CB_TEST_16ZERO, + CB_TEST_A0A, + CB_TEST_A0B, + CB_TEST_MATCH_SIZE, + CB_TEST_EXCEED_SIZE +} CALLBACK_TEST; +static CALLBACK_TEST callback_test = CB_TEST_NEGATIVE; + +typedef enum KeyEncoding { + KE_PEM = 0, + KE_PKCS8 +} KEY_ENCODING; + +typedef enum ExpectedResult { + ER_FAILURE = 0, + ER_SUCCESS +} EXPECTED_RESULT; + +typedef enum OPTION_choice { + OPT_ERR = -1, + OPT_EOF = 0, + OPT_KEY_FILE, + OPT_TEST_ENUM +} OPTION_CHOICE; + +const OPTIONS *test_get_options(void) +{ + static const OPTIONS test_options[] = { + OPT_TEST_OPTIONS_DEFAULT_USAGE, + { "keyfile", OPT_KEY_FILE, '<', + "The PEM file with the encrypted key to load" }, + { NULL } + }; + return test_options; +} + +static int callback_copy_password(char *buf, int size) +{ + int ret = -1; + + switch (callback_test) { + case CB_TEST_NEGATIVE: + break; + case CB_TEST_ZERO_LENGTH: + ret = 0; + break; + case CB_TEST_WEAK: + ret = sizeof(weak_password) - 1; + memcpy(buf, weak_password, ret); + break; + case CB_TEST_16ZERO: + memset(buf, 0, 16); + ret = 16; + break; + case CB_TEST_A0A: + ret = sizeof(a0a_password) - 1; + memcpy(buf, a0a_password, ret); + break; + case CB_TEST_A0B: + ret = sizeof(a0b_password) - 1; + memcpy(buf, a0b_password, ret); + break; + case CB_TEST_MATCH_SIZE: + memset(buf, 'e', size); + ret = size; + break; + case CB_TEST_EXCEED_SIZE: + memset(buf, 'e', size); + ret = 1000000; + break; + } + return ret; +} + +static int read_callback(char *buf, int size, int rwflag, void *u) +{ + CALLBACK_DATA *cb_data = (CALLBACK_DATA *)u; + int ret = -1; + + /* basic verification of the received data */ + if (!TEST_ptr(cb_data)) + goto err; + if (!TEST_char_eq(cb_data->magic, cb_magic)) + goto err; + if (!TEST_ptr(buf)) + goto err; + if (!TEST_int_gt(size, 0)) + goto err; + if (!TEST_int_eq(rwflag, 0)) + goto err; + ret = callback_copy_password(buf, size); + cb_data->result = 1; +err: + return ret; +} + +static int write_callback(char *buf, int size, int rwflag, void *u) +{ + CALLBACK_DATA *cb_data = (CALLBACK_DATA *)u; + int ret = -1; + + /* basic verification of the received data */ + if (!TEST_ptr(cb_data)) + goto err; + if (!TEST_char_eq(cb_data->magic, cb_magic)) + goto err; + if (!TEST_ptr(buf)) + goto err; + if (!TEST_int_gt(size, 0)) + goto err; + if (!TEST_int_eq(rwflag, 1)) + goto err; + ret = callback_copy_password(buf, size); + cb_data->result = 1; +err: + return ret; +} + +static int re_encrypt_key(char **enc_data, int *enc_data_size, + KEY_ENCODING key_encoding) +{ + CALLBACK_DATA cb_data; + int w_ret = 0; + BUF_MEM *bptr = NULL; + BIO *bio = NULL; + int ret = 0; + + if (!TEST_ptr(enc_data)) + goto err; + if (!TEST_ptr(enc_data_size)) + goto err; + if (!TEST_ptr(bio = BIO_new(BIO_s_mem()))) + goto err; + cb_data.magic = cb_magic; + cb_data.result = 0; + switch (key_encoding) { + case KE_PEM: + w_ret = PEM_write_bio_PrivateKey(bio, original_pkey, EVP_aes_256_cbc(), + NULL, 0, write_callback, &cb_data); + break; + case KE_PKCS8: + w_ret = i2d_PKCS8PrivateKey_bio(bio, original_pkey, EVP_aes_256_cbc(), + NULL, 0, write_callback, &cb_data); + break; + } + if (!TEST_int_ne(w_ret, 0)) + goto err; + if (!TEST_char_eq(cb_data.magic, cb_magic)) + goto err; + if (!TEST_int_eq(cb_data.result, 1)) + goto err; + *enc_data_size = BIO_get_mem_data(bio, enc_data); + BIO_get_mem_ptr(bio, &bptr); + if (!BIO_set_close(bio, BIO_NOCLOSE)) + goto err; + bptr->data = NULL; + ret = 1; +err: + BUF_MEM_free(bptr); + BIO_free(bio); + return ret; +} + +static int decrypt_key(char *enc_data, int enc_data_size, + KEY_ENCODING key_encoding, + EXPECTED_RESULT expected_result) +{ + CALLBACK_DATA cb_data; + EVP_PKEY *r_ret = NULL; + BIO *bio = NULL; + EVP_PKEY *pkey = NULL; + int ret = 0; + + if (!TEST_ptr(bio = BIO_new_mem_buf(enc_data, enc_data_size))) + goto err; + cb_data.magic = cb_magic; + cb_data.result = 0; + switch (key_encoding) { + case KE_PEM: + r_ret = PEM_read_bio_PrivateKey(bio, &pkey, read_callback, &cb_data); + break; + case KE_PKCS8: + r_ret = d2i_PKCS8PrivateKey_bio(bio, &pkey, read_callback, &cb_data); + break; + } + if (expected_result == ER_SUCCESS) { + if (!TEST_ptr(r_ret)) + goto err; + } else { + if (!TEST_ptr_null(r_ret)) + goto err; + } + if (!TEST_char_eq(cb_data.magic, cb_magic)) + goto err; + if (!TEST_int_eq(cb_data.result, 1)) + goto err; + ret = 1; +err: + EVP_PKEY_free(pkey); + BIO_free(bio); + return ret; +} + +static int full_cycle_test(KEY_ENCODING key_encoding, CALLBACK_TEST write_test, + CALLBACK_TEST read_test, + EXPECTED_RESULT expected_read_result) +{ + char *enc_data = NULL; + int enc_data_size = 0; + int ret = 0; + + callback_test = write_test; + if (!re_encrypt_key(&enc_data, &enc_data_size, key_encoding)) + goto err; + callback_test = read_test; + if (!decrypt_key(enc_data, enc_data_size, key_encoding, + expected_read_result)) + goto err; + ret = 1; +err: + OPENSSL_free(enc_data); + return ret; +} + +static int test_pem_negative(void) +{ + return full_cycle_test(KE_PEM, CB_TEST_WEAK, CB_TEST_NEGATIVE, ER_FAILURE); +} + +static int test_pem_zero_length(void) +{ + return full_cycle_test(KE_PEM, CB_TEST_ZERO_LENGTH, CB_TEST_ZERO_LENGTH, + ER_SUCCESS); +} + +static int test_pem_weak(void) +{ + return full_cycle_test(KE_PEM, CB_TEST_WEAK, CB_TEST_WEAK, ER_SUCCESS); +} + +static int test_pem_16zero(void) +{ + return full_cycle_test(KE_PEM, CB_TEST_16ZERO, CB_TEST_16ZERO, ER_SUCCESS); +} + +static int test_pem_a0a(void) +{ + return full_cycle_test(KE_PEM, CB_TEST_A0A, CB_TEST_A0A, ER_SUCCESS); +} + +static int test_pem_a0a_a0b(void) +{ + return full_cycle_test(KE_PEM, CB_TEST_A0A, CB_TEST_A0B, ER_FAILURE); +} + +static int test_pem_match_size(void) +{ + return full_cycle_test(KE_PEM, CB_TEST_MATCH_SIZE, CB_TEST_MATCH_SIZE, + ER_SUCCESS); +} + +static int test_pem_exceed_size(void) +{ + return full_cycle_test(KE_PEM, CB_TEST_MATCH_SIZE, CB_TEST_EXCEED_SIZE, + ER_FAILURE); +} + +static int test_pkcs8_negative(void) +{ + return full_cycle_test(KE_PKCS8, CB_TEST_WEAK, CB_TEST_NEGATIVE, ER_FAILURE); +} + +static int test_pkcs8_zero_length(void) +{ + return full_cycle_test(KE_PKCS8, CB_TEST_ZERO_LENGTH, CB_TEST_ZERO_LENGTH, + ER_SUCCESS); +} + +static int test_pkcs8_weak(void) +{ + return full_cycle_test(KE_PKCS8, CB_TEST_WEAK, CB_TEST_WEAK, ER_SUCCESS); +} + +static int test_pkcs8_16zero(void) +{ + return full_cycle_test(KE_PKCS8, CB_TEST_16ZERO, CB_TEST_16ZERO, + ER_SUCCESS); +} + +static int test_pkcs8_a0a(void) +{ + return full_cycle_test(KE_PKCS8, CB_TEST_A0A, CB_TEST_A0A, ER_SUCCESS); +} + +static int test_pkcs8_a0a_a0b(void) +{ + return full_cycle_test(KE_PKCS8, CB_TEST_A0A, CB_TEST_A0B, ER_FAILURE); +} + +static int test_pkcs8_match_size(void) +{ + return full_cycle_test(KE_PKCS8, CB_TEST_MATCH_SIZE, CB_TEST_MATCH_SIZE, + ER_SUCCESS); +} + +static int test_pkcs8_exceed_size(void) +{ + return full_cycle_test(KE_PKCS8, CB_TEST_MATCH_SIZE, CB_TEST_EXCEED_SIZE, + ER_FAILURE); +} + +static int callback_original_pw(char *buf, int size, int rwflag, void *u) +{ + memcpy(buf, weak_password, sizeof(weak_password) - 1); + return sizeof(weak_password) - 1; +} + +int setup_tests(void) +{ + OPTION_CHOICE o; + BIO *bio = NULL; + + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_KEY_FILE: + key_file = opt_arg(); + break; + case OPT_TEST_CASES: + break; + default: + case OPT_ERR: + return 0; + } + } + + /* read the original key */ + if (!TEST_ptr(bio = BIO_new_file(key_file, "r"))) + return 0; + if (!TEST_ptr(PEM_read_bio_PrivateKey(bio, &original_pkey, + callback_original_pw, NULL))) + return 0; + BIO_free(bio); + + /* add all tests */ + ADD_TEST(test_pem_negative); + ADD_TEST(test_pem_zero_length); + ADD_TEST(test_pem_weak); + ADD_TEST(test_pem_16zero); + ADD_TEST(test_pem_a0a); + ADD_TEST(test_pem_a0a_a0b); + ADD_TEST(test_pem_match_size); + ADD_TEST(test_pem_exceed_size); + ADD_TEST(test_pkcs8_negative); + ADD_TEST(test_pkcs8_zero_length); + ADD_TEST(test_pkcs8_weak); + ADD_TEST(test_pkcs8_16zero); + ADD_TEST(test_pkcs8_a0a); + ADD_TEST(test_pkcs8_a0a_a0b); + ADD_TEST(test_pkcs8_match_size); + ADD_TEST(test_pkcs8_exceed_size); + return 1; +} + +void cleanup_tests(void) +{ + EVP_PKEY_free(original_pkey); +} diff --git a/test/bioprinttest.c b/test/bioprinttest.c index 04d1613c6cf4..46d2a3e644a2 100644 --- a/test/bioprinttest.c +++ b/test/bioprinttest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 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 @@ -20,90 +20,97 @@ static int justprint = 0; -static char *fpexpected[][10][5] = { +static char *fpexpected[][11][5] = { { - /* 00 */ { "0.0000e+00", "0.0000", "0", "0.0000E+00", "0" }, - /* 01 */ { "6.7000e-01", "0.6700", "0.67", "6.7000E-01", "0.67" }, - /* 02 */ { "6.6667e-01", "0.6667", "0.6667", "6.6667E-01", "0.6667" }, - /* 03 */ { "6.6667e-04", "0.0007", "0.0006667", "6.6667E-04", "0.0006667" }, - /* 04 */ { "6.6667e-05", "0.0001", "6.667e-05", "6.6667E-05", "6.667E-05" }, - /* 05 */ { "6.6667e+00", "6.6667", "6.667", "6.6667E+00", "6.667" }, - /* 06 */ { "6.6667e+01", "66.6667", "66.67", "6.6667E+01", "66.67" }, - /* 07 */ { "6.6667e+02", "666.6667", "666.7", "6.6667E+02", "666.7" }, - /* 08 */ { "6.6667e+03", "6666.6667", "6667", "6.6667E+03", "6667" }, - /* 09 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" }, + /* 0.00 */ { "0.0000e+00", "0.0000", "0", "0.0000E+00", "0" }, + /* 0.01 */ { "6.7000e-01", "0.6700", "0.67", "6.7000E-01", "0.67" }, + /* 0.02 */ { "6.6667e-01", "0.6667", "0.6667", "6.6667E-01", "0.6667" }, + /* 0.03 */ { "6.6667e-04", "0.0007", "0.0006667", "6.6667E-04", "0.0006667" }, + /* 0.04 */ { "6.6667e-05", "0.0001", "6.667e-05", "6.6667E-05", "6.667E-05" }, + /* 0.05 */ { "6.6667e+00", "6.6667", "6.667", "6.6667E+00", "6.667" }, + /* 0.06 */ { "6.6667e+01", "66.6667", "66.67", "6.6667E+01", "66.67" }, + /* 0.07 */ { "6.6667e+02", "666.6667", "666.7", "6.6667E+02", "666.7" }, + /* 0.08 */ { "6.6667e+03", "6666.6667", "6667", "6.6667E+03", "6667" }, + /* 0.09 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" }, + /* 0.10 */ { "-6.6667e+04", "-66666.6667", "-6.667e+04", "-6.6667E+04", "-6.667E+04" }, }, { - /* 10 */ { "0.00000e+00", "0.00000", "0", "0.00000E+00", "0" }, - /* 11 */ { "6.70000e-01", "0.67000", "0.67", "6.70000E-01", "0.67" }, - /* 12 */ { "6.66667e-01", "0.66667", "0.66667", "6.66667E-01", "0.66667" }, - /* 13 */ { "6.66667e-04", "0.00067", "0.00066667", "6.66667E-04", "0.00066667" }, - /* 14 */ { "6.66667e-05", "0.00007", "6.6667e-05", "6.66667E-05", "6.6667E-05" }, - /* 15 */ { "6.66667e+00", "6.66667", "6.6667", "6.66667E+00", "6.6667" }, - /* 16 */ { "6.66667e+01", "66.66667", "66.667", "6.66667E+01", "66.667" }, - /* 17 */ { "6.66667e+02", "666.66667", "666.67", "6.66667E+02", "666.67" }, - /* 18 */ { "6.66667e+03", "6666.66667", "6666.7", "6.66667E+03", "6666.7" }, - /* 19 */ { "6.66667e+04", "66666.66667", "66667", "6.66667E+04", "66667" }, + /* 1.00 */ { "0.00000e+00", "0.00000", "0", "0.00000E+00", "0" }, + /* 1.01 */ { "6.70000e-01", "0.67000", "0.67", "6.70000E-01", "0.67" }, + /* 1.02 */ { "6.66667e-01", "0.66667", "0.66667", "6.66667E-01", "0.66667" }, + /* 1.03 */ { "6.66667e-04", "0.00067", "0.00066667", "6.66667E-04", "0.00066667" }, + /* 1.04 */ { "6.66667e-05", "0.00007", "6.6667e-05", "6.66667E-05", "6.6667E-05" }, + /* 1.05 */ { "6.66667e+00", "6.66667", "6.6667", "6.66667E+00", "6.6667" }, + /* 1.06 */ { "6.66667e+01", "66.66667", "66.667", "6.66667E+01", "66.667" }, + /* 1.07 */ { "6.66667e+02", "666.66667", "666.67", "6.66667E+02", "666.67" }, + /* 1.08 */ { "6.66667e+03", "6666.66667", "6666.7", "6.66667E+03", "6666.7" }, + /* 1.09 */ { "6.66667e+04", "66666.66667", "66667", "6.66667E+04", "66667" }, + /* 1.10 */ { "-6.66667e+04", "-66666.66667", "-66667", "-6.66667E+04", "-66667" }, }, { - /* 20 */ { " 0.0000e+00", " 0.0000", " 0", " 0.0000E+00", " 0" }, - /* 21 */ { " 6.7000e-01", " 0.6700", " 0.67", " 6.7000E-01", " 0.67" }, - /* 22 */ { " 6.6667e-01", " 0.6667", " 0.6667", " 6.6667E-01", " 0.6667" }, - /* 23 */ { " 6.6667e-04", " 0.0007", " 0.0006667", " 6.6667E-04", " 0.0006667" }, - /* 24 */ { " 6.6667e-05", " 0.0001", " 6.667e-05", " 6.6667E-05", " 6.667E-05" }, - /* 25 */ { " 6.6667e+00", " 6.6667", " 6.667", " 6.6667E+00", " 6.667" }, - /* 26 */ { " 6.6667e+01", " 66.6667", " 66.67", " 6.6667E+01", " 66.67" }, - /* 27 */ { " 6.6667e+02", " 666.6667", " 666.7", " 6.6667E+02", " 666.7" }, - /* 28 */ { " 6.6667e+03", " 6666.6667", " 6667", " 6.6667E+03", " 6667" }, - /* 29 */ { " 6.6667e+04", " 66666.6667", " 6.667e+04", " 6.6667E+04", " 6.667E+04" }, + /* 2.00 */ { " 0.0000e+00", " 0.0000", " 0", " 0.0000E+00", " 0" }, + /* 2.01 */ { " 6.7000e-01", " 0.6700", " 0.67", " 6.7000E-01", " 0.67" }, + /* 2.02 */ { " 6.6667e-01", " 0.6667", " 0.6667", " 6.6667E-01", " 0.6667" }, + /* 2.03 */ { " 6.6667e-04", " 0.0007", " 0.0006667", " 6.6667E-04", " 0.0006667" }, + /* 2.04 */ { " 6.6667e-05", " 0.0001", " 6.667e-05", " 6.6667E-05", " 6.667E-05" }, + /* 2.05 */ { " 6.6667e+00", " 6.6667", " 6.667", " 6.6667E+00", " 6.667" }, + /* 2.06 */ { " 6.6667e+01", " 66.6667", " 66.67", " 6.6667E+01", " 66.67" }, + /* 2.07 */ { " 6.6667e+02", " 666.6667", " 666.7", " 6.6667E+02", " 666.7" }, + /* 2.08 */ { " 6.6667e+03", " 6666.6667", " 6667", " 6.6667E+03", " 6667" }, + /* 2.09 */ { " 6.6667e+04", " 66666.6667", " 6.667e+04", " 6.6667E+04", " 6.667E+04" }, + /* 2.10 */ { " -6.6667e+04", " -66666.6667", " -6.667e+04", " -6.6667E+04", " -6.667E+04" }, }, { - /* 30 */ { " 0.00000e+00", " 0.00000", " 0", " 0.00000E+00", " 0" }, - /* 31 */ { " 6.70000e-01", " 0.67000", " 0.67", " 6.70000E-01", " 0.67" }, - /* 32 */ { " 6.66667e-01", " 0.66667", " 0.66667", " 6.66667E-01", " 0.66667" }, - /* 33 */ { " 6.66667e-04", " 0.00067", " 0.00066667", " 6.66667E-04", " 0.00066667" }, - /* 34 */ { " 6.66667e-05", " 0.00007", " 6.6667e-05", " 6.66667E-05", " 6.6667E-05" }, - /* 35 */ { " 6.66667e+00", " 6.66667", " 6.6667", " 6.66667E+00", " 6.6667" }, - /* 36 */ { " 6.66667e+01", " 66.66667", " 66.667", " 6.66667E+01", " 66.667" }, - /* 37 */ { " 6.66667e+02", " 666.66667", " 666.67", " 6.66667E+02", " 666.67" }, - /* 38 */ { " 6.66667e+03", " 6666.66667", " 6666.7", " 6.66667E+03", " 6666.7" }, - /* 39 */ { " 6.66667e+04", " 66666.66667", " 66667", " 6.66667E+04", " 66667" }, + /* 3.00 */ { " 0.00000e+00", " 0.00000", " 0", " 0.00000E+00", " 0" }, + /* 3.01 */ { " 6.70000e-01", " 0.67000", " 0.67", " 6.70000E-01", " 0.67" }, + /* 3.02 */ { " 6.66667e-01", " 0.66667", " 0.66667", " 6.66667E-01", " 0.66667" }, + /* 3.03 */ { " 6.66667e-04", " 0.00067", " 0.00066667", " 6.66667E-04", " 0.00066667" }, + /* 3.04 */ { " 6.66667e-05", " 0.00007", " 6.6667e-05", " 6.66667E-05", " 6.6667E-05" }, + /* 3.05 */ { " 6.66667e+00", " 6.66667", " 6.6667", " 6.66667E+00", " 6.6667" }, + /* 3.06 */ { " 6.66667e+01", " 66.66667", " 66.667", " 6.66667E+01", " 66.667" }, + /* 3.07 */ { " 6.66667e+02", " 666.66667", " 666.67", " 6.66667E+02", " 666.67" }, + /* 3.08 */ { " 6.66667e+03", " 6666.66667", " 6666.7", " 6.66667E+03", " 6666.7" }, + /* 3.09 */ { " 6.66667e+04", " 66666.66667", " 66667", " 6.66667E+04", " 66667" }, + /* 3.10 */ { "-6.66667e+04", "-66666.66667", " -66667", "-6.66667E+04", " -66667" }, }, { - /* 40 */ { "0e+00", "0", "0", "0E+00", "0" }, - /* 41 */ { "7e-01", "1", "0.7", "7E-01", "0.7" }, - /* 42 */ { "7e-01", "1", "0.7", "7E-01", "0.7" }, - /* 43 */ { "7e-04", "0", "0.0007", "7E-04", "0.0007" }, - /* 44 */ { "7e-05", "0", "7e-05", "7E-05", "7E-05" }, - /* 45 */ { "7e+00", "7", "7", "7E+00", "7" }, - /* 46 */ { "7e+01", "67", "7e+01", "7E+01", "7E+01" }, - /* 47 */ { "7e+02", "667", "7e+02", "7E+02", "7E+02" }, - /* 48 */ { "7e+03", "6667", "7e+03", "7E+03", "7E+03" }, - /* 49 */ { "7e+04", "66667", "7e+04", "7E+04", "7E+04" }, + /* 4.00 */ { "0e+00", "0", "0", "0E+00", "0" }, + /* 4.01 */ { "7e-01", "1", "0.7", "7E-01", "0.7" }, + /* 4.02 */ { "7e-01", "1", "0.7", "7E-01", "0.7" }, + /* 4.03 */ { "7e-04", "0", "0.0007", "7E-04", "0.0007" }, + /* 4.04 */ { "7e-05", "0", "7e-05", "7E-05", "7E-05" }, + /* 4.05 */ { "7e+00", "7", "7", "7E+00", "7" }, + /* 4.06 */ { "7e+01", "67", "7e+01", "7E+01", "7E+01" }, + /* 4.07 */ { "7e+02", "667", "7e+02", "7E+02", "7E+02" }, + /* 4.08 */ { "7e+03", "6667", "7e+03", "7E+03", "7E+03" }, + /* 4.09 */ { "7e+04", "66667", "7e+04", "7E+04", "7E+04" }, + /* 4.10 */ { "-7e+04", "-66667", "-7e+04", "-7E+04", "-7E+04" }, }, { - /* 50 */ { "0.000000e+00", "0.000000", "0", "0.000000E+00", "0" }, - /* 51 */ { "6.700000e-01", "0.670000", "0.67", "6.700000E-01", "0.67" }, - /* 52 */ { "6.666667e-01", "0.666667", "0.666667", "6.666667E-01", "0.666667" }, - /* 53 */ { "6.666667e-04", "0.000667", "0.000666667", "6.666667E-04", "0.000666667" }, - /* 54 */ { "6.666667e-05", "0.000067", "6.66667e-05", "6.666667E-05", "6.66667E-05" }, - /* 55 */ { "6.666667e+00", "6.666667", "6.66667", "6.666667E+00", "6.66667" }, - /* 56 */ { "6.666667e+01", "66.666667", "66.6667", "6.666667E+01", "66.6667" }, - /* 57 */ { "6.666667e+02", "666.666667", "666.667", "6.666667E+02", "666.667" }, - /* 58 */ { "6.666667e+03", "6666.666667", "6666.67", "6.666667E+03", "6666.67" }, - /* 59 */ { "6.666667e+04", "66666.666667", "66666.7", "6.666667E+04", "66666.7" }, + /* 5.00 */ { "0.000000e+00", "0.000000", "0", "0.000000E+00", "0" }, + /* 5.01 */ { "6.700000e-01", "0.670000", "0.67", "6.700000E-01", "0.67" }, + /* 5.02 */ { "6.666667e-01", "0.666667", "0.666667", "6.666667E-01", "0.666667" }, + /* 5.03 */ { "6.666667e-04", "0.000667", "0.000666667", "6.666667E-04", "0.000666667" }, + /* 5.04 */ { "6.666667e-05", "0.000067", "6.66667e-05", "6.666667E-05", "6.66667E-05" }, + /* 5.05 */ { "6.666667e+00", "6.666667", "6.66667", "6.666667E+00", "6.66667" }, + /* 5.06 */ { "6.666667e+01", "66.666667", "66.6667", "6.666667E+01", "66.6667" }, + /* 5.07 */ { "6.666667e+02", "666.666667", "666.667", "6.666667E+02", "666.667" }, + /* 5.08 */ { "6.666667e+03", "6666.666667", "6666.67", "6.666667E+03", "6666.67" }, + /* 5.09 */ { "6.666667e+04", "66666.666667", "66666.7", "6.666667E+04", "66666.7" }, + /* 5.10 */ { "-6.666667e+04", "-66666.666667", "-66666.7", "-6.666667E+04", "-66666.7" }, }, { - /* 60 */ { "0.0000e+00", "000.0000", "00000000", "0.0000E+00", "00000000" }, - /* 61 */ { "6.7000e-01", "000.6700", "00000.67", "6.7000E-01", "00000.67" }, - /* 62 */ { "6.6667e-01", "000.6667", "000.6667", "6.6667E-01", "000.6667" }, - /* 63 */ { "6.6667e-04", "000.0007", "0.0006667", "6.6667E-04", "0.0006667" }, - /* 64 */ { "6.6667e-05", "000.0001", "6.667e-05", "6.6667E-05", "6.667E-05" }, - /* 65 */ { "6.6667e+00", "006.6667", "0006.667", "6.6667E+00", "0006.667" }, - /* 66 */ { "6.6667e+01", "066.6667", "00066.67", "6.6667E+01", "00066.67" }, - /* 67 */ { "6.6667e+02", "666.6667", "000666.7", "6.6667E+02", "000666.7" }, - /* 68 */ { "6.6667e+03", "6666.6667", "00006667", "6.6667E+03", "00006667" }, - /* 69 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" }, + /* 6.00 */ { "0.0000e+00", "000.0000", "00000000", "0.0000E+00", "00000000" }, + /* 6.01 */ { "6.7000e-01", "000.6700", "00000.67", "6.7000E-01", "00000.67" }, + /* 6.02 */ { "6.6667e-01", "000.6667", "000.6667", "6.6667E-01", "000.6667" }, + /* 6.03 */ { "6.6667e-04", "000.0007", "0.0006667", "6.6667E-04", "0.0006667" }, + /* 6.04 */ { "6.6667e-05", "000.0001", "6.667e-05", "6.6667E-05", "6.667E-05" }, + /* 6.05 */ { "6.6667e+00", "006.6667", "0006.667", "6.6667E+00", "0006.667" }, + /* 6.06 */ { "6.6667e+01", "066.6667", "00066.67", "6.6667E+01", "00066.67" }, + /* 6.07 */ { "6.6667e+02", "666.6667", "000666.7", "6.6667E+02", "000666.7" }, + /* 6.08 */ { "6.6667e+03", "6666.6667", "00006667", "6.6667E+03", "00006667" }, + /* 6.09 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" }, + /* 6.10 */ { "-6.6667e+04", "-66666.6667", "-6.667e+04", "-6.6667E+04", "-6.667E+04" }, }, }; @@ -204,7 +211,7 @@ static int dofptest(int test, int sub, double val, const char *width, int prec) if (justprint) { if (i == 0) - printf(" /* %d%d */ { \"%s\"", test, sub, result); + printf(" /* %d.%02d */ { \"%s\"", test, sub, result); else printf(", \"%s\"", result); } else if (!TEST_str_eq(fpexpected[test][sub][i], result)) { @@ -235,7 +242,8 @@ static int test_fp(int i) && TEST_true(dofptest(i, t++, 66.0 + frac, pwp->w, pwp->p)) && TEST_true(dofptest(i, t++, 666.0 + frac, pwp->w, pwp->p)) && TEST_true(dofptest(i, t++, 6666.0 + frac, pwp->w, pwp->p)) - && TEST_true(dofptest(i, t++, 66666.0 + frac, pwp->w, pwp->p)); + && TEST_true(dofptest(i, t++, 66666.0 + frac, pwp->w, pwp->p)) + && TEST_true(dofptest(i, t++, -66666.0 - frac, pwp->w, pwp->p)); if (justprint) printf(" },\n"); return r; diff --git a/test/dhtest.c b/test/dhtest.c index 000dd5b69805..a49cb6cb5f84 100644 --- a/test/dhtest.c +++ b/test/dhtest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 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 @@ -208,17 +208,17 @@ static int dh_test(void) alen = DH_size(a); if (!TEST_ptr(abuf = OPENSSL_malloc(alen)) - || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1)) + || !TEST_int_gt((aout = DH_compute_key(abuf, bpub_key, a)), 0)) goto err3; blen = DH_size(b); if (!TEST_ptr(bbuf = OPENSSL_malloc(blen)) - || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1)) + || !TEST_int_gt((bout = DH_compute_key(bbuf, apub_key, b)), 0)) goto err3; clen = DH_size(c); if (!TEST_ptr(cbuf = OPENSSL_malloc(clen)) - || !TEST_true((cout = DH_compute_key(cbuf, apub_key, c)) != -1)) + || !TEST_int_gt((cout = DH_compute_key(cbuf, apub_key, c)), 0)) goto err3; if (!TEST_true(aout >= 20) @@ -694,12 +694,12 @@ static int rfc7919_test(void) alen = DH_size(a); if (!TEST_int_gt(alen, 0) || !TEST_ptr(abuf = OPENSSL_malloc(alen)) - || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1)) + || !TEST_int_gt((aout = DH_compute_key(abuf, bpub_key, a)), 0)) goto err; blen = DH_size(b); if (!TEST_int_gt(blen, 0) || !TEST_ptr(bbuf = OPENSSL_malloc(blen)) - || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1)) + || !TEST_int_gt((bout = DH_compute_key(bbuf, apub_key, b)), 0)) goto err; if (!TEST_true(aout >= 20) diff --git a/test/ectest.c b/test/ectest.c index 946973c2f4d9..061aec97f42c 100644 --- a/test/ectest.c +++ b/test/ectest.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -2707,7 +2707,7 @@ static int custom_params_test(int id) int is_prime = 0; EC_KEY *eckey1 = NULL, *eckey2 = NULL; EVP_PKEY *pkey1 = NULL, *pkey2 = NULL; - EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL; + EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL, *dctx = NULL; size_t sslen, t; unsigned char *pub1 = NULL , *pub2 = NULL; OSSL_PARAM_BLD *param_bld = NULL; @@ -2930,11 +2930,12 @@ static int custom_params_test(int id) EVP_PKEY_CTX_free(pctx1); if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL)) || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1) - || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1) - || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &t), 1) + || !TEST_ptr(dctx = EVP_PKEY_CTX_dup(pctx1)) + || !TEST_int_eq(EVP_PKEY_derive_set_peer_ex(dctx, pkey2, 1), 1) + || !TEST_int_eq(EVP_PKEY_derive(dctx, NULL, &t), 1) || !TEST_int_gt(bsize, t) || !TEST_int_le(sslen, t) - || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &t), 1) + || !TEST_int_eq(EVP_PKEY_derive(dctx, buf1, &t), 1) /* compare with previous result */ || !TEST_mem_eq(buf1, t, buf2, sslen)) goto err; @@ -2962,6 +2963,7 @@ static int custom_params_test(int id) EVP_PKEY_free(pkey2); EVP_PKEY_CTX_free(pctx1); EVP_PKEY_CTX_free(pctx2); + EVP_PKEY_CTX_free(dctx); return ret; } diff --git a/test/endecode_test.c b/test/endecode_test.c index 0611d94216f0..b34659529e2c 100644 --- a/test/endecode_test.c +++ b/test/endecode_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 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 @@ -1241,6 +1241,28 @@ static int create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld) return do_create_ec_explicit_trinomial_params(bld, gen2, sizeof(gen2)); } # endif /* OPENSSL_NO_EC2M */ + +/* + * Test that multiple calls to OSSL_ENCODER_to_data() do not cause side effects + */ +static int ec_encode_to_data_multi(void) +{ + int ret; + OSSL_ENCODER_CTX *ectx = NULL; + EVP_PKEY *key = NULL; + uint8_t *enc = NULL; + size_t enc_len = 0; + + ret = TEST_ptr(key = EVP_PKEY_Q_keygen(testctx, "", "EC", "P-256")) + && TEST_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(key, EVP_PKEY_KEYPAIR, + "DER", NULL, NULL)) + && TEST_int_eq(OSSL_ENCODER_to_data(ectx, NULL, &enc_len), 1) + && TEST_int_eq(OSSL_ENCODER_to_data(ectx, &enc, &enc_len), 1); + OPENSSL_free(enc); + EVP_PKEY_free(key); + OSSL_ENCODER_CTX_free(ectx); + return ret; +} #endif /* OPENSSL_NO_EC */ typedef enum OPTION_choice { @@ -1421,6 +1443,7 @@ int setup_tests(void) # endif #endif #ifndef OPENSSL_NO_EC + ADD_TEST(ec_encode_to_data_multi); ADD_TEST_SUITE(EC); ADD_TEST_SUITE_PARAMS(EC); ADD_TEST_SUITE_LEGACY(EC); diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index c5fbbf8a8309..c626829fdfb8 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2025 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 @@ -716,7 +716,9 @@ static EVP_PKEY *make_key_fromdata(char *keytype, OSSL_PARAM *params) if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(testctx, keytype, testpropq))) goto err; - if (!TEST_int_gt(EVP_PKEY_fromdata_init(pctx), 0) + /* Check that premature EVP_PKEY_CTX_set_params() fails gracefully */ + if (!TEST_int_eq(EVP_PKEY_CTX_set_params(pctx, params), 0) + || !TEST_int_gt(EVP_PKEY_fromdata_init(pctx), 0) || !TEST_int_gt(EVP_PKEY_fromdata(pctx, &tmp_pkey, EVP_PKEY_KEYPAIR, params), 0)) goto err; @@ -2594,6 +2596,7 @@ static int test_empty_salt_info_HKDF(void) size_t outlen; int ret = 0; unsigned char salt[] = ""; + unsigned char fake[] = "0123456789"; unsigned char key[] = "012345678901234567890123456789"; unsigned char info[] = ""; const unsigned char expected[] = { @@ -2610,6 +2613,8 @@ static int test_empty_salt_info_HKDF(void) if (!TEST_int_gt(EVP_PKEY_derive_init(pctx), 0) || !TEST_int_gt(EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_salt(pctx, fake, + sizeof(fake) - 1), 0) || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, sizeof(salt) - 1), 0) || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_key(pctx, key, diff --git a/test/evp_libctx_test.c b/test/evp_libctx_test.c index fd114a118cb2..1a4b398643d8 100644 --- a/test/evp_libctx_test.c +++ b/test/evp_libctx_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 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 @@ -38,6 +38,8 @@ static OSSL_LIB_CTX *libctx = NULL; static OSSL_PROVIDER *nullprov = NULL; static OSSL_PROVIDER *libprov = NULL; static STACK_OF(OPENSSL_STRING) *cipher_names = NULL; +static int is_fips = 0; +static int is_fips_lt_3_5 = 0; typedef enum OPTION_choice { OPT_ERR = -1, @@ -631,9 +633,10 @@ static int kem_rsa_params(void) && TEST_int_eq(EVP_PKEY_decapsulate(pubctx, secret, &secretlen, ct, sizeof(ct)), 0) && TEST_uchar_eq(secret[0], 0) - /* Test encapsulate fails if the mode is not set */ + /* Unless newer FIPS, test encapsulate fails when the mode is not set. */ && TEST_int_eq(EVP_PKEY_encapsulate_init(pubctx, NULL), 1) - && TEST_int_eq(EVP_PKEY_encapsulate(pubctx, ct, &ctlen, secret, &secretlen), -2) + && (!is_fips_lt_3_5 || + TEST_int_eq(EVP_PKEY_encapsulate(pubctx, ct, &ctlen, secret, &secretlen), -2)) /* Test setting a bad kem ops fail */ && TEST_int_eq(EVP_PKEY_CTX_set_kem_op(pubctx, "RSA"), 0) && TEST_int_eq(EVP_PKEY_CTX_set_kem_op(pubctx, NULL), 0) @@ -743,8 +746,14 @@ int setup_tests(void) if (!test_get_libctx(&libctx, &nullprov, config_file, &libprov, prov_name)) return 0; + if (strcmp(prov_name, "fips") == 0) + is_fips = 1; + + is_fips_lt_3_5 = is_fips && fips_provider_version_lt(libctx, 3, 5, 0); + #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DH) - ADD_ALL_TESTS(test_dsa_param_keygen, 3 * 3 * 3); + if (!is_fips || fips_provider_version_lt(libctx, 3, 4, 0)) + ADD_ALL_TESTS(test_dsa_param_keygen, 3 * 3 * 3); #endif #ifndef OPENSSL_NO_DH ADD_ALL_TESTS(test_dh_safeprime_param_keygen, 3 * 3 * 3); diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c index 688a8c1c5e55..5c4920d0720e 100644 --- a/test/evp_pkey_provided_test.c +++ b/test/evp_pkey_provided_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 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 @@ -1782,6 +1782,53 @@ err: return ret; } +static const char *name_dup_algs[] = { +#ifndef OPENSSL_NO_ECX + "ED25519", +#endif +#ifndef OPENSSL_NO_ML_KEM + "ML-KEM-512", +#endif +#ifndef OPENSSL_NO_ML_DSA + "ML-DSA-44", +#endif + NULL +}; + +static int test_name_dup(int idx) +{ + const char *alg = name_dup_algs[idx]; + EVP_PKEY *key = NULL; + EVP_PKEY_CTX *factory = NULL, *ctx = NULL; + int i, ret = 0; + + if (alg == NULL + || (factory = EVP_PKEY_CTX_new_from_name(NULL, alg, NULL)) == NULL) + return 1; + TEST_info("Testing fresh context dup for: %s", alg); + + /* Run twice to check that *repeated* use works */ + for (i = 0; i < 2; ++i) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(key); + key = NULL; + if (!TEST_ptr(ctx = EVP_PKEY_CTX_dup(factory)) + || !TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0) + || !TEST_int_gt(EVP_PKEY_keygen(ctx, &key), 0)) { + ERR_print_errors(bio_err); + goto end; + } + } + ret = 1; + + end: + EVP_PKEY_CTX_free(factory); + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(key); + + return ret; +} + int setup_tests(void) { if (!test_skip_common_options()) { @@ -1793,6 +1840,7 @@ int setup_tests(void) return 0; ADD_TEST(test_evp_pkey_ctx_dup_kdf_fail); + ADD_ALL_TESTS(test_name_dup, OSSL_NELEM(name_dup_algs)); ADD_TEST(test_evp_pkey_get_bn_param_large); ADD_TEST(test_fromdata_rsa); #ifndef OPENSSL_NO_DH diff --git a/test/evp_test.c b/test/evp_test.c index 2701040dabe7..020a5d55013e 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2025 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 @@ -352,8 +352,10 @@ static int digest_test_init(EVP_TEST *t, const char *alg) if ((digest = fetched_digest = EVP_MD_fetch(libctx, alg, NULL)) == NULL && (digest = EVP_get_digestbyname(alg)) == NULL) return 0; - if (!TEST_ptr(mdat = OPENSSL_zalloc(sizeof(*mdat)))) + if (!TEST_ptr(mdat = OPENSSL_zalloc(sizeof(*mdat)))) { + EVP_MD_free(fetched_digest); return 0; + } t->data = mdat; mdat->digest = digest; mdat->fetched_digest = fetched_digest; @@ -3960,7 +3962,9 @@ static int run_file_tests(int i) clear_test(t); free_key_list(public_keys); + public_keys = NULL; free_key_list(private_keys); + private_keys = NULL; BIO_free(t->s.key); c = t->s.errors; OPENSSL_free(t); diff --git a/test/nocache-and-default.cnf b/test/nocache-and-default.cnf new file mode 100644 index 000000000000..cf5ca8d11415 --- /dev/null +++ b/test/nocache-and-default.cnf @@ -0,0 +1,18 @@ +openssl_conf = openssl_init + +# Comment out the next line to ignore configuration errors +config_diagnostics = 1 + +[openssl_init] +providers = provider_sect + +[provider_sect] +test = test_sect +default = default_sect + +[test_sect] +module = ../test/p_test.so +activate = true + +[default_sect] +activate = true diff --git a/test/params_api_test.c b/test/params_api_test.c index 48e2f8920aa2..9c68825de216 100644 --- a/test/params_api_test.c +++ b/test/params_api_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -692,6 +692,33 @@ static int test_param_copy_null(void) OSSL_PARAM_free(cp1); return ret; } +static int test_param_merge(void) +{ + int val, ret; + int values[] = {1, 2, 3, 4}; + OSSL_PARAM *p = NULL, *cp = NULL; + OSSL_PARAM param[3], param1[3]; + + param[0] = OSSL_PARAM_construct_int("diff1", &values[0]); + param[1] = OSSL_PARAM_construct_int("same", &values[1]); + param[2] = OSSL_PARAM_construct_end(); + param1[0] = OSSL_PARAM_construct_int("diff2", &values[2]); + param1[1] = OSSL_PARAM_construct_int("same", &values[3]); + param1[2] = OSSL_PARAM_construct_end(); + + ret = TEST_ptr(p = OSSL_PARAM_merge(param, param1)) + && TEST_ptr(cp = OSSL_PARAM_locate(p, "diff1")) + && TEST_true(OSSL_PARAM_get_int(p, &val)) + && TEST_int_eq(val, values[0]) + && TEST_ptr(cp = OSSL_PARAM_locate(p, "diff2")) + && TEST_true(OSSL_PARAM_get_int(cp, &val)) + && TEST_int_eq(val, values[2]) + && TEST_ptr(cp = OSSL_PARAM_locate(p, "same")) + && TEST_true(OSSL_PARAM_get_int(cp, &val)) + && TEST_int_eq(val, values[3]); + OSSL_PARAM_free(p); + return ret; +} int setup_tests(void) { @@ -710,5 +737,6 @@ int setup_tests(void) ADD_ALL_TESTS(test_param_construct, 4); ADD_TEST(test_param_modified); ADD_TEST(test_param_copy_null); + ADD_TEST(test_param_merge); return 1; } diff --git a/test/rand_test.c b/test/rand_test.c index c6cf32610eb3..7d7af4c6bf40 100644 --- a/test/rand_test.c +++ b/test/rand_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2025 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 @@ -19,6 +19,7 @@ static int test_rand(void) OSSL_PARAM params[2], *p = params; unsigned char entropy1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; unsigned char entropy2[] = { 0xff, 0xfe, 0xfd }; + unsigned char nonce[] = { 0x00, 0x01, 0x02, 0x03, 0x04 }; unsigned char outbuf[3]; *p++ = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, @@ -41,6 +42,14 @@ static int test_rand(void) || !TEST_int_gt(RAND_priv_bytes(outbuf, sizeof(outbuf)), 0) || !TEST_mem_eq(outbuf, sizeof(outbuf), entropy2, sizeof(outbuf))) return 0; + + *params = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE, + nonce, sizeof(nonce)); + if (!TEST_true(EVP_RAND_CTX_set_params(privctx, params)) + || !TEST_true(EVP_RAND_nonce(privctx, outbuf, sizeof(outbuf))) + || !TEST_mem_eq(outbuf, sizeof(outbuf), nonce, sizeof(outbuf))) + return 0; + return 1; } diff --git a/test/recipes/20-test_nocache.t b/test/recipes/20-test_nocache.t new file mode 100644 index 000000000000..f7a956ee05ef --- /dev/null +++ b/test/recipes/20-test_nocache.t @@ -0,0 +1,34 @@ +#! /usr/bin/env perl +# Copyright 2016-2025 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 + +use strict; +use warnings; + +use OpenSSL::Test qw/:DEFAULT bldtop_file srctop_file bldtop_dir with/; +use OpenSSL::Test::Utils; + +setup("test_nocache"); + +plan tests => 4; + +ok(run(app(["openssl", "list", "-mac-algorithms"], + stdout => "listout.txt")), +"List mac algorithms - default configuration"); +open DATA, "listout.txt"; +my @match = grep /MAC/, <DATA>; +close DATA; +ok(scalar @match > 1 ? 1 : 0, "Several algorithms are listed - default configuration"); + +$ENV{OPENSSL_CONF} = bldtop_file("test", "nocache-and-default.cnf"); +ok(run(app(["openssl", "list", "-mac-algorithms"], + stdout => "listout.txt")), +"List mac algorithms"); +open DATA, "listout.txt"; +my @match = grep /MAC/, <DATA>; +close DATA; +ok(scalar @match > 1 ? 1 : 0, "Several algorithms are listed - nocache-and-default"); diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t index 7fa14d9daa8b..7bada5186d75 100644 --- a/test/recipes/25-test_verify.t +++ b/test/recipes/25-test_verify.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2025 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 @@ -10,6 +10,7 @@ use strict; use warnings; +use Cwd qw(abs_path); use File::Spec::Functions qw/canonpath/; use File::Copy; use OpenSSL::Test qw/:DEFAULT srctop_file bldtop_dir ok_nofips with/; @@ -17,19 +18,19 @@ use OpenSSL::Test::Utils; setup("test_verify"); +my @certspath = qw(test certs); sub verify { my ($cert, $purpose, $trusted, $untrusted, @opts) = @_; - my @path = qw(test certs); my @args = qw(openssl verify -auth_level 1); push(@args, "-purpose", $purpose) if $purpose ne ""; push(@args, @opts); - for (@$trusted) { push(@args, "-trusted", srctop_file(@path, "$_.pem")) } - for (@$untrusted) { push(@args, "-untrusted", srctop_file(@path, "$_.pem")) } - push(@args, srctop_file(@path, "$cert.pem")); + for (@$trusted) { push(@args, "-trusted", srctop_file(@certspath, "$_.pem")) } + for (@$untrusted) { push(@args, "-untrusted", srctop_file(@certspath, "$_.pem")) } + push(@args, srctop_file(@certspath, "$cert.pem")); run(app([@args])); } -plan tests => 166; +plan tests => 175; # Canonical success ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]), @@ -527,3 +528,31 @@ ok(!verify("ee-cert-policies-bad", "", ["root-cert"], ["ca-pol-cert"], "-policy_check", "-policy", "1.3.6.1.4.1.16604.998855.1", "-explicit_policy"), "Bad certificate policy"); + +# CAstore option +my $rootcertname = "root-cert"; +my $rootcert = srctop_file(@certspath, "${rootcertname}.pem"); +sub vfy_root { verify($rootcertname, "", [], [], @_) } +ok(vfy_root("-CAfile", $rootcert), "CAfile"); +ok(vfy_root("-CAstore", $rootcert), "CAstore"); +ok(vfy_root("-CAstore", $rootcert, "-CAfile", $rootcert), "CAfile and existing CAstore"); +ok(!vfy_root("-CAstore", "non-existing", "-CAfile", $rootcert), "CAfile and non-existing CAstore"); +SKIP: { + skip "file names with colons aren't supported on Windows and VMS", 2 + if $^O =~ /^(MsWin32|VMS)$/; + my $foo_file = "foo:cert.pem"; + copy($rootcert, $foo_file); + ok(vfy_root("-CAstore", $foo_file), "CAstore foo:file"); +} +my $foo_file = "cert.pem"; +copy($rootcert, $foo_file); +ok(vfy_root("-CAstore", $foo_file), "CAstore file"); +my $abs_cert = abs_path($rootcert); +# Windows file: URIs should have a path part starting with a slash, i.e. +# file://authority/C:/what/ever/foo.pem and file:///C:/what/ever/foo.pem +# file://C:/what/ever/foo.pem is non-standard and may not be accepted. +# See RFC 8089 for details. +$abs_cert = "/" . $abs_cert if ($^O eq "MSWin32"); +ok(vfy_root("-CAstore", "file://".$abs_cert), "CAstore file:///path"); +ok(vfy_root("-CAstore", "file://localhost".$abs_cert), "CAstore file://localhost/path"); +ok(!vfy_root("-CAstore", "file://otherhost".$abs_cert), "CAstore file://otherhost/path"); diff --git a/test/recipes/61-test_bio_pw_callback.t b/test/recipes/61-test_bio_pw_callback.t new file mode 100644 index 000000000000..4cb1db1f589f --- /dev/null +++ b/test/recipes/61-test_bio_pw_callback.t @@ -0,0 +1,20 @@ +#! /usr/bin/env perl +# Copyright 2024 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 + +use strict; +use warnings; + +use OpenSSL::Test qw(:DEFAULT data_file); + +setup('test_bio_pw_callback'); + +plan tests => 1; + +my $private_key_path = data_file("private_key.pem"); +ok(run(test(["bio_pw_callback_test", "-keyfile", $private_key_path])), + "Running bio_pw_callback_test"); diff --git a/test/recipes/61-test_bio_pw_callback_data/private_key.pem b/test/recipes/61-test_bio_pw_callback_data/private_key.pem new file mode 100644 index 000000000000..f9c9ae5dbc4a --- /dev/null +++ b/test/recipes/61-test_bio_pw_callback_data/private_key.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQmftpln/ZNiEznncq ++u0FuwICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEBO5TGcD0mGTfRS8 +HgafEXYEggTQOasEXPm4ChGPzfXACYhaAtMFnfL9qpI1S30bHMUHsWuXLZDFPNty +7KNKWr35woaq3XFEeul7onszcBBRrRwPkTqOifuv/J01s7oS0uC6jwbvSkAFNjHe +jkgvMMQA3y7nwZ2wSwVjO2K91qasTjNivus3ZaCvGqGpgNckEXILPZJEdWteWP+1 +SN9zLxxeHwgt5SrMfylrTghLB8b119/uq4GnOYHZdhMbp4YmneuGqvlZ7nle7qLY +33tuM5deajk9hINLfbYWGwURaOZ+r++Rvrz4OxISfe70uXT+2fcSZPVkNT5a6B5T +9rCwdF69W/+3au50gfc2VEF/xZBajxLI0PBpMSpxNE3a5/3YLKXAs+z0YJdQKNhN +U+SpOUv8D2GraJVfP7MddO2JvETh8w7tGN/a8qSw07Z91SE3Vfuq0l5PheC/vXJq +/xxU3YSbZC7LCSZn1aXBlj9KbTh2o1ARzdJsVYo1xY2OIFtFpncOjQDuaAmsNcZE +CuB9FUcBwwO/bjooIkv4lJU+DWDxrCR7Si8PZ4hHgXCXXKiXA20SBccUYm0Z4HR3 +i2tm9UTwAuCy1BF7hRmPLIyvlgtlKh2V9Cre5j86GoKTmPh/q5DHdSmNAM8Aakct +GdQgscOXRmHq7/1nec28wEhlbqVyYJ45MZbWhBTrycMru/ch9+ZnsIgPXLfbBA+P +6GHK1DF+onKZtMkH0SNMU3X1arlJKRreVQsvkbgL7aw3mI0veYa4/tJUf7hbkPpA +LArQU5wQ+A9mzC+tYMfz3mrIE05FrpYkHRxiB/odeNvCTMR7DhGoghhnYUN/gSSN +qH5EBG2hQ/pJ5ZSawE+P9+vCLlvcc4n00zgi0s3rMN2AntPZoI3sWKZcbbgJoOIH +cbAmBAKCIiwmlPmI0hjEAIXRBixJzHVGNowuSc3jy5pIiSjmDESnARl+n5imqI3D +po9OuCHpo4nRLcAX0GrJqqKxUG+R1A8g/AooIGEPQgkXk/4v9gwd4aBvwT4YxR44 +onAXdyBMM0T8C+8dUmT6OPvU5w6JHFidJfhBgJhDIdj9JM+wWdr1CW94todjEyKY +Xe3NRG1bGbcN6HBVwbe4UZ39A9p4kKGyiXexlsD+DvFxwaGvSy2rp0lLabz19Kkr +fnLU1Ugb38AnEYTGYJMB9nO19lHW62Mk6+9ky42x8X9vBn81Nif/c0kmvEKsZEfw +UM7m0fIWTZOWSH01DGIXqCoCk7vJ1CSm0wUsAvyKFLm1qnM5eJJNMlBbayDDBsnU +Jj9hx7GWjujVKFwFngUOoFpmFWB72bqeBWenaQJhIVydQa1rolny0TECJIkFOsUK +Wa0y52V4h68Ig5G5p2WHG0RlEVtmcgzSoL1mLE5UdOYaH5oB7nTVM+Z0b8HJFrYc +7Xhym8uNq6UHc4Ae6TT8EA3lA3fDttedKzWxlBFXqX9behl2uBnPzCl3cS2G2Uek +xtexjecZINP8L5i6eIL7bPoVMF5CUsUhIWFA0gzIovRBRvVS91HnTrIDLvqF8YgQ +ToctUU/vS8r3x2/TIR60UBvW0vkoFa+lfzHtsxBnT1nMBZNeeHOCM8QtboyI9Ir9 +UkJbTO+QpJQ5A3ELharpcqr7iywDOnLSV9LZSUZr934zOrRl2oAXx/0= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/test/recipes/70-test_tls13downgrade.t b/test/recipes/70-test_tls13downgrade.t index 9e10a9c9c4ca..f40bd5f7036b 100644 --- a/test/recipes/70-test_tls13downgrade.t +++ b/test/recipes/70-test_tls13downgrade.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2025 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 @@ -24,9 +24,8 @@ plan skip_all => "$test_name needs the sock feature enabled" if disabled("sock"); plan skip_all => "$test_name needs TLS1.3 and TLS1.2 enabled" - if disabled("tls1_3") - || (disabled("ec") && disabled("dh")) - || disabled("tls1_2"); + if disabled("tls1_3") || disabled("tls1_2") + || (disabled("ec") && disabled("dh")); $ENV{OPENSSL_ia32cap} = '~0x200000200000000'; @@ -41,89 +40,150 @@ use constant { DOWNGRADE_TO_TLS_1_2 => 0, DOWNGRADE_TO_TLS_1_1 => 1, FALLBACK_FROM_TLS_1_3 => 2, + DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL => 3, + DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL => 4, }; #Test 1: Downgrade from TLSv1.3 to TLSv1.2 $proxy->filter(\&downgrade_filter); my $testtype = DOWNGRADE_TO_TLS_1_2; $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 6; -ok(TLSProxy::Message->fail(), "Downgrade TLSv1.3 to TLSv1.2"); +plan tests => 8; +ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.3 to TLSv1.2"); -#Test 2: Downgrade from TLSv1.3 to TLSv1.1 +#Test 2: Downgrade from TLSv1.3 to TLSv1.2 (server sends TLSv1.1 signal) $proxy->clear(); -$testtype = DOWNGRADE_TO_TLS_1_1; +$testtype = DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL; $proxy->start(); -ok(TLSProxy::Message->fail(), "Downgrade TLSv1.3 to TLSv1.1"); +ok(is_illegal_parameter_client_alert(), + "Downgrade from TLSv1.3 to TLSv1.2 (server sends TLSv1.1 signal)"); -#Test 3: Downgrade from TLSv1.2 to TLSv1.1 -$proxy->clear(); -$proxy->clientflags("-no_tls1_3"); -$proxy->serverflags("-no_tls1_3"); -$proxy->start(); -ok(TLSProxy::Message->fail(), "Downgrade TLSv1.2 to TLSv1.1"); - -#Test 4: Client falls back from TLSv1.3 (server does not support the fallback +#Test 3: Client falls back from TLSv1.3 (server does not support the fallback # SCSV) $proxy->clear(); $testtype = FALLBACK_FROM_TLS_1_3; $proxy->clientflags("-fallback_scsv -no_tls1_3"); $proxy->start(); -my $alert = TLSProxy::Message->alert(); -ok(TLSProxy::Message->fail() - && !$alert->server() - && $alert->description() == TLSProxy::Message::AL_DESC_ILLEGAL_PARAMETER, - "Fallback from TLSv1.3"); +ok(is_illegal_parameter_client_alert(), "Fallback from TLSv1.3"); SKIP: { - skip "TLSv1.1 disabled", 2 if disabled("tls1_1"); - #Test 5: A client side protocol "hole" should not be detected as a downgrade + skip "TLSv1.1 disabled", 5 if disabled("tls1_1"); + + my $client_flags = "-min_protocol TLSv1.1 -cipher DEFAULT:\@SECLEVEL=0"; + my $server_flags = "-min_protocol TLSv1.1"; + my $ciphers = "AES128-SHA:\@SECLEVEL=0"; + + #Test 4: Downgrade from TLSv1.3 to TLSv1.1 + $proxy->clear(); + $testtype = DOWNGRADE_TO_TLS_1_1; + $proxy->clientflags($client_flags); + $proxy->serverflags($server_flags); + $proxy->ciphers($ciphers); + $proxy->start(); + ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.3 to TLSv1.1"); + + #Test 5: Downgrade from TLSv1.3 to TLSv1.1 (server sends TLSv1.2 signal) + $proxy->clear(); + $testtype = DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL; + $proxy->clientflags($client_flags); + $proxy->serverflags($server_flags); + $proxy->ciphers($ciphers); + $proxy->start(); + ok(is_illegal_parameter_client_alert(), + "Downgrade TLSv1.3 to TLSv1.1 (server sends TLSv1.2 signal)"); + + #Test 6: Downgrade from TLSv1.2 to TLSv1.1 + $proxy->clear(); + $testtype = DOWNGRADE_TO_TLS_1_1; + $proxy->clientflags($client_flags." -max_protocol TLSv1.2"); + $proxy->serverflags($server_flags." -max_protocol TLSv1.2"); + $proxy->ciphers($ciphers); + $proxy->start(); + ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.2 to TLSv1.1"); + + #Test 7: A client side protocol "hole" should not be detected as a downgrade $proxy->clear(); $proxy->filter(undef); - $proxy->clientflags("-no_tls1_2"); - $proxy->ciphers("AES128-SHA:\@SECLEVEL=0"); + $proxy->clientflags($client_flags." -no_tls1_2"); + $proxy->serverflags($server_flags); + $proxy->ciphers($ciphers); $proxy->start(); ok(TLSProxy::Message->success(), "TLSv1.2 client-side protocol hole"); - #Test 6: A server side protocol "hole" should not be detected as a downgrade + #Test 8: A server side protocol "hole" should not be detected as a downgrade $proxy->clear(); $proxy->filter(undef); - $proxy->serverflags("-no_tls1_2"); + $proxy->clientflags($client_flags); + $proxy->serverflags($server_flags." -no_tls1_2"); + $proxy->ciphers($ciphers); $proxy->start(); ok(TLSProxy::Message->success(), "TLSv1.2 server-side protocol hole"); } +# Validate that the exchange fails with an illegal parameter alert from +# the client +sub is_illegal_parameter_client_alert +{ + return 0 unless TLSProxy::Message->fail(); + my $alert = TLSProxy::Message->alert(); + return 1 if !$alert->server() + && $alert->description() + == TLSProxy::Message::AL_DESC_ILLEGAL_PARAMETER; + return 0; +} + sub downgrade_filter { my $proxy = shift; - # We're only interested in the initial ClientHello - if ($proxy->flight != 0) { + # We're only interested in the initial ClientHello and ServerHello + if ($proxy->flight > 1) { return; } - my $message = ${$proxy->message_list}[0]; - - my $ext; - if ($testtype == FALLBACK_FROM_TLS_1_3) { - #The default ciphersuite we use for TLSv1.2 without any SCSV - my @ciphersuites = (TLSProxy::Message::CIPHER_RSA_WITH_AES_128_CBC_SHA); - $message->ciphersuite_len(2 * scalar @ciphersuites); - $message->ciphersuites(\@ciphersuites); - } else { - if ($testtype == DOWNGRADE_TO_TLS_1_2) { - $ext = pack "C3", - 0x02, # Length - 0x03, 0x03; #TLSv1.2 - } else { - $ext = pack "C3", - 0x02, # Length - 0x03, 0x02; #TLSv1.1 + my $message = ${$proxy->message_list}[$proxy->flight]; + + # ServerHello + if ($proxy->flight == 1 && defined($message)) { + # Update the last byte of the downgrade signal + if ($testtype == DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL) { + $message->random(substr($message->random, 0, 31) . "\0"); + $message->repack(); + } elsif ($testtype == DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL) { + $message->random(substr($message->random, 0, 31) . "\1"); + $message->repack(); } - $message->set_extension(TLSProxy::Message::EXT_SUPPORTED_VERSIONS, $ext); + return; } - $message->repack(); + # ClientHello + if ($proxy->flight == 0) { + my $ext; + if ($testtype == FALLBACK_FROM_TLS_1_3) { + #The default ciphersuite we use for TLSv1.2 without any SCSV + my @ciphersuites = (TLSProxy::Message::CIPHER_RSA_WITH_AES_128_CBC_SHA); + $message->ciphersuite_len(2 * scalar @ciphersuites); + $message->ciphersuites(\@ciphersuites); + } + else { + if ($testtype == DOWNGRADE_TO_TLS_1_2 + || $testtype == DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL) { + $ext = pack "C3", + 0x02, # Length + 0x03, 0x03; #TLSv1.2 + } + else { + $ext = pack "C3", + 0x02, # Length + 0x03, 0x02; #TLSv1.1 + } + + $message->set_extension(TLSProxy::Message::EXT_SUPPORTED_VERSIONS, + $ext); + } + + $message->repack(); + } } diff --git a/test/recipes/80-test_ca.t b/test/recipes/80-test_ca.t index eb025f4d591f..c477df3929e7 100644 --- a/test/recipes/80-test_ca.t +++ b/test/recipes/80-test_ca.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2025 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 @@ -21,9 +21,7 @@ setup("test_ca"); $ENV{OPENSSL} = cmdstr(app(["openssl"]), display => 1); my $cnf = srctop_file("test","ca-and-certs.cnf"); -my $std_openssl_cnf = '"' - . srctop_file("apps", $^O eq "VMS" ? "openssl-vms.cnf" : "openssl.cnf") - . '"'; +my $std_openssl_cnf = srctop_file("apps", $^O eq "VMS" ? "openssl-vms.cnf" : "openssl.cnf"); rmtree("demoCA", { safe => 0 }); @@ -33,14 +31,14 @@ plan tests => 15; $ENV{OPENSSL_CONFIG} = qq(-config "$cnf"); skip "failed creating CA structure", 4 if !ok(run(perlapp(["CA.pl","-newca", - "-extra-req", "-key $cakey"], stdin => undef)), + "-extra-req", qq{-key "$cakey"}], stdin => undef)), 'creating CA structure'); my $eekey = srctop_file("test", "certs", "ee-key.pem"); $ENV{OPENSSL_CONFIG} = qq(-config "$cnf"); skip "failed creating new certificate request", 3 if !ok(run(perlapp(["CA.pl","-newreq", - '-extra-req', "-outform DER -section userreq -key $eekey"])), + '-extra-req', qq{-outform DER -section userreq -key "$eekey"}])), 'creating certificate request'); $ENV{OPENSSL_CONFIG} = qq(-rand_serial -inform DER -config "$std_openssl_cnf"); skip "failed to sign certificate request", 2 @@ -55,7 +53,8 @@ plan tests => 15; my $eekey2 = srctop_file("test", "certs", "ee-key-3072.pem"); $ENV{OPENSSL_CONFIG} = qq(-config "$cnf"); - ok(run(perlapp(["CA.pl", "-precert", '-extra-req', "-section userreq -key $eekey2"], stderr => undef)), + ok(run(perlapp(["CA.pl", "-precert", + '-extra-req', qq{-section userreq -key "$eekey2"}], stderr => undef)), 'creating new pre-certificate'); } diff --git a/test/recipes/80-test_cmp_http.t b/test/recipes/80-test_cmp_http.t index c704cc758e91..8ea33d90c09f 100644 --- a/test/recipes/80-test_cmp_http.t +++ b/test/recipes/80-test_cmp_http.t @@ -274,6 +274,7 @@ sub start_mock_server { print "Pid is: $pid\n"; if ($server_port == 0) { # Find out the actual server port + my $pid0 = $pid; while (<$server_fh>) { print "Server output: $_"; next if m/using section/; @@ -281,6 +282,11 @@ sub start_mock_server { ($server_port, $pid) = ($1, $2) if /^ACCEPT\s.*:(\d+) PID=(\d+)$/; last; # Do not loop further to prevent hangs on server misbehavior } + if ($pid0 != $pid) { + # kill the shell process + kill('KILL', $pid0); + waitpid($pid0, 0); + } } unless ($server_port > 0) { stop_mock_server($pid); diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t index 0e8b0259f1c2..df8e7e614464 100644 --- a/test/recipes/80-test_cms.t +++ b/test/recipes/80-test_cms.t @@ -347,6 +347,16 @@ my @smime_cms_tests = ( \&final_compare ], + [ "enveloped content test streaming PEM format, AES-128-CBC cipher, password", + [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128", + "-stream", "-out", "{output}.cms", + "-pwri_password", "test" ], + [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt", + "-inform", "PEM", + "-pwri_password", "test" ], + \&final_compare + ], + [ "data content test streaming PEM format", [ "{cmd1}", @prov, "-data_create", "-in", $smcont, "-outform", "PEM", "-nodetach", "-stream", "-out", "{output}.cms" ], diff --git a/test/sslapitest.c b/test/sslapitest.c index 368b15f22b72..a26b78907424 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -11127,6 +11127,79 @@ static int test_alpn(int idx) return testresult; } +static int test_no_renegotiation(int idx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + int testresult = 0, ret; + int max_proto; + const SSL_METHOD *sm, *cm; + unsigned char buf[5]; + + if (idx == 0) { +#ifndef OPENSSL_NO_TLS1_2 + max_proto = TLS1_2_VERSION; + sm = TLS_server_method(); + cm = TLS_client_method(); +#else + return TEST_skip("TLSv1.2 is disabled in this build"); +#endif + } else { +#ifndef OPENSSL_NO_DTLS1_2 + max_proto = DTLS1_2_VERSION; + sm = DTLS_server_method(); + cm = DTLS_client_method(); +#else + return TEST_skip("DTLSv1.2 is disabled in this build"); +#endif + } + if (!TEST_true(create_ssl_ctx_pair(libctx, sm, cm, 0, max_proto, + &sctx, &cctx, cert, privkey))) + goto end; + + SSL_CTX_set_options(sctx, SSL_OP_NO_RENEGOTIATION); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, + NULL))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + if (!TEST_true(SSL_renegotiate(clientssl)) + || !TEST_int_le(ret = SSL_connect(clientssl), 0) + || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ)) + goto end; + + /* + * We've not sent any application data, so we expect this to fail. It should + * also read the renegotiation attempt, and send back a no_renegotiation + * warning alert because we have renegotiation disabled. + */ + if (!TEST_int_le(ret = SSL_read(serverssl, buf, sizeof(buf)), 0)) + goto end; + if (!TEST_int_eq(SSL_get_error(serverssl, ret), SSL_ERROR_WANT_READ)) + goto end; + + /* + * The client should now see the no_renegotiation warning and fail the + * connection + */ + if (!TEST_int_le(ret = SSL_connect(clientssl), 0) + || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_SSL) + || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_RENEGOTIATION)) + goto end; + + testresult = 1; + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n") int setup_tests(void) @@ -11408,6 +11481,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_npn, 5); #endif ADD_ALL_TESTS(test_alpn, 4); + ADD_ALL_TESTS(test_no_renegotiation, 2); return 1; err: diff --git a/test/testutil/testutil_init.c b/test/testutil/testutil_init.c index 87013694c29e..64224186e477 100644 --- a/test/testutil/testutil_init.c +++ b/test/testutil/testutil_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2025 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 @@ -92,6 +92,7 @@ static void setup_trace_category(int category) "warning: unable to setup trace callback for category '%s'.\n", OSSL_trace_get_category_name(category)); + OPENSSL_free(trace_data); OSSL_trace_set_callback(category, NULL, NULL); BIO_free_all(channel); } diff --git a/test/tls-provider.c b/test/tls-provider.c index 7375792c3125..52b1f3709d61 100644 --- a/test/tls-provider.c +++ b/test/tls-provider.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 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 @@ -594,9 +594,10 @@ static void *xor_gen_init(void *provctx, int selection, | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)) == 0) return NULL; - if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) - gctx->selection = selection; + if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) == NULL) + return NULL; + gctx->selection = selection; /* Our provctx is really just an OSSL_LIB_CTX */ gctx->libctx = (OSSL_LIB_CTX *)provctx; |