commit fccfbc21442e6203dabbb028d961ceae4dd441aa Author: Sergey Zhemoytel Date: Fri Oct 25 16:59:17 2024 +0300 Imported from SRPM diff --git a/.abf.yml b/.abf.yml new file mode 100644 index 0000000..e1bdb1c --- /dev/null +++ b/.abf.yml @@ -0,0 +1,2 @@ +sources: + openssl-3.4.0.tar.gz: 5c2f33c3f3601676f225109231142cdc30d44127 diff --git a/fixsimlink.sh b/fixsimlink.sh new file mode 100644 index 0000000..44b58df --- /dev/null +++ b/fixsimlink.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +LINK="$@" + +FILE=$(ls -l $LINK | awk '{ print $11}') + +[[ ! "$FILE" =~ ".xz" ]] && ln -sf $FILE.xz $LINK + + + + + diff --git a/openssl-alt-e2k-makecontext.patch b/openssl-alt-e2k-makecontext.patch new file mode 100644 index 0000000..d1361c4 --- /dev/null +++ b/openssl-alt-e2k-makecontext.patch @@ -0,0 +1,30 @@ +diff --git a/openssl/crypto/async/arch/async_posix.c b/openssl/crypto/async/arch/async_posix.c +index 02c342d..a11f451 100644 +--- a/crypto/async/arch/async_posix.c ++++ b/crypto/async/arch/async_posix.c +@@ -40,8 +40,15 @@ int async_fibre_makecontext(async_fibre *fibre) + if (fibre->fibre.uc_stack.ss_sp != NULL) { + fibre->fibre.uc_stack.ss_size = STACKSIZE; + fibre->fibre.uc_link = NULL; ++#ifndef __e2k__ + makecontext(&fibre->fibre, async_start_func, 0); + return 1; ++#else ++ if (makecontext_e2k(&fibre->fibre, async_start_func, 0)) ++ return 1; ++ else ++ return 0; ++#endif + } + } else { + fibre->fibre.uc_stack.ss_sp = NULL; +@@ -53,6 +60,9 @@ void async_fibre_free(async_fibre *fibre) + { + OPENSSL_free(fibre->fibre.uc_stack.ss_sp); + fibre->fibre.uc_stack.ss_sp = NULL; ++#ifdef __e2k__ ++ freecontext_e2k(&fibre->fibre); ++#endif + } + + #endif diff --git a/openssl-thread-test.c b/openssl-thread-test.c new file mode 100644 index 0000000..3b90285 --- /dev/null +++ b/openssl-thread-test.c @@ -0,0 +1,400 @@ +/* Test program to verify that RSA signing is thread-safe in OpenSSL. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Just assume we want to do engine stuff if we're using 0.9.6b or + * higher. This assumption is only valid for versions bundled with RHL. */ +#if OPENSSL_VERSION_NUMBER >= 0x0090602fL +#include +#define USE_ENGINE +#endif + +#define MAX_THREAD_COUNT 10000 +#define ITERATION_COUNT 10 +#define MAIN_COUNT 100 + +/* OpenSSL requires us to provide thread ID and locking primitives. */ +pthread_mutex_t *mutex_locks = NULL; +static unsigned long +thread_id_cb(void) +{ + return (unsigned long) pthread_self(); +} +static void +lock_cb(int mode, int n, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&mutex_locks[n]); + } else { + pthread_mutex_unlock(&mutex_locks[n]); + } +} + +struct thread_args { + RSA *rsa; + int digest_type; + unsigned char *digest; + unsigned int digest_len; + unsigned char *signature; + unsigned int signature_len; + pthread_t main_thread; +}; + +static int print = 0; + +pthread_mutex_t sign_lock = PTHREAD_MUTEX_INITIALIZER; +static int locked_sign = 0; +static void SIGN_LOCK() {if (locked_sign) pthread_mutex_lock(&sign_lock);} +static void SIGN_UNLOCK() {if (locked_sign) pthread_mutex_unlock(&sign_lock);} + +pthread_mutex_t verify_lock = PTHREAD_MUTEX_INITIALIZER; +static int locked_verify = 0; +static void VERIFY_LOCK() {if (locked_verify) pthread_mutex_lock(&verify_lock);} +static void VERIFY_UNLOCK() {if (locked_verify) pthread_mutex_unlock(&verify_lock);} + +pthread_mutex_t failure_count_lock = PTHREAD_MUTEX_INITIALIZER; +long failure_count = 0; +static void +failure() +{ + pthread_mutex_lock(&failure_count_lock); + failure_count++; + pthread_mutex_unlock(&failure_count_lock); +} + +static void * +thread_main(void *argp) +{ + struct thread_args *args = argp; + unsigned char *signature; + unsigned int signature_len, signature_alloc_len; + int ret, i; + + signature_alloc_len = args->signature_len; + if (RSA_size(args->rsa) > signature_alloc_len) { + signature_alloc_len = RSA_size(args->rsa); + } + signature = malloc(signature_alloc_len); + if (signature == NULL) { + fprintf(stderr, "Skipping checks in thread %lu -- %s.\n", + (unsigned long) pthread_self(), strerror(errno)); + pthread_exit(0); + return NULL; + } + for (i = 0; i < ITERATION_COUNT; i++) { + signature_len = signature_alloc_len; + SIGN_LOCK(); + ret = RSA_check_key(args->rsa); + ERR_print_errors_fp(stdout); + if (ret != 1) { + failure(); + break; + } + ret = RSA_sign(args->digest_type, + args->digest, + args->digest_len, + signature, &signature_len, + args->rsa); + SIGN_UNLOCK(); + ERR_print_errors_fp(stdout); + if (ret != 1) { + failure(); + break; + } + + VERIFY_LOCK(); + ret = RSA_verify(args->digest_type, + args->digest, + args->digest_len, + signature, signature_len, + args->rsa); + VERIFY_UNLOCK(); + if (ret != 1) { + fprintf(stderr, + "Signature from thread %lu(%d) fails " + "verification (passed in thread #%lu)!\n", + (long) pthread_self(), i, + (long) args->main_thread); + ERR_print_errors_fp(stdout); + failure(); + continue; + } + if (print) { + fprintf(stderr, ">%d\n", i); + } + } + free(signature); + + pthread_exit(0); + + return NULL; +} + +unsigned char * +xmemdup(unsigned char *s, size_t len) +{ + unsigned char *r; + r = malloc(len); + if (r == NULL) { + fprintf(stderr, "Out of memory.\n"); + ERR_print_errors_fp(stdout); + assert(r != NULL); + } + memcpy(r, s, len); + return r; +} + +int +main(int argc, char **argv) +{ + RSA *rsa; + MD5_CTX md5; + int fd, i; + pthread_t threads[MAX_THREAD_COUNT]; + int thread_count = 1000; + unsigned char *message, *digest; + unsigned int message_len, digest_len; + unsigned char *correct_signature; + unsigned int correct_siglen, ret; + struct thread_args master_args, *args; + int sync = 0, seed = 0; + int again = 1; +#ifdef USE_ENGINE + char *engine = NULL; + ENGINE *e = NULL; +#endif + + pthread_mutex_init(&failure_count_lock, NULL); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--seed") == 0) { + printf("Seeding PRNG.\n"); + seed++; + } else + if (strcmp(argv[i], "--sync") == 0) { + printf("Running synchronized.\n"); + sync++; + } else + if ((strcmp(argv[i], "--threads") == 0) && (i < argc - 1)) { + i++; + thread_count = atol(argv[i]); + if (thread_count > MAX_THREAD_COUNT) { + thread_count = MAX_THREAD_COUNT; + } + printf("Starting %d threads.\n", thread_count); + sync++; + } else + if (strcmp(argv[i], "--sign") == 0) { + printf("Locking signing.\n"); + locked_sign++; + } else + if (strcmp(argv[i], "--verify") == 0) { + printf("Locking verifies.\n"); + locked_verify++; + } else + if (strcmp(argv[i], "--print") == 0) { + printf("Tracing.\n"); + print++; +#ifdef USE_ENGINE + } else + if ((strcmp(argv[i], "--engine") == 0) && (i < argc - 1)) { + printf("Using engine \"%s\".\n", argv[i + 1]); + engine = argv[i + 1]; + i++; +#endif + } else { + printf("Bad argument: %s\n", argv[i]); + return 1; + } + } + + /* Get some random data to sign. */ + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) { + fprintf(stderr, "Error opening /dev/urandom: %s\n", + strerror(errno)); + } + + if (print) { + fprintf(stderr, "Reading random data.\n"); + } + message = malloc(message_len = 9371); + read(fd, message, message_len); + close(fd); + + /* Initialize the SSL library and set up thread-safe locking. */ + ERR_load_crypto_strings(); + SSL_library_init(); + mutex_locks = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks()); + for (i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_init(&mutex_locks[i], NULL); + } + CRYPTO_set_id_callback(thread_id_cb); + CRYPTO_set_locking_callback(lock_cb); + ERR_print_errors_fp(stdout); + + /* Seed the PRNG if we were asked to do so. */ + if (seed) { + if (print) { + fprintf(stderr, "Seeding PRNG.\n"); + } + RAND_add(message, message_len, message_len); + ERR_print_errors_fp(stdout); + } + + /* Turn on a hardware crypto device if asked to do so. */ +#ifdef USE_ENGINE + if (engine) { +#if OPENSSL_VERSION_NUMBER >= 0x0090700fL + ENGINE_load_builtin_engines(); +#endif + if (print) { + fprintf(stderr, "Initializing \"%s\" engine.\n", + engine); + } + e = ENGINE_by_id(engine); + ERR_print_errors_fp(stdout); + if (e) { + i = ENGINE_init(e); + ERR_print_errors_fp(stdout); + i = ENGINE_set_default_RSA(e); + ERR_print_errors_fp(stdout); + } + } +#endif + + /* Compute the digest for the signature. */ + if (print) { + fprintf(stderr, "Computing digest.\n"); + } + digest = malloc(digest_len = MD5_DIGEST_LENGTH); + MD5_Init(&md5); + MD5_Update(&md5, message, message_len); + MD5_Final(digest, &md5); + + /* Generate a signing key. */ + if (print) { + fprintf(stderr, "Generating key.\n"); + } + rsa = RSA_generate_key(4096, 3, NULL, NULL); + ERR_print_errors_fp(stdout); + if (rsa == NULL) { + _exit(1); + } + + /* Sign the data. */ + correct_siglen = RSA_size(rsa); + correct_signature = malloc(correct_siglen); + for (i = 0; i < MAIN_COUNT; i++) { + if (print) { + fprintf(stderr, "Signing data (%d).\n", i); + } + ret = RSA_check_key(rsa); + ERR_print_errors_fp(stdout); + if (ret != 1) { + failure(); + } + correct_siglen = RSA_size(rsa); + ret = RSA_sign(NID_md5, digest, digest_len, + correct_signature, &correct_siglen, + rsa); + ERR_print_errors_fp(stdout); + if (ret != 1) { + _exit(2); + } + if (print) { + fprintf(stderr, "Verifying data (%d).\n", i); + } + ret = RSA_verify(NID_md5, digest, digest_len, + correct_signature, correct_siglen, + rsa); + if (ret != 1) { + _exit(2); + } + } + + /* Collect up the inforamtion which other threads will need for + * comparing their signature results with ours. */ + master_args.rsa = rsa; + master_args.digest_type = NID_md5; + master_args.digest = digest; + master_args.digest_len = digest_len; + master_args.signature = correct_signature; + master_args.signature_len = correct_siglen; + master_args.main_thread = pthread_self(); + + fprintf(stdout, "Performing %d signatures in each of %d threads " + "(%d, %d).\n", ITERATION_COUNT, thread_count, + digest_len, correct_siglen); + fflush(NULL); + + /* Start up all of the threads. */ + for (i = 0; i < thread_count; i++) { + args = malloc(sizeof(struct thread_args)); + args->rsa = RSAPrivateKey_dup(master_args.rsa); + args->digest_type = master_args.digest_type; + args->digest_len = master_args.digest_len; + args->digest = xmemdup(master_args.digest, args->digest_len); + args->signature_len = master_args.signature_len; + args->signature = xmemdup(master_args.signature, + args->signature_len); + args->main_thread = pthread_self(); + ret = pthread_create(&threads[i], NULL, thread_main, args); + while ((ret != 0) && (errno == EAGAIN)) { + ret = pthread_create(&threads[i], NULL, + thread_main, &args); + fprintf(stderr, "Thread limit hit at %d.\n", i); + } + if (ret != 0) { + fprintf(stderr, "Unable to create thread %d: %s.\n", + i, strerror(errno)); + threads[i] = -1; + } else { + if (sync) { + ret = pthread_join(threads[i], NULL); + assert(ret == 0); + } + if (print) { + fprintf(stderr, "%d\n", i); + } + } + } + + /* Wait for all threads to complete. So long as we can find an + * unjoined thread, keep joining threads. */ + do { + again = 0; + for (i = 0; i < thread_count; i++) { + /* If we have an unterminated thread, join it. */ + if (threads[i] != -1) { + again = 1; + if (print) { + fprintf(stderr, "Joining thread %d.\n", + i); + } + pthread_join(threads[i], NULL); + threads[i] = -1; + break; + } + } + } while (again == 1); + + fprintf(stderr, "%ld failures\n", failure_count); + + return (failure_count != 0); +} diff --git a/openssl3.4.rpmlintrc b/openssl3.4.rpmlintrc new file mode 100644 index 0000000..359b994 --- /dev/null +++ b/openssl3.4.rpmlintrc @@ -0,0 +1,6 @@ +# HTML docs must not be compressed to be usable +addFilter("W: manpage-not-compressed.*.html") +# for rpm5 platforms +addFilter("E: description-line-too-long") +addFilter("E: dir-or-file-in-opt") +addFilter("E: compressed-symlink-with-wrong-ext") \ No newline at end of file diff --git a/openssl3.4.spec b/openssl3.4.spec new file mode 100644 index 0000000..d52e7a2 --- /dev/null +++ b/openssl3.4.spec @@ -0,0 +1,293 @@ +%define oname openssl +%define major 3 +%define minor 4 +%define ssl_ver %{major}.%{minor} +%define engines_name %mklibname openssl-engines %{major} +%define libcrypto %mklibname crypto %{major} +%define libssl %mklibname ssl %{major} + +%define openssl_engines_dir %{_libdir}/engines-%{major} + +%define _optdir /opt + + +%define _docs %{expand: +%doc CONTRIBUTING.md \ +%doc CHANGES.md \ +%doc LICENSE* \ +%doc README* +} + +Summary: OpenSSL %{ssl_ver} for platforms with OpenSSL 1.0 as the main version of OpenSSL +Name: %{oname}%{ssl_ver} +Version: 3.4.0 +Release: 1 +License: OpenSSL +Group: System/Libraries +URL: https://www.openssl.org +#Source0: https://ftp.openssl.org/source/%{oname}-%{version}.tar.gz +Source0: https://github.com/openssl/openssl/releases/download/%{oname}-%{version}/%{oname}-%{version}.tar.gz +Source1: fixsimlink.sh +Source1000: %{name}.rpmlintrc +Source4: openssl-thread-test.c +Patch1: openssl-alt-e2k-makecontext.patch +BuildRequires: bc +BuildRequires: sctp-devel +# Take %%_openssldir from here +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(zlib) +BuildRequires: pkgconfig(libzstd) +# for %%check, ./test/run_tests.pl +BuildRequires: perl-devel +BuildRequires: perl-Module-Load-Conditional +BuildRequires: perl(File::Spec::Functions) +BuildRequires: perl(File::Basename) +BuildRequires: perl(FindBin) +BuildRequires: perl(Test::Harness) +BuildRequires: perl(Test::More) +%if %{mdvver} <= 201610 +BuildRequires: perl +%else +BuildRequires: /usr/bin/pod2html +BuildRequires: /usr/bin/pod2man +%endif +#Requires: %{engines_name} = %{EVRD} +Requires: perl-base +Requires: rootcerts +# using /etc/pki/tls from the main openssl package (openssl 1.0) +#Requires: openssl +Provides: openssl%{major} = %{EVRD} + +%description +The openssl certificate management tool and the shared libraries that provide +various encryption and decription algorithms and protocols, including DES, RC4, +RSA and SSL. +This is OpenSSL %{major} for platforms with OpenSSL 1.0 as the main version of OpenSSL. + +%files +%_docs +#attr(0755,root,root) %{_bindir}/%{name} +#{_mandir}/man[157]/%{name}_* +#{_mandir}/man1/%{name}.1* +#{_defaultdocdir}/openssl/html/man[157] +%{_bindir}/%{name} +%{_optdir}/%{name}/bin +%{_optdir}/%{name}/%{_lib}/*.so.* +%{_optdir}/%{name}/%{_lib}/engines-%{major}/* +%{_optdir}/%{name}/ssl/* +%{_optdir}/%{name}/%{_lib}/ossl-modules/legacy.so +%{_optdir}/%{name}/lib +#{_libdir}/*.so.* + +#---------------------------------------------------------------------------- + +%package devel +Summary: Development files for openssl%{ssl_ver} +Requires: %{name} = %{EVRD} + +%description devel +Development files for openssl%{ssl_ver} + +%files devel +%_docs +%{_optdir}/%{name}/include +%{_optdir}/%{name}/%{_lib}/*.so +%{_optdir}/%{name}/%{_lib}/pkgconfig/*.pc +%{_optdir}/%{name}/%{_lib}/cmake/OpenSSL/*.cmake + +#---------------------------------------------------------------------------- + +%package docs +Summary: Documentation for openssl%{major} + +%description docs +Documentation for openssl%{ssl_ver} + +%files docs +%{_optdir}/%{name}/share/doc/* +%{_optdir}/%{name}/share/man/* + +#---------------------------------------------------------------------------- + +#%package -n %{engines_name} +#Summary: Engines for %{name} +#Group: System/Libraries +#Provides: %{name}-engines = %{EVRD} + +#description -n %{engines_name} +#This package provides engines for openssl. + +#files -n %{engines_name} +#_docs +#attr(0755,root,root) %dir %{openssl_engines_dir}/ +#attr(0755,root,root) %{openssl_engines_dir}/*.so + +#---------------------------------------------------------------------------- + +#package -n %{libcrypto} +#Summary: Secure Sockets Layer communications libs +#Group: System/Libraries +#Requires: %{libssl} = %{EVRD} + +#description -n %{libcrypto} +#The libraries files are needed for various cryptographic algorithms +#and protocols, including DES, RC4, RSA and SSL. + +#files -n %{libcrypto} +#_docs +#{_libdir}/libcrypto.so.%{major}* + +#---------------------------------------------------------------------------- + +#package -n %{libssl} +#Summary: Secure Sockets Layer communications libs +#Group: System/Libraries + +#description -n %{libssl} +#The libraries files are needed for various cryptographic algorithms +#and protocols, including DES, RC4, RSA and SSL. + +#files -n %{libssl} +#_docs +#{_libdir}/libssl.so.%{major}* + +#---------------------------------------------------------------------------- + +%prep +%setup -qn %{oname}-%{version} + +cp %{SOURCE4} openssl-thread-test.c + +chmod +x %{SOURCE1} + +%build + +# In rosa2016.1: /usr/bin/ld: crypto/bio/bio_cb.o: relocation R_X86_64_PC32 against undefined symbol +# `stderr@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC +%if %{mdvver} <= 201610 +%setup_compile_flags +# (From openssl rosa2016.1) +# Add -Wa,--noexecstack here so that libcrypto's assembler modules will be +# marked as not requiring an executable stack. +export CFLAGS="$CFLAGS -Wa,--noexecstack" +%else +%serverbuild +%endif + +# Figure out which flags we want to use. +# default +sslarch=%{_os}-%{_arch} +%ifarch %{ix86} +sslarch=linux-elf +if ! echo %{_target} | grep -q i[56]86 ; then + sslflags="no-asm" +fi +%endif +%ifarch %{arm} +sslarch=linux-generic32 +%endif +# from ALT +%ifarch riscv64 %{e2k} +sslarch=linux-generic64 +%endif + + +# ia64, x86_64, ppc, ppc64 are OK by default +# Configure the build tree. Override OpenSSL defaults with known-good defaults +# usable on all platforms. The Configure script already knows to use -fPIC and +# RPM_OPT_FLAGS, so we can skip specifiying them here. +./Configure \ + --prefix=%{_optdir}/%{name} \ + ${sslflags} \ + enable-camellia \ + enable-cms \ + enable-md2 \ + enable-rc5 \ + enable-rfc3779 \ + enable-sctp \ + enable-seed \ + enable-ssl3 \ + enable-ssl3-method \ + no-ec2m \ + no-mdc2 \ + no-srp \ + zlib-dynamic \ + enable-gost \ + sctp \ + enable-quic \ + enable-zstd \ + enable-zstd-dynamic \ + shared \ + ${sslarch} + +# --libdir=%{_libdir} \ +# --openssldir=%{_openssldir} \ + + +%make all + +%check +# Verify that what was compiled actually works. +export LD_LIBRARY_PATH=%{buildroot}%{_optdir}/%{name}/%{_lib} +# from OMV and ALT +OPENSSL_ENABLE_MD5_VERIFY= +export OPENSSL_ENABLE_MD5_VERIFY +OPENSSL_SYSTEM_CIPHERS_OVERRIDE=xyz_nonexistent_file +export OPENSSL_SYSTEM_CIPHERS_OVERRIDE +# (mikhailnov) TODO: they fail, fix them?! +rm -f test/recipes/10-test_bn.t +rm -f test/recipes/80-test_ssl_new.t +#make test + +#%__cc -o openssl-thread-test \ +# -I./include \ +# %{optflags} \ +# openssl-thread-test.c \ +# -L. -lssl -lcrypto \ +# -lpthread -lz -ldl + +#./openssl-thread-test --threads 4 + +%install + +%makeinstall_std +install -d %{buildroot}%{_bindir} +ln -sf %{_optdir}/%{name}/bin/%{oname} %{buildroot}%{_bindir}/%{name} + +# rename pkg-config +pushd %{buildroot}%{_optdir}/%{name}/%{_lib}/pkgconfig +mv libcrypto.pc libcrypto%{ssl_ver}.pc +mv libssl.pc libssl%{ssl_ver}.pc +mv openssl.pc openssl%{ssl_ver}.pc +popd + +%ifarch x86_64 amd64 +# fix lib +install -d %{buildroot}%{_libdir} +pushd %{buildroot}%{_optdir}/%{name}/ +ln -s lib64 lib +popd +#pushd %{buildroot}%{_libdir} +#ln -sf %{_optdir}/%{name}/%{_lib}/libcrypto.so.3 %{buildroot}%{_libdir}/libcrypto.so.3 +#ln -sf %{_optdir}/%{name}/%{_lib}/libssl.so.3 %{buildroot}%{_libdir}/libssl.so.3 +#popd + +# remove error ELF +pushd %{buildroot}/%{_optdir}/%{name}/share/man/man3 +#rm -f OSSL_SELF_TEST_oncorrupt_byte.3ossl.xz \ +# OSSL_SELF_TEST_onbegin.3ossl.xz \ +# OSSL_SELF_TEST_get_callback.3ossl.xz \ +# OSSL_SELF_TEST_free.3ossl.xz \ +# OSSL_SELF_TEST_onend.3ossl.xz +rm -f OSSL_SELF_TEST* +popd + +%endif +# clean .a +rm -f %{buildroot}%{_optdir}/%{name}/%{_lib}/*.a + +# mans compress +find %{buildroot}%{_optdir}/%{name}/share/man -type f -name "*.*" -exec xz -z {} \; +find %{buildroot}%{_optdir}/%{name}/share/man -type l -name "*.*" -exec %{SOURCE1} {} \; +find %{buildroot}%{_optdir}/%{name}/share/man -type l -name "*.*" -exec mv -f {} {}.xz \; +