/* * Copyright 2016-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 *//* * The test_multi_downgrade_shared_pkey function tests the thread safety of a * deprecated function. */#ifndef OPENSSL_NO_DEPRECATED_3_0# define OPENSSL_SUPPRESS_DEPRECATED#endif#if defined(_WIN32)#include<windows.h>#endif#include<string.h>#include<openssl/crypto.h>#include<openssl/rsa.h>#include<openssl/aes.h>#include<openssl/err.h>#include<openssl/rand.h>#include<openssl/pem.h>#include<openssl/evp.h>#include"internal/tsan_assist.h"#include"internal/nelem.h"#include"internal/time.h"#include"internal/rcu.h"#include"testutil.h"#include"threadstest.h"#ifdef __SANITIZE_THREAD__#include<sanitizer/tsan_interface.h>#define TSAN_ACQUIRE(s) __tsan_acquire(s)#else#define TSAN_ACQUIRE(s)#endif/* Limit the maximum number of threads */#define MAXIMUM_THREADS 10/* Limit the maximum number of providers loaded into a library context */#define MAXIMUM_PROVIDERS 4staticintdo_fips=0;staticchar*privkey;staticchar*config_file=NULL;staticintmultidefault_run=0;staticconstchar*default_provider[]={"default",NULL};staticconstchar*fips_provider[]={"fips",NULL};staticconstchar*fips_and_default_providers[]={"default","fips",NULL};staticCRYPTO_RWLOCK*global_lock;#ifdef TSAN_REQUIRES_LOCKINGstaticCRYPTO_RWLOCK*tsan_lock;#endif/* Grab a globally unique integer value, return 0 on failure */staticintget_new_uid(void){/* * Start with a nice large number to avoid potential conflicts when * we generate a new OID. */staticTSAN_QUALIFIERintcurrent_uid=1<<(sizeof(int)*8-2);#ifdef TSAN_REQUIRES_LOCKINGintr;if(!TEST_true(CRYPTO_THREAD_write_lock(tsan_lock)))return0;r=++current_uid;if(!TEST_true(CRYPTO_THREAD_unlock(tsan_lock)))return0;returnr;#elsereturntsan_counter(¤t_uid);#endif}staticinttest_lock(void){CRYPTO_RWLOCK*lock=CRYPTO_THREAD_lock_new();intres;res=TEST_true(CRYPTO_THREAD_read_lock(lock))&&TEST_true(CRYPTO_THREAD_unlock(lock))&&TEST_true(CRYPTO_THREAD_write_lock(lock))&&TEST_true(CRYPTO_THREAD_unlock(lock));CRYPTO_THREAD_lock_free(lock);returnres;}#if defined(OPENSSL_THREADS)staticintcontention=0;staticintrwwriter1_done=0;