diff --git a/.github/workflows/provider-compatibility.yml b/.github/workflows/provider-compatibility.yml index f118db1aee5f900d24f5264aa15be624a7fdb918..e95a8475220c86e81912700aa93c7e3e87b3882f 100644 --- a/.github/workflows/provider-compatibility.yml +++ b/.github/workflows/provider-compatibility.yml @@ -10,6 +10,10 @@ name: Provider compatibility across versions + +# NOTE: if this is being run on pull_request, it will **not** use the pull +# request's branch. It is hardcoded to use the master branch. +# on: #[pull_request] schedule: - cron: '0 15 * * *' diff --git a/apps/genpkey.c b/apps/genpkey.c index 080f1f60756e7824107f0a5dbcbed7b33f47b7d1..66f0e1eaf01af3f7c6f7ad50f5c16187d98017a8 100644 --- a/apps/genpkey.c +++ b/apps/genpkey.c @@ -23,7 +23,7 @@ typedef enum OPTION_choice { OPT_COMMON, OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE, OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER, - OPT_VERBOSE, OPT_QUIET, OPT_CONFIG, + OPT_VERBOSE, OPT_QUIET, OPT_CONFIG, OPT_OUTPUBKEY, OPT_PROV_ENUM } OPTION_CHOICE; @@ -42,11 +42,12 @@ const OPTIONS genpkey_options[] = { OPT_CONFIG_OPTION, OPT_SECTION("Output"), - {"out", OPT_OUT, '>', "Output file"}, + {"out", OPT_OUT, '>', "Output (private key) file"}, + {"outpubkey", OPT_OUTPUBKEY, '>', "Output public key file"}, {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"}, {"pass", OPT_PASS, 's', "Output file pass phrase source"}, {"genparam", OPT_GENPARAM, '-', "Generate parameters, not key"}, - {"text", OPT_TEXT, '-', "Print the in text"}, + {"text", OPT_TEXT, '-', "Print the private key in text"}, {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"}, OPT_PROV_OPTIONS, @@ -104,11 +105,12 @@ cleanup: int genpkey_main(int argc, char **argv) { CONF *conf = NULL; - BIO *in = NULL, *out = NULL; + BIO *in = NULL, *out = NULL, *outpubkey = NULL; ENGINE *e = NULL; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; char *outfile = NULL, *passarg = NULL, *pass = NULL, *prog, *p; + char *outpubkeyfile = NULL; const char *ciphername = NULL, *paramfile = NULL, *algname = NULL; EVP_CIPHER *cipher = NULL; OPTION_CHOICE o; @@ -141,6 +143,9 @@ int genpkey_main(int argc, char **argv) case OPT_OUT: outfile = opt_arg(); break; + case OPT_OUTPUBKEY: + outpubkeyfile = opt_arg(); + break; case OPT_PASS: passarg = opt_arg(); break; @@ -228,6 +233,12 @@ int genpkey_main(int argc, char **argv) if (out == NULL) goto end; + if (outpubkeyfile != NULL) { + outpubkey = bio_open_owner(outpubkeyfile, outformat, private); + if (outpubkey == NULL) + goto end; + } + if (verbose) EVP_PKEY_CTX_set_cb(ctx, progress_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); @@ -242,9 +253,13 @@ int genpkey_main(int argc, char **argv) } else if (outformat == FORMAT_PEM) { assert(private); rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass); + if (rv > 0 && outpubkey != NULL) + rv = PEM_write_bio_PUBKEY(outpubkey, pkey); } else if (outformat == FORMAT_ASN1) { assert(private); rv = i2d_PrivateKey_bio(out, pkey); + if (rv > 0 && outpubkey != NULL) + rv = i2d_PUBKEY_bio(outpubkey, pkey); } else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; @@ -253,7 +268,7 @@ int genpkey_main(int argc, char **argv) ret = 0; if (rv <= 0) { - BIO_puts(bio_err, "Error writing key\n"); + BIO_puts(bio_err, "Error writing key(s)\n"); ret = 1; } @@ -277,6 +292,7 @@ int genpkey_main(int argc, char **argv) EVP_PKEY_CTX_free(ctx); EVP_CIPHER_free(cipher); BIO_free_all(out); + BIO_free_all(outpubkey); BIO_free(in); release_engine(e); OPENSSL_free(pass); diff --git a/crypto/bio/bio_addr.c b/crypto/bio/bio_addr.c index aec94237fc8c8815b6049895019145341e84600f..2a6f6d522c7a51d848d298b2f8e5e98805d99992 100644 --- a/crypto/bio/bio_addr.c +++ b/crypto/bio/bio_addr.c @@ -65,14 +65,29 @@ void BIO_ADDR_free(BIO_ADDR *ap) OPENSSL_free(ap); } +int BIO_ADDR_copy(BIO_ADDR *dst, const BIO_ADDR *src) +{ + if (dst == NULL || src == NULL) + return 0; + + if (src->sa.sa_family == AF_UNSPEC) { + BIO_ADDR_clear(dst); + return 1; + } + + return BIO_ADDR_make(dst, &src->sa); +} + BIO_ADDR *BIO_ADDR_dup(const BIO_ADDR *ap) { BIO_ADDR *ret = NULL; if (ap != NULL) { ret = BIO_ADDR_new(); - if (ret != NULL) - BIO_ADDR_make(ret, &ap->sa); + if (ret != NULL && !BIO_ADDR_copy(ret, ap)) { + BIO_ADDR_free(ret); + ret = NULL; + } } return ret; } diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 3eeaa6d5d5799e0cf3e3fd5c4a6272986c2c2585..6952560d86610d7380537875cfce6ffd13bf6a99 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1154,6 +1154,7 @@ RAND_R_FWRITE_ERROR:123:Error writing file RAND_R_GENERATE_ERROR:112:generate error RAND_R_INSUFFICIENT_DRBG_STRENGTH:139:insufficient drbg strength RAND_R_INTERNAL_ERROR:113:internal error +RAND_R_INVALID_PROPERTY_QUERY:137:invalid property query RAND_R_IN_ERROR_STATE:114:in error state RAND_R_NOT_A_REGULAR_FILE:122:Not a regular file RAND_R_NOT_INSTANTIATED:115:not instantiated diff --git a/crypto/initthread.c b/crypto/initthread.c index 03586bcbca668323e77998625f11590b895cb999..23ad0a07391071f07a72add10da4ff8815d87fed 100644 --- a/crypto/initthread.c +++ b/crypto/initthread.c @@ -249,6 +249,15 @@ void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx) #else +static void ossl_arg_thread_stop(void *arg); + +/* Register the current thread so that we are informed if it gets stopped */ +int ossl_thread_register_fips(OSSL_LIB_CTX *libctx) +{ + return c_thread_start(FIPS_get_core_handle(libctx), ossl_arg_thread_stop, + libctx); +} + void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *libctx) { THREAD_EVENT_HANDLER **hands = NULL; @@ -257,7 +266,7 @@ void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *libctx) if (tlocal == NULL) return NULL; - if (!CRYPTO_THREAD_init_local(tlocal, NULL)) { + if (!CRYPTO_THREAD_init_local(tlocal, NULL)) { goto err; } @@ -268,6 +277,16 @@ void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *libctx) if (!CRYPTO_THREAD_set_local(tlocal, hands)) goto err; + /* + * We should ideally call ossl_thread_register_fips() here. This function + * is called during the startup of the FIPS provider and we need to ensure + * that the main thread is registered to receive thread callbacks in order + * to free |hands| that we allocated above. However we are too early in + * the FIPS provider initialisation that FIPS_get_core_handle() doesn't work + * yet. So we defer this to the main provider OSSL_provider_init_int() + * function. + */ + return tlocal; err: OPENSSL_free(hands); @@ -379,8 +398,7 @@ int ossl_init_thread_start(const void *index, void *arg, * libcrypto to tell us about later thread stop events. c_thread_start * is a callback to libcrypto defined in fipsprov.c */ - if (!c_thread_start(FIPS_get_core_handle(ctx), ossl_arg_thread_stop, - ctx)) + if (!ossl_thread_register_fips(ctx)) return 0; } #endif diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 7f5e48f26c68aa0c7457c9e243ba9d43945a21e4..266934937cb892aa7d3b39541056e4d81bb58b60 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -1930,10 +1930,12 @@ OSSL_FUNC_BIO_free_fn ossl_core_bio_free; OSSL_FUNC_BIO_vprintf_fn ossl_core_bio_vprintf; OSSL_FUNC_BIO_vsnprintf_fn BIO_vsnprintf; static OSSL_FUNC_self_test_cb_fn core_self_test_get_callback; -OSSL_FUNC_get_entropy_fn ossl_rand_get_entropy; -OSSL_FUNC_cleanup_entropy_fn ossl_rand_cleanup_entropy; -OSSL_FUNC_get_nonce_fn ossl_rand_get_nonce; -OSSL_FUNC_cleanup_nonce_fn ossl_rand_cleanup_nonce; +static OSSL_FUNC_get_user_entropy_fn rand_get_user_entropy; +static OSSL_FUNC_get_entropy_fn rand_get_entropy; +static OSSL_FUNC_cleanup_entropy_fn rand_cleanup_entropy; +static OSSL_FUNC_get_user_nonce_fn rand_get_user_nonce; +static OSSL_FUNC_get_nonce_fn rand_get_nonce; +static OSSL_FUNC_cleanup_nonce_fn rand_cleanup_nonce; #endif OSSL_FUNC_CRYPTO_malloc_fn CRYPTO_malloc; OSSL_FUNC_CRYPTO_zalloc_fn CRYPTO_zalloc; @@ -2094,6 +2096,54 @@ static void core_self_test_get_callback(OPENSSL_CORE_CTX *libctx, OSSL_SELF_TEST_get_callback((OSSL_LIB_CTX *)libctx, cb, cbarg); } +static size_t rand_get_entropy(const OSSL_CORE_HANDLE *handle, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len) +{ + return ossl_rand_get_entropy((OSSL_LIB_CTX *)core_get_libctx(handle), + pout, entropy, min_len, max_len); +} + +static size_t rand_get_user_entropy(const OSSL_CORE_HANDLE *handle, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len) +{ + return ossl_rand_get_user_entropy((OSSL_LIB_CTX *)core_get_libctx(handle), + pout, entropy, min_len, max_len); +} + +static void rand_cleanup_entropy(const OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len) +{ + ossl_rand_cleanup_entropy((OSSL_LIB_CTX *)core_get_libctx(handle), + buf, len); +} + +static size_t rand_get_nonce(const OSSL_CORE_HANDLE *handle, + unsigned char **pout, + size_t min_len, size_t max_len, + const void *salt, size_t salt_len) +{ + return ossl_rand_get_nonce((OSSL_LIB_CTX *)core_get_libctx(handle), + pout, min_len, max_len, salt, salt_len); +} + +static size_t rand_get_user_nonce(const OSSL_CORE_HANDLE *handle, + unsigned char **pout, + size_t min_len, size_t max_len, + const void *salt, size_t salt_len) +{ + return ossl_rand_get_user_nonce((OSSL_LIB_CTX *)core_get_libctx(handle), + pout, min_len, max_len, salt, salt_len); +} + +static void rand_cleanup_nonce(const OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len) +{ + ossl_rand_cleanup_nonce((OSSL_LIB_CTX *)core_get_libctx(handle), + buf, len); +} + static const char *core_provider_get0_name(const OSSL_CORE_HANDLE *prov) { return OSSL_PROVIDER_get0_name((const OSSL_PROVIDER *)prov); @@ -2187,10 +2237,12 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))ossl_core_bio_vprintf }, { OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf }, { OSSL_FUNC_SELF_TEST_CB, (void (*)(void))core_self_test_get_callback }, - { OSSL_FUNC_GET_ENTROPY, (void (*)(void))ossl_rand_get_entropy }, - { OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))ossl_rand_cleanup_entropy }, - { OSSL_FUNC_GET_NONCE, (void (*)(void))ossl_rand_get_nonce }, - { OSSL_FUNC_CLEANUP_NONCE, (void (*)(void))ossl_rand_cleanup_nonce }, + { OSSL_FUNC_GET_ENTROPY, (void (*)(void))rand_get_entropy }, + { OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))rand_cleanup_entropy }, + { OSSL_FUNC_GET_NONCE, (void (*)(void))rand_get_nonce }, + { OSSL_FUNC_CLEANUP_NONCE, (void (*)(void))rand_cleanup_nonce }, + { OSSL_FUNC_GET_USER_ENTROPY, (void (*)(void))rand_get_user_entropy }, + { OSSL_FUNC_GET_USER_NONCE, (void (*)(void))rand_get_user_nonce }, #endif { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc }, { OSSL_FUNC_CRYPTO_ZALLOC, (void (*)(void))CRYPTO_zalloc }, diff --git a/crypto/rand/prov_seed.c b/crypto/rand/prov_seed.c index 546c2040946efadc48a86bf63bd58742d4974810..96c73f7e66020f5bbc00b14b3e4a286aacd09dfd 100644 --- a/crypto/rand/prov_seed.c +++ b/crypto/rand/prov_seed.c @@ -7,12 +7,14 @@ * https://www.openssl.org/source/license.html */ +#include "rand_local.h" #include "crypto/rand.h" #include "crypto/rand_pool.h" +#include "internal/core.h" #include #include -size_t ossl_rand_get_entropy(ossl_unused const OSSL_CORE_HANDLE *handle, +size_t ossl_rand_get_entropy(ossl_unused OSSL_LIB_CTX *ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { @@ -38,14 +40,46 @@ size_t ossl_rand_get_entropy(ossl_unused const OSSL_CORE_HANDLE *handle, return ret; } -void ossl_rand_cleanup_entropy(ossl_unused const OSSL_CORE_HANDLE *handle, +size_t ossl_rand_get_user_entropy(OSSL_LIB_CTX *ctx, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len) +{ + unsigned char *buf; + EVP_RAND_CTX *rng = ossl_rand_get0_seed_noncreating(ctx); + size_t ret; + + if (rng == NULL) + return ossl_rand_get_entropy(ctx, pout, entropy, min_len, max_len); + + /* Determine how many bytes to generate */ + ret = entropy > 0 ? (size_t)(7 + entropy) / 8 : min_len; + if (ret < min_len) + ret = min_len; + else if (ret > max_len) + ret = max_len; + + /* Allocate the return buffer */ + if ((buf = OPENSSL_secure_malloc(ret)) == NULL) + return 0; + + /* Fill the buffer */ + if (!EVP_RAND_generate(rng, buf, ret, entropy, 0, NULL, 0)) { + OPENSSL_free(buf); + return 0; + } + *pout = buf; + return ret; +} + +void ossl_rand_cleanup_entropy(ossl_unused OSSL_LIB_CTX *ctx, unsigned char *buf, size_t len) { OPENSSL_secure_clear_free(buf, len); } -size_t ossl_rand_get_nonce(ossl_unused const OSSL_CORE_HANDLE *handle, - unsigned char **pout, size_t min_len, size_t max_len, +size_t ossl_rand_get_nonce(ossl_unused OSSL_LIB_CTX *ctx, + unsigned char **pout, + size_t min_len, ossl_unused size_t max_len, const void *salt, size_t salt_len) { size_t ret = 0; @@ -69,7 +103,29 @@ size_t ossl_rand_get_nonce(ossl_unused const OSSL_CORE_HANDLE *handle, return ret; } -void ossl_rand_cleanup_nonce(ossl_unused const OSSL_CORE_HANDLE *handle, +size_t ossl_rand_get_user_nonce(OSSL_LIB_CTX *ctx, + unsigned char **pout, + size_t min_len, size_t max_len, + const void *salt, size_t salt_len) +{ + unsigned char *buf; + EVP_RAND_CTX *rng = ossl_rand_get0_seed_noncreating(ctx); + + if (rng == NULL) + return ossl_rand_get_nonce(ctx, pout, min_len, max_len, salt, salt_len); + + if ((buf = OPENSSL_malloc(min_len)) == NULL) + return 0; + + if (!EVP_RAND_generate(rng, buf, min_len, 0, 0, salt, salt_len)) { + OPENSSL_free(buf); + return 0; + } + *pout = buf; + return min_len; +} + +void ossl_rand_cleanup_nonce(ossl_unused OSSL_LIB_CTX *ctx, unsigned char *buf, size_t len) { OPENSSL_clear_free(buf, len); diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c index b9c2bf1760f501122b0ecc702d15936342b76b45..41a4c9cdeacc207718e0bead5b9043dace6cdb34 100644 --- a/crypto/rand/rand_err.c +++ b/crypto/rand/rand_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -51,6 +51,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = { {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INSUFFICIENT_DRBG_STRENGTH), "insufficient drbg strength"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INTERNAL_ERROR), "internal error"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INVALID_PROPERTY_QUERY), + "invalid property query"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_IN_ERROR_STATE), "in error state"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_A_REGULAR_FILE), "Not a regular file"}, diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 8dd1d071e89410f695022a5ad39a56f07de568de..46e294a37835e0cd4fb13ef8aed4b74cd7a1e9fa 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -30,6 +30,7 @@ # include "crypto/rand_pool.h" # include "prov/seeding.h" # include "internal/e_os.h" +# include "internal/property.h" # ifndef OPENSSL_NO_ENGINE /* non-NULL if default_RAND_meth is ENGINE-provided */ @@ -534,29 +535,104 @@ static EVP_RAND_CTX *rand_new_seed(OSSL_LIB_CTX *libctx) { EVP_RAND *rand; RAND_GLOBAL *dgbl = rand_get_global(libctx); - EVP_RAND_CTX *ctx; - char *name; + EVP_RAND_CTX *ctx = NULL; + const char *propq = dgbl->seed_propq; + char *name, *props = NULL; + size_t props_len; + OSSL_PROPERTY_LIST *pl1, *pl2, *pl3 = NULL; if (dgbl == NULL) return NULL; - name = dgbl->seed_name != NULL ? dgbl->seed_name : "SEED-SRC"; - rand = EVP_RAND_fetch(libctx, name, dgbl->seed_propq); + if (dgbl->seed_name != NULL) { + name = dgbl->seed_name; + } else { + /* + * Default to our internal seed source. This isn't part of the FIPS + * provider so we need to override any FIPS properties. + */ + if (propq == NULL || *propq == '\0') { + propq = "-fips"; + } else { + pl1 = ossl_parse_query(libctx, propq, 1); + if (pl1 == NULL) { + ERR_raise(ERR_LIB_RAND, RAND_R_INVALID_PROPERTY_QUERY); + return NULL; + } + pl2 = ossl_parse_query(libctx, "-fips", 1); + if (pl2 == NULL) { + ossl_property_free(pl1); + ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR); + return NULL; + } + pl3 = ossl_property_merge(pl2, pl1); + ossl_property_free(pl1); + ossl_property_free(pl2); + if (pl3 == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR); + return NULL; + } + props_len = ossl_property_list_to_string(libctx, pl3, NULL, 0); + if (props_len == 0) { + /* Shouldn't happen since we added a query element */ + ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR); + goto err; + } else { + props = OPENSSL_malloc(props_len); + if (props == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + goto err; + } + if (ossl_property_list_to_string(libctx, pl3, + props, props_len) == 0) { + ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR); + goto err; + } + ossl_property_free(pl3); + pl3 = NULL; + propq = props; + } + } + name = "SEED-SRC"; + } + + rand = EVP_RAND_fetch(libctx, name, propq); if (rand == NULL) { ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG); - return NULL; + goto err; } ctx = EVP_RAND_CTX_new(rand, NULL); EVP_RAND_free(rand); if (ctx == NULL) { ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG); - return NULL; + goto err; } if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0, NULL)) { ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG); EVP_RAND_CTX_free(ctx); - return NULL; + goto err; } + OPENSSL_free(props); return ctx; + err: + EVP_RAND_CTX_free(ctx); + ossl_property_free(pl3); + OPENSSL_free(props); + return NULL; +} + +EVP_RAND_CTX *ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX *ctx) +{ + RAND_GLOBAL *dgbl = rand_get_global(ctx); + EVP_RAND_CTX *ret; + + if (dgbl == NULL) + return NULL; + + if (!CRYPTO_THREAD_read_lock(dgbl->lock)) + return NULL; + ret = dgbl->seed; + CRYPTO_THREAD_unlock(dgbl->lock); + return ret; } #endif @@ -738,6 +814,18 @@ EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx) return rand; } +#ifdef FIPS_MODULE +EVP_RAND_CTX *ossl_rand_get0_private_noncreating(OSSL_LIB_CTX *ctx) +{ + RAND_GLOBAL *dgbl = rand_get_global(ctx); + + if (dgbl == NULL) + return NULL; + + return CRYPTO_THREAD_get_local(&dgbl->private); +} +#endif + int RAND_set0_public(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand) { RAND_GLOBAL *dgbl = rand_get_global(ctx); @@ -870,7 +958,7 @@ int RAND_set_seed_source_type(OSSL_LIB_CTX *ctx, const char *seed, if (dgbl == NULL) return 0; - if (dgbl->primary != NULL) { + if (dgbl->seed != NULL) { ERR_raise(ERR_LIB_CRYPTO, RAND_R_ALREADY_INSTANTIATED); return 0; } diff --git a/crypto/x509/build.info b/crypto/x509/build.info index 8820f983bb3d01f04eb5adfbd82d8226e01e01b4..3f70f3ff36dfbc07ffbab2ab186ff8b80b34c627 100644 --- a/crypto/x509/build.info +++ b/crypto/x509/build.info @@ -14,7 +14,8 @@ SOURCE[../../libcrypto]=\ v3_info.c v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c \ v3_pcia.c v3_pci.c v3_ist.c \ pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \ - v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c + v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c v3_no_rev_avail.c \ + v3_soa_id.c v3_no_ass.c v3_group_ac.c v3_single_use.c v3_ind_iss.c IF[{- !$disabled{'deprecated-3.0'} -}] SOURCE[../../libcrypto]=x509type.c diff --git a/crypto/x509/ext_dat.h b/crypto/x509/ext_dat.h index a0a7f88ccd8ad63fe8cce6e06745e11a11db2fd9..8325aacfa5306aa47315eef6f93976c06d46150d 100644 --- a/crypto/x509/ext_dat.h +++ b/crypto/x509/ext_dat.h @@ -25,3 +25,9 @@ extern const X509V3_EXT_METHOD ossl_v3_tls_feature; extern const X509V3_EXT_METHOD ossl_v3_ext_admission; extern const X509V3_EXT_METHOD ossl_v3_utf8_list[1]; extern const X509V3_EXT_METHOD ossl_v3_issuer_sign_tool; +extern const X509V3_EXT_METHOD ossl_v3_group_ac; +extern const X509V3_EXT_METHOD ossl_v3_soa_identifier; +extern const X509V3_EXT_METHOD ossl_v3_no_assertion; +extern const X509V3_EXT_METHOD ossl_v3_no_rev_avail; +extern const X509V3_EXT_METHOD ossl_v3_single_use; +extern const X509V3_EXT_METHOD ossl_v3_indirect_issuer; diff --git a/crypto/x509/standard_exts.h b/crypto/x509/standard_exts.h index 27a99a4b13ed7ec1f1aaa069c14fd3510d18e67c..e5c9e3f9e01ac6f8e6dd91685df9d6a70e9b1e8b 100644 --- a/crypto/x509/standard_exts.h +++ b/crypto/x509/standard_exts.h @@ -53,6 +53,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = { #endif &ossl_v3_sinfo, &ossl_v3_policy_constraints, + &ossl_v3_no_rev_avail, #ifndef OPENSSL_NO_OCSP &ossl_v3_crl_hold, #endif @@ -71,7 +72,12 @@ static const X509V3_EXT_METHOD *standard_exts[] = { &ossl_v3_utf8_list[0], &ossl_v3_issuer_sign_tool, &ossl_v3_tls_feature, - &ossl_v3_ext_admission + &ossl_v3_ext_admission, + &ossl_v3_soa_identifier, + &ossl_v3_indirect_issuer, + &ossl_v3_no_assertion, + &ossl_v3_single_use, + &ossl_v3_group_ac }; /* Number of standard extensions */ diff --git a/crypto/x509/v3_group_ac.c b/crypto/x509/v3_group_ac.c new file mode 100644 index 0000000000000000000000000000000000000000..9a2b69deceb43789433120640222be46586b5682 --- /dev/null +++ b/crypto/x509/v3_group_ac.c @@ -0,0 +1,53 @@ +/* + * 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 "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_GROUP_AC(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_GROUP_AC(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_GROUP_AC(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_GROUP_AC(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The groupAC X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.1.2.6. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_group_ac = { + NID_group_ac, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_GROUP_AC, + (X509V3_EXT_S2I)s2i_GROUP_AC, + 0, 0, + (X509V3_EXT_I2R)i2r_GROUP_AC, + (X509V3_EXT_R2I)r2i_GROUP_AC, + NULL +}; diff --git a/crypto/x509/v3_ind_iss.c b/crypto/x509/v3_ind_iss.c new file mode 100644 index 0000000000000000000000000000000000000000..ff41ba7bed023d16960c817ade505874ee015519 --- /dev/null +++ b/crypto/x509/v3_ind_iss.c @@ -0,0 +1,53 @@ +/* + * 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 "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_INDIRECT_ISSUER(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_INDIRECT_ISSUER(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_INDIRECT_ISSUER(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_INDIRECT_ISSUER(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The indirectIssuer X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.5.2.5. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_indirect_issuer = { + NID_indirect_issuer, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_INDIRECT_ISSUER, + (X509V3_EXT_S2I)s2i_INDIRECT_ISSUER, + 0, 0, + (X509V3_EXT_I2R)i2r_INDIRECT_ISSUER, + (X509V3_EXT_R2I)r2i_INDIRECT_ISSUER, + NULL +}; diff --git a/crypto/x509/v3_no_ass.c b/crypto/x509/v3_no_ass.c new file mode 100644 index 0000000000000000000000000000000000000000..873e20a751c71eea2489cf5acb04e0e127d90392 --- /dev/null +++ b/crypto/x509/v3_no_ass.c @@ -0,0 +1,53 @@ +/* + * 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 "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_NO_ASSERTION(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_NO_ASSERTION(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_NO_ASSERTION(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_NO_ASSERTION(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The noAssertion X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.5.2.7. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_no_assertion = { + NID_no_assertion, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_NO_ASSERTION, + (X509V3_EXT_S2I)s2i_NO_ASSERTION, + 0, 0, + (X509V3_EXT_I2R)i2r_NO_ASSERTION, + (X509V3_EXT_R2I)r2i_NO_ASSERTION, + NULL +}; diff --git a/crypto/x509/v3_no_rev_avail.c b/crypto/x509/v3_no_rev_avail.c new file mode 100644 index 0000000000000000000000000000000000000000..849feda5ec0072874fcbbb8f11a08d7975fbca85 --- /dev/null +++ b/crypto/x509/v3_no_rev_avail.c @@ -0,0 +1,53 @@ +/* + * 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 "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_NO_REV_AVAIL(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_NO_REV_AVAIL(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_NO_REV_AVAIL(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_NO_REV_AVAIL(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The noRevAvail X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.2.2.7. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_no_rev_avail = { + NID_no_rev_avail, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_NO_REV_AVAIL, + (X509V3_EXT_S2I)s2i_NO_REV_AVAIL, + 0, 0, + (X509V3_EXT_I2R)i2r_NO_REV_AVAIL, + (X509V3_EXT_R2I)r2i_NO_REV_AVAIL, + NULL +}; diff --git a/crypto/x509/v3_single_use.c b/crypto/x509/v3_single_use.c new file mode 100644 index 0000000000000000000000000000000000000000..50da6e17700748d12eb1a7ef8f42651e01d14ee4 --- /dev/null +++ b/crypto/x509/v3_single_use.c @@ -0,0 +1,53 @@ +/* + * 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 "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_SINGLE_USE(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_SINGLE_USE(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_SINGLE_USE(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_SINGLE_USE(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The singleUse X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.1.2.5. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_single_use = { + NID_single_use, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_SINGLE_USE, + (X509V3_EXT_S2I)s2i_SINGLE_USE, + 0, 0, + (X509V3_EXT_I2R)i2r_SINGLE_USE, + (X509V3_EXT_R2I)r2i_SINGLE_USE, + NULL +}; diff --git a/crypto/x509/v3_soa_id.c b/crypto/x509/v3_soa_id.c new file mode 100644 index 0000000000000000000000000000000000000000..8be5bd8aa5a3055c62f5740451c1fa3f76cb2bc5 --- /dev/null +++ b/crypto/x509/v3_soa_id.c @@ -0,0 +1,53 @@ +/* + * 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 "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_SOA_IDENTIFIER(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_SOA_IDENTIFIER(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_SOA_IDENTIFIER(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_SOA_IDENTIFIER(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The sOAIdentifier X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.3.2.1.1. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_soa_identifier = { + NID_soa_identifier, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_SOA_IDENTIFIER, + (X509V3_EXT_S2I)s2i_SOA_IDENTIFIER, + 0, 0, + (X509V3_EXT_I2R)i2r_SOA_IDENTIFIER, + (X509V3_EXT_R2I)r2i_SOA_IDENTIFIER, + NULL +}; diff --git a/doc/internal/man3/ossl_rand_get_entropy.pod b/doc/internal/man3/ossl_rand_get_entropy.pod index 4da3f1f4d9db5f80e2769bbc95d8b1f4bd40854f..48343b6fe04938efce4f2b0b964183fb88a80569 100644 --- a/doc/internal/man3/ossl_rand_get_entropy.pod +++ b/doc/internal/man3/ossl_rand_get_entropy.pod @@ -2,8 +2,8 @@ =head1 NAME -ossl_rand_get_entropy, ossl_rand_cleanup_entropy, -ossl_rand_get_nonce, ossl_rand_cleanup_nonce +ossl_rand_get_entropy, ossl_rand_get_user_entropy, ossl_rand_cleanup_entropy, +ossl_rand_get_nonce, ossl_rand_get_user_nonce, ossl_rand_cleanup_nonce - get seed material from the operating system =head1 SYNOPSIS @@ -13,11 +13,17 @@ ossl_rand_get_nonce, ossl_rand_cleanup_nonce size_t ossl_rand_get_entropy(OSSL_CORE_HANDLE *handle, unsigned char **pout, int entropy, size_t min_len, size_t max_len); + size_t ossl_rand_get_user_entropy(OSSL_CORE_HANDLE *handle, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len); void ossl_rand_cleanup_entropy(OSSL_CORE_HANDLE *handle, unsigned char *buf, size_t len); size_t ossl_rand_get_nonce(OSSL_CORE_HANDLE *handle, unsigned char **pout, size_t min_len, size_t max_len, const void *salt, size_t salt_len); + size_t ossl_rand_get_user_nonce(OSSL_CORE_HANDLE *handle, unsigned char **pout, + size_t min_len, size_t max_len, + const void *salt, size_t salt_len); void ossl_rand_cleanup_nonce(OSSL_CORE_HANDLE *handle, unsigned char *buf, size_t len); @@ -29,9 +35,14 @@ stored in a buffer which contains at least I and at most I bytes. The buffer address is stored in I<*pout> and the buffer length is returned to the caller. +ossl_rand_get_user_entropy() is the same as ossl_rand_get_entropy() +except that it retrieves the seeding material from the library context's +DRBG seed source. By default this is the operating system but it can +be changed by calling L. + ossl_rand_cleanup_entropy() cleanses and frees any storage allocated by -ossl_rand_get_entropy(). The seeding buffer is pointed to by I and is -of length I bytes. +ossl_rand_get_entropy() or ossl_rand_get_user_entropy(). The entropy +buffer is pointed to by I and is of length I bytes. ossl_rand_get_nonce() retrieves a nonce using the passed I parameter of length I and operating system specific information. @@ -41,18 +52,34 @@ The output is stored in a buffer which contains at least I and at most I bytes. The buffer address is stored in I<*pout> and the buffer length returned to the caller. +ossl_rand_get_user_nonce() is the same as ossl_rand_get_nonce() except +that it retrieves the seeding material from the library context's DRBG +seed source. By default this is the operating system but it can be +changed by calling L. + ossl_rand_cleanup_nonce() cleanses and frees any storage allocated by -ossl_rand_get_nonce(). The nonce buffer is pointed to by I and is -of length I bytes. +ossl_rand_get_nonce() or ossl_rand_get_user_nonce(). The nonce buffer +is pointed to by I and is of length I bytes. + +=head1 NOTES + +FIPS providers 3.0.0, 3.0.8 and 3.0.9 incorrectly pass a provider +internal pointer to ossl_rand_get_entropy(), ossl_rand_cleanup_entropy(), +ossl_rand_get_nonce() and ossl_rand_cleanup_nonce(). This pointer cannot +be safely dereferenced. =head1 RETURN VALUES -ossl_rand_get_entropy() and ossl_rand_get_nonce() return the number of bytes -in I<*pout> or 0 on error. +ossl_rand_get_entropy(), ossl_rand_get_user_entropy(), +ossl_rand_get_nonce() and ossl_rand_get_user_nonce() return the number +of bytes in I<*pout> or 0 on error. =head1 HISTORY -The functions described here were all added in OpenSSL 3.0. +The functions ossl_rand_get_user_entropy() and ossl_rand_get_user_nonce() +were added in OpenSSL 3.0.12, 3.1.4 and 3.2.0. + +The remaining functions described here were all added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man1/openssl-genpkey.pod.in b/doc/man1/openssl-genpkey.pod.in index e760d613fe0716e33b33accde4355b626001ba72..aa0b74e8aaeba153a697c0fdcc49d2565303b48b 100644 --- a/doc/man1/openssl-genpkey.pod.in +++ b/doc/man1/openssl-genpkey.pod.in @@ -7,13 +7,14 @@ =head1 NAME -openssl-genpkey - generate a private key +openssl-genpkey - generate a private key or key pair =head1 SYNOPSIS B B [B<-help>] [B<-out> I] +[B<-outpubkey> I] [B<-outform> B|B] [B<-verbose>] [B<-quiet>] @@ -29,7 +30,7 @@ B B =head1 DESCRIPTION -This command generates a private key. +This command generates a private key or key pair. =head1 OPTIONS @@ -41,8 +42,13 @@ Print out a usage message. =item B<-out> I -Output the key to the specified file. If this argument is not specified then -standard output is used. +Output the private key to the specified file. If this argument is not +specified then standard output is used. + +=item B<-outpubkey> I + +Output the public key to the specified file. If this argument is not +specified then the public key is not output. =item B<-outform> B|B @@ -73,8 +79,8 @@ name accepted by EVP_get_cipherbyname() is acceptable such as B. Public key algorithm to use such as RSA, DSA, DH or DHX. If used this option must precede any B<-pkeyopt> options. The options B<-paramfile> and B<-algorithm> -are mutually exclusive. Engines may add algorithms in addition to the standard -built-in ones. +are mutually exclusive. Engines or providers may add algorithms in addition to +the standard built-in ones. Valid built-in algorithm names for private key generation are RSA, RSA-PSS, EC, X25519, X448, ED25519 and ED448. diff --git a/doc/man3/BIO_ADDR.pod b/doc/man3/BIO_ADDR.pod index aa5bf77191461085da6de7b7589f46c81207eefb..20cd364d48aeea20f6991102da8da522a550d841 100644 --- a/doc/man3/BIO_ADDR.pod +++ b/doc/man3/BIO_ADDR.pod @@ -2,8 +2,8 @@ =head1 NAME -BIO_ADDR, BIO_ADDR_new, BIO_ADDR_dup, BIO_ADDR_clear, BIO_ADDR_free, -BIO_ADDR_rawmake, +BIO_ADDR, BIO_ADDR_new, BIO_ADDR_copy, BIO_ADDR_dup, BIO_ADDR_clear, +BIO_ADDR_free, BIO_ADDR_rawmake, BIO_ADDR_family, BIO_ADDR_rawaddress, BIO_ADDR_rawport, BIO_ADDR_hostname_string, BIO_ADDR_service_string, BIO_ADDR_path_string - BIO_ADDR routines @@ -16,6 +16,7 @@ BIO_ADDR_path_string - BIO_ADDR routines typedef union bio_addr_st BIO_ADDR; BIO_ADDR *BIO_ADDR_new(void); + int BIO_ADDR_copy(BIO_ADDR *dst, const BIO_ADDR *src); BIO_ADDR *BIO_ADDR_dup(const BIO_ADDR *ap); void BIO_ADDR_free(BIO_ADDR *); void BIO_ADDR_clear(BIO_ADDR *ap); @@ -39,6 +40,9 @@ BIO_ADDR_new() creates a new unfilled B, to be used with routines that will fill it with information, such as BIO_accept_ex(). +BIO_ADDR_copy() copies the contents of B into B. Neither B or +B can be NULL. + BIO_ADDR_dup() creates a new B, with a copy of the address data in B. @@ -112,6 +116,8 @@ BIO_ADDR_service_string() and BIO_ADDR_path_string() will return B on error and leave an error indication on the OpenSSL error stack. +BIO_ADDR_copy() returns 1 on success or 0 on error. + All other functions described here return 0 or B when the information they should return isn't available. @@ -121,7 +127,7 @@ L, L =head1 HISTORY -BIO_ADDR_dup() was added in OpenSSL 3.2. +BIO_ADDR_copy() and BIO_ADDR_dup() were added in OpenSSL 3.2. =head1 COPYRIGHT diff --git a/doc/man7/EVP_RAND-TEST-RAND.pod b/doc/man7/EVP_RAND-TEST-RAND.pod index ff5207565c62cf348f86d6ffcc4e69eb375c5e0d..feab01431d928decda8e7ca636fe70f7ed6e0bde 100644 --- a/doc/man7/EVP_RAND-TEST-RAND.pod +++ b/doc/man7/EVP_RAND-TEST-RAND.pod @@ -60,6 +60,13 @@ If there are insufficient data present to satisfy a call, an error is returned. Sets the bytes returned when the test generator is sent a nonce request. Each nonce request will return all of the bytes. +=item "generate" (B) + +If this parameter is zero, it will only emit the nonce and entropy data +supplied via the aforementioned parameters. Otherwise, low quality +non-cryptographic pseudorandom output is produced. This parameter defaults +to zero. + =back =head1 NOTES diff --git a/doc/man7/provider-base.pod b/doc/man7/provider-base.pod index 33d7fe7f55140aaa77905e809da714071cacc9c5..eb9e8d35758ffd6650eb345bcf2fb63c2878190e 100644 --- a/doc/man7/provider-base.pod +++ b/doc/man7/provider-base.pod @@ -76,11 +76,17 @@ provider-base size_t get_entropy(const OSSL_CORE_HANDLE *handle, unsigned char **pout, int entropy, size_t min_len, size_t max_len); + size_t get_user_entropy(const OSSL_CORE_HANDLE *handle, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len); void cleanup_entropy(const OSSL_CORE_HANDLE *handle, unsigned char *buf, size_t len); size_t get_nonce(const OSSL_CORE_HANDLE *handle, unsigned char **pout, size_t min_len, size_t max_len, const void *salt, size_t salt_len); + size_t get_user_nonce(const OSSL_CORE_HANDLE *handle, + unsigned char **pout, size_t min_len, size_t max_len, + const void *salt, size_t salt_len); void cleanup_nonce(const OSSL_CORE_HANDLE *handle, unsigned char *buf, size_t len); @@ -171,8 +177,10 @@ provider): OPENSSL_cleanse OSSL_FUNC_OPENSSL_CLEANSE OSSL_SELF_TEST_set_callback OSSL_FUNC_SELF_TEST_CB ossl_rand_get_entropy OSSL_FUNC_GET_ENTROPY + ossl_rand_get_user_entropy OSSL_FUNC_GET_USER_ENTROPY ossl_rand_cleanup_entropy OSSL_FUNC_CLEANUP_ENTROPY ossl_rand_get_nonce OSSL_FUNC_GET_NONCE + ossl_rand_get_user_nonce OSSL_FUNC_GET_USER_NONCE ossl_rand_cleanup_nonce OSSL_FUNC_CLEANUP_NONCE provider_register_child_cb OSSL_FUNC_PROVIDER_REGISTER_CHILD_CB provider_deregister_child_cb OSSL_FUNC_PROVIDER_DEREGISTER_CHILD_CB @@ -302,9 +310,14 @@ output will have at least I and at most I bytes. The buffer address is stored in I<*pout> and the buffer length is returned to the caller. On error, zero is returned. +get_user_entropy() is the same as get_entropy() except that it will +attempt to gather seed material via the seed source specified by a call to +L or via L. + cleanup_entropy() is used to clean up and free the buffer returned by -get_entropy(). The entropy pointer returned by get_entropy() is passed in -B and its length in B. +get_entropy() or get_user_entropy(). The entropy pointer returned by +get_entropy() or get_user_entropy() is passed in B and its length +in B. get_nonce() retrieves a nonce using the passed I parameter of length I and operating system specific information. @@ -314,9 +327,14 @@ The output is stored in a buffer which contains at least I and at most I bytes. The buffer address is stored in I<*pout> and the buffer length returned to the caller. On error, zero is returned. -cleanup_nonce() is used to clean up and free the buffer returned by -get_nonce(). The nonce pointer returned by get_nonce() is passed in -B and its length in B. +get_user_nonce() is the same as get_nonce() except that it will attempt +to gather seed material via the seed source specified by a call to +L or via L. + +cleanup_nonce() is used to clean up and free the buffer returned +by get_nonce() or get_user_nonce(). The nonce pointer returned by +get_nonce() or get_user_nonce() is passed in B and its length +in B. provider_register_child_cb() registers callbacks for being informed about the loading and unloading of providers in the application's library context. diff --git a/include/crypto/context.h b/include/crypto/context.h index 56c68f4ec114fa1db592adc01a97b700e64d80fd..af81e15e1dc515803adb3247ab713f119576c8bf 100644 --- a/include/crypto/context.h +++ b/include/crypto/context.h @@ -21,6 +21,7 @@ void *ossl_child_prov_ctx_new(OSSL_LIB_CTX *); void *ossl_prov_drbg_nonce_ctx_new(OSSL_LIB_CTX *); void *ossl_self_test_set_callback_new(OSSL_LIB_CTX *); void *ossl_rand_crng_ctx_new(OSSL_LIB_CTX *); +int ossl_thread_register_fips(OSSL_LIB_CTX *); void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *); void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *); #if defined(OPENSSL_THREADS) diff --git a/include/crypto/rand.h b/include/crypto/rand.h index 758aeed4af22c6a1f9d2e3d1c9d2f20c771d38c0..730be8b5d0245302769b450398b271ff0ae2f5e4 100644 --- a/include/crypto/rand.h +++ b/include/crypto/rand.h @@ -108,15 +108,21 @@ void ossl_random_add_conf_module(void); /* * Get and cleanup random seed material. */ -size_t ossl_rand_get_entropy(ossl_unused const OSSL_CORE_HANDLE *handle, +size_t ossl_rand_get_entropy(OSSL_LIB_CTX *ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len); -void ossl_rand_cleanup_entropy(ossl_unused const OSSL_CORE_HANDLE *handle, +size_t ossl_rand_get_user_entropy(OSSL_LIB_CTX *ctx, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len); +void ossl_rand_cleanup_entropy(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t len); -size_t ossl_rand_get_nonce(ossl_unused const OSSL_CORE_HANDLE *handle, +size_t ossl_rand_get_nonce(OSSL_LIB_CTX *ctx, unsigned char **pout, size_t min_len, size_t max_len, const void *salt, size_t salt_len); -void ossl_rand_cleanup_nonce(ossl_unused const OSSL_CORE_HANDLE *handle, +size_t ossl_rand_get_user_nonce(OSSL_LIB_CTX *ctx, unsigned char **pout, + size_t min_len, size_t max_len, + const void *salt, size_t salt_len); +void ossl_rand_cleanup_nonce(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t len); /* @@ -125,4 +131,9 @@ void ossl_rand_cleanup_nonce(ossl_unused const OSSL_CORE_HANDLE *handle, size_t ossl_pool_acquire_entropy(RAND_POOL *pool); int ossl_pool_add_nonce_data(RAND_POOL *pool); +# ifdef FIPS_MODULE +EVP_RAND_CTX *ossl_rand_get0_private_noncreating(OSSL_LIB_CTX *ctx); +# else +EVP_RAND_CTX *ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX *ctx); +# endif #endif diff --git a/include/crypto/randerr.h b/include/crypto/randerr.h index 832a8b7d36f5cd8e89b43ce3452dec0a7871f579..6e2eb0716fb3dab6b7b766a1cb4128d09e45bb03 100644 --- a/include/crypto/randerr.h +++ b/include/crypto/randerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-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 diff --git a/include/openssl/bio.h.in b/include/openssl/bio.h.in index 8aad1414460d9533ab1e43f5d67852011da5387a..c534dcd76cdb6d6ea0228979aa8c76a6b744c43a 100644 --- a/include/openssl/bio.h.in +++ b/include/openssl/bio.h.in @@ -806,6 +806,7 @@ int BIO_hex_string(BIO *out, int indent, int width, const void *data, # ifndef OPENSSL_NO_SOCK BIO_ADDR *BIO_ADDR_new(void); +int BIO_ADDR_copy(BIO_ADDR *dst, const BIO_ADDR *src); BIO_ADDR *BIO_ADDR_dup(const BIO_ADDR *ap); int BIO_ADDR_rawmake(BIO_ADDR *ap, int family, const void *where, size_t wherelen, unsigned short port); diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index 73f040285cd5134172b80855a7611ab34db6a169..6c952f18aac00fa038d48b4c95c95c489575ea72 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -176,6 +176,10 @@ OSSL_CORE_MAKE_FUNC(int, BIO_vsnprintf, OSSL_CORE_MAKE_FUNC(int, BIO_ctrl, (OSSL_CORE_BIO *bio, int cmd, long num, void *ptr)) +/* New seeding functions prototypes with the 101-104 series */ +#define OSSL_FUNC_GET_USER_ENTROPY 98 +#define OSSL_FUNC_GET_USER_NONCE 99 + #define OSSL_FUNC_SELF_TEST_CB 100 OSSL_CORE_MAKE_FUNC(void, self_test_cb, (OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **cb, void **cbarg)) @@ -188,12 +192,19 @@ OSSL_CORE_MAKE_FUNC(void, self_test_cb, (OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK ** OSSL_CORE_MAKE_FUNC(size_t, get_entropy, (const OSSL_CORE_HANDLE *handle, unsigned char **pout, int entropy, size_t min_len, size_t max_len)) +OSSL_CORE_MAKE_FUNC(size_t, get_user_entropy, (const OSSL_CORE_HANDLE *handle, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len)) OSSL_CORE_MAKE_FUNC(void, cleanup_entropy, (const OSSL_CORE_HANDLE *handle, unsigned char *buf, size_t len)) OSSL_CORE_MAKE_FUNC(size_t, get_nonce, (const OSSL_CORE_HANDLE *handle, unsigned char **pout, size_t min_len, size_t max_len, const void *salt, size_t salt_len)) +OSSL_CORE_MAKE_FUNC(size_t, get_user_nonce, (const OSSL_CORE_HANDLE *handle, + unsigned char **pout, size_t min_len, + size_t max_len, const void *salt, + size_t salt_len)) OSSL_CORE_MAKE_FUNC(void, cleanup_nonce, (const OSSL_CORE_HANDLE *handle, unsigned char *buf, size_t len)) diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h index b5e08e4362dea22c03fac4b1a05aa357e1a03384..04880374a3b745a0a3dd8358d96f8b682479969d 100644 --- a/include/openssl/randerr.h +++ b/include/openssl/randerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -41,6 +41,7 @@ # define RAND_R_GENERATE_ERROR 112 # define RAND_R_INSUFFICIENT_DRBG_STRENGTH 139 # define RAND_R_INTERNAL_ERROR 113 +# define RAND_R_INVALID_PROPERTY_QUERY 137 # define RAND_R_IN_ERROR_STATE 114 # define RAND_R_NOT_A_REGULAR_FILE 122 # define RAND_R_NOT_INSTANTIATED 115 diff --git a/providers/baseprov.c b/providers/baseprov.c index 2e5dbe410feceee69da5f21e304cf3a0957f66c9..6b8de7cb367d1ccf7ca6f62812a3f84d18562c0c 100644 --- a/providers/baseprov.c +++ b/providers/baseprov.c @@ -19,6 +19,7 @@ #include "prov/providercommon.h" #include "prov/implementations.h" #include "prov/provider_util.h" +#include "prov/names.h" /* * Forward declarations to ensure that interface functions are correctly @@ -90,6 +91,11 @@ static const OSSL_ALGORITHM base_store[] = { #undef STORE }; +static const OSSL_ALGORITHM base_rands[] = { + { PROV_NAMES_SEED_SRC, "provider=base", ossl_seed_src_functions }, + { NULL, NULL, NULL } +}; + static const OSSL_ALGORITHM *base_query(void *provctx, int operation_id, int *no_cache) { @@ -101,6 +107,8 @@ static const OSSL_ALGORITHM *base_query(void *provctx, int operation_id, return base_decoder; case OSSL_OP_STORE: return base_store; + case OSSL_OP_RAND: + return base_rands; } return NULL; } diff --git a/providers/common/provider_seeding.c b/providers/common/provider_seeding.c index d67ddf7b136d4c97143c32d0bb70038225909b01..f6463f8ada30cc29d2342b0aacffc12a58858297 100644 --- a/providers/common/provider_seeding.c +++ b/providers/common/provider_seeding.c @@ -9,12 +9,33 @@ #include #include "prov/seeding.h" +#include "prov/providercommon.h" static OSSL_FUNC_get_entropy_fn *c_get_entropy = NULL; +static OSSL_FUNC_get_user_entropy_fn *c_get_user_entropy = NULL; static OSSL_FUNC_cleanup_entropy_fn *c_cleanup_entropy = NULL; static OSSL_FUNC_get_nonce_fn *c_get_nonce = NULL; +static OSSL_FUNC_get_user_nonce_fn *c_get_user_nonce = NULL; static OSSL_FUNC_cleanup_nonce_fn *c_cleanup_nonce = NULL; +#ifdef FIPS_MODULE +/* + * The FIPS provider uses an internal library context which is what the + * passed provider context references. Since the seed source is external + * to the FIPS provider, this is the wrong one. We need to convert this + * to the correct core handle before up-calling libcrypto. + */ +# define CORE_HANDLE(provctx) \ + FIPS_get_core_handle(ossl_prov_ctx_get0_libctx(provctx)) +#else +/* + * The non-FIPS path *should* be unused because the full DRBG chain including + * seed source is instantiated. However, that might not apply for third + * party providers, so this is retained for compatibility. + */ +# define CORE_HANDLE(provctx) ossl_prov_ctx_get0_handle(provctx) +#endif + int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns) { for (; fns->function_id != 0; fns++) { @@ -29,12 +50,18 @@ int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns) case OSSL_FUNC_GET_ENTROPY: set_func(c_get_entropy, OSSL_FUNC_get_entropy(fns)); break; + case OSSL_FUNC_GET_USER_ENTROPY: + set_func(c_get_user_entropy, OSSL_FUNC_get_user_entropy(fns)); + break; case OSSL_FUNC_CLEANUP_ENTROPY: set_func(c_cleanup_entropy, OSSL_FUNC_cleanup_entropy(fns)); break; case OSSL_FUNC_GET_NONCE: set_func(c_get_nonce, OSSL_FUNC_get_nonce(fns)); break; + case OSSL_FUNC_GET_USER_NONCE: + set_func(c_get_user_nonce, OSSL_FUNC_get_user_nonce(fns)); + break; case OSSL_FUNC_CLEANUP_NONCE: set_func(c_cleanup_nonce, OSSL_FUNC_cleanup_nonce(fns)); break; @@ -47,31 +74,37 @@ int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns) size_t ossl_prov_get_entropy(PROV_CTX *prov_ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { - if (c_get_entropy == NULL) - return 0; - return c_get_entropy(ossl_prov_ctx_get0_handle(prov_ctx), - pout, entropy, min_len, max_len); + const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx); + + if (c_get_user_entropy != NULL) + return c_get_user_entropy(handle, pout, entropy, min_len, max_len); + if (c_get_entropy != NULL) + return c_get_entropy(handle, pout, entropy, min_len, max_len); + return 0; } void ossl_prov_cleanup_entropy(PROV_CTX *prov_ctx, unsigned char *buf, size_t len) { if (c_cleanup_entropy != NULL) - c_cleanup_entropy(ossl_prov_ctx_get0_handle(prov_ctx), buf, len); + c_cleanup_entropy(CORE_HANDLE(prov_ctx), buf, len); } size_t ossl_prov_get_nonce(PROV_CTX *prov_ctx, unsigned char **pout, size_t min_len, size_t max_len, const void *salt, size_t salt_len) { - if (c_get_nonce == NULL) - return 0; - return c_get_nonce(ossl_prov_ctx_get0_handle(prov_ctx), pout, - min_len, max_len, salt, salt_len); + const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx); + + if (c_get_user_nonce != NULL) + return c_get_user_nonce(handle, pout, min_len, max_len, salt, salt_len); + if (c_get_nonce != NULL) + return c_get_nonce(handle, pout, min_len, max_len, salt, salt_len); + return 0; } void ossl_prov_cleanup_nonce(PROV_CTX *prov_ctx, unsigned char *buf, size_t len) { if (c_cleanup_nonce != NULL) - c_cleanup_nonce(ossl_prov_ctx_get0_handle(prov_ctx), buf, len); + c_cleanup_nonce(CORE_HANDLE(prov_ctx), buf, len); } diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 0a95d2364d43e9039e1f847d3fb1a4dcf5a529f5..7ec409710b6cc02835d4d00f83a06d3caad895d0 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -697,21 +697,23 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, /* Create a context. */ if ((*provctx = ossl_prov_ctx_new()) == NULL - || (libctx = OSSL_LIB_CTX_new()) == NULL) { - /* - * We free libctx separately here and only here because it hasn't - * been attached to *provctx. All other error paths below rely - * solely on fips_teardown. - */ - OSSL_LIB_CTX_free(libctx); + || (libctx = OSSL_LIB_CTX_new()) == NULL) goto err; - } if ((fgbl = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_FIPS_PROV_INDEX)) == NULL) goto err; fgbl->handle = handle; + /* + * We need to register this thread to receive thread lifecycle callbacks. + * This wouldn't matter if the current thread is also the same thread that + * closes the FIPS provider down. But if that happens on a different thread + * then memory leaks could otherwise occur. + */ + if (!ossl_thread_register_fips(libctx)) + goto err; + /* * We did initial set up of selftest_params in a local copy, because we * could not create fgbl until c_CRYPTO_zalloc was defined in the loop diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c index 0be314692e8872a53a7d4924cbdaa942ea6b27f3..b8dc9817b283cde10a539df2ec0e51e795e8bd8e 100644 --- a/providers/fips/self_test.c +++ b/providers/fips/self_test.c @@ -19,6 +19,7 @@ #include "internal/e_os.h" #include "internal/tsan_assist.h" #include "prov/providercommon.h" +#include "crypto/rand.h" /* * We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS @@ -406,14 +407,14 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) } /* Verify that the RNG has been restored properly */ - testrand = EVP_RAND_fetch(st->libctx, "TEST-RAND", NULL); - if (testrand == NULL - || (rng = RAND_get0_private(st->libctx)) == NULL - || strcmp(EVP_RAND_get0_name(EVP_RAND_CTX_get0_rand(rng)), - EVP_RAND_get0_name(testrand)) == 0) { - ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE); - goto end; - } + rng = ossl_rand_get0_private_noncreating(st->libctx); + if (rng != NULL) + if ((testrand = EVP_RAND_fetch(st->libctx, "TEST-RAND", NULL)) == NULL + || strcmp(EVP_RAND_get0_name(EVP_RAND_CTX_get0_rand(rng)), + EVP_RAND_get0_name(testrand)) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE); + goto end; + } ok = 1; end: diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c index bdf599aaada4188a9b8482b4cef1ea382e691dd1..82a7ac78fb01341ff682fcb35711dbf6e51f61f5 100644 --- a/providers/fips/self_test_kats.c +++ b/providers/fips/self_test_kats.c @@ -13,6 +13,7 @@ #include #include #include +#include "crypto/rand.h" #include "internal/cryptlib.h" #include "internal/nelem.h" #include "self_test.h" @@ -22,7 +23,7 @@ static int set_kat_drbg(OSSL_LIB_CTX *ctx, const unsigned char *entropy, size_t entropy_len, const unsigned char *nonce, size_t nonce_len, const unsigned char *persstr, size_t persstr_len); -static int reset_original_drbg(OSSL_LIB_CTX *ctx); +static int reset_main_drbg(OSSL_LIB_CTX *ctx); static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) @@ -701,39 +702,12 @@ static int self_test_signatures(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) return 0; if (!self_test_sign(t, st, libctx)) ret = 0; - if (!reset_original_drbg(libctx)) + if (!reset_main_drbg(libctx)) ret = 0; } return ret; } -/* - * Run the algorithm KAT's. - * Return 1 is successful, otherwise return 0. - * This runs all the tests regardless of if any fail. - */ -int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) -{ - int ret = 1; - - if (!self_test_digests(st, libctx)) - ret = 0; - if (!self_test_ciphers(st, libctx)) - ret = 0; - if (!self_test_signatures(st, libctx)) - ret = 0; - if (!self_test_kdfs(st, libctx)) - ret = 0; - if (!self_test_drbgs(st, libctx)) - ret = 0; - if (!self_test_kas(st, libctx)) - ret = 0; - if (!self_test_asym_ciphers(st, libctx)) - ret = 0; - - return ret; -} - /* * Swap the library context DRBG for KAT testing * @@ -745,13 +719,12 @@ int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) */ /* - * The default private DRBG of the library context, saved for the duration - * of KAT testing. + * Replacement "random" sources + * main_rand is used for most tests and it's set to generate mode. + * kat_rand is used for KATs where specific input is mandated. */ -static EVP_RAND_CTX *saved_rand = NULL; - -/* Replacement "random" source */ static EVP_RAND_CTX *kat_rand = NULL; +static EVP_RAND_CTX *main_rand = NULL; static int set_kat_drbg(OSSL_LIB_CTX *ctx, const unsigned char *entropy, size_t entropy_len, @@ -765,7 +738,7 @@ static int set_kat_drbg(OSSL_LIB_CTX *ctx, }; /* If not NULL, we didn't cleanup from last call: BAD */ - if (kat_rand != NULL || saved_rand != NULL) + if (kat_rand != NULL) return 0; rand = EVP_RAND_fetch(ctx, "TEST-RAND", NULL); @@ -777,7 +750,8 @@ static int set_kat_drbg(OSSL_LIB_CTX *ctx, if (parent_rand == NULL) goto err; - drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, &strength); + drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, + &strength); if (!EVP_RAND_CTX_set_params(parent_rand, drbg_params)) goto err; @@ -810,37 +784,30 @@ static int set_kat_drbg(OSSL_LIB_CTX *ctx, if (!EVP_RAND_instantiate(kat_rand, strength, 0, persstr, persstr_len, NULL)) goto err; + /* When we set the new private generator this one is freed, so upref it */ + if (!EVP_RAND_CTX_up_ref(main_rand)) + goto err; + /* Update the library context DRBG */ - if ((saved_rand = RAND_get0_private(ctx)) != NULL) - /* Avoid freeing this since we replace it */ - if (!EVP_RAND_CTX_up_ref(saved_rand)) { - saved_rand = NULL; - goto err; - } if (RAND_set0_private(ctx, kat_rand) > 0) { /* Keeping a copy to verify zeroization */ if (EVP_RAND_CTX_up_ref(kat_rand)) return 1; - if (saved_rand != NULL) - RAND_set0_private(ctx, saved_rand); + RAND_set0_private(ctx, main_rand); } err: EVP_RAND_CTX_free(parent_rand); - EVP_RAND_CTX_free(saved_rand); EVP_RAND_CTX_free(kat_rand); - kat_rand = saved_rand = NULL; + kat_rand = NULL; return 0; } -static int reset_original_drbg(OSSL_LIB_CTX *ctx) { +static int reset_main_drbg(OSSL_LIB_CTX *ctx) { int ret = 1; - if (saved_rand != NULL) { - if (!RAND_set0_private(ctx, saved_rand)) - ret = 0; - saved_rand = NULL; - } + if (!RAND_set0_private(ctx, main_rand)) + ret = 0; if (kat_rand != NULL) { if (!EVP_RAND_uninstantiate(kat_rand) || !EVP_RAND_verify_zeroization(kat_rand)) @@ -851,3 +818,68 @@ static int reset_original_drbg(OSSL_LIB_CTX *ctx) { return ret; } +static int setup_main_random(OSSL_LIB_CTX *libctx) +{ + OSSL_PARAM drbg_params[3] = { + OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END + }; + unsigned int strength = 256, generate = 1; + EVP_RAND *rand; + + rand = EVP_RAND_fetch(libctx, "TEST-RAND", NULL); + if (rand == NULL) + return 0; + + main_rand = EVP_RAND_CTX_new(rand, NULL); + EVP_RAND_free(rand); + if (main_rand == NULL) + goto err; + + drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_GENERATE, + &generate); + drbg_params[1] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, + &strength); + + if (!EVP_RAND_instantiate(main_rand, strength, 0, NULL, 0, drbg_params)) + goto err; + return 1; + err: + EVP_RAND_CTX_free(main_rand); + return 0; +} + +/* + * Run the algorithm KAT's. + * Return 1 is successful, otherwise return 0. + * This runs all the tests regardless of if any fail. + */ +int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) +{ + EVP_RAND_CTX *saved_rand = ossl_rand_get0_private_noncreating(libctx); + int ret = 1; + + if (!setup_main_random(libctx) + || !RAND_set0_private(libctx, main_rand)) { + EVP_RAND_CTX_free(main_rand); + return 0; + } + + if (!self_test_digests(st, libctx)) + ret = 0; + if (!self_test_ciphers(st, libctx)) + ret = 0; + if (!self_test_signatures(st, libctx)) + ret = 0; + if (!self_test_kdfs(st, libctx)) + ret = 0; + if (!self_test_drbgs(st, libctx)) + ret = 0; + if (!self_test_kas(st, libctx)) + ret = 0; + if (!self_test_asym_ciphers(st, libctx)) + ret = 0; + + RAND_set0_private(libctx, saved_rand); + return ret; +} + diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c index 348d5f50808edb19a0b4ea51407da50833e7e3c5..158628869252574945e8a400bbfefd5b63b3833d 100644 --- a/providers/implementations/rands/drbg.c +++ b/providers/implementations/rands/drbg.c @@ -336,7 +336,7 @@ static size_t prov_drbg_get_nonce(PROV_DRBG *drbg, unsigned char **pout, memset(&data, 0, sizeof(data)); data.drbg = drbg; if (!CRYPTO_atomic_add(&dngbl->rand_nonce_count, 1, &data.count, - dngbl->rand_nonce_lock)) + dngbl->rand_nonce_lock)) return 0; return ossl_prov_get_nonce(drbg->provctx, pout, min_len, max_len, &data, sizeof(data)); diff --git a/providers/implementations/rands/test_rng.c b/providers/implementations/rands/test_rng.c index bbea11cd6baf06a3a03fc8b76c0f6864d18360d0..0006468d06638aa76b79b4c297ead1b8b0e03319 100644 --- a/providers/implementations/rands/test_rng.c +++ b/providers/implementations/rands/test_rng.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -39,6 +40,7 @@ static OSSL_FUNC_rand_get_seed_fn test_rng_get_seed; typedef struct { void *provctx; + unsigned int generate; int state; unsigned int strength; size_t max_request; @@ -99,16 +101,30 @@ static int test_rng_uninstantiate(void *vtest) return 1; } +static unsigned char gen_byte(PROV_TEST_RNG *t) +{ + return rand() & 0xff; +} + static int test_rng_generate(void *vtest, unsigned char *out, size_t outlen, unsigned int strength, int prediction_resistance, const unsigned char *adin, size_t adin_len) { PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest; + size_t i; - if (strength > t->strength || t->entropy_len - t->entropy_pos < outlen) + if (strength > t->strength) return 0; - memcpy(out, t->entropy + t->entropy_pos, outlen); - t->entropy_pos += outlen; + if (t->generate) { + for (i = 0; i < outlen; i++) + out[i] = gen_byte(t); + } else { + if (t->entropy_len - t->entropy_pos < outlen) + return 0; + + memcpy(out, t->entropy + t->entropy_pos, outlen); + t->entropy_pos += outlen; + } return 1; } @@ -123,15 +139,23 @@ static int test_rng_reseed(ossl_unused void *vtest, } static size_t test_rng_nonce(void *vtest, unsigned char *out, - unsigned int strength, - ossl_unused size_t min_noncelen, + unsigned int strength, size_t min_noncelen, ossl_unused size_t max_noncelen) { PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest; + size_t i; - if (t->nonce == NULL || strength > t->strength) + if (strength > t->strength) return 0; + if (t->generate) { + for (i = 0; i < min_noncelen; i++) + out[i] = gen_byte(t); + return min_noncelen; + } + + if (t->nonce == NULL) + return 0; if (out != NULL) memcpy(out, t->nonce, t->nonce_len); return t->nonce_len; @@ -153,6 +177,10 @@ static int test_rng_get_ctx_params(void *vtest, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST); if (p != NULL && !OSSL_PARAM_set_size_t(p, t->max_request)) return 0; + + p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_GENERATE); + if (p != NULL && OSSL_PARAM_set_uint(p, t->generate)) + return 0; return 1; } @@ -163,6 +191,7 @@ static const OSSL_PARAM *test_rng_gettable_ctx_params(ossl_unused void *vtest, OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL), OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL), OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL), + OSSL_PARAM_uint(OSSL_RAND_PARAM_GENERATE, NULL), OSSL_PARAM_END }; return known_gettable_ctx_params; @@ -203,9 +232,12 @@ static int test_rng_set_ctx_params(void *vtest, const OSSL_PARAM params[]) } p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_MAX_REQUEST); - if (p != NULL && !OSSL_PARAM_get_size_t(p, &t->max_request)) + if (p != NULL && !OSSL_PARAM_get_size_t(p, &t->max_request)) return 0; + p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_GENERATE); + if (p != NULL && !OSSL_PARAM_get_uint(p, &t->generate)) + return 0; return 1; } @@ -217,6 +249,7 @@ static const OSSL_PARAM *test_rng_settable_ctx_params(ossl_unused void *vtest, OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_NONCE, NULL, 0), OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL), OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL), + OSSL_PARAM_uint(OSSL_RAND_PARAM_GENERATE, NULL), OSSL_PARAM_END }; return known_settable_ctx_params; diff --git a/ssl/event_queue.c b/ssl/event_queue.c index 49890a36b505f643e4c1b80800d8f8cdfb694215..20f4020db51b4f8de05f307ab38f751c157b01d7 100644 --- a/ssl/event_queue.c +++ b/ssl/event_queue.c @@ -9,7 +9,6 @@ #include #include "internal/event_queue.h" -#include "crypto/sparse_array.h" #include "ssl_local.h" struct ossl_event_queue_st { diff --git a/test/bio_addr_test.c b/test/bio_addr_test.c new file mode 100644 index 0000000000000000000000000000000000000000..a985d03b14c1a131e598b18c6e8c21eb54a036b4 --- /dev/null +++ b/test/bio_addr_test.c @@ -0,0 +1,164 @@ +/* + * 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 "internal/e_os.h" +#include "internal/sockets.h" +#include "testutil.h" + +static int families[] = { + AF_INET, +#if OPENSSL_USE_IPV6 + AF_INET6, +#endif +#ifndef OPENSSL_NO_UNIX_SOCK + AF_UNIX +#endif +}; + +static BIO_ADDR *make_dummy_addr(int family) +{ + BIO_ADDR *addr; + union { + struct sockaddr_in sin; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 sin6; +#endif +#ifndef OPENSSL_NO_UNIX_SOCK + struct sockaddr_un sun; +#endif + } sa; + void *where; + size_t wherelen; + + /* Fill with a dummy address */ + switch(family) { + case AF_INET: + where = &(sa.sin.sin_addr); + wherelen = sizeof(sa.sin.sin_addr); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + where = &(sa.sin6.sin6_addr); + wherelen = sizeof(sa.sin6.sin6_addr); + break; +#endif +#ifndef OPENSSL_NO_UNIX_SOCK + case AF_UNIX: + where = &(sa.sun.sun_path); + /* BIO_ADDR_rawmake needs an extra byte for a NUL-terminator*/ + wherelen = sizeof(sa.sun.sun_path) - 1; + break; +#endif + default: + TEST_error("Unsupported address family"); + return 0; + } + /* + * Could be any data, but we make it printable because BIO_ADDR_rawmake + * expects the AF_UNIX address to be a string. + */ + memset(where, 'a', wherelen); + + addr = BIO_ADDR_new(); + if (!TEST_ptr(addr)) + return NULL; + + if (!TEST_true(BIO_ADDR_rawmake(addr, family, where, wherelen, 1000))) { + BIO_ADDR_free(addr); + return NULL; + } + + return addr; +} + +static int bio_addr_is_eq(const BIO_ADDR *a, const BIO_ADDR *b) +{ + struct sockaddr_storage adata, bdata; + size_t alen, blen; + + /* True even if a and b are NULL */ + if (a == b) + return 1; + + /* If one is NULL the other cannot be due to the test above */ + if (a == NULL || b == NULL) + return 0; + + if (BIO_ADDR_family(a) != BIO_ADDR_family(b)) + return 0; + + /* Works even with AF_UNIX/AF_UNSPEC which just returns 0 */ + if (BIO_ADDR_rawport(a) != BIO_ADDR_rawport(b)) + return 0; + + if (!BIO_ADDR_rawaddress(a, NULL, &alen) + || alen > sizeof(adata) + || !BIO_ADDR_rawaddress(a, &adata, &alen)) + return 0; + + if (!BIO_ADDR_rawaddress(a, NULL, &blen) + || blen > sizeof(bdata) + || !BIO_ADDR_rawaddress(a, &bdata, &blen)) + return 0; + + if (alen != blen) + return 0; + + if (alen == 0) + return 1; + + return memcmp(&adata, &bdata, alen) == 0; +} + +static int test_bio_addr_copy_dup(int idx) +{ + BIO_ADDR *src = NULL, *dst = NULL; + int ret = 0; + int docopy = idx & 1; + + idx >>= 1; + + src = make_dummy_addr(families[idx]); + if (!TEST_ptr(src)) + return 0; + + if (docopy) { + dst = BIO_ADDR_new(); + if (!TEST_ptr(dst)) + goto err; + + if (!TEST_true(BIO_ADDR_copy(dst, src))) + goto err; + } else { + dst = BIO_ADDR_dup(src); + if (!TEST_ptr(dst)) + goto err; + } + + if (!TEST_true(bio_addr_is_eq(src, dst))) + goto err; + + ret = 1; + err: + BIO_ADDR_free(src); + BIO_ADDR_free(dst); + return ret; +} + +int setup_tests(void) +{ + if (!test_skip_common_options()) { + TEST_error("Error parsing test options\n"); + return 0; + } + + ADD_ALL_TESTS(test_bio_addr_copy_dup, OSSL_NELEM(families) * 2); + return 1; +} diff --git a/test/build.info b/test/build.info index 4c81a2b77984c708217a39f3de11ff809a041f6d..73f8de1f7a125b96eba58b2a4ca3382bc987d7af 100644 --- a/test/build.info +++ b/test/build.info @@ -522,6 +522,12 @@ IF[{- !$disabled{tests} -}] INCLUDE[http_test]=../include ../apps/include DEPEND[http_test]=../libcrypto libtestutil.a ENDIF + + PROGRAMS{noinst}=bio_addr_test + + SOURCE[bio_addr_test]=bio_addr_test.c + INCLUDE[bio_addr_test]=../include ../apps/include + DEPEND[bio_addr_test]=../libcrypto libtestutil.a ENDIF SOURCE[dtlstest]=dtlstest.c helpers/ssltestlib.c diff --git a/test/certs/ext-groupAC.pem b/test/certs/ext-groupAC.pem new file mode 100644 index 0000000000000000000000000000000000000000..f5325eb2ae6ebbd32877aeb0199f078e67417ba3 --- /dev/null +++ b/test/certs/ext-groupAC.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBhjCCAXKgAwIBAgIDAQIDMAsGCSqGSIb3DQEBBTAAMCIYDzIwMjEwODMwMDA1 +MzE3WhgPMjAyMTA4MzAwMDUzMTdaMAAwggEgMAsGCSqGSIb3DQEBAQOCAQ8AMIIB +CgKCAQEAtnjLm1ts1hC4fNNt3UnQD9y73bDXgioTyWYSI3ca/KNfuTydjFTEYAmq +nuGrBOUfgbmH3PRQ0AmpqljgWTb3d3K8H4UFvDWQTPSS21IMjm8oqd19nE5GxWir +Gu0oDRzhWLHe1RZ7ZrohCPg/1Ocsy47QZuK2laFB0rEmrRWBmEYbDl3/wxf5XfqI +qpOynJB02thXrTCcTM7Rz1FqCFt/ZVZB5hKY2S+CTdE9OIVKlr4WHMfuvUYeOj06 +GkwLFJHNv2tU+tovI3mYRxUuY4UupkS3MC+Otey7XKm1P+INjWWoegm6iCAt3Vus +pVz+6pU2xgl3nrAVMQHB4fReQPH0pQIDAQABow0wCzAJBgNVHUIEAgUAMAsGCSqG +SIb3DQEBBQMBAA== +-----END CERTIFICATE----- diff --git a/test/certs/ext-indirectIssuer.pem b/test/certs/ext-indirectIssuer.pem new file mode 100644 index 0000000000000000000000000000000000000000..afc21806aef02d9112aa9919be4f25cd8a93733c --- /dev/null +++ b/test/certs/ext-indirectIssuer.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBhjCCAXKgAwIBAgIDAQIDMAsGCSqGSIb3DQEBBTAAMCIYDzIwMjEwODMxMDIy +NzM4WhgPMjAyMTA4MzEwMjI3MzhaMAAwggEgMAsGCSqGSIb3DQEBAQOCAQ8AMIIB +CgKCAQEAtnjLm1ts1hC4fNNt3UnQD9y73bDXgioTyWYSI3ca/KNfuTydjFTEYAmq +nuGrBOUfgbmH3PRQ0AmpqljgWTb3d3K8H4UFvDWQTPSS21IMjm8oqd19nE5GxWir +Gu0oDRzhWLHe1RZ7ZrohCPg/1Ocsy47QZuK2laFB0rEmrRWBmEYbDl3/wxf5XfqI +qpOynJB02thXrTCcTM7Rz1FqCFt/ZVZB5hKY2S+CTdE9OIVKlr4WHMfuvUYeOj06 +GkwLFJHNv2tU+tovI3mYRxUuY4UupkS3MC+Otey7XKm1P+INjWWoegm6iCAt3Vus +pVz+6pU2xgl3nrAVMQHB4fReQPH0pQIDAQABow0wCzAJBgNVHT0EAgUAMAsGCSqG +SIb3DQEBBQMBAA== +-----END CERTIFICATE----- diff --git a/test/certs/ext-noAssertion.pem b/test/certs/ext-noAssertion.pem new file mode 100644 index 0000000000000000000000000000000000000000..1aaa860bdda5892ddfdb357191c55f8c2bd3b25c --- /dev/null +++ b/test/certs/ext-noAssertion.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBhjCCAXKgAwIBAgIDAQIDMAsGCSqGSIb3DQEBBTAAMCIYDzIwMjEwODMwMDA1 +NDMyWhgPMjAyMTA4MzAwMDU0MzJaMAAwggEgMAsGCSqGSIb3DQEBAQOCAQ8AMIIB +CgKCAQEAtnjLm1ts1hC4fNNt3UnQD9y73bDXgioTyWYSI3ca/KNfuTydjFTEYAmq +nuGrBOUfgbmH3PRQ0AmpqljgWTb3d3K8H4UFvDWQTPSS21IMjm8oqd19nE5GxWir +Gu0oDRzhWLHe1RZ7ZrohCPg/1Ocsy47QZuK2laFB0rEmrRWBmEYbDl3/wxf5XfqI +qpOynJB02thXrTCcTM7Rz1FqCFt/ZVZB5hKY2S+CTdE9OIVKlr4WHMfuvUYeOj06 +GkwLFJHNv2tU+tovI3mYRxUuY4UupkS3MC+Otey7XKm1P+INjWWoegm6iCAt3Vus +pVz+6pU2xgl3nrAVMQHB4fReQPH0pQIDAQABow0wCzAJBgNVHT4EAgUAMAsGCSqG +SIb3DQEBBQMBAA== +-----END CERTIFICATE----- diff --git a/test/certs/ext-noRevAvail.pem b/test/certs/ext-noRevAvail.pem new file mode 100644 index 0000000000000000000000000000000000000000..23bf49b9852a804873b513b306be27dad6b43c20 --- /dev/null +++ b/test/certs/ext-noRevAvail.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBiTCCAXWgAwIBAgIDAQIDMAsGCSqGSIb3DQEBBTAAMCIYDzIwMjEwOTE1MDAw +OTM1WhgPMjAyMTA5MTUwMDA5MzVaMAAwggEgMAsGCSqGSIb3DQEBAQOCAQ8AMIIB +CgKCAQEAtnjLm1ts1hC4fNNt3UnQD9y73bDXgioTyWYSI3ca/KNfuTydjFTEYAmq +nuGrBOUfgbmH3PRQ0AmpqljgWTb3d3K8H4UFvDWQTPSS21IMjm8oqd19nE5GxWir +Gu0oDRzhWLHe1RZ7ZrohCPg/1Ocsy47QZuK2laFB0rEmrRWBmEYbDl3/wxf5XfqI +qpOynJB02thXrTCcTM7Rz1FqCFt/ZVZB5hKY2S+CTdE9OIVKlr4WHMfuvUYeOj06 +GkwLFJHNv2tU+tovI3mYRxUuY4UupkS3MC+Otey7XKm1P+INjWWoegm6iCAt3Vus +pVz+6pU2xgl3nrAVMQHB4fReQPH0pQIDAQABoxAwDjAMBgNVHTgBAf8EAgUAMAsG +CSqGSIb3DQEBBQMBAA== +-----END CERTIFICATE----- diff --git a/test/certs/ext-sOAIdentifier.pem b/test/certs/ext-sOAIdentifier.pem new file mode 100644 index 0000000000000000000000000000000000000000..7da3a3b4485416c301d6ef4e3fa5cd8c3c24de62 --- /dev/null +++ b/test/certs/ext-sOAIdentifier.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBhjCCAXKgAwIBAgIDAQIDMAsGCSqGSIb3DQEBBTAAMCIYDzIwMjEwODMwMDA1 +NDA4WhgPMjAyMTA4MzAwMDU0MDhaMAAwggEgMAsGCSqGSIb3DQEBAQOCAQ8AMIIB +CgKCAQEAtnjLm1ts1hC4fNNt3UnQD9y73bDXgioTyWYSI3ca/KNfuTydjFTEYAmq +nuGrBOUfgbmH3PRQ0AmpqljgWTb3d3K8H4UFvDWQTPSS21IMjm8oqd19nE5GxWir +Gu0oDRzhWLHe1RZ7ZrohCPg/1Ocsy47QZuK2laFB0rEmrRWBmEYbDl3/wxf5XfqI +qpOynJB02thXrTCcTM7Rz1FqCFt/ZVZB5hKY2S+CTdE9OIVKlr4WHMfuvUYeOj06 +GkwLFJHNv2tU+tovI3mYRxUuY4UupkS3MC+Otey7XKm1P+INjWWoegm6iCAt3Vus +pVz+6pU2xgl3nrAVMQHB4fReQPH0pQIDAQABow0wCzAJBgNVHTIEAgUAMAsGCSqG +SIb3DQEBBQMBAA== +-----END CERTIFICATE----- diff --git a/test/certs/ext-singleUse.pem b/test/certs/ext-singleUse.pem new file mode 100644 index 0000000000000000000000000000000000000000..e72701c3059483aaf1fd5583265306fb18882946 --- /dev/null +++ b/test/certs/ext-singleUse.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBrzCCAZmgAwIBAgIEDCI4TjANBgkqhkiG9w0BAQUFADARMQ8wDQYDVQQDDAZI +aSBtb20wIhgPMjAyMzA3MDExMzA4MDRaGA8yMDIzMDcwMTEzMDgwNFowETEPMA0G +A1UEAwwGSGkgbW9tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtnjL +m1ts1hC4fNNt3UnQD9y73bDXgioTyWYSI3ca/KNfuTydjFTEYAmqnuGrBOUfgbmH +3PRQ0AmpqljgWTb3d3K8H4UFvDWQTPSS21IMjm8oqd19nE5GxWirGu0oDRzhWLHe +1RZ7ZrohCPg/1Ocsy47QZuK2laFB0rEmrRWBmEYbDl3/wxf5XfqIqpOynJB02thX +rTCcTM7Rz1FqCFt/ZVZB5hKY2S+CTdE9OIVKlr4WHMfuvUYeOj06GkwLFJHNv2tU ++tovI3mYRxUuY4UupkS3MC+Otey7XKm1P+INjWWoegm6iCAt3VuspVz+6pU2xgl3 +nrAVMQHB4fReQPH0pQIDAQABow0wCzAJBgNVHUEEAgUAMA0GCSqGSIb3DQEBBQUA +AwEA +-----END CERTIFICATE----- diff --git a/test/evp_test.c b/test/evp_test.c index 309ab94c21b540ae63c85e5c642ffeffc92d09b8..bd1a7cc122f370e811000e36d538ff44ee8f9016 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -739,9 +739,7 @@ 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, 12) - && fips_provider_version_lt(libctx, 3, 1, 0)) - || fips_provider_version_ge(libctx, 3, 1, 4); + int fips_dupctx_supported = fips_provider_version_ge(libctx, 3, 2, 0); t->err = "TEST_FAILURE"; if (!TEST_ptr(ctx_base = EVP_CIPHER_CTX_new())) diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index f5a46efb6f01601acd25be95015290b6dda4c640..8d71d6002f6607e7e55ca9de15f4b4630c376423 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -10,6 +10,7 @@ #include #include #include +#include "internal/e_os.h" /* For struct timeval */ #include "quictestlib.h" #include "ssltestlib.h" #include "../testutil.h" @@ -1086,44 +1087,6 @@ 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) { /* @@ -1135,13 +1098,13 @@ int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src) dst->flags = src->flags; if (dst->local != NULL) { if (src->local != NULL) { - if (!TEST_true(bio_addr_copy(dst->local, src->local))) + 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))) + 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 844aec8a60be63ab302b7f4ef605076e2743bb3a..f090299b22798a1263913524d07cea8828859d63 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -242,9 +242,6 @@ 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); diff --git a/test/recipes/15-test_genec.t b/test/recipes/15-test_genec.t index 2dfed387ca061e7b139b2994ff4d26e23bb8afad..3e8c55071c4b1fb2ea04341369feff30d7e6d32f 100644 --- a/test/recipes/15-test_genec.t +++ b/test/recipes/15-test_genec.t @@ -232,13 +232,15 @@ foreach my $curvename (@curve_list) { foreach my $outform (@output_formats) { my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform; + my $outpubfile = "ecgen.${curvename}.${paramenc}-pub." . lc $outform; $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})", app([ 'openssl', 'genpkey', '-algorithm', 'EC', '-pkeyopt', 'ec_paramgen_curve:'.$curvename, '-pkeyopt', 'ec_param_enc:'.$paramenc, '-outform', $outform, - '-out', $outfile])); + '-out', $outfile, + '-outpubkey', $outpubfile])); } } } diff --git a/test/recipes/25-test_x509.t b/test/recipes/25-test_x509.t index 408ac40c7c3e5b3a9132809767481c4181094014..9bf011c1885cd4b118913c4daa0bc7013f4741bf 100644 --- a/test/recipes/25-test_x509.t +++ b/test/recipes/25-test_x509.t @@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; setup("test_x509"); -plan tests => 37; +plan tests => 43; # Prevent MSys2 filename munging for arguments that look like file paths but # aren't @@ -110,6 +110,30 @@ cert_contains(srctop_file(@certs, "fake-gp.pem"), "2.16.528.1.1003.1.3.5.5.2-1-0000006666-Z-12345678-01.015-12345678", 1, 'x500 -- subjectAltName'); +cert_contains(srctop_file(@certs, "ext-noAssertion.pem"), + "No Assertion", + 1, 'X.509 Not Assertion Extension'); + +cert_contains(srctop_file(@certs, "ext-groupAC.pem"), + "Group Attribute Certificate", + 1, 'X.509 Group Attribute Certificate Extension'); + +cert_contains(srctop_file(@certs, "ext-sOAIdentifier.pem"), + "Source of Authority", + 1, 'X.509 Source of Authority Extension'); + +cert_contains(srctop_file(@certs, "ext-noRevAvail.pem"), + "No Revocation Available", + 1, 'X.509 No Revocation Available'); + +cert_contains(srctop_file(@certs, "ext-singleUse.pem"), + "Single Use", + 1, 'X509v3 Single Use'); + +cert_contains(srctop_file(@certs, "ext-indirectIssuer.pem"), + "Indirect Issuer", + 1, 'X.509 Indirect Issuer'); + sub test_errors { # actually tests diagnostics of OSSL_STORE my ($expected, $cert, @opts) = @_; my $infile = srctop_file(@certs, $cert); diff --git a/test/recipes/61-test_bio_addr.t b/test/recipes/61-test_bio_addr.t new file mode 100644 index 0000000000000000000000000000000000000000..bd4c23a71f5ac9a390e6ac822fc3dddd894fbaa4 --- /dev/null +++ b/test/recipes/61-test_bio_addr.t @@ -0,0 +1,20 @@ +#! /usr/bin/env perl +# 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 + + +use OpenSSL::Test; +use OpenSSL::Test::Utils; + +setup("test_bio_addr"); + +plan skip_all => "No sockets in this configuration" + if disabled("sock"); + +plan tests => 1; + +ok(run(test(["bio_addr_test"])), "running bio_addr_test"); diff --git a/util/libcrypto.num b/util/libcrypto.num index e4265b4cef0b66c4f76ac98f279d7f53d46741cf..6af1fe1707b9a349745f8a1fc5789b80ef93347b 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5535,3 +5535,4 @@ 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: +BIO_ADDR_copy ? 3_2_0 EXIST::FUNCTION:SOCK diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm index a5126858e791af9669ac313a6d1470b2bb6f557c..c37ed7815f350ee6144f96b67859407dd8a9f1f6 100644 --- a/util/perl/OpenSSL/paramnames.pm +++ b/util/perl/OpenSSL/paramnames.pm @@ -198,6 +198,7 @@ my %params = ( 'RAND_PARAM_MAX_REQUEST' => "max_request", 'RAND_PARAM_TEST_ENTROPY' => "test_entropy", 'RAND_PARAM_TEST_NONCE' => "test_nonce", + 'RAND_PARAM_GENERATE' => "generate", # RAND/DRBG names 'DRBG_PARAM_RESEED_REQUESTS' => "reseed_requests",